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;
};
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { TabPanel } from './TabPanel';
import { Icon } from './Icon';
import { NavDropdown } from './NavDropdown';
import ReactDOM from 'react-dom';
import Measure from 'react-measure';
import { getElementBorder, getElementMargin, getElementPadding } from './utils';
import { cleanEmptyChildren } from '../utils/functions';
var DROPDOWN_STYLES = {
    visibility: 'hidden',
    position: 'absolute',
    left: '-100%'
};
var TAB_PANEL_STYLES = { whiteSpace: 'nowrap' };
var a11yIdCounter = 1;
var TabPanelOverflowContainer = /** @class */ (function (_super) {
    __extends(TabPanelOverflowContainer, _super);
    function TabPanelOverflowContainer(props, context) {
        var _this = _super.call(this, props, context) || this;
        _this.handleResizeRootContainer = function (contentRect) {
            _this.setState({
                dimensions: contentRect.bounds,
                visibleAmount: -1 // reset to recalculate visible amount
            });
        };
        _this.tabPanelRef = React.createRef();
        _this.dropdownRef = React.createRef();
        _this.dropdownA11yId = 'dropdown' + a11yIdCounter++;
        _this.state = {
            visibleAmount: -1,
            dropdownWidth: -1,
            dimensions: {
                width: -1,
                right: -1
            }
        };
        return _this;
    }
    TabPanelOverflowContainer.prototype.componentDidUpdate = function (prevProps, prevState) {
        var _a = this.state, visibleAmount = _a.visibleAmount, dimensions = _a.dimensions;
        var dropdownNode = ReactDOM.findDOMNode(this.dropdownRef.current);
        if (dropdownNode) {
            var dropdownWidth = dropdownNode.getBoundingClientRect().width;
            if (this.state.dropdownWidth !== dropdownWidth) {
                this.setState({
                    dropdownWidth: dropdownWidth
                });
            }
        }
        var nextVisibleAmount = this.calculateVisibleAmount();
        var actualWidth = dimensions.width;
        var prevWidth = prevState.dimensions.width;
        var isDimensionsChanged = prevWidth !== actualWidth;
        var isChildrenChanged = prevProps.children.length !== this.props.children.length;
        if (isChildrenChanged || isDimensionsChanged) {
            // force to show all items to measure
            nextVisibleAmount = cleanEmptyChildren(this.props.children).length;
        }
        if (visibleAmount !== nextVisibleAmount) {
            this.setState({
                visibleAmount: nextVisibleAmount
            });
        }
    };
    TabPanelOverflowContainer.prototype.calculateVisibleAmount = function () {
        var rootNode = ReactDOM.findDOMNode(this.tabPanelRef.current);
        var dropdownNode = ReactDOM.findDOMNode(this.dropdownRef.current);
        if (!rootNode) {
            return -1;
        }
        var children = Array.from(rootNode.children).filter(function (child) { return child !== dropdownNode; });
        var dropdownNodeWidth = this.state.dropdownWidth;
        var rootNodePaddingRight = getElementPadding(rootNode).paddingRight;
        var rootNodeBorderRight = getElementBorder(rootNode).borderRight;
        var allowedRightBoundaryPoint = this.state.dimensions.right - rootNodePaddingRight - rootNodeBorderRight;
        var lastVisibleIndex = this.findLastVisibleIndex(children, allowedRightBoundaryPoint);
        var isOverflow = lastVisibleIndex !== cleanEmptyChildren(this.props.children).length - 1;
        if (isOverflow) {
            // in case of overflow, recalculate, taking into consideration that dropdown is on the screen
            var lastVisibleIndexIncludingDropdown = this.findLastVisibleIndex(children, allowedRightBoundaryPoint - dropdownNodeWidth);
            lastVisibleIndex = Math.min(lastVisibleIndex, lastVisibleIndexIncludingDropdown);
        }
        return lastVisibleIndex + 1;
    };
    TabPanelOverflowContainer.prototype.findLastVisibleIndex = function (nodes, allowedRightBoundaryPoint) {
        var childIndex = nodes.length - 1;
        var visibleIndex = nodes.length - 1;
        while (childIndex >= 0) {
            var child = nodes[childIndex];
            childIndex--;
            var boundaryRect = child.getBoundingClientRect();
            var rightBoundaryPoint = boundaryRect.right;
            var childRightMargin = getElementMargin(child).marginRight;
            if (rightBoundaryPoint + childRightMargin > allowedRightBoundaryPoint) {
                visibleIndex--;
            }
            else {
                break;
            }
        }
        return visibleIndex;
    };
    TabPanelOverflowContainer.prototype.render = function () {
        var _a = this.props, rawChildren = _a.children, props = __rest(_a, ["children"]);
        var _b = this.state, visibleAmount = _b.visibleAmount, dropdownWidth = _b.dropdownWidth;
        var children = cleanEmptyChildren(rawChildren);
        visibleAmount = visibleAmount === -1 ? children.length : visibleAmount;
        var head = _.take(children, visibleAmount);
        var tail = _.takeRight(children, children.length - visibleAmount);
        var isOverflow = tail.length > 0;
        var resultChildren = head;
        var dropdown = null;
        if (dropdownWidth === -1 || isOverflow) {
            // show it to measure dropdown size, but out of viewport to avoid UI flicker
            var dropdownStyles = null;
            if (dropdownWidth === -1) {
                dropdownStyles = DROPDOWN_STYLES;
            }
            var id = this.dropdownA11yId;
            dropdown = (React.createElement(NavDropdown, { role: "tab", testAutomationId: "menuItemMore", id: id, "aria-label": "menuItemMore", ref: this.dropdownRef, className: "pull-right", title: React.createElement(Icon, { name: "three-dots" }), style: dropdownStyles }, tail));
            if (!isOverflow) {
                dropdown = null;
            }
            if (dropdown) {
                resultChildren.push(dropdown);
            }
        }
        var tabPanel = (React.createElement(TabPanel, __assign({ ref: this.tabPanelRef }, props, { style: TAB_PANEL_STYLES }), resultChildren));
        return (React.createElement(Measure, { bounds: true, onResize: this.handleResizeRootContainer }, function (_a) {
            var measureRef = _a.measureRef;
            return React.createElement("div", { ref: measureRef }, tabPanel);
        }));
    };
    TabPanelOverflowContainer.propTypes = {
        children: PropTypes.node
    };
    TabPanelOverflowContainer.defaultProps = {
        children: null
    };
    return TabPanelOverflowContainer;
}(React.Component));
export { TabPanelOverflowContainer };
//# sourceMappingURL=TabPanelOverflowContainer.js.map