/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
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 __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
import './sash.css';
import { dispose, Disposable, DisposableStore } from '../../../common/lifecycle';
import { isIPad } from '../../browser';
import { isMacintosh } from '../../../common/platform';
import * as types from '../../../common/types';
import { EventType, Gesture } from '../../touch';
import { StandardMouseEvent } from '../../mouseEvent';
import { Emitter } from '../../../common/event';
import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $, addClass, removeClass, toggleClass } from '../../dom';
import { domEvent } from '../../event';
var DEBUG = false;
var Sash = /** @class */ (function (_super) {
    __extends(Sash, _super);
    function Sash(container, layoutProvider, options) {
        if (options === void 0) { options = {}; }
        var _this = _super.call(this) || this;
        _this._state = 3 /* Enabled */;
        _this._onDidEnablementChange = _this._register(new Emitter());
        _this.onDidEnablementChange = _this._onDidEnablementChange.event;
        _this._onDidStart = _this._register(new Emitter());
        _this.onDidStart = _this._onDidStart.event;
        _this._onDidChange = _this._register(new Emitter());
        _this.onDidChange = _this._onDidChange.event;
        _this._onDidReset = _this._register(new Emitter());
        _this.onDidReset = _this._onDidReset.event;
        _this._onDidEnd = _this._register(new Emitter());
        _this.onDidEnd = _this._onDidEnd.event;
        _this.linkedSash = undefined;
        _this.orthogonalStartSashDisposables = _this._register(new DisposableStore());
        _this.orthogonalEndSashDisposables = _this._register(new DisposableStore());
        _this.el = append(container, $('.monaco-sash'));
        if (isMacintosh) {
            addClass(_this.el, 'mac');
        }
        _this._register(domEvent(_this.el, 'mousedown')(_this.onMouseDown, _this));
        _this._register(domEvent(_this.el, 'dblclick')(_this.onMouseDoubleClick, _this));
        _this._register(Gesture.addTarget(_this.el));
        _this._register(domEvent(_this.el, EventType.Start)(_this.onTouchStart, _this));
        if (isIPad) {
            // see also https://ux.stackexchange.com/questions/39023/what-is-the-optimum-button-size-of-touch-screen-applications
            addClass(_this.el, 'touch');
        }
        _this.setOrientation(options.orientation || 0 /* VERTICAL */);
        _this.hidden = false;
        _this.layoutProvider = layoutProvider;
        _this.orthogonalStartSash = options.orthogonalStartSash;
        _this.orthogonalEndSash = options.orthogonalEndSash;
        toggleClass(_this.el, 'debug', DEBUG);
        return _this;
    }
    Object.defineProperty(Sash.prototype, "state", {
        get: function () { return this._state; },
        set: function (state) {
            if (this._state === state) {
                return;
            }
            toggleClass(this.el, 'disabled', state === 0 /* Disabled */);
            toggleClass(this.el, 'minimum', state === 1 /* Minimum */);
            toggleClass(this.el, 'maximum', state === 2 /* Maximum */);
            this._state = state;
            this._onDidEnablementChange.fire(state);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Sash.prototype, "orthogonalStartSash", {
        get: function () { return this._orthogonalStartSash; },
        set: function (sash) {
            this.orthogonalStartSashDisposables.clear();
            if (sash) {
                this.orthogonalStartSashDisposables.add(sash.onDidEnablementChange(this.onOrthogonalStartSashEnablementChange, this));
                this.onOrthogonalStartSashEnablementChange(sash.state);
            }
            else {
                this.onOrthogonalStartSashEnablementChange(0 /* Disabled */);
            }
            this._orthogonalStartSash = sash;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Sash.prototype, "orthogonalEndSash", {
        get: function () { return this._orthogonalEndSash; },
        set: function (sash) {
            this.orthogonalEndSashDisposables.clear();
            if (sash) {
                this.orthogonalEndSashDisposables.add(sash.onDidEnablementChange(this.onOrthogonalEndSashEnablementChange, this));
                this.onOrthogonalEndSashEnablementChange(sash.state);
            }
            else {
                this.onOrthogonalEndSashEnablementChange(0 /* Disabled */);
            }
            this._orthogonalEndSash = sash;
        },
        enumerable: true,
        configurable: true
    });
    Sash.prototype.setOrientation = function (orientation) {
        this.orientation = orientation;
        if (this.orientation === 1 /* HORIZONTAL */) {
            addClass(this.el, 'horizontal');
            removeClass(this.el, 'vertical');
        }
        else {
            removeClass(this.el, 'horizontal');
            addClass(this.el, 'vertical');
        }
        if (this.layoutProvider) {
            this.layout();
        }
    };
    Sash.prototype.onMouseDown = function (e) {
        var _this = this;
        EventHelper.stop(e, false);
        var isMultisashResize = false;
        if (!e.__orthogonalSashEvent) {
            var orthogonalSash = this.getOrthogonalSash(e);
            if (orthogonalSash) {
                isMultisashResize = true;
                e.__orthogonalSashEvent = true;
                orthogonalSash.onMouseDown(e);
            }
        }
        if (this.linkedSash && !e.__linkedSashEvent) {
            e.__linkedSashEvent = true;
            this.linkedSash.onMouseDown(e);
        }
        if (!this.state) {
            return;
        }
        // Select both iframes and webviews; internally Electron nests an iframe
        // in its <webview> component, but this isn't queryable.
        var iframes = __spreadArrays(getElementsByTagName('iframe'), getElementsByTagName('webview'));
        for (var _i = 0, iframes_1 = iframes; _i < iframes_1.length; _i++) {
            var iframe = iframes_1[_i];
            iframe.style.pointerEvents = 'none'; // disable mouse events on iframes as long as we drag the sash
        }
        var mouseDownEvent = new StandardMouseEvent(e);
        var startX = mouseDownEvent.posx;
        var startY = mouseDownEvent.posy;
        var altKey = mouseDownEvent.altKey;
        var startEvent = { startX: startX, currentX: startX, startY: startY, currentY: startY, altKey: altKey };
        addClass(this.el, 'active');
        this._onDidStart.fire(startEvent);
        // fix https://github.com/Microsoft/vscode/issues/21675
        var style = createStyleSheet(this.el);
        var updateStyle = function () {
            var cursor = '';
            if (isMultisashResize) {
                cursor = 'all-scroll';
            }
            else if (_this.orientation === 1 /* HORIZONTAL */) {
                if (_this.state === 1 /* Minimum */) {
                    cursor = 's-resize';
                }
                else if (_this.state === 2 /* Maximum */) {
                    cursor = 'n-resize';
                }
                else {
                    cursor = isMacintosh ? 'row-resize' : 'ns-resize';
                }
            }
            else {
                if (_this.state === 1 /* Minimum */) {
                    cursor = 'e-resize';
                }
                else if (_this.state === 2 /* Maximum */) {
                    cursor = 'w-resize';
                }
                else {
                    cursor = isMacintosh ? 'col-resize' : 'ew-resize';
                }
            }
            style.innerHTML = "* { cursor: " + cursor + " !important; }";
        };
        var disposables = new DisposableStore();
        updateStyle();
        if (!isMultisashResize) {
            this.onDidEnablementChange(updateStyle, null, disposables);
        }
        var onMouseMove = function (e) {
            EventHelper.stop(e, false);
            var mouseMoveEvent = new StandardMouseEvent(e);
            var event = { startX: startX, currentX: mouseMoveEvent.posx, startY: startY, currentY: mouseMoveEvent.posy, altKey: altKey };
            _this._onDidChange.fire(event);
        };
        var onMouseUp = function (e) {
            EventHelper.stop(e, false);
            _this.el.removeChild(style);
            removeClass(_this.el, 'active');
            _this._onDidEnd.fire();
            disposables.dispose();
            for (var _i = 0, iframes_2 = iframes; _i < iframes_2.length; _i++) {
                var iframe = iframes_2[_i];
                iframe.style.pointerEvents = 'auto';
            }
        };
        domEvent(window, 'mousemove')(onMouseMove, null, disposables);
        domEvent(window, 'mouseup')(onMouseUp, null, disposables);
    };
    Sash.prototype.onMouseDoubleClick = function (e) {
        var orthogonalSash = this.getOrthogonalSash(e);
        if (orthogonalSash) {
            orthogonalSash._onDidReset.fire();
        }
        if (this.linkedSash) {
            this.linkedSash._onDidReset.fire();
        }
        this._onDidReset.fire();
    };
    Sash.prototype.onTouchStart = function (event) {
        var _this = this;
        EventHelper.stop(event);
        var listeners = [];
        var startX = event.pageX;
        var startY = event.pageY;
        var altKey = event.altKey;
        this._onDidStart.fire({
            startX: startX,
            currentX: startX,
            startY: startY,
            currentY: startY,
            altKey: altKey
        });
        listeners.push(addDisposableListener(this.el, EventType.Change, function (event) {
            if (types.isNumber(event.pageX) && types.isNumber(event.pageY)) {
                _this._onDidChange.fire({
                    startX: startX,
                    currentX: event.pageX,
                    startY: startY,
                    currentY: event.pageY,
                    altKey: altKey
                });
            }
        }));
        listeners.push(addDisposableListener(this.el, EventType.End, function (event) {
            _this._onDidEnd.fire();
            dispose(listeners);
        }));
    };
    Sash.prototype.layout = function () {
        var size = isIPad ? 20 : 4;
        if (this.orientation === 0 /* VERTICAL */) {
            var verticalProvider = this.layoutProvider;
            this.el.style.left = verticalProvider.getVerticalSashLeft(this) - (size / 2) + 'px';
            if (verticalProvider.getVerticalSashTop) {
                this.el.style.top = verticalProvider.getVerticalSashTop(this) + 'px';
            }
            if (verticalProvider.getVerticalSashHeight) {
                this.el.style.height = verticalProvider.getVerticalSashHeight(this) + 'px';
            }
        }
        else {
            var horizontalProvider = this.layoutProvider;
            this.el.style.top = horizontalProvider.getHorizontalSashTop(this) - (size / 2) + 'px';
            if (horizontalProvider.getHorizontalSashLeft) {
                this.el.style.left = horizontalProvider.getHorizontalSashLeft(this) + 'px';
            }
            if (horizontalProvider.getHorizontalSashWidth) {
                this.el.style.width = horizontalProvider.getHorizontalSashWidth(this) + 'px';
            }
        }
    };
    Sash.prototype.show = function () {
        this.hidden = false;
        this.el.style.removeProperty('display');
        this.el.setAttribute('aria-hidden', 'false');
    };
    Sash.prototype.hide = function () {
        this.hidden = true;
        this.el.style.display = 'none';
        this.el.setAttribute('aria-hidden', 'true');
    };
    Sash.prototype.isHidden = function () {
        return this.hidden;
    };
    Sash.prototype.onOrthogonalStartSashEnablementChange = function (state) {
        toggleClass(this.el, 'orthogonal-start', state !== 0 /* Disabled */);
    };
    Sash.prototype.onOrthogonalEndSashEnablementChange = function (state) {
        toggleClass(this.el, 'orthogonal-end', state !== 0 /* Disabled */);
    };
    Sash.prototype.getOrthogonalSash = function (e) {
        if (this.orientation === 0 /* VERTICAL */) {
            if (e.offsetY <= 4) {
                return this.orthogonalStartSash;
            }
            else if (e.offsetY >= this.el.clientHeight - 4) {
                return this.orthogonalEndSash;
            }
        }
        else {
            if (e.offsetX <= 4) {
                return this.orthogonalStartSash;
            }
            else if (e.offsetX >= this.el.clientWidth - 4) {
                return this.orthogonalEndSash;
            }
        }
        return undefined;
    };
    Sash.prototype.dispose = function () {
        _super.prototype.dispose.call(this);
        this.el.remove();
    };
    return Sash;
}(Disposable));
export { Sash };
