"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var React = require("react");
var ReactDOM = require("react-dom");
var hoistNonReactStatic = require("hoist-non-react-statics");
var domHelperWwnerDocument = require("dom-helpers/ownerDocument");
var getOffset = require("dom-helpers/query/offset");
var getPosition = require("dom-helpers/query/position");
var getScrollTop = require("dom-helpers/query/scrollTop");
var bsMapping = {
    level: 'bsStyle',
    classPrefix: 'bsClass',
    size: 'bsSize',
};
/**
 * 主要目的是希望在是用 bootstrap 组件的时候不需要带 bs 前缀。
 *
 * @param {Object} rawProps 原始属性对象。
 * @return {Object}
 */
exports.props2BsProps = function (rawProps) {
    var props = {};
    Object.keys(rawProps).forEach(function (key) { return (props[bsMapping[key] || key] = rawProps[key]); });
    return props;
};
/**
 * props2BsProps 的 hoc 版本
 *
 * @param {*} ComposedComponent 组合组件
 * @return {Component}
 */
exports.props2BsPropsHoc = function (ComposedComponent) {
    var BsComponent = /** @class */ (function (_super) {
        tslib_1.__extends(BsComponent, _super);
        function BsComponent() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        BsComponent.prototype.render = function () {
            return React.createElement(ComposedComponent, tslib_1.__assign({}, exports.props2BsProps(this.props)));
        };
        return BsComponent;
    }(React.Component));
    hoistNonReactStatic(BsComponent, ComposedComponent);
    return BsComponent;
};
function getContainer(container, defaultContainer) {
    container = typeof container === 'function' ? container() : container;
    return ReactDOM.findDOMNode(container) || defaultContainer;
}
exports.getContainer = getContainer;
function ownerDocument(componentOrElement) {
    return domHelperWwnerDocument(ReactDOM.findDOMNode(componentOrElement));
}
exports.ownerDocument = ownerDocument;
function getContainerDimensions(containerNode) {
    var width, height, scroll;
    if (containerNode.tagName === 'BODY') {
        width = window.innerWidth;
        height = window.innerHeight;
        scroll = getScrollTop(ownerDocument(containerNode).documentElement) || getScrollTop(containerNode);
    }
    else {
        (_a = getOffset(containerNode), width = _a.width, height = _a.height);
        scroll = getScrollTop(containerNode);
    }
    return { width: width, height: height, scroll: scroll };
    var _a;
}
function getTopDelta(top, overlayHeight, container, padding) {
    var containerDimensions = getContainerDimensions(container);
    var containerScroll = containerDimensions.scroll;
    var containerHeight = containerDimensions.height;
    var topEdgeOffset = top - padding - containerScroll;
    var bottomEdgeOffset = top + padding - containerScroll + overlayHeight;
    if (topEdgeOffset < 0) {
        return -topEdgeOffset;
    }
    else if (bottomEdgeOffset > containerHeight) {
        return containerHeight - bottomEdgeOffset;
    }
    else {
        return 0;
    }
}
function getLeftDelta(left, overlayWidth, container, padding) {
    var containerDimensions = getContainerDimensions(container);
    var containerWidth = containerDimensions.width;
    var leftEdgeOffset = left - padding;
    var rightEdgeOffset = left + padding + overlayWidth;
    if (leftEdgeOffset < 0) {
        return -leftEdgeOffset;
    }
    else if (rightEdgeOffset > containerWidth) {
        return containerWidth - rightEdgeOffset;
    }
    return 0;
}
function calculatePosition(placement, overlayNode, target, container, padding) {
    var childOffset = container.tagName === 'BODY' ? getOffset(target) : getPosition(target, container);
    var _a = getOffset(overlayNode), overlayHeight = _a.height, overlayWidth = _a.width;
    var positionLeft = 0, positionTop = 0, arrowOffsetLeft = '', arrowOffsetTop = '';
    if (~placement.indexOf('-')) {
        var tests = placement.split(/\s+/);
        while (tests.length) {
            var current = tests.shift();
            var _b = current.split('-'), atX = _b[0], atY = _b[1], myX = _b[2], myY = _b[3];
            myX = myX || atX;
            myY = myY || atY;
            positionLeft =
                atX === 'left'
                    ? childOffset.left
                    : atX === 'right'
                        ? childOffset.left + childOffset.width
                        : childOffset.left + childOffset.width / 2;
            positionTop =
                atY === 'top'
                    ? childOffset.top
                    : atY === 'bottom'
                        ? childOffset.top + childOffset.height
                        : childOffset.top + childOffset.height / 2;
            positionLeft -= myX === 'left' ? 0 : myX === 'right' ? overlayWidth : overlayWidth / 2;
            positionTop -= myY === 'top' ? 0 : myY === 'bottom' ? overlayHeight : overlayHeight / 2;
            // 如果还有其他可选项，则做位置判断，是否在可视区域，不完全在则继续看其他定位情况。
            if (tests.length) {
                var clip = target.getBoundingClientRect();
                var transformed = {
                    x: clip.x + positionLeft - childOffset.left,
                    y: clip.y + positionTop - childOffset.top,
                    width: overlayWidth,
                    height: overlayHeight,
                };
                if (transformed.x > 0 &&
                    transformed.x + transformed.width < window.innerWidth &&
                    transformed.y > 0 &&
                    transformed.y + transformed.height < window.innerHeight) {
                    break;
                }
            }
        }
        // todo arrow 位置支持
    }
    else if (placement === 'left' || placement === 'right') {
        // atX = placement;
        // atY = myY = 'center';
        // myX = placement === 'left' ? 'right' : 'left';
        if (placement === 'left') {
            positionLeft = childOffset.left - overlayWidth;
        }
        else {
            positionLeft = childOffset.left + childOffset.width;
        }
        positionTop = childOffset.top + (childOffset.height - overlayHeight) / 2;
        var topDelta = getTopDelta(positionTop, overlayHeight, container, padding);
        positionTop += topDelta;
        arrowOffsetTop = 50 * (1 - (2 * topDelta) / overlayHeight) + '%';
    }
    else if (placement === 'top' || placement === 'bottom') {
        // atY = placement;
        // atX = myX = 'center';
        // myY = placement === 'top' ? 'bottom': 'top';
        if (placement === 'top') {
            positionTop = childOffset.top - overlayHeight;
        }
        else {
            positionTop = childOffset.top + childOffset.height;
        }
        positionLeft = childOffset.left + (childOffset.width - overlayWidth) / 2;
        var leftDelta = getLeftDelta(positionLeft, overlayWidth, container, padding);
        positionLeft += leftDelta;
        arrowOffsetLeft = 50 * (1 - (2 * leftDelta) / overlayHeight) + '%';
    }
    else if ((placement = 'center')) {
        // atX = atY = myX = myY = 'center';
        positionLeft = childOffset.left + (childOffset.width - overlayWidth) / 2;
        positionTop = childOffset.top + (childOffset.height - overlayHeight) / 2;
        arrowOffsetLeft = arrowOffsetTop = void 0;
    }
    else {
        throw new Error("calcOverlayPosition(): No such placement of \"" + placement + "\" found.");
    }
    return { positionLeft: positionLeft, positionTop: positionTop, arrowOffsetLeft: arrowOffsetLeft, arrowOffsetTop: arrowOffsetTop };
}
exports.calculatePosition = calculatePosition;
//# sourceMappingURL=./utils/dom.js.map
