<!DOCTYPE html>
<!--
Copyright (c) 2013 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/bbox2.html">
<link rel="import" href="/base/math.html">
<link rel="import" href="/base/quad.html">
<link rel="import" href="/base/raf.html">
<link rel="import" href="/base/rect.html">
<link rel="import" href="/base/settings.html">
<link rel="import" href="/ui/base/camera.html">
<link rel="import" href="/ui/base/mouse_mode_selector.html">
<link rel="import" href="/ui/base/mouse_tracker.html">
<link rel="import" href="/ui/base/utils.html">

<style>
* /deep/ quad-stack-view {
  display: block;
  float: left;
  height: 100%;
  overflow: hidden;
  position: relative; /* For the absolute positioned mouse-mode-selector */
  width: 100%;
}

* /deep/ quad-stack-view > #header {
  position: absolute;
  font-size: 70%;
  top: 10px;
  left: 10px;
  width: 800px;
}
* /deep/ quad-stack-view > #stacking-distance-slider {
  position: absolute;
  font-size: 70%;
  top: 10px;
  right: 10px;
}

* /deep/ quad-stack-view > #chrome-left {
  content: url('../images/chrome-left.png');
  display: none;
}

* /deep/ quad-stack-view > #chrome-mid {
  content: url('../images/chrome-mid.png');
  display: none;
}

* /deep/ quad-stack-view > #chrome-right {
  content: url('../images/chrome-right.png');
  display: none;
}
</style>

<template id='quad-stack-view-template'>
  <div id="header"></div>
  <input id="stacking-distance-slider" type="range" min=1 max=400 step=1>
  </input>
  <canvas id='canvas'></canvas>
  <img id='chrome-left'/>
  <img id='chrome-mid'/>
  <img id='chrome-right'/>
</template>

<script>
'use strict';

/**
 * @fileoverview QuadStackView controls the content and viewing angle a
 * QuadStack.
 */
tr.exportTo('tr.ui.b', function() {
  var THIS_DOC = document.currentScript.ownerDocument;

  var constants = {};
  constants.IMAGE_LOAD_RETRY_TIME_MS = 500;
  constants.SUBDIVISION_MINIMUM = 1;
  constants.SUBDIVISION_RECURSION_DEPTH = 3;
  constants.SUBDIVISION_DEPTH_THRESHOLD = 100;
  constants.FAR_PLANE_DISTANCE = 10000;

  // Care of bckenney@ via
  // http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
  function drawTexturedTriangle(ctx, img, p0, p1, p2, t0, t1, t2) {
    var tmp_p0 = [p0[0], p0[1]];
    var tmp_p1 = [p1[0], p1[1]];
    var tmp_p2 = [p2[0], p2[1]];
    var tmp_t0 = [t0[0], t0[1]];
    var tmp_t1 = [t1[0], t1[1]];
    var tmp_t2 = [t2[0], t2[1]];

    ctx.beginPath();
    ctx.moveTo(tmp_p0[0], tmp_p0[1]);
    ctx.lineTo(tmp_p1[0], tmp_p1[1]);
    ctx.lineTo(tmp_p2[0], tmp_p2[1]);
    ctx.closePath();

    tmp_p1[0] -= tmp_p0[0];
    tmp_p1[1] -= tmp_p0[1];
    tmp_p2[0] -= tmp_p0[0];
    tmp_p2[1] -= tmp_p0[1];

    tmp_t1[0] -= tmp_t0[0];
    tmp_t1[1] -= tmp_t0[1];
    tmp_t2[0] -= tmp_t0[0];
    tmp_t2[1] -= tmp_t0[1];

    var det = 1 / (tmp_t1[0] * tmp_t2[1] - tmp_t2[0] * tmp_t1[1]),

        // linear transformation
        a = (tmp_t2[1] * tmp_p1[0] - tmp_t1[1] * tmp_p2[0]) * det,
        b = (tmp_t2[1] * tmp_p1[1] - tmp_t1[1] * tmp_p2[1]) * det,
        c = (tmp_t1[0] * tmp_p2[0] - tmp_t2[0] * tmp_p1[0]) * det,
        d = (tmp_t1[0] * tmp_p2[1] - tmp_t2[0] * tmp_p1[1]) * det,

        // translation
        e = tmp_p0[0] - a * tmp_t0[0] - c * tmp_t0[1],
        f = tmp_p0[1] - b * tmp_t0[0] - d * tmp_t0[1];

    ctx.save();
    ctx.transform(a, b, c, d, e, f);
    ctx.clip();
    ctx.drawImage(img, 0, 0);
    ctx.restore();
  }

  function drawTriangleSub(
      ctx, img, p0, p1, p2, t0, t1, t2, opt_recursion_depth) {
    var depth = opt_recursion_depth || 0;

    // We may subdivide if we are not at the limit of recursion.
    var subdivisionIndex = 0;
    if (depth < constants.SUBDIVISION_MINIMUM) {
      subdivisionIndex = 7;
    } else if (depth < constants.SUBDIVISION_RECURSION_DEPTH) {
      if (Math.abs(p0[2] - p1[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
        subdivisionIndex += 1;
      if (Math.abs(p0[2] - p2[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
        subdivisionIndex += 2;
      if (Math.abs(p1[2] - p2[2]) > constants.SUBDIVISION_DEPTH_THRESHOLD)
        subdivisionIndex += 4;
    }

    // These need to be created every time, since temporaries
    // outside of the scope will be rewritten in recursion.
    var p01 = vec4.create();
    var p02 = vec4.create();
    var p12 = vec4.create();
    var t01 = vec2.create();
    var t02 = vec2.create();
    var t12 = vec2.create();

    // Calculate the position before w-divide.
    for (var i = 0; i < 2; ++i) {
      p0[i] *= p0[2];
      p1[i] *= p1[2];
      p2[i] *= p2[2];
    }

    // Interpolate the 3d position.
    for (var i = 0; i < 4; ++i) {
      p01[i] = (p0[i] + p1[i]) / 2;
      p02[i] = (p0[i] + p2[i]) / 2;
      p12[i] = (p1[i] + p2[i]) / 2;
    }

    // Re-apply w-divide to the original points and the interpolated ones.
    for (var i = 0; i < 2; ++i) {
      p0[i] /= p0[2];
      p1[i] /= p1[2];
      p2[i] /= p2[2];

      p01[i] /= p01[2];
      p02[i] /= p02[2];
      p12[i] /= p12[2];
    }

    // Interpolate the texture coordinates.
    for (var i = 0; i < 2; ++i) {
      t01[i] = (t0[i] + t1[i]) / 2;
      t02[i] = (t0[i] + t2[i]) / 2;
      t12[i] = (t1[i] + t2[i]) / 2;
    }

    // Based on the index, we subdivide the triangle differently.
    // Assuming the triangle is p0, p1, p2 and points between i j
    // are represented as pij (that is, a point between p2 and p0
    // is p02, etc), then the new triangles are defined by
    // the 3rd 4th and 5th arguments into the function.
    switch (subdivisionIndex) {
      case 1:
        drawTriangleSub(ctx, img, p0, p01, p2, t0, t01, t2, depth + 1);
        drawTriangleSub(ctx, img, p01, p1, p2, t01, t1, t2, depth + 1);
        break;
      case 2:
        drawTriangleSub(ctx, img, p0, p1, p02, t0, t1, t02, depth + 1);
        drawTriangleSub(ctx, img, p1, p02, p2, t1, t02, t2, depth + 1);
        break;
      case 3:
        drawTriangleSub(ctx, img, p0, p01, p02, t0, t01, t02, depth + 1);
        drawTriangleSub(ctx, img, p02, p01, p2, t02, t01, t2, depth + 1);
        drawTriangleSub(ctx, img, p01, p1, p2, t01, t1, t2, depth + 1);
        break;
      case 4:
        drawTriangleSub(ctx, img, p0, p12, p2, t0, t12, t2, depth + 1);
        drawTriangleSub(ctx, img, p0, p1, p12, t0, t1, t12, depth + 1);
        break;
      case 5:
        drawTriangleSub(ctx, img, p0, p01, p2, t0, t01, t2, depth + 1);
        drawTriangleSub(ctx, img, p2, p01, p12, t2, t01, t12, depth + 1);
        drawTriangleSub(ctx, img, p01, p1, p12, t01, t1, t12, depth + 1);
        break;
      case 6:
        drawTriangleSub(ctx, img, p0, p12, p02, t0, t12, t02, depth + 1);
        drawTriangleSub(ctx, img, p0, p1, p12, t0, t1, t12, depth + 1);
        drawTriangleSub(ctx, img, p02, p12, p2, t02, t12, t2, depth + 1);
        break;
      case 7:
        drawTriangleSub(ctx, img, p0, p01, p02, t0, t01, t02, depth + 1);
        drawTriangleSub(ctx, img, p01, p12, p02, t01, t12, t02, depth + 1);
        drawTriangleSub(ctx, img, p01, p1, p12, t01, t1, t12, depth + 1);
        drawTriangleSub(ctx, img, p02, p12, p2, t02, t12, t2, depth + 1);
        break;
      default:
        // In the 0 case and all other cases, we simply draw the triangle.
        drawTexturedTriangle(ctx, img, p0, p1, p2, t0, t1, t2);
        break;
    }
  }

  // Created to avoid creating garbage when doing bulk transforms.
  var tmp_vec4 = vec4.create();
  function transform(transformed, point, matrix, viewport) {
    vec4.set(tmp_vec4, point[0], point[1], 0, 1);
    vec4.transformMat4(tmp_vec4, tmp_vec4, matrix);

    var w = tmp_vec4[3];
    if (w < 1e-6) w = 1e-6;

    transformed[0] = ((tmp_vec4[0] / w) + 1) * viewport.width / 2;
    transformed[1] = ((tmp_vec4[1] / w) + 1) * viewport.height / 2;
    transformed[2] = w;
  }

  function drawProjectedQuadBackgroundToContext(
      quad, p1, p2, p3, p4, ctx, quadCanvas) {
    if (quad.imageData) {
      quadCanvas.width = quad.imageData.width;
      quadCanvas.height = quad.imageData.height;
      quadCanvas.getContext('2d').putImageData(quad.imageData, 0, 0);
      var quadBBox = new tr.b.BBox2();
      quadBBox.addQuad(quad);
      var iw = quadCanvas.width;
      var ih = quadCanvas.height;
      drawTriangleSub(
          ctx, quadCanvas,
          p1, p2, p4,
          [0, 0], [iw, 0], [0, ih]);
      drawTriangleSub(
          ctx, quadCanvas,
          p2, p3, p4,
          [iw, 0], [iw, ih], [0, ih]);
    }

    if (quad.backgroundColor) {
      ctx.fillStyle = quad.backgroundColor;
      ctx.beginPath();
      ctx.moveTo(p1[0], p1[1]);
      ctx.lineTo(p2[0], p2[1]);
      ctx.lineTo(p3[0], p3[1]);
      ctx.lineTo(p4[0], p4[1]);
      ctx.closePath();
      ctx.fill();
    }
  }

  function drawProjectedQuadOutlineToContext(
      quad, p1, p2, p3, p4, ctx, quadCanvas) {
    ctx.beginPath();
    ctx.moveTo(p1[0], p1[1]);
    ctx.lineTo(p2[0], p2[1]);
    ctx.lineTo(p3[0], p3[1]);
    ctx.lineTo(p4[0], p4[1]);
    ctx.closePath();
    ctx.save();
    if (quad.borderColor)
      ctx.strokeStyle = quad.borderColor;
    else
      ctx.strokeStyle = 'rgb(128,128,128)';

    if (quad.shadowOffset) {
      ctx.shadowColor = 'rgb(0, 0, 0)';
      ctx.shadowOffsetX = quad.shadowOffset[0];
      ctx.shadowOffsetY = quad.shadowOffset[1];
      if (quad.shadowBlur)
        ctx.shadowBlur = quad.shadowBlur;
    }

    if (quad.borderWidth)
      ctx.lineWidth = quad.borderWidth;
    else
      ctx.lineWidth = 1;

    ctx.stroke();
    ctx.restore();
  }

  function drawProjectedQuadSelectionOutlineToContext(
      quad, p1, p2, p3, p4, ctx, quadCanvas) {
    if (!quad.upperBorderColor)
      return;

    ctx.lineWidth = 8;
    ctx.strokeStyle = quad.upperBorderColor;

    ctx.beginPath();
    ctx.moveTo(p1[0], p1[1]);
    ctx.lineTo(p2[0], p2[1]);
    ctx.lineTo(p3[0], p3[1]);
    ctx.lineTo(p4[0], p4[1]);
    ctx.closePath();
    ctx.stroke();
  }

  function drawProjectedQuadToContext(
      passNumber, quad, p1, p2, p3, p4, ctx, quadCanvas) {
    if (passNumber === 0) {
      drawProjectedQuadBackgroundToContext(
          quad, p1, p2, p3, p4, ctx, quadCanvas);
    } else if (passNumber === 1) {
      drawProjectedQuadOutlineToContext(
          quad, p1, p2, p3, p4, ctx, quadCanvas);
    } else if (passNumber === 2) {
      drawProjectedQuadSelectionOutlineToContext(
          quad, p1, p2, p3, p4, ctx, quadCanvas);
    } else {
      throw new Error('Invalid pass number');
    }
  }

  var tmp_p1 = vec3.create();
  var tmp_p2 = vec3.create();
  var tmp_p3 = vec3.create();
  var tmp_p4 = vec3.create();
  function transformAndProcessQuads(
      matrix, viewport, quads, numPasses, handleQuadFunc, opt_arg1, opt_arg2) {

    for (var passNumber = 0; passNumber < numPasses; passNumber++) {
      for (var i = 0; i < quads.length; i++) {
        var quad = quads[i];
        transform(tmp_p1, quad.p1, matrix, viewport);
        transform(tmp_p2, quad.p2, matrix, viewport);
        transform(tmp_p3, quad.p3, matrix, viewport);
        transform(tmp_p4, quad.p4, matrix, viewport);
        handleQuadFunc(passNumber, quad,
                       tmp_p1, tmp_p2, tmp_p3, tmp_p4,
                       opt_arg1, opt_arg2);
      }
    }
  }

  /**
   * @constructor
   */
  var QuadStackView = tr.ui.b.define('quad-stack-view');

  QuadStackView.prototype = {
    __proto__: HTMLUnknownElement.prototype,

    decorate: function() {
      this.className = 'quad-stack-view';

      var node = tr.ui.b.instantiateTemplate('#quad-stack-view-template',
                                          THIS_DOC);
      this.appendChild(node);
      this.updateHeaderVisibility_();
      this.canvas_ = this.querySelector('#canvas');
      this.chromeImages_ = {
        left: this.querySelector('#chrome-left'),
        mid: this.querySelector('#chrome-mid'),
        right: this.querySelector('#chrome-right')
      };

      var stackingDistanceSlider = this.querySelector(
          '#stacking-distance-slider');
      stackingDistanceSlider.value = tr.b.Settings.get(
          'quadStackView.stackingDistance', 45);
      stackingDistanceSlider.addEventListener(
          'change', this.onStackingDistanceChange_.bind(this));
      stackingDistanceSlider.addEventListener(
          'input', this.onStackingDistanceChange_.bind(this));

      this.trackMouse_();

      this.camera_ = new tr.ui.b.Camera(this.mouseModeSelector_);
      this.camera_.addEventListener('renderrequired',
          this.onRenderRequired_.bind(this));
      this.cameraWasReset_ = false;
      this.camera_.canvas = this.canvas_;

      this.viewportRect_ = tr.b.Rect.fromXYWH(0, 0, 0, 0);

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

    updateHeaderVisibility_: function() {
      if (this.headerText)
        this.querySelector('#header').style.display = '';
      else
        this.querySelector('#header').style.display = 'none';
    },

    get headerText() {
      return this.querySelector('#header').textContent;
    },

    set headerText(headerText) {
      this.querySelector('#header').textContent = headerText;
      this.updateHeaderVisibility_();
    },

    onStackingDistanceChange_: function(e) {
      tr.b.Settings.set('quadStackView.stackingDistance',
                        this.stackingDistance);
      this.scheduleRender();
      e.stopPropagation();
    },

    get stackingDistance() {
      return this.querySelector('#stacking-distance-slider').value;
    },

    get mouseModeSelector() {
      return this.mouseModeSelector_;
    },

    get camera() {
      return this.camera_;
    },

    set quads(q) {
      this.quads_ = q;
      this.scheduleRender();
    },

    set deviceRect(rect) {
      if (!rect || rect.equalTo(this.deviceRect_))
        return;

      this.deviceRect_ = rect;
      this.camera_.deviceRect = rect;
      this.chromeQuad_ = undefined;
    },

    resize: function() {
      if (!this.offsetParent)
        return true;

      var width = parseInt(window.getComputedStyle(this.offsetParent).width);
      var height = parseInt(window.getComputedStyle(this.offsetParent).height);
      var rect = tr.b.Rect.fromXYWH(0, 0, width, height);

      if (rect.equalTo(this.viewportRect_))
        return false;

      this.viewportRect_ = rect;
      this.style.width = width + 'px';
      this.style.height = height + 'px';
      this.canvas_.style.width = width + 'px';
      this.canvas_.style.height = height + 'px';
      this.canvas_.width = this.pixelRatio_ * width;
      this.canvas_.height = this.pixelRatio_ * height;
      if (!this.cameraWasReset_) {
        this.camera_.resetCamera();
        this.cameraWasReset_ = true;
      }
      return true;
    },

    readyToDraw: function() {
      // If src isn't set yet, set it to ensure we can use
      // the image to draw onto a canvas.
      if (!this.chromeImages_.left.src) {
        var leftContent =
            window.getComputedStyle(this.chromeImages_.left).content;
        leftContent = leftContent.replace(/url\((.*)\)/, '$1');

        var midContent =
            window.getComputedStyle(this.chromeImages_.mid).content;
        midContent = midContent.replace(/url\((.*)\)/, '$1');

        var rightContent =
            window.getComputedStyle(this.chromeImages_.right).content;
        rightContent = rightContent.replace(/url\((.*)\)/, '$1');

        this.chromeImages_.left.src = leftContent;
        this.chromeImages_.mid.src = midContent;
        this.chromeImages_.right.src = rightContent;
      }

      // If all of the images are loaded (height > 0), then
      // we are ready to draw.
      return (this.chromeImages_.left.height > 0) &&
             (this.chromeImages_.mid.height > 0) &&
             (this.chromeImages_.right.height > 0);
    },

    get chromeQuad() {
      if (this.chromeQuad_)
        return this.chromeQuad_;

      // Draw the chrome border into a separate canvas.
      var chromeCanvas = document.createElement('canvas');
      var offsetY = this.chromeImages_.left.height;

      chromeCanvas.width = this.deviceRect_.width;
      chromeCanvas.height = this.deviceRect_.height + offsetY;

      var leftWidth = this.chromeImages_.left.width;
      var midWidth = this.chromeImages_.mid.width;
      var rightWidth = this.chromeImages_.right.width;

      var chromeCtx = chromeCanvas.getContext('2d');
      chromeCtx.drawImage(this.chromeImages_.left, 0, 0);

      chromeCtx.save();
      chromeCtx.translate(leftWidth, 0);

      // Calculate the scale of the mid image.
      var s = (this.deviceRect_.width - leftWidth - rightWidth) / midWidth;
      chromeCtx.scale(s, 1);

      chromeCtx.drawImage(this.chromeImages_.mid, 0, 0);
      chromeCtx.restore();

      chromeCtx.drawImage(
          this.chromeImages_.right, leftWidth + s * midWidth, 0);

      // Construct the quad.
      var chromeRect = tr.b.Rect.fromXYWH(
          this.deviceRect_.x,
          this.deviceRect_.y - offsetY,
          this.deviceRect_.width,
          this.deviceRect_.height + offsetY);
      var chromeQuad = tr.b.Quad.fromRect(chromeRect);
      chromeQuad.stackingGroupId = this.maxStackingGroupId_ + 1;
      chromeQuad.imageData = chromeCtx.getImageData(
          0, 0, chromeCanvas.width, chromeCanvas.height);
      chromeQuad.shadowOffset = [0, 0];
      chromeQuad.shadowBlur = 5;
      chromeQuad.borderWidth = 3;
      this.chromeQuad_ = chromeQuad;
      return this.chromeQuad_;
    },

    scheduleRender: function() {
      if (this.redrawScheduled_)
        return false;
      this.redrawScheduled_ = true;
      tr.b.requestAnimationFrame(this.render, this);
    },

    onRenderRequired_: function(e) {
      this.scheduleRender();
    },

    stackTransformAndProcessQuads_: function(
        numPasses, handleQuadFunc, includeChromeQuad, opt_arg1, opt_arg2) {
      var mv = this.camera_.modelViewMatrix;
      var p = this.camera_.projectionMatrix;

      var viewport = tr.b.Rect.fromXYWH(
          0, 0, this.canvas_.width, this.canvas_.height);

      // Calculate the quad stacks.
      var quadStacks = [];
      for (var i = 0; i < this.quads_.length; ++i) {
        var quad = this.quads_[i];
        var stackingId = quad.stackingGroupId || 0;
        while (stackingId >= quadStacks.length)
          quadStacks.push([]);

        quadStacks[stackingId].push(quad);
      }

      var mvp = mat4.create();
      this.maxStackingGroupId_ = quadStacks.length;
      var effectiveStackingDistance =
          this.stackingDistance * this.camera_.stackingDistanceDampening;

      // Draw the quad stacks, raising each subsequent level.
      mat4.multiply(mvp, p, mv);
      for (var i = 0; i < quadStacks.length; ++i) {
        transformAndProcessQuads(mvp, viewport, quadStacks[i],
                                 numPasses, handleQuadFunc,
                                 opt_arg1, opt_arg2);

        mat4.translate(mv, mv, [0, 0, effectiveStackingDistance]);
        mat4.multiply(mvp, p, mv);
      }

      if (includeChromeQuad && this.deviceRect_) {
        transformAndProcessQuads(mvp, viewport, [this.chromeQuad],
                                 numPasses, drawProjectedQuadToContext,
                                 opt_arg1, opt_arg2);
      }
    },

    render: function() {
      this.redrawScheduled_ = false;

      if (!this.readyToDraw()) {
        setTimeout(this.scheduleRender.bind(this),
                   constants.IMAGE_LOAD_RETRY_TIME_MS);
        return;
      }

      if (!this.quads_)
        return;

      var canvasCtx = this.canvas_.getContext('2d');
      if (!this.resize())
        canvasCtx.clearRect(0, 0, this.canvas_.width, this.canvas_.height);

      var quadCanvas = document.createElement('canvas');
      this.stackTransformAndProcessQuads_(
          3, drawProjectedQuadToContext, true,
          canvasCtx, quadCanvas);
      quadCanvas.width = 0; // Hack: Frees the quadCanvas' resources.
    },

    trackMouse_: function() {
      this.mouseModeSelector_ = document.createElement(
          'tr-ui-b-mouse-mode-selector');
      this.mouseModeSelector_.targetElement = this.canvas_;
      this.mouseModeSelector_.supportedModeMask =
          tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION |
          tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN |
          tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM |
          tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;
      this.mouseModeSelector_.mode = tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;
      this.mouseModeSelector_.pos = {x: 0, y: 100};
      this.appendChild(this.mouseModeSelector_);
      this.mouseModeSelector_.settingsKey =
          'quadStackView.mouseModeSelector';

      this.mouseModeSelector_.setModifierForAlternateMode(
          tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE, tr.ui.b.MODIFIER.SHIFT);
      this.mouseModeSelector_.setModifierForAlternateMode(
          tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN, tr.ui.b.MODIFIER.SPACE);
      this.mouseModeSelector_.setModifierForAlternateMode(
          tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM, tr.ui.b.MODIFIER.CMD_OR_CTRL);

      this.mouseModeSelector_.addEventListener('updateselection',
          this.onSelectionUpdate_.bind(this));
      this.mouseModeSelector_.addEventListener('endselection',
          this.onSelectionUpdate_.bind(this));
    },

    extractRelativeMousePosition_: function(e) {
      var br = this.canvas_.getBoundingClientRect();
      return [
        this.pixelRatio_ * (e.clientX - this.canvas_.offsetLeft - br.left),
        this.pixelRatio_ * (e.clientY - this.canvas_.offsetTop - br.top)
      ];
    },

    onSelectionUpdate_: function(e) {
      var mousePos = this.extractRelativeMousePosition_(e);
      var res = [];
      function handleQuad(passNumber, quad, p1, p2, p3, p4) {
        if (tr.b.pointInImplicitQuad(mousePos, p1, p2, p3, p4))
          res.push(quad);
      }
      this.stackTransformAndProcessQuads_(1, handleQuad, false);
      var e = new tr.b.Event('selectionchange');
      e.quads = res;
      this.dispatchEvent(e);
    }
  };

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