"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const matrix = require("./matrix.js");
const vector = require("./vector.js");
var mIdentity = matrix.identity;
var EPSILON = 5e-5;
function isNotAroundZero(val) {
  return val > EPSILON || val < -EPSILON;
}
var scaleTmp = [];
var tmpTransform = [];
var originTransform = matrix.create();
var abs = Math.abs;
var Transformable = function() {
  function Transformable2() {
  }
  Transformable2.prototype.getLocalTransform = function(m) {
    return Transformable2.getLocalTransform(this, m);
  };
  Transformable2.prototype.setPosition = function(arr) {
    this.x = arr[0];
    this.y = arr[1];
  };
  Transformable2.prototype.setScale = function(arr) {
    this.scaleX = arr[0];
    this.scaleY = arr[1];
  };
  Transformable2.prototype.setSkew = function(arr) {
    this.skewX = arr[0];
    this.skewY = arr[1];
  };
  Transformable2.prototype.setOrigin = function(arr) {
    this.originX = arr[0];
    this.originY = arr[1];
  };
  Transformable2.prototype.needLocalTransform = function() {
    return isNotAroundZero(this.rotation) || isNotAroundZero(this.x) || isNotAroundZero(this.y) || isNotAroundZero(this.scaleX - 1) || isNotAroundZero(this.scaleY - 1) || isNotAroundZero(this.skewX) || isNotAroundZero(this.skewY);
  };
  Transformable2.prototype.updateTransform = function() {
    var parentTransform = this.parent && this.parent.transform;
    var needLocalTransform = this.needLocalTransform();
    var m = this.transform;
    if (!(needLocalTransform || parentTransform)) {
      if (m) {
        mIdentity(m);
        this.invTransform = null;
      }
      return;
    }
    m = m || matrix.create();
    if (needLocalTransform) {
      this.getLocalTransform(m);
    } else {
      mIdentity(m);
    }
    if (parentTransform) {
      if (needLocalTransform) {
        matrix.mul(m, parentTransform, m);
      } else {
        matrix.copy(m, parentTransform);
      }
    }
    this.transform = m;
    this._resolveGlobalScaleRatio(m);
  };
  Transformable2.prototype._resolveGlobalScaleRatio = function(m) {
    var globalScaleRatio = this.globalScaleRatio;
    if (globalScaleRatio != null && globalScaleRatio !== 1) {
      this.getGlobalScale(scaleTmp);
      var relX = scaleTmp[0] < 0 ? -1 : 1;
      var relY = scaleTmp[1] < 0 ? -1 : 1;
      var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
      var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
      m[0] *= sx;
      m[1] *= sx;
      m[2] *= sy;
      m[3] *= sy;
    }
    this.invTransform = this.invTransform || matrix.create();
    matrix.invert(this.invTransform, m);
  };
  Transformable2.prototype.getComputedTransform = function() {
    var transformNode = this;
    var ancestors = [];
    while (transformNode) {
      ancestors.push(transformNode);
      transformNode = transformNode.parent;
    }
    while (transformNode = ancestors.pop()) {
      transformNode.updateTransform();
    }
    return this.transform;
  };
  Transformable2.prototype.setLocalTransform = function(m) {
    if (!m) {
      return;
    }
    var sx = m[0] * m[0] + m[1] * m[1];
    var sy = m[2] * m[2] + m[3] * m[3];
    var rotation = Math.atan2(m[1], m[0]);
    var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]);
    sy = Math.sqrt(sy) * Math.cos(shearX);
    sx = Math.sqrt(sx);
    this.skewX = shearX;
    this.skewY = 0;
    this.rotation = -rotation;
    this.x = +m[4];
    this.y = +m[5];
    this.scaleX = sx;
    this.scaleY = sy;
    this.originX = 0;
    this.originY = 0;
  };
  Transformable2.prototype.decomposeTransform = function() {
    if (!this.transform) {
      return;
    }
    var parent = this.parent;
    var m = this.transform;
    if (parent && parent.transform) {
      matrix.mul(tmpTransform, parent.invTransform, m);
      m = tmpTransform;
    }
    var ox = this.originX;
    var oy = this.originY;
    if (ox || oy) {
      originTransform[4] = ox;
      originTransform[5] = oy;
      matrix.mul(tmpTransform, m, originTransform);
      tmpTransform[4] -= ox;
      tmpTransform[5] -= oy;
      m = tmpTransform;
    }
    this.setLocalTransform(m);
  };
  Transformable2.prototype.getGlobalScale = function(out) {
    var m = this.transform;
    out = out || [];
    if (!m) {
      out[0] = 1;
      out[1] = 1;
      return out;
    }
    out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
    out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
    if (m[0] < 0) {
      out[0] = -out[0];
    }
    if (m[3] < 0) {
      out[1] = -out[1];
    }
    return out;
  };
  Transformable2.prototype.transformCoordToLocal = function(x, y) {
    var v2 = [x, y];
    var invTransform = this.invTransform;
    if (invTransform) {
      vector.applyTransform(v2, v2, invTransform);
    }
    return v2;
  };
  Transformable2.prototype.transformCoordToGlobal = function(x, y) {
    var v2 = [x, y];
    var transform = this.transform;
    if (transform) {
      vector.applyTransform(v2, v2, transform);
    }
    return v2;
  };
  Transformable2.prototype.getLineScale = function() {
    var m = this.transform;
    return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10 ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1])) : 1;
  };
  Transformable2.prototype.copyTransform = function(source) {
    copyTransform(this, source);
  };
  Transformable2.getLocalTransform = function(target, m) {
    m = m || [];
    var ox = target.originX || 0;
    var oy = target.originY || 0;
    var sx = target.scaleX;
    var sy = target.scaleY;
    var ax = target.anchorX;
    var ay = target.anchorY;
    var rotation = target.rotation || 0;
    var x = target.x;
    var y = target.y;
    var skewX = target.skewX ? Math.tan(target.skewX) : 0;
    var skewY = target.skewY ? Math.tan(-target.skewY) : 0;
    if (ox || oy || ax || ay) {
      var dx = ox + ax;
      var dy = oy + ay;
      m[4] = -dx * sx - skewX * dy * sy;
      m[5] = -dy * sy - skewY * dx * sx;
    } else {
      m[4] = m[5] = 0;
    }
    m[0] = sx;
    m[3] = sy;
    m[1] = skewY * sx;
    m[2] = skewX * sy;
    rotation && matrix.rotate(m, m, rotation);
    m[4] += ox + x;
    m[5] += oy + y;
    return m;
  };
  Transformable2.initDefaultProps = function() {
    var proto = Transformable2.prototype;
    proto.scaleX = proto.scaleY = proto.globalScaleRatio = 1;
    proto.x = proto.y = proto.originX = proto.originY = proto.skewX = proto.skewY = proto.rotation = proto.anchorX = proto.anchorY = 0;
  }();
  return Transformable2;
}();
var TRANSFORMABLE_PROPS = [
  "x",
  "y",
  "originX",
  "originY",
  "anchorX",
  "anchorY",
  "rotation",
  "scaleX",
  "scaleY",
  "skewX",
  "skewY"
];
function copyTransform(target, source) {
  for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
    var propName = TRANSFORMABLE_PROPS[i];
    target[propName] = source[propName];
  }
}
const Transformable$1 = Transformable;
exports.TRANSFORMABLE_PROPS = TRANSFORMABLE_PROPS;
exports.copyTransform = copyTransform;
exports.default = Transformable$1;
