<!DOCTYPE html>
<!--
Copyright (c) 2014 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.
-->
<link rel="import" href="/base/ui.html">
<link rel="import" href="/base/settings.html">
<script>
'use strict';

tv.exportTo('tv.b.ui', function() {

  var constants = {
    DEFAULT_SCALE: 0.5,
    DEFAULT_EYE_DISTANCE: 10000,
    MINIMUM_DISTANCE: 1000,
    MAXIMUM_DISTANCE: 100000,
    FOV: 15,
    RESCALE_TIMEOUT_MS: 200,
    MAXIMUM_TILT: 80,
    SETTINGS_NAMESPACE: 'tv.ui_camera'
  };


  var Camera = tv.b.ui.define('camera');

  Camera.prototype = {
    __proto__: HTMLUnknownElement.prototype,

    decorate: function(eventSource) {
      this.eventSource_ = eventSource;

      this.eventSource_.addEventListener('beginpan',
          this.onPanBegin_.bind(this));
      this.eventSource_.addEventListener('updatepan',
          this.onPanUpdate_.bind(this));
      this.eventSource_.addEventListener('endpan',
          this.onPanEnd_.bind(this));

      this.eventSource_.addEventListener('beginzoom',
          this.onZoomBegin_.bind(this));
      this.eventSource_.addEventListener('updatezoom',
          this.onZoomUpdate_.bind(this));
      this.eventSource_.addEventListener('endzoom',
          this.onZoomEnd_.bind(this));

      this.eventSource_.addEventListener('beginrotate',
          this.onRotateBegin_.bind(this));
      this.eventSource_.addEventListener('updaterotate',
          this.onRotateUpdate_.bind(this));
      this.eventSource_.addEventListener('endrotate',
          this.onRotateEnd_.bind(this));

      this.eye_ = [0, 0, constants.DEFAULT_EYE_DISTANCE];
      this.gazeTarget_ = [0, 0, 0];
      this.rotation_ = [0, 0];

      this.pixelRatio_ = window.devicePixelRatio || 1;
    },


    get modelViewMatrix() {
      var mvMatrix = mat4.create();

      mat4.lookAt(mvMatrix, this.eye_, this.gazeTarget_, [0, 1, 0]);
      return mvMatrix;
    },

    get projectionMatrix() {
      var rect =
          tv.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);

      var aspectRatio = rect.width / rect.height;
      var matrix = mat4.create();
      mat4.perspective(
          matrix, tv.b.deg2rad(constants.FOV), aspectRatio, 1, 100000);

      return matrix;
    },

    set canvas(c) {
      this.canvas_ = c;
    },

    set deviceRect(rect) {
      this.deviceRect_ = rect;
    },

    get stackingDistanceDampening() {
      var gazeVector = [
        this.gazeTarget_[0] - this.eye_[0],
        this.gazeTarget_[1] - this.eye_[1],
        this.gazeTarget_[2] - this.eye_[2]];
      vec3.normalize(gazeVector, gazeVector);
      return 1 + gazeVector[2];
    },

    loadCameraFromSettings: function(settings) {
      this.eye_ = settings.get(
          'eye', this.eye_, constants.SETTINGS_NAMESPACE);
      this.gazeTarget_ = settings.get(
          'gaze_target', this.gazeTarget_, constants.SETTINGS_NAMESPACE);
      this.rotation_ = settings.get(
          'rotation', this.rotation_, constants.SETTINGS_NAMESPACE);

      this.dispatchRenderEvent_();
    },

    saveCameraToSettings: function(settings) {
      settings.set(
          'eye', this.eye_, constants.SETTINGS_NAMESPACE);
      settings.set(
          'gaze_target', this.gazeTarget_, constants.SETTINGS_NAMESPACE);
      settings.set(
          'rotation', this.rotation_, constants.SETTINGS_NAMESPACE);
    },

    resetCamera: function() {
      this.eye_ = [0, 0, constants.DEFAULT_EYE_DISTANCE];
      this.gazeTarget_ = [0, 0, 0];
      this.rotation_ = [0, 0];

      var settings = tv.b.SessionSettings();
      var keys = settings.keys(constants.SETTINGS_NAMESPACE);
      if (keys.length !== 0) {
        this.loadCameraFromSettings(settings);
        return;
      }

      if (this.deviceRect_) {
        var rect =
            tv.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);

        this.eye_[0] = this.deviceRect_.width / 2;
        this.eye_[1] = this.deviceRect_.height / 2;

        this.gazeTarget_[0] = this.deviceRect_.width / 2;
        this.gazeTarget_[1] = this.deviceRect_.height / 2;
      }

      this.saveCameraToSettings(settings);
      this.dispatchRenderEvent_();
    },

    updatePanByDelta: function(delta) {
      var rect =
          tv.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);

      // Get the eye vector, since we'll be adjusting gazeTarget.
      var eyeVector = [
        this.eye_[0] - this.gazeTarget_[0],
        this.eye_[1] - this.gazeTarget_[1],
        this.eye_[2] - this.gazeTarget_[2]];
      var length = vec3.length(eyeVector);
      vec3.normalize(eyeVector, eyeVector);

      var halfFov = constants.FOV / 2;
      var multiplier =
          2.0 * length * Math.tan(tv.b.deg2rad(halfFov)) / rect.height;

      // Get the up and right vectors.
      var up = [0, 1, 0];
      var rotMatrix = mat4.create();
      mat4.rotate(
          rotMatrix, rotMatrix, tv.b.deg2rad(this.rotation_[1]), [0, 1, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, tv.b.deg2rad(this.rotation_[0]), [1, 0, 0]);
      vec3.transformMat4(up, up, rotMatrix);

      var right = [0, 0, 0];
      vec3.cross(right, eyeVector, up);
      vec3.normalize(right, right);

      // Update the gaze target.
      for (var i = 0; i < 3; ++i) {
        this.gazeTarget_[i] +=
            delta[0] * multiplier * right[i] - delta[1] * multiplier * up[i];

        this.eye_[i] = this.gazeTarget_[i] + length * eyeVector[i];
      }

      // If we have some z offset, we need to reposition gazeTarget
      // to be on the plane z = 0 with normal [0, 0, 1].
      if (Math.abs(this.gazeTarget_[2]) > 1e-6) {
        var gazeVector = [-eyeVector[0], -eyeVector[1], -eyeVector[2]];
        var newLength = tv.b.clamp(
            -this.eye_[2] / gazeVector[2],
            constants.MINIMUM_DISTANCE,
            constants.MAXIMUM_DISTANCE);

        for (var i = 0; i < 3; ++i)
          this.gazeTarget_[i] = this.eye_[i] + newLength * gazeVector[i];
      }

      this.saveCameraToSettings(tv.b.SessionSettings());
      this.dispatchRenderEvent_();
    },

    updateZoomByDelta: function(delta) {
      var deltaY = delta[1];
      deltaY = tv.b.clamp(deltaY, -50, 50);
      var scale = 1.0 - deltaY / 100.0;

      var eyeVector = [0, 0, 0];
      vec3.subtract(eyeVector, this.eye_, this.gazeTarget_);

      var length = vec3.length(eyeVector);

      // Clamp the length to allowed values by changing the scale.
      if (length * scale < constants.MINIMUM_DISTANCE)
        scale = constants.MINIMUM_DISTANCE / length;
      else if (length * scale > constants.MAXIMUM_DISTANCE)
        scale = constants.MAXIMUM_DISTANCE / length;

      vec3.scale(eyeVector, eyeVector, scale);
      vec3.add(this.eye_, this.gazeTarget_, eyeVector);

      this.saveCameraToSettings(tv.b.SessionSettings());
      this.dispatchRenderEvent_();
    },

    updateRotateByDelta: function(delta) {
      delta[0] *= 0.5;
      delta[1] *= 0.5;

      if (Math.abs(this.rotation_[0] + delta[1]) > constants.MAXIMUM_TILT)
        return;
      if (Math.abs(this.rotation_[1] - delta[0]) > constants.MAXIMUM_TILT)
        return;

      var eyeVector = [0, 0, 0, 0];
      vec3.subtract(eyeVector, this.eye_, this.gazeTarget_);

      // Undo the current rotation.
      var rotMatrix = mat4.create();
      mat4.rotate(
          rotMatrix, rotMatrix, -tv.b.deg2rad(this.rotation_[0]), [1, 0, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, -tv.b.deg2rad(this.rotation_[1]), [0, 1, 0]);
      vec4.transformMat4(eyeVector, eyeVector, rotMatrix);

      // Update rotation values.
      this.rotation_[0] += delta[1];
      this.rotation_[1] -= delta[0];

      // Redo the new rotation.
      mat4.identity(rotMatrix);
      mat4.rotate(
          rotMatrix, rotMatrix, tv.b.deg2rad(this.rotation_[1]), [0, 1, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, tv.b.deg2rad(this.rotation_[0]), [1, 0, 0]);
      vec4.transformMat4(eyeVector, eyeVector, rotMatrix);

      vec3.add(this.eye_, this.gazeTarget_, eyeVector);

      this.saveCameraToSettings(tv.b.SessionSettings());
      this.dispatchRenderEvent_();
    },


    // Event callbacks.
    onPanBegin_: function(e) {
      this.panning_ = true;
      this.lastMousePosition_ = this.getMousePosition_(e);
    },

    onPanUpdate_: function(e) {
      if (!this.panning_)
        return;

      var delta = this.getMouseDelta_(e, this.lastMousePosition_);
      this.lastMousePosition_ = this.getMousePosition_(e);
      this.updatePanByDelta(delta);
    },

    onPanEnd_: function(e) {
      this.panning_ = false;
    },

    onZoomBegin_: function(e) {
      this.zooming_ = true;

      var p = this.getMousePosition_(e);

      this.lastMousePosition_ = p;
      this.zoomPoint_ = p;
    },

    onZoomUpdate_: function(e) {
      if (!this.zooming_)
        return;

      var delta = this.getMouseDelta_(e, this.lastMousePosition_);
      this.lastMousePosition_ = this.getMousePosition_(e);
      this.updateZoomByDelta(delta);
    },

    onZoomEnd_: function(e) {
      this.zooming_ = false;
      this.zoomPoint_ = undefined;
    },

    onRotateBegin_: function(e) {
      this.rotating_ = true;
      this.lastMousePosition_ = this.getMousePosition_(e);
    },

    onRotateUpdate_: function(e) {
      if (!this.rotating_)
        return;

      var delta = this.getMouseDelta_(e, this.lastMousePosition_);
      this.lastMousePosition_ = this.getMousePosition_(e);
      this.updateRotateByDelta(delta);
    },

    onRotateEnd_: function(e) {
      this.rotating_ = false;
    },


    // Misc helper functions.
    getMousePosition_: function(e) {
      var rect = tv.b.windowRectForElement(this.canvas_);
      return [(e.clientX - rect.x) * this.pixelRatio_,
              (e.clientY - rect.y) * this.pixelRatio_];
    },

    getMouseDelta_: function(e, p) {
      var newP = this.getMousePosition_(e);
      return [newP[0] - p[0], newP[1] - p[1]];
    },

    dispatchRenderEvent_: function() {
      tv.b.dispatchSimpleEvent(this, 'renderrequired', false, false);
    }
  };

  return {
    Camera: Camera
  };
});
</script>
