import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import { ConnectedPositionStrategy } from './connected-position.strategy';
import { GlobalPositionStrategy } from './global-position.strategy';
import { ViewportRuler } from './scroll-strategy';
var OverlayPositionService = /** @class */ (function () {
    function OverlayPositionService(_viewportRuler) {
        this._viewportRuler = _viewportRuler;
        /** offset when overlay has Arrow */
        this.offsetWhenHasArrow = 8;
    }
    /**
     * Set overlay reference
     * @return this
     */
    OverlayPositionService.prototype.setOverlayRef = function (overlayRef) {
        this.overlayComponent = overlayRef;
        return this;
    };
    /**
     * Creates a global position strategy
     * @return { GlobalPositionStrategy }
     */
    OverlayPositionService.prototype.global = function () {
        return new GlobalPositionStrategy();
    };
    /**
     * Creates a relative position strategy.
     * @param ElementRef
     * @param any
     * @param Placement
     * @return ConnectedPositionStrategy
     */
    OverlayPositionService.prototype.attachTo = function (targetRef, overlayComponent, placement) {
        this.splitPlacement(placement);
        this.overlayComponent = overlayComponent;
        var positionStrategy = new ConnectedPositionStrategy(targetRef, this.overlayComponent);
        this.withPosition(positionStrategy);
        this.subscribeWindowEvent(positionStrategy);
        return positionStrategy;
    };
    /**
     * Adds two new preferred fallback position as default
     * @param positionStrategy
     */
    OverlayPositionService.prototype.withPosition = function (positionStrategy) {
        this.withFirstPositon(positionStrategy);
        this.withNextPositon(positionStrategy);
    };
    /**
     * Adds first new preferred fallback position
     * @param positionStrategy
     */
    OverlayPositionService.prototype.withFirstPositon = function (positionStrategy) {
        this.originPos = this.getOriginPosition();
        this.overlayPos = this.getOverlayPosition();
        var _a = this.getOffset(), offsetX = _a.offsetX, offsetY = _a.offsetY;
        positionStrategy.withFallbackPosition(this.originPos, this.overlayPos, offsetX, offsetY);
    };
    /**
     * Adds second new preferred fallback position
     * @param positionStrategy
     */
    OverlayPositionService.prototype.withNextPositon = function (positionStrategy) {
        var origin = this.getOrigin();
        var overlay = this.getOverlay();
        var _a = this.getOffset(origin.fallback, overlay.fallback), offsetX = _a.offsetX, offsetY = _a.offsetY;
        positionStrategy.withFallbackPosition(origin.fallback, overlay.fallback, offsetX, offsetY);
    };
    /**
     * Subscribe window's srcoll and resize event and once change, update the position
     * @param positionStrategy
     */
    OverlayPositionService.prototype.subscribeWindowEvent = function (positionStrategy) {
        var _this = this;
        // 不能保存到this上，否则select组件的demo上只定位最后一个
        // this._resizeSubscription.unsubscribe();
        this._viewportRuler.change().subscribe(function () { return _this.updatePosition(positionStrategy); });
    };
    /**
     * Split placement e.g 'bottom-left' by '-'
     * @param positionStrategy
     */
    OverlayPositionService.prototype.splitPlacement = function (placement) {
        this.placement = placement;
        var _a = this.placement.split('-'), firstPlacement = _a[0], seconedPlacement = _a[1];
        this.firstPlacement = firstPlacement;
        this.seconedPlacement = seconedPlacement;
    };
    /**
     * Update position once change
     * @param positionStrategy
     */
    OverlayPositionService.prototype.updatePosition = function (positionStrategy) {
        positionStrategy.apply();
    };
    /**
     * calculate four direction's offset for two preferred fallback position
     * @param ConnectionPositionPair
     * @param ConnectionPositionPair
     * @return object e.g {offsetX, offsetY}
     */
    OverlayPositionService.prototype.getOffset = function (originPos, overlayPos) {
        var offsetX = 0;
        var offsetY = 0;
        if (this.overlayComponent.hasArrow) {
            if (originPos && overlayPos) {
                // 相异为主方向
                if (originPos.vertical !== overlayPos.vertical) {
                    if (originPos.vertical === 'top') {
                        offsetY = -this.offsetWhenHasArrow;
                    }
                    else {
                        offsetY = this.offsetWhenHasArrow;
                    }
                }
                else if (originPos.horizontal !== overlayPos.horizontal) {
                    if (originPos.horizontal === 'left') {
                        offsetX = -this.offsetWhenHasArrow;
                    }
                    else {
                        offsetX = this.offsetWhenHasArrow;
                    }
                }
            }
            else {
                if (this.firstPlacement === 'left') {
                    offsetX = -this.offsetWhenHasArrow;
                }
                else if (this.firstPlacement === 'right') {
                    offsetX = this.offsetWhenHasArrow;
                }
                else if (this.firstPlacement === 'top') {
                    offsetY = -this.offsetWhenHasArrow;
                }
                else if (this.firstPlacement === 'bottom') {
                    offsetY = this.offsetWhenHasArrow;
                }
            }
        }
        return { offsetX: offsetX, offsetY: offsetY };
    };
    /**
     * change placement to ConnectionPosition, e.g { horizontal: horizontal, vertical: vertical }
     * @return ConnectionPosition
     */
    OverlayPositionService.prototype.getOriginPosition = function () {
        var horizontal;
        var vertical;
        var firstPlacement = this.firstPlacement;
        var seconedPlacement = this.seconedPlacement;
        if (firstPlacement === 'top' || firstPlacement === 'bottom') {
            vertical = firstPlacement;
        }
        if (firstPlacement === 'left') {
            horizontal = 'left';
        }
        if (firstPlacement === 'right') {
            horizontal = 'right';
        }
        if (seconedPlacement === 'left') {
            horizontal = 'left';
        }
        if (seconedPlacement === 'right') {
            horizontal = 'right';
        }
        if (seconedPlacement === 'top' || seconedPlacement === 'bottom') {
            vertical = seconedPlacement;
        }
        if (seconedPlacement == null || seconedPlacement === 'center') {
            if (firstPlacement === 'top' || firstPlacement === 'bottom') {
                horizontal = 'center';
            }
            else {
                vertical = 'center';
            }
        }
        if (typeof horizontal === 'undefined' || typeof vertical === 'undefined') {
            throw this.getInvalidplacementError(this.placement);
        }
        return {
            horizontal: horizontal,
            vertical: vertical
        };
    };
    /**
     * throw the error of invalid position
     * @return { string } position
     */
    OverlayPositionService.prototype.getInvalidplacementError = function (position) {
        return Error("Tooltip position \"" + position + "\" is invalid.");
    };
    /**
     * change placement to ConnectionPosition, e.g { horizontal: horizontal, vertical: vertical }
     * @return { ConnectionPosition } position
     */
    OverlayPositionService.prototype.getOverlayPosition = function () {
        var firstPlacement = this.firstPlacement;
        var seconedPlacement = this.seconedPlacement;
        var horizontal;
        var vertical;
        if (firstPlacement === 'top') {
            vertical = 'bottom';
        }
        if (firstPlacement === 'bottom') {
            vertical = 'top';
        }
        if (firstPlacement === 'left') {
            horizontal = 'right';
        }
        if (firstPlacement === 'right') {
            horizontal = 'left';
        }
        if (seconedPlacement === 'left') {
            horizontal = 'left';
        }
        if (seconedPlacement === 'right') {
            horizontal = 'right';
        }
        if (seconedPlacement === 'top' || seconedPlacement === 'bottom') {
            vertical = seconedPlacement;
        }
        if (seconedPlacement == null || seconedPlacement === 'center') {
            if (firstPlacement === 'top' || firstPlacement === 'bottom') {
                horizontal = 'center';
            }
            else {
                vertical = 'center';
            }
        }
        if (typeof horizontal === 'undefined' || typeof vertical === 'undefined') {
            throw this.getInvalidplacementError(this.placement);
        }
        return {
            horizontal: horizontal,
            vertical: vertical
        };
    };
    /**
     * Returns the origin position and a fallback position based on the user's position preference.
     * The fallback position is the inverse of the origin (e.g. 'bottom' -> 'top').
     * @return { main: ConnectionPosition, fallback: ConnectionPosition }
     */
    OverlayPositionService.prototype.getOrigin = function () {
        var _a = this.invertPosition(this.originPos.horizontal, this.originPos.vertical), x = _a.x, y = _a.y;
        return {
            main: this.originPos,
            fallback: { horizontal: x, vertical: y }
        };
    };
    /**
     * Returns the overlay position and a fallback position based on the user's preference.
     * @return { main: ConnectionPosition, fallback: ConnectionPosition }
     */
    OverlayPositionService.prototype.getOverlay = function () {
        var _a = this.invertPosition(this.overlayPos.horizontal, this.overlayPos.vertical), x = _a.x, y = _a.y;
        return {
            main: this.overlayPos,
            fallback: { horizontal: x, vertical: y }
        };
    };
    /**
     * Inverts an overlay position.
     * @param { HorizontalConnectionPos } x
     * @param { VerticalConnectionPos } y
     * @return { Point } { x, y }
     */
    OverlayPositionService.prototype.invertPosition = function (x, y) {
        if (this.firstPlacement === 'top' || this.firstPlacement === 'bottom') {
            if (y === 'top') {
                y = 'bottom';
            }
            else if (y === 'bottom') {
                y = 'top';
            }
        }
        else {
            if (x === 'right') {
                x = 'left';
            }
            else if (x === 'left') {
                x = 'right';
            }
        }
        return { x: x, y: y };
    };
    OverlayPositionService = tslib_1.__decorate([
        Injectable(),
        tslib_1.__metadata("design:paramtypes", [ViewportRuler])
    ], OverlayPositionService);
    return OverlayPositionService;
}());
export { OverlayPositionService };
//# sourceMappingURL=overlay-position.service.js.map