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

var vrShellUi = (function() {
  'use strict';

  /**
   * Enumeration of valid Anchroing for X axis.
   * A mesh can either be anchored to the left, right, or center of the main
   * content rect (or it can be absolutely positioned using NONE). Any
   * translations applied will be relative to this anchoring.
   * @enum {number}
   * @const
   */
  var XAnchoring = Object.freeze({
    'XNONE': 0,
    'XLEFT': 1,
    'XRIGHT': 2
  });

  /**
   * Enumeration of valid Anchroing for Y axis.
   * @enum {number}
   * @const
   */
  var YAnchoring = Object.freeze({
    'YNONE': 0,
    'YTOP': 1,
    'YBOTTOM': 2
  });

  /**
   * Enumeration of animatable properties.
   * @enum {number}
   * @const
   */
  var Property = Object.freeze({
    'COPYRECT': 0,
    'SIZE': 1,
    'TRANSLATION': 2,
    'ORIENTATION': 3,
    'ROTATION': 4
  });

  /**
   * Enumeration of easing type.
   * @enum {number}
   * @const
   */
  var Easing = Object.freeze({
    'LINEAR': 0,
    'CUBICBEZIER': 1,
    'EASEIN': 2,
    'EASEOUT': 3
  });

  /**
   * Enumeration of scene update commands.
   * @enum {number}
   * @const
   */
  var Command = Object.freeze({
    'ADD_ELEMENT': 0,
    'UPDATE_ELEMENT': 1,
    'REMOVE_ELEMENT': 2,
    'ADD_ANIMATION': 3,
    'REMOVE_ANIMATION': 4
  });

  /**
   * @type {number} Id generator.
   */
  var idIndex = 1;

  class UiElement {
    /**
     * Constructor of UiElement.
     * pixelX and pixelY values indicate the left upper corner; pixelWidth and
     * pixelHeight is width and height of the texture to be copied from the web
     * contents. metersX and metersY indicate the size of the rectangle onto
     * which the pixel region will be mapped.
     */
    constructor(pixelX, pixelY, pixelWidth, pixelHeight, metersX, metersY) {
      this.copyRect = {
          x: pixelX,
          y: pixelY,
          width: pixelWidth,
          height: pixelHeight
      };
      this.size = { x: metersX, y: metersY };
      this.xAnchoring = XAnchoring.XNONE;
      this.yAnchoring = YAnchoring.YNONE;
      this.translation = { x: 0, y: 0, z: 0 };
      this.orientationAxisAngle = { x: 0, y: 0, z: 0, a: 0 };
      this.rotationAxisAngle = { x: 0, y: 0, z: 0, a: 0 };
    }

    /**
     * The rotation for the mesh in 3D, applied before translation. The
     * rotation is axis-angle representation (rotated around unit vector [x, y,
     * z] by 'a' radians).
     */
    setRotation(x, y, z, a) {
      this.rotationAxisAngle = { x: x, y: y, z: z, a: a };
    }

    /**
     * The offset for the mesh in 3D.  If anchoring is specified, the offset is
     * applied to the anchoring position rather than the origin.
     */
    setTranslation(x, y, z) {
      this.translation = { x: x, y: y, z: z };
    }

    /**
     * Anchoring allows a rectangle to be positioned relative to the edge of
     * content window.  Values should be XAnchoring and YAnchoring elements.
     * Example: rect.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM);
     */
    setAnchoring(x, y, z) {
      this.xAnchoring = x;
      this.yAnchoring = y;
    }
  };

  class Animation {
    constructor(meshId, durationMs) {
      this.meshId = meshId;
      this.easing = {};
      this.to = {};
      this.easing.type = Easing.LINEAR;

      // How many milliseconds in the future to start the animation.
      this.startInMillis = 0.0;
      // Duration of the animation (milliseconds).
      this.durationMillis = durationMs;
    }

    setRotateTo(x, y, z, a) {
      this.property = Property.ROTATION;
      this.to.x = x;
      this.to.y = y;
      this.to.z = z;
      this.to.a = a;
    }

    setResizeTo(newWidth, newHeight) {
      this.property = Property.SIZE;
      this.to.x = newWidth;
      this.to.y = newHeight;
    }
  };

  function initialize() {
    domLoaded();

    // Change the body background so that the transparency applies.
    window.setTimeout(function() {
      document.body.parentNode.style.backgroundColor = 'rgba(255,255,255,0)';
    }, 100);

    addControlButtons();
  }

  // Build a row of control buttons.
  function addControlButtons() {
    var buttons = [
        // Button text, UI action passed down to native.
        ['<', 'HISTORY_BACK'],
        ['>', 'HISTORY_FORWARD'],
        ['R', 'RELOAD'],
        ['-', 'ZOOM_OUT'],
        ['+', 'ZOOM_IN']
    ];

    var buttonWidth = 0.3;
    var buttonHeight = 0.2;
    var buttonSpacing = 0.5;
    var buttonStartPosition = -buttonSpacing * (buttons.length / 2.0 - 0.5);

    for (var i = 0; i < buttons.length; i++) {
      var b = document.createElement('div');
      b.position = 'absolute';
      b.style.top = '384px';
      b.style.left = 50 * i + 'px';
      b.style.width = '50px';
      b.style.height = '50px';
      b.className = 'ui-button';
      b.textContent = buttons[i][0];

      // Add click behaviour.
      b.addEventListener('click', function(action, e) {
        chrome.send('doAction', [action]);
      }.bind(undefined, buttons[i][1]));

      document.body.appendChild(b);

      // Add a UI rectangle for the button.
      var el = new UiElement(50 * i, 384, 50, 50, buttonWidth, buttonHeight);
      el.parentId = 0;
      el.setAnchoring(XAnchoring.XNONE, YAnchoring.YBOTTOM);
      el.setTranslation(buttonStartPosition + buttonSpacing * i, -0.3, 0.0);
      var id = idIndex++;
      addMesh(id, el);

      // Add transitions when the mouse hovers over (and leaves) the button.
      b.addEventListener('mouseenter', function(buttonId, width, height, e) {
        var resize = new Animation(buttonId, 250);
        resize.id = idIndex++;
        resize.setResizeTo(width, height);
        addAnimations([resize]);
      }.bind(undefined, id, buttonWidth * 1.5, buttonHeight * 1.5));
      b.addEventListener('mouseleave', function(buttonId, width, height) {
        var resize = new Animation(buttonId, 250);
        resize.id = idIndex++;
        resize.setResizeTo(width, height);
        addAnimations([resize]);
      }.bind(undefined, id, buttonWidth, buttonHeight));
    }
  }

  function domLoaded() {
    chrome.send('domLoaded', [window.innerWidth, window.innerHeight]);
  }

  function addMesh(id, mesh) {
    mesh.id = id;
    chrome.send('updateScene', [{
      'type': Command.ADD_ELEMENT,
      'data': mesh
    }]);
  }

  function removeMesh(id) {
    chrome.send('updateScene', [{
      'type': Command.REMOVE_ELEMENT,
      'data': {'id': id}
    }]);
  }

  function addAnimations(animations) {
    var commands = [];
    for (var i = 0; i < animations.length; i++) {
      commands.push({
        'type': Command.ADD_ANIMATION,
        'data': animations[i]
      });
    }
    chrome.send('updateScene', commands);
  }

  return {
    initialize: initialize,
  };
})();

document.addEventListener('DOMContentLoaded', vrShellUi.initialize);
