<!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="/tracing/base/settings.html">
<link rel="import" href="/tracing/ui/base/utils.html">
<link rel="import" href="/tracing/ui/base/ui.html">

<script>
'use strict';

tr.exportTo('tr.ui.b', 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: 'tr.ui_camera'
  };


  var Camera = tr.ui.b.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 =
          tr.ui.b.windowRectForElement(this.canvas_).
              scaleSize(this.pixelRatio_);

      var aspectRatio = rect.width / rect.height;
      var matrix = mat4.create();
      mat4.perspective(
          matrix, tr.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 = tr.b.SessionSettings();
      var keys = settings.keys(constants.SETTINGS_NAMESPACE);
      if (keys.length !== 0) {
        this.loadCameraFromSettings(settings);
        return;
      }

      if (this.deviceRect_) {
        var rect = tr.ui.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 =
          tr.ui.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(tr.b.deg2rad(halfFov)) / rect.height;

      // Get the up and right vectors.
      var up = [0, 1, 0];
      var rotMatrix = mat4.create();
      mat4.rotate(
          rotMatrix, rotMatrix, tr.b.deg2rad(this.rotation_[1]), [0, 1, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, tr.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 = tr.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(tr.b.SessionSettings());
      this.dispatchRenderEvent_();
    },

    updateZoomByDelta: function(delta) {
      var deltaY = delta[1];
      deltaY = tr.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(tr.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, -tr.b.deg2rad(this.rotation_[0]), [1, 0, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, -tr.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, tr.b.deg2rad(this.rotation_[1]), [0, 1, 0]);
      mat4.rotate(
          rotMatrix, rotMatrix, tr.b.deg2rad(this.rotation_[0]), [1, 0, 0]);
      vec4.transformMat4(eyeVector, eyeVector, rotMatrix);

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

      this.saveCameraToSettings(tr.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 = tr.ui.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() {
      tr.b.dispatchSimpleEvent(this, 'renderrequired', false, false);
    }
  };

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