var vectorUtil = require("../utils/vector_util");

var matrixUtil = require("../utils/affine_matrix_util");

var _constants = require("../utils/constants");

var mathMin = _constants.mathMin;
var mathMax = _constants.mathMax;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * @class qrenderer.graphic.transform.BoundingRect
 * 
 * Bounding Rect.
 * 
 * 边界矩形。
 * 
 * @docauthor 大漠穷秋 <damoqiongqiu@126.com>
 */
var v2ApplyTransform = vectorUtil.applyTransform;
var lt = [];
var rb = [];
var lb = [];
var rt = [];

var BoundingRect =
/*#__PURE__*/
function () {
  /**
   * @method constructor BoundingRect
   */
  function BoundingRect() {
    var x1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
    var y1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var x2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
    var y2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
    var width = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
    var height = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;

    _classCallCheck(this, BoundingRect);

    /**
     * @property {Number}
     */
    this.x1 = x1;
    /**
     * @property {Number}
     */

    this.y1 = y1;
    /**
     * @property {Number}
     */

    this.x2 = x2;
    /**
     * @property {Number}
     */

    this.y2 = y2;
    /**
     * @property {Number}
     */

    this.width = width;
    /**
     * @property {Number}
     */

    this.height = height;
  }
  /**
   * @param {Object|BoundingRect} rect
   * @param {Number} rect.x1
   * @param {Number} rect.y1
   * @param {Number} rect.x2
   * @param {Number} rect.y2
   * @param {Number} rect.width
   * @param {Number} rect.height
   * @return {BoundingRect}
   */


  _createClass(BoundingRect, [{
    key: "union",

    /**
     * @method union
     * @param {BoundingRect} other
     */
    value: function union(other) {
      this.x1 = mathMin(other.x1, this.x1);
      this.y1 = mathMin(other.y1, this.y1);
      this.x2 = mathMax(other.x2, this.x2);
      this.y2 = mathMax(other.y2, this.y2);
      this.width = this.x2 - this.x1;
      this.height = this.y2 - this.y1;
    }
    /**
     * @method applyTransform
     * @param {Array<Number>}
     */

  }, {
    key: "applyTransform",
    value: function applyTransform(m) {
      // In case usage like this
      // el.getBoundingRect().applyTransform(el.transform)
      // And element has no transform
      if (!m) {
        return;
      }

      lt[0] = lb[0] = this.x1;
      lt[1] = rt[1] = this.y1;
      rb[0] = rt[0] = this.x2;
      rb[1] = lb[1] = this.y2;
      v2ApplyTransform(lt, lt, m);
      v2ApplyTransform(rb, rb, m);
      v2ApplyTransform(lb, lb, m);
      v2ApplyTransform(rt, rt, m);
      this.x1 = mathMin(lt[0], rb[0], lb[0], rt[0]);
      this.y1 = mathMin(lt[1], rb[1], lb[1], rt[1]);
      this.x2 = mathMax(lt[0], rb[0], lb[0], rt[0]);
      this.y2 = mathMax(lt[1], rb[1], lb[1], rt[1]);
      this.width = this.x2 - this.x1;
      this.height = this.y2 - this.y1;
    }
    /**
     * @method calculateTransform
     * Calculate matrix of transforming from self to target rect
     * @param  {BoundingRect} b
     * @return {Array<Number>}
     */

  }, {
    key: "calculateTransform",
    value: function calculateTransform(b) {
      var a = this;
      var sx = b.width / a.width;
      var sy = b.height / a.height;
      var m = matrixUtil.create();
      m = matrixUtil.translate(m, [-a.x1, -a.y1]);
      m = matrixUtil.scale(m, [sx, sy]);
      m = matrixUtil.translate(m, [b.x1, b.y1]);
      return m;
    }
    /**
     * @method intersect
     * @param {(BoundingRect|Object)} b
     * @return {Boolean}
     */

  }, {
    key: "intersect",
    value: function intersect(b) {
      if (!b) {
        return false;
      }

      if (!(b instanceof BoundingRect)) {
        // Normalize negative width/height.
        b = BoundingRect.create(b);
      }

      var a = this;
      var ax0 = a.x1;
      var ax1 = a.x2;
      var ay0 = a.y1;
      var ay1 = a.y2;
      var bx0 = b.x1;
      var bx1 = b.x2;
      var by0 = b.y1;
      var by1 = b.y2;
      return !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
    }
    /**
     * @method containPoint
     * @param {*} x 
     * @param {*} y 
     */

  }, {
    key: "containPoint",
    value: function containPoint(x, y) {
      var rect = this;
      return x >= rect.x1 && x <= rect.x2 && y >= rect.y1 && y <= rect.y2;
    }
    /**
     * @method clone
     * @return {BoundingRect}
     */

  }, {
    key: "clone",
    value: function clone() {
      return new BoundingRect(this.x1, this.y1, this.x2, this.y2, this.width, this.height);
    }
    /**
     * @method copy
     * Copy from another rect
     * @param other
     */

  }, {
    key: "copy",
    value: function copy(other) {
      this.x1 = other.x1;
      this.y1 = other.y1;
      this.x2 = other.x2;
      this.y2 = other.y2;
      this.width = other.width;
      this.height = other.height;
    }
  }], [{
    key: "create",
    value: function create(rect) {
      return new BoundingRect(rect.x1, rect.y1, rect.x2, rect.y2, rect.width, rect.height);
    }
  }]);

  return BoundingRect;
}();

var _default = BoundingRect;
module.exports = _default;