// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package templates

import "html/template"

var SelectCaveats = template.Must(selectCaveats.Parse(headPartial))

var selectCaveats = template.Must(template.New("bless").Parse(`<!doctype html>
<html>
<head>
  {{template "head" .}}
  <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

  <title>Blessings: Select Caveats</title>
  <script>
  $(document).ready(function() {
    var numCaveats = 1;
    // When a caveat selector changes show the corresponding input box.
    $('body').on('change', '.caveats', function (){
      var caveatSelector = $(this).parents('.caveatRow');

      // Hide the visible inputs and show the selected one.
      caveatSelector.find('.caveatInput').hide();
      var caveatName = $(this).val();
      if (caveatName !== 'RevocationCaveat') {
        caveatSelector.find('#'+caveatName).show();
      }
    });

    var updateNewSelector = function(newSelector, caveatName) {
      // disable the option from being selected again and make the next caveat the
      // default for the next selector.
      var selectedOption = newSelector.find('option[name="' + caveatName + '"]');
      selectedOption.prop('disabled', true);
      var newCaveat = newSelector.find('option:enabled').first();
      newCaveat.prop('selected', true);
      newSelector.find('.caveatInput').hide();
      newSelector.find('#'+newCaveat.attr('name')).show();
    }

    // Upon clicking the 'Add Caveat' button a new caveat selector should appear.
    $('body').on('click', '.addCaveat', function() {
      var selector = $(this).parents('.caveatRow');
      var newSelector = selector.clone();
      var caveatName = selector.find('.caveats').val();

      updateNewSelector(newSelector, caveatName);

      // Change the selector's select to a fixed label and fix the inputs.
      selector.find('.caveats').hide();
      selector.find('.'+caveatName+'Selected').show();
      selector.find('.caveatInput').prop('readonly', true);

      selector.after(newSelector);
      $(this).replaceWith('<button type="button" class="button-passive right removeCaveat hidden">Remove</button>');

      numCaveats += 1;
      if (numCaveats > 1) {
        $('.removeCaveat').show();
      }
      if (numCaveats >= 4) {
        $('.addCaveat').hide();
        $('.caveats').hide();
      }
    });

    // If add more is selected, remove the button and show the caveats selector.
    $('body').on('click', '.addMore', function() {
      var selector = $(this).parents('.caveatRow');
      var newSelector = selector.clone();
      var caveatName = selector.find('.caveats').val();

      updateNewSelector(newSelector, caveatName);

      newSelector.find('.caveats').show();
      // Change the 'Add more' button in the copied selector to an 'Add caveats' button.
      newSelector.find('.addMore').replaceWith('<button type="button" class="button-primary right addCaveat">Add</button>');
      // Hide the default selected caveat for the copied selector.
      newSelector.find('.selected').hide();

      selector.after(newSelector);
      $(this).replaceWith('<button type="button" class="button-passive right removeCaveat hidden">Remove</button>');
    });

    // Upon clicking submit, caveats that have not been added yet should be removed,
    // before they are sent to the server.
    $('#caveats-form').submit(function(){
      $('.addCaveat').parents('.caveatRow').remove();
      return true;
    });

    // Upon clicking the 'Remove Caveat' button, the caveat row should be removed.
    $('body').on('click', '.removeCaveat', function() {
      var selector = $(this).parents('.caveatRow')
      var caveatName = selector.find('.caveats').val();

      // Enable choosing this caveat again.
      $('option[name="' + caveatName + '"]').last().prop('disabled', false);

      selector.remove();

      numCaveats -= 1;
      if (numCaveats == 1) {
        $('.removeCaveat').hide();
      }
      $('.addCaveat').show();
      $('.caveats').last().show();
    });

    // Get the timezoneOffset for the server to create a correct expiry caveat.
    // The offset is the minutes between UTC and local time.
    var d = new Date();
    $('#timezoneOffset').val(d.getTimezoneOffset());

    // Set the datetime picker to have a default value of one day from now.
    $('.expiry').val(moment().add(1, 'd').format('YYYY-MM-DDTHH:mm'));

    // Activate the cancel button.
    $('#cancel').click(window.close);
  });
  </script>
</head>

<body class="default-layout">

<header>
  <nav class="left">
    <a href="#" class="logo">Vanadium</a>
  </nav>
  <nav class="right">
    <a href="#">{{.Extension}}</a>
  </nav>
</header>

<main style="max-width: 80%; margin-left: 10px;">
  <form method="POST" id="caveats-form" name="input" action="{{.MacaroonURL}}" role="form">
  <h1>Add blessing</h1>
  <input type="text" class="hidden" name="macaroon" value="{{.Macaroon}}">

  <h3>Blessing Name</h3>
  <div class="grid">
    <div class="cell">
      <span>{{.BlessingName}}/{{.Extension}}/</span><input name="blessingExtension" type="text" placeholder="extension">
    </div>
    <input type="text" class="hidden" id="timezoneOffset" name="timezoneOffset">
  </div>
  <div>
      The blessing name contains your email and will be visible to any peers that
      this blessing is shared with, e.g. when you make a RPC.
  </div>

  <h4>Caveats</h4>
  <div class="grid caveatRow">
    <div class="cell">
      <span class="selected RevocationCaveatSelected">Active until revoked</span>
      <span class="selected ExpiryCaveatSelected hidden">Expires on</span>
      <span class="selected MethodCaveatSelected hidden">Allowed methods are</span>
      <span class="selected PeerBlessingsCaveatSelected hidden">Allowed peers are</span>

      <select name="caveat" class="caveats hidden">
        <option name="RevocationCaveat" value="RevocationCaveat" class="cavOption">Active until revoked</option>
        <option name="ExpiryCaveat" value="ExpiryCaveat" class="cavOption">Expires on</option>
        <option name="MethodCaveat" value="MethodCaveat" class="cavOption">Allowed methods are</option>
        <option name="PeerBlessingsCaveat" value="PeerBlessingsCaveat" class="cavOption">Allowed peers are</option>
      </select>

      <input type="text" class="caveatInput hidden" id="RevocationCaveat" name="RevocationCaveat">
      <input type="datetime-local" class="caveatInput expiry hidden" id="ExpiryCaveat" name="ExpiryCaveat">
      <input type="text" id="MethodCaveat" class="caveatInput hidden" name="MethodCaveat" placeholder="comma-separated method list">
      <input type="text" id="PeerBlessingsCaveat" class="caveatInput hidden" name="PeerBlessingsCaveat" placeholder="comma-separated blessing list">

      <a href="#" class="right addMore">Add more</a>
    </div>
  </div>
  </br>
  <div class="grid">
    <button class="cell button-passive" id="cancel">Cancel</button>
    <button class="cell button-primary" type="submit">Bless</button>
    <div class="cell"></div>
    <div class="cell"></div>
  </div>
  <div>
  By clicking "Bless", you consent to be bound by
  Google's general <a href="https://www.google.com/intl/en/policies/terms/">Terms of Service</a>,
  the <a href="https://developers.google.com/terms/">Google APIs Terms of Service</a>,
  and Google's general <a href="https://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>.
  </div>
  </form>
</main>

</body>
</html>`))
