<!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/base.html">
<link rel="import" href="/base/math.html">
<script>
'use strict';

tr.exportTo('tr.b', function() {
  var tmpVec2s = [];
  for (var i = 0; i < 8; i++)
    tmpVec2s[i] = vec2.create();

  var tmpVec2a = vec4.create();
  var tmpVec4a = vec4.create();
  var tmpVec4b = vec4.create();
  var tmpMat4 = mat4.create();
  var tmpMat4b = mat4.create();

  var p00 = vec2.createXY(0, 0);
  var p10 = vec2.createXY(1, 0);
  var p01 = vec2.createXY(0, 1);
  var p11 = vec2.createXY(1, 1);

  var lerpingVecA = vec2.create();
  var lerpingVecB = vec2.create();
  function lerpVec2(out, a, b, amt) {
    vec2.scale(lerpingVecA, a, amt);
    vec2.scale(lerpingVecB, b, 1 - amt);
    vec2.add(out, lerpingVecA, lerpingVecB);
    vec2.normalize(out, out);
    return out;
  }

  /**
   * @constructor
   */
  function Quad() {
    this.p1 = vec2.create();
    this.p2 = vec2.create();
    this.p3 = vec2.create();
    this.p4 = vec2.create();
  }

  Quad.fromXYWH = function(x, y, w, h) {
    var q = new Quad();
    vec2.set(q.p1, x, y);
    vec2.set(q.p2, x + w, y);
    vec2.set(q.p3, x + w, y + h);
    vec2.set(q.p4, x, y + h);
    return q;
  }

  Quad.fromRect = function(r) {
    return new Quad.fromXYWH(
        r.x, r.y,
        r.width, r.height);
  }

  Quad.from4Vecs = function(p1, p2, p3, p4) {
    var q = new Quad();
    vec2.set(q.p1, p1[0], p1[1]);
    vec2.set(q.p2, p2[0], p2[1]);
    vec2.set(q.p3, p3[0], p3[1]);
    vec2.set(q.p4, p4[0], p4[1]);
    return q;
  }

  Quad.from8Array = function(arr) {
    if (arr.length != 8)
      throw new Error('Array must be 8 long');
    var q = new Quad();
    q.p1[0] = arr[0];
    q.p1[1] = arr[1];
    q.p2[0] = arr[2];
    q.p2[1] = arr[3];
    q.p3[0] = arr[4];
    q.p3[1] = arr[5];
    q.p4[0] = arr[6];
    q.p4[1] = arr[7];
    return q;
  };

  Quad.prototype = {
    pointInside: function(point) {
      return pointInImplicitQuad(point,
                                 this.p1, this.p2, this.p3, this.p4);
    },

    boundingRect: function() {
      var x0 = Math.min(this.p1[0], this.p2[0], this.p3[0], this.p4[0]);
      var y0 = Math.min(this.p1[1], this.p2[1], this.p3[1], this.p4[1]);

      var x1 = Math.max(this.p1[0], this.p2[0], this.p3[0], this.p4[0]);
      var y1 = Math.max(this.p1[1], this.p2[1], this.p3[1], this.p4[1]);

      return new tr.b.Rect.fromXYWH(x0, y0, x1 - x0, y1 - y0);
    },

    clone: function() {
      var q = new Quad();
      vec2.copy(q.p1, this.p1);
      vec2.copy(q.p2, this.p2);
      vec2.copy(q.p3, this.p3);
      vec2.copy(q.p4, this.p4);
      return q;
    },

    scale: function(s) {
      var q = new Quad();
      this.scaleFast(q, s);
      return q;
    },

    scaleFast: function(dstQuad, s) {
      vec2.copy(dstQuad.p1, this.p1, s);
      vec2.copy(dstQuad.p2, this.p2, s);
      vec2.copy(dstQuad.p3, this.p3, s);
      vec2.copy(dstQuad.p3, this.p3, s);
    },

    isRectangle: function() {
      // Simple rectangle check. Note: will not handle out-of-order components.
      var bounds = this.boundingRect();
      return (
          bounds.x == this.p1[0] &&
          bounds.y == this.p1[1] &&
          bounds.width == this.p2[0] - this.p1[0] &&
          bounds.y == this.p2[1] &&
          bounds.width == this.p3[0] - this.p1[0] &&
          bounds.height == this.p3[1] - this.p2[1] &&
          bounds.x == this.p4[0] &&
          bounds.height == this.p4[1] - this.p2[1]
      );
    },

    projectUnitRect: function(rect) {
      var q = new Quad();
      this.projectUnitRectFast(q, rect);
      return q;
    },

    projectUnitRectFast: function(dstQuad, rect) {
      var v12 = tmpVec2s[0];
      var v14 = tmpVec2s[1];
      var v23 = tmpVec2s[2];
      var v43 = tmpVec2s[3];
      var l12, l14, l23, l43;

      vec2.sub(v12, this.p2, this.p1);
      l12 = vec2.length(v12);
      vec2.scale(v12, v12, 1 / l12);

      vec2.sub(v14, this.p4, this.p1);
      l14 = vec2.length(v14);
      vec2.scale(v14, v14, 1 / l14);

      vec2.sub(v23, this.p3, this.p2);
      l23 = vec2.length(v23);
      vec2.scale(v23, v23, 1 / l23);

      vec2.sub(v43, this.p3, this.p4);
      l43 = vec2.length(v43);
      vec2.scale(v43, v43, 1 / l43);

      var b12 = tmpVec2s[0];
      var b14 = tmpVec2s[1];
      var b23 = tmpVec2s[2];
      var b43 = tmpVec2s[3];
      lerpVec2(b12, v12, v43, rect.y);
      lerpVec2(b43, v12, v43, 1 - rect.bottom);
      lerpVec2(b14, v14, v23, rect.x);
      lerpVec2(b23, v14, v23, 1 - rect.right);

      vec2.addTwoScaledUnitVectors(tmpVec2a,
                                   b12, l12 * rect.x,
                                   b14, l14 * rect.y);
      vec2.add(dstQuad.p1, this.p1, tmpVec2a);

      vec2.addTwoScaledUnitVectors(tmpVec2a,
                                   b12, l12 * -(1.0 - rect.right),
                                   b23, l23 * rect.y);
      vec2.add(dstQuad.p2, this.p2, tmpVec2a);


      vec2.addTwoScaledUnitVectors(tmpVec2a,
                                   b43, l43 * -(1.0 - rect.right),
                                   b23, l23 * -(1.0 - rect.bottom));
      vec2.add(dstQuad.p3, this.p3, tmpVec2a);

      vec2.addTwoScaledUnitVectors(tmpVec2a,
                                   b43, l43 * rect.left,
                                   b14, l14 * -(1.0 - rect.bottom));
      vec2.add(dstQuad.p4, this.p4, tmpVec2a);
    },

    toString: function() {
      return 'Quad(' +
          vec2.toString(this.p1) + ', ' +
          vec2.toString(this.p2) + ', ' +
          vec2.toString(this.p3) + ', ' +
          vec2.toString(this.p4) + ')';
    }
  };

  function sign(p1, p2, p3) {
    return (p1[0] - p3[0]) * (p2[1] - p3[1]) -
        (p2[0] - p3[0]) * (p1[1] - p3[1]);
  }

  function pointInTriangle2(pt, p1, p2, p3) {
    var b1 = sign(pt, p1, p2) < 0.0;
    var b2 = sign(pt, p2, p3) < 0.0;
    var b3 = sign(pt, p3, p1) < 0.0;
    return ((b1 == b2) && (b2 == b3));
  }

  function pointInImplicitQuad(point, p1, p2, p3, p4) {
    return pointInTriangle2(point, p1, p2, p3) ||
        pointInTriangle2(point, p1, p3, p4);
  }

  return {
    pointInTriangle2: pointInTriangle2,
    pointInImplicitQuad: pointInImplicitQuad,
    Quad: Quad
  };
});
</script>
