"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var utils_1 = require("./utils");
var constants_1 = require("./constants");
var Touch = (function (_super) {
    __extends(Touch, _super);
    function Touch() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.node = null;
        _this.x = null;
        _this.y = null;
        _this.rotateStart = null;
        _this.rotated = false;
        _this.panStart = null;
        _this.panned = false;
        _this.lastDistance = 0;
        _this.zoomLevel = 0;
        _this.matrixEvents = null;
        _this._onTranslate = function (x, y) {
            var onTranslate = _this.props.onTranslate;
            if (onTranslate)
                onTranslate(x, y);
        };
        _this._onScale = function (factor) {
            var onScale = _this.props.onScale;
            if (onScale)
                onScale(factor);
        };
        _this._setup = function (node) {
            if (!node)
                return;
            _this.node = node;
            _this.node.style.display = 'block';
            _this.node.style.margin = '0px';
            _this.node.style.padding = '0px';
        };
        _this._reset = function () {
            var onReset = _this.props.onReset;
            utils_1.reset();
            _this.zoomLevel = 0;
            if (onReset)
                onReset();
        };
        _this._updateCoordinates = function (x, y) {
            var onCoordinates = _this.props.onCoordinates;
            _this.x = x;
            _this.y = y;
            if (onCoordinates)
                onCoordinates(x, y);
        };
        _this._updateCoordinatesMouse = function (event) {
            var x = event.pageX - _this.node.offsetLeft;
            var y = event.pageY - _this.node.offsetTop;
            _this._updateCoordinates(x, y);
        };
        _this._updateCoordinatesTouch = function (event) {
            var x = event.targetTouches[0].pageX - _this.node.offsetLeft;
            var y = event.targetTouches[0].pageY - _this.node.offsetTop;
            _this._updateCoordinates(x, y);
        };
        _this._onMouseDown = function (event) {
            event.preventDefault();
            _this._updateCoordinatesMouse(event);
            return _this._onPanStart(event);
        };
        _this._onTouchStart = function (event) {
            _this._updateCoordinatesTouch(event);
            if (event.targetTouches.length > 1)
                return _this._onPinchStart(event);
            return _this._onPanStart(event);
        };
        _this._onPanStart = function (event) {
            var onPanStart = _this.props.onPanStart;
            _this.panStart = utils_1.transformedPoint(_this.x, _this.y);
            _this.panned = false;
            if (onPanStart)
                onPanStart(event);
        };
        _this._onMouseMove = function (event) {
            event.preventDefault();
            _this._updateCoordinatesMouse(event);
            if (_this.panStart)
                return _this._onPanMove(event);
        };
        _this._onTouchMove = function (event) {
            event.preventDefault();
            _this._updateCoordinatesTouch(event);
            if (event.targetTouches.length > 1)
                return _this._onPinch(event);
            return _this._onPanMove(event);
        };
        _this._onPanMove = function (event) {
            var onPan = _this.props.onPan;
            _this.panned = true;
            var pt = utils_1.transformedPoint(_this.x, _this.y);
            var x = pt.x - _this.panStart.x;
            var y = pt.y - _this.panStart.y;
            utils_1.translate(x, y);
            if (onPan)
                onPan(event);
        };
        _this._onMouseUp = function (event) {
            event.preventDefault();
            if (_this.rotateStart)
                _this.rotateStart = null;
            return _this._onPanEnd(event);
        };
        _this._onMouseLeave = function (event) {
            event.preventDefault();
            return _this._onPanEnd(event);
        };
        _this._onTouchEnd = function (event) {
            event.preventDefault();
            if (event.targetTouches.length > 1)
                return _this._onPinchEnd(event);
            return _this._onPanEnd(event);
        };
        _this._onPanEnd = function (event) {
            var onPanEnd = _this.props.onPanEnd;
            _this.panStart = null;
            if (!_this.panned && !_this.rotated)
                _this._onZoom(event.shiftKey ? -1 : 1);
            if (onPanEnd)
                onPanEnd(event);
        };
        _this._onZoom = function (clicks) {
            var _a = _this.props, _b = _a.options, options = _b === void 0 ? {} : _b, onZoom = _a.onZoom;
            var _c = options.scaleFactor, scaleFactor = _c === void 0 ? constants_1.SCALE_FACTOR : _c, _d = options.minZoomLevel, minZoomLevel = _d === void 0 ? constants_1.MIN_ZOOM_LEVEL : _d;
            var actualClicks = 0;
            if ((_this.zoomLevel + clicks) < minZoomLevel) {
                actualClicks = minZoomLevel - _this.zoomLevel;
            }
            else {
                actualClicks = clicks;
            }
            _this.zoomLevel += actualClicks;
            var _e = utils_1.transformedPoint(_this.x, _this.y), x = _e.x, y = _e.y;
            var factor = Math.pow(scaleFactor, actualClicks);
            utils_1.translate(x, y, false);
            utils_1.scale(factor);
            utils_1.translate(-x, -y, false);
            if (onZoom)
                onZoom(factor, x, y);
        };
        _this._onPinchStart = function (event) {
            var onPinchStart = _this.props.onPinchStart;
            _this.touchCache = [];
            for (var i = 0; i < event.targetTouches.length; i += 1) {
                var touch = event.targetTouches[i];
                _this.touchCache.push(touch);
            }
            _this.lastDistance = 0;
            if (onPinchStart)
                onPinchStart(event);
        };
        _this._onPinch = function (event) {
            var _a = _this.props, onPinch = _a.onPinch, _b = _a.options, options = _b === void 0 ? {} : _b;
            var _c = options.touchSensitivity, touchSensitivity = _c === void 0 ? constants_1.TOUCH_SENSITIVITY : _c;
            var touch1 = event.targetTouches[0];
            var touch2 = event.targetTouches[1];
            var startTouch1 = _this.touchCache.find(function (touch) { return touch.identifier === touch1.identifier; });
            var startTouch2 = _this.touchCache.find(function (touch) { return touch.identifier === touch2.identifier; });
            var x = ((touch1.clientX + touch2.clientX) / 2) - _this.node.offsetLeft;
            var y = ((touch1.clientY + touch2.clientY) / 2) - _this.node.offsetTop;
            _this._updateCoordinates(x, y);
            if (startTouch1 && startTouch2) {
                var distance = utils_1.getDistance(touch1, touch2);
                if (_this.lastDistance) {
                    var initialDistance = utils_1.getDistance(startTouch1, startTouch2);
                    var ratio = (distance - _this.lastDistance) / initialDistance;
                    _this._onZoom(ratio * touchSensitivity);
                }
                _this.lastDistance = distance;
            }
            if (onPinch)
                onPinch(event);
        };
        _this._onPinchEnd = function (event) {
            var onPinchEnd = _this.props.onPinchEnd;
            if (onPinchEnd)
                onPinchEnd(event);
        };
        _this._onRotate = function (delta) {
            var height = _this.node.getBoundingClientRect().height;
            var degrees = delta / height;
            var onRotate = _this.props.onRotate;
            utils_1.rotate(degrees);
            if (onRotate)
                onRotate(degrees);
        };
        _this._onWheel = function (event) {
            event.preventDefault();
            var _a = _this.props.options, options = _a === void 0 ? {} : _a;
            var _b = options.wheelMax, wheelMax = _b === void 0 ? constants_1.WHEEL_MAX : _b, _c = options.wheelSensitivityRotate, wheelSensitivityRotate = _c === void 0 ? constants_1.WHEEL_SENSITIVITY_ROTATE : _c, _d = options.wheelSensitivityZoom, wheelSensitivityZoom = _d === void 0 ? constants_1.WHEEL_SENSITIVITY_ZOOM : _d;
            var delta = event.deltaY / 10;
            delta = delta > wheelMax ? wheelMax : delta < -wheelMax ? -wheelMax : delta;
            if (delta < 0 || delta > 0) {
                if (event.ctrlKey)
                    return _this._onRotate(delta / wheelSensitivityRotate);
                return _this._onZoom(delta / wheelSensitivityZoom);
            }
        };
        return _this;
    }
    Touch.prototype.componentDidMount = function () {
        utils_1.reset();
        window.addEventListener('resize', this._reset);
        utils_1.onChange.addListener(constants_1.TRANSLATE, this._onTranslate);
        utils_1.onChange.addListener(constants_1.SCALE, this._onScale);
    };
    Touch.prototype.componentWillUnmount = function () {
        window.removeEventListener('resize', this._reset);
        utils_1.onChange.removeListener(constants_1.TRANSLATE, this._onTranslate);
        utils_1.onChange.removeListener(constants_1.SCALE, this._onScale);
    };
    Touch.prototype.render = function () {
        var _a = this.props, onPanStart = _a.onPanStart, onPan = _a.onPan, onPanEnd = _a.onPanEnd, onPinchStart = _a.onPinchStart, onPinch = _a.onPinch, onPinchEnd = _a.onPinchEnd, onTranslate = _a.onTranslate, onScale = _a.onScale, onRotate = _a.onRotate, onReset = _a.onReset, onZoom = _a.onZoom, onCoordinates = _a.onCoordinates, options = _a.options, props = __rest(_a, ["onPanStart", "onPan", "onPanEnd", "onPinchStart", "onPinch", "onPinchEnd", "onTranslate", "onScale", "onRotate", "onReset", "onZoom", "onCoordinates", "options"]);
        return (React.createElement("div", __assign({ onMouseDown: this._onMouseDown, onMouseMove: this._onMouseMove, onMouseUp: this._onMouseUp, onMouseLeave: this._onMouseLeave, onWheel: this._onWheel, onTouchStart: this._onTouchStart, onTouchMove: this._onTouchMove, onTouchEnd: this._onTouchEnd, ref: this._setup }, props)));
    };
    return Touch;
}(React.Component));
exports.Touch = Touch;
//# sourceMappingURL=Touch.js.map