import * as tslib_1 from "tslib";
import * as React from 'react';
import { findDOMNode } from 'react-dom';
import { BaseComponent, css, getRTL, getId, KeyCodes } from '../../Utilities';
import { ColumnDragEndLocation, CheckboxVisibility } from './DetailsList.types';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { Icon } from '../../Icon';
import { Layer } from '../../Layer';
import { GroupSpacer } from '../GroupedList/GroupSpacer';
import { CollapseAllVisibility } from '../../GroupedList';
import { DetailsRowCheck } from './DetailsRowCheck';
import { SelectionMode, SELECTION_CHANGE } from '../../utilities/selection/interfaces';
import { DragDropHelper } from '../../utilities/dragdrop/index';
import { DetailsColumn } from '../../components/DetailsList/DetailsColumn';
import { SelectAllVisibility } from './DetailsHeader.types';
import { classNamesFunction } from '../../Utilities';
var getClassNames = classNamesFunction();
var MOUSEDOWN_PRIMARY_BUTTON = 0; // for mouse down event we are using ev.button property, 0 means left button
var MOUSEMOVE_PRIMARY_BUTTON = 1; // for mouse move event we are using ev.buttons property, 1 means left button
var NO_COLUMNS = [];
var DetailsHeaderBase = /** @class */ (function (_super) {
    tslib_1.__extends(DetailsHeaderBase, _super);
    function DetailsHeaderBase(props) {
        var _this = _super.call(this, props) || this;
        _this._rootComponent = React.createRef();
        _this._draggedColumnIndex = -1;
        _this._dropHintDetails = {};
        _this._getDropHintPositions = function () {
            var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
            var columnReorderProps = _this.state.columnReorderProps;
            var prevX = 0;
            var prevMid = 0;
            var prevRef;
            var frozenColumnCountFromStart = columnReorderProps && columnReorderProps.frozenColumnCountFromStart ? columnReorderProps.frozenColumnCountFromStart : 0;
            var frozenColumnCountFromEnd = columnReorderProps && columnReorderProps.frozenColumnCountFromEnd ? columnReorderProps.frozenColumnCountFromEnd : 0;
            for (var i = frozenColumnCountFromStart; i < columns.length - frozenColumnCountFromEnd + 1; i++) {
                if (_this._rootElement) {
                    var dropHintElement = _this._rootElement.querySelectorAll('#columnDropHint_' + i)[0];
                    if (dropHintElement) {
                        if (i === frozenColumnCountFromStart) {
                            prevX = dropHintElement.offsetLeft;
                            prevMid = dropHintElement.offsetLeft;
                            prevRef = dropHintElement;
                        }
                        else {
                            var newMid = (dropHintElement.offsetLeft + prevX) / 2;
                            _this._dropHintDetails[i - 1] = {
                                originX: prevX,
                                startX: prevMid,
                                endX: newMid,
                                dropHintElementRef: prevRef
                            };
                            prevMid = newMid;
                            prevRef = dropHintElement;
                            prevX = dropHintElement.offsetLeft;
                            if (i === columns.length - frozenColumnCountFromEnd) {
                                _this._dropHintDetails[i] = {
                                    originX: prevX,
                                    startX: prevMid,
                                    endX: dropHintElement.offsetLeft,
                                    dropHintElementRef: prevRef
                                };
                            }
                        }
                    }
                }
            }
        };
        /**
         * Based on the given cursor position, finds the nearest drop hint and updates the state to make it visible
         *
         */
        _this._computeDropHintToBeShown = function (clientX) {
            if (_this._rootElement) {
                var clientRect = _this._rootElement.getBoundingClientRect();
                var headerOriginX = clientRect.left;
                var eventXRelativePosition = clientX - headerOriginX;
                var currentDropHintIndex = _this._currentDropHintIndex;
                if (_this._isValidCurrentDropHintIndex()) {
                    if (_this._liesBetween(eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex].startX, _this._dropHintDetails[currentDropHintIndex].endX)) {
                        return;
                    }
                }
                var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
                var columnReorderProps = _this.state.columnReorderProps;
                var frozenColumnCountFromStart = columnReorderProps && columnReorderProps.frozenColumnCountFromStart ? columnReorderProps.frozenColumnCountFromStart : 0;
                var frozenColumnCountFromEnd = columnReorderProps && columnReorderProps.frozenColumnCountFromEnd ? columnReorderProps.frozenColumnCountFromEnd : 0;
                var currentIndex = frozenColumnCountFromStart;
                var lastValidColumn = columns.length - frozenColumnCountFromEnd;
                var indexToUpdate = -1;
                if (_this._isBefore(eventXRelativePosition, _this._dropHintDetails[currentIndex].endX)) {
                    indexToUpdate = currentIndex;
                }
                else if (_this._isAfter(eventXRelativePosition, _this._dropHintDetails[lastValidColumn].startX)) {
                    indexToUpdate = lastValidColumn;
                }
                else if (_this._isValidCurrentDropHintIndex()) {
                    if (_this._dropHintDetails[currentDropHintIndex + 1] &&
                        _this._liesBetween(eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex + 1].startX, _this._dropHintDetails[currentDropHintIndex + 1].endX)) {
                        indexToUpdate = currentDropHintIndex + 1;
                    }
                    else if (_this._dropHintDetails[currentDropHintIndex - 1] &&
                        _this._liesBetween(eventXRelativePosition, _this._dropHintDetails[currentDropHintIndex - 1].startX, _this._dropHintDetails[currentDropHintIndex - 1].endX)) {
                        indexToUpdate = currentDropHintIndex - 1;
                    }
                }
                if (indexToUpdate === -1) {
                    var startIndex = frozenColumnCountFromStart;
                    var endIndex = lastValidColumn;
                    while (startIndex < endIndex) {
                        var middleIndex = Math.ceil((endIndex + startIndex) / 2);
                        if (_this._liesBetween(eventXRelativePosition, _this._dropHintDetails[middleIndex].startX, _this._dropHintDetails[middleIndex].endX)) {
                            indexToUpdate = middleIndex;
                            break;
                        }
                        else if (_this._isBefore(eventXRelativePosition, _this._dropHintDetails[middleIndex].originX)) {
                            endIndex = middleIndex;
                        }
                        else if (_this._isAfter(eventXRelativePosition, _this._dropHintDetails[middleIndex].originX)) {
                            startIndex = middleIndex;
                        }
                    }
                }
                if (indexToUpdate === _this._draggedColumnIndex || indexToUpdate === _this._draggedColumnIndex + 1) {
                    if (_this._isValidCurrentDropHintIndex()) {
                        _this._resetDropHints();
                    }
                }
                else if (currentDropHintIndex !== indexToUpdate && indexToUpdate >= 0) {
                    _this._resetDropHints();
                    _this._updateDropHintElement(_this._dropHintDetails[indexToUpdate].dropHintElementRef, 'inline-block');
                    _this._currentDropHintIndex = indexToUpdate;
                }
            }
        };
        _this._renderColumnSizer = function (_a) {
            var columnIndex = _a.columnIndex;
            var _b = _this.props.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
            var column = columns[columnIndex];
            var columnResizeDetails = _this.state.columnResizeDetails;
            var classNames = _this._classNames;
            return column.isResizable ? (React.createElement("div", { key: column.key + "_sizer", "aria-hidden": true, role: "button", "data-is-focusable": false, onClick: stopPropagation, "data-sizer-index": columnIndex, onBlur: _this._onSizerBlur, className: css(classNames.cellSizer, columnIndex < columns.length - 1 ? classNames.cellSizerStart : classNames.cellSizerEnd, (_c = {},
                    _c[classNames.cellIsResizing] = columnResizeDetails && columnResizeDetails.columnIndex === columnIndex,
                    _c)), onDoubleClick: _this._onSizerDoubleClick.bind(_this, columnIndex) })) : null;
            var _c;
        };
        _this._onRenderColumnHeaderTooltip = function (tooltipHostProps, defaultRender) {
            return React.createElement("span", { className: tooltipHostProps.hostClassName }, tooltipHostProps.children);
        };
        /**
         * Called when the select all toggle is clicked.
         */
        _this._onSelectAllClicked = function () {
            var selection = _this.props.selection;
            if (selection) {
                selection.toggleAllSelected();
            }
        };
        _this._onRootMouseDown = function (ev) {
            var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
            var columnIndex = Number(columnIndexAttr);
            var _a = _this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
            if (columnIndexAttr === null || ev.button !== MOUSEDOWN_PRIMARY_BUTTON) {
                // Ignore anything except the primary button.
                return;
            }
            _this.setState({
                columnResizeDetails: {
                    columnIndex: columnIndex,
                    columnMinWidth: columns[columnIndex].calculatedWidth,
                    originX: ev.clientX
                }
            });
            ev.preventDefault();
            ev.stopPropagation();
        };
        _this._onRootMouseMove = function (ev) {
            var _a = _this.state, columnResizeDetails = _a.columnResizeDetails, isSizing = _a.isSizing;
            if (columnResizeDetails && !isSizing && ev.clientX !== columnResizeDetails.originX) {
                _this.setState({ isSizing: true });
            }
        };
        _this._onRootRef = function (focusZone) {
            if (focusZone) {
                // Need to resolve the actual DOM node, not the component. The element itself will be used for drag/drop and focusing.
                _this._rootElement = findDOMNode(focusZone);
            }
            else {
                _this._rootElement = undefined;
            }
        };
        _this._onRootKeyDown = function (ev) {
            var _a = _this.state, columnResizeDetails = _a.columnResizeDetails, isSizing = _a.isSizing;
            var _b = _this.props, _c = _b.columns, columns = _c === void 0 ? NO_COLUMNS : _c, onColumnResized = _b.onColumnResized;
            var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
            if (!columnIndexAttr || isSizing) {
                return;
            }
            var columnIndex = Number(columnIndexAttr);
            if (!columnResizeDetails) {
                if (ev.which === KeyCodes.enter) {
                    _this.setState({
                        columnResizeDetails: {
                            columnIndex: columnIndex,
                            columnMinWidth: columns[columnIndex].calculatedWidth
                        }
                    });
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            }
            else {
                var increment = void 0;
                if (ev.which === KeyCodes.enter) {
                    _this.setState({
                        columnResizeDetails: undefined
                    });
                    ev.preventDefault();
                    ev.stopPropagation();
                }
                else if (ev.which === KeyCodes.left) {
                    increment = getRTL() ? 1 : -1;
                }
                else if (ev.which === KeyCodes.right) {
                    increment = getRTL() ? -1 : 1;
                }
                if (increment) {
                    if (!ev.shiftKey) {
                        increment *= 10;
                    }
                    _this.setState({
                        columnResizeDetails: tslib_1.__assign({}, columnResizeDetails, { columnMinWidth: columnResizeDetails.columnMinWidth + increment })
                    });
                    if (onColumnResized) {
                        onColumnResized(columns[columnIndex], columnResizeDetails.columnMinWidth + increment, columnIndex);
                    }
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            }
        };
        /**
         * mouse move event handler in the header
         * it will set isSizing state to true when user clicked on the sizer and move the mouse.
         *
         * @private
         * @param {React.MouseEvent} ev (mouse move event)
         */
        _this._onSizerMouseMove = function (ev) {
            var 
            // use buttons property here since ev.button in some edge case is not upding well during the move.
            // but firefox doesn't support it, so we set the default value when it is not defined.
            buttons = ev.buttons;
            var _a = _this.props, onColumnIsSizingChanged = _a.onColumnIsSizingChanged, onColumnResized = _a.onColumnResized, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
            var columnResizeDetails = _this.state.columnResizeDetails;
            if (buttons !== undefined && buttons !== MOUSEMOVE_PRIMARY_BUTTON) {
                // cancel mouse down event and return early when the primary button is not pressed
                _this._onSizerMouseUp(ev);
                return;
            }
            if (ev.clientX !== columnResizeDetails.originX) {
                if (onColumnIsSizingChanged) {
                    onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], true);
                }
            }
            if (onColumnResized) {
                var movement = ev.clientX - columnResizeDetails.originX;
                if (getRTL()) {
                    movement = -movement;
                }
                onColumnResized(columns[columnResizeDetails.columnIndex], columnResizeDetails.columnMinWidth + movement, columnResizeDetails.columnIndex);
            }
        };
        _this._onSizerBlur = function (ev) {
            var columnResizeDetails = _this.state.columnResizeDetails;
            if (columnResizeDetails) {
                _this.setState({
                    columnResizeDetails: undefined,
                    isSizing: false
                });
            }
        };
        /**
         * mouse up event handler in the header
         * clear the resize related state.
         * This is to ensure we can catch double click event
         *
         * @private
         * @param {React.MouseEvent} ev (mouse up event)
         */
        _this._onSizerMouseUp = function (ev) {
            var _a = _this.props, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b, onColumnIsSizingChanged = _a.onColumnIsSizingChanged;
            var columnResizeDetails = _this.state.columnResizeDetails;
            _this.setState({
                columnResizeDetails: undefined,
                isSizing: false
            });
            if (onColumnIsSizingChanged) {
                onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], false);
            }
        };
        var columnReorderProps = props.columnReorderProps || (props.columnReorderOptions && getLegacyColumnReorderProps(props.columnReorderOptions));
        _this.state = {
            columnReorderProps: columnReorderProps,
            columnResizeDetails: undefined,
            groupNestingDepth: _this.props.groupNestingDepth,
            isAllCollapsed: _this.props.isAllCollapsed,
            isAllSelected: !!_this.props.selection && _this.props.selection.isAllSelected()
        };
        _this._onToggleCollapseAll = _this._onToggleCollapseAll.bind(_this);
        _this._onSelectAllClicked = _this._onSelectAllClicked.bind(_this);
        _this._updateDragInfo = _this._updateDragInfo.bind(_this);
        _this._onDragOver = _this._onDragOver.bind(_this);
        _this._onDrop = _this._onDrop.bind(_this);
        _this._getHeaderDragDropOptions = _this._getHeaderDragDropOptions.bind(_this);
        _this._updateDroppingState = _this._updateDroppingState.bind(_this);
        _this._getDropHintPositions = _this._getDropHintPositions.bind(_this);
        _this._computeDropHintToBeShown = _this._computeDropHintToBeShown.bind(_this);
        _this._resetDropHints = _this._resetDropHints.bind(_this);
        _this._isValidCurrentDropHintIndex = _this._isValidCurrentDropHintIndex.bind(_this);
        _this._onRootRef = _this._onRootRef.bind(_this);
        _this._isEventOnHeader = _this._isEventOnHeader.bind(_this);
        _this._onDropIndexInfo = {
            sourceIndex: Number.MIN_SAFE_INTEGER,
            targetIndex: Number.MIN_SAFE_INTEGER
        };
        _this._id = getId('header');
        _this._currentDropHintIndex = Number.MIN_SAFE_INTEGER;
        return _this;
    }
    DetailsHeaderBase.getDerivedStateFromProps = function (newProps, prevState) {
        var columnReorderProps = newProps.columnReorderProps || (newProps.columnReorderOptions && getLegacyColumnReorderProps(newProps.columnReorderOptions));
        var groupNestingDepth = newProps.groupNestingDepth;
        var newState = { columnReorderProps: columnReorderProps, groupNestingDepth: groupNestingDepth };
        if (newProps.isAllCollapsed !== undefined) {
            newState.isAllCollapsed = newProps.isAllCollapsed;
        }
        return newState;
    };
    DetailsHeaderBase.prototype.componentDidMount = function () {
        var selection = this.props.selection;
        var columnReorderProps = this.state.columnReorderProps;
        this._events.on(selection, SELECTION_CHANGE, this._onSelectionChanged);
        // We need to use native on this to avoid MarqueeSelection from handling the event before us.
        this._events.on(this._rootElement, 'mousedown', this._onRootMouseDown);
        this._events.on(this._rootElement, 'keydown', this._onRootKeyDown);
        if (columnReorderProps && this._dragDropHelper) {
            this._subscriptionObject = this._dragDropHelper.subscribe(this._rootElement, this._events, this._getHeaderDragDropOptions());
        }
    };
    DetailsHeaderBase.prototype.componentDidUpdate = function (prevProps) {
        var columnReorderProps = this.state.columnReorderProps;
        if (!columnReorderProps) {
            if (this._subscriptionObject) {
                this._subscriptionObject.dispose();
                delete this._subscriptionObject;
            }
        }
        else if (!this._subscriptionObject && this._dragDropHelper) {
            this._subscriptionObject = this._dragDropHelper.subscribe(this._rootElement, this._events, this._getHeaderDragDropOptions());
        }
        if (this.props !== prevProps && this._onDropIndexInfo.sourceIndex >= 0 && this._onDropIndexInfo.targetIndex >= 0) {
            var _a = prevProps.columns, previousColumns = _a === void 0 ? NO_COLUMNS : _a;
            var _b = this.props.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
            if (previousColumns[this._onDropIndexInfo.sourceIndex].key === columns[this._onDropIndexInfo.targetIndex].key) {
                this._onDropIndexInfo = {
                    sourceIndex: Number.MIN_SAFE_INTEGER,
                    targetIndex: Number.MIN_SAFE_INTEGER
                };
            }
        }
    };
    DetailsHeaderBase.prototype.componentWillUnmount = function () {
        if (this._subscriptionObject) {
            this._subscriptionObject.dispose();
            delete this._subscriptionObject;
        }
    };
    DetailsHeaderBase.prototype.render = function () {
        var _this = this;
        var _a = this.props, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b, ariaLabel = _a.ariaLabel, ariaLabelForSelectAllCheckbox = _a.ariaLabelForSelectAllCheckbox, selectAllVisibility = _a.selectAllVisibility, ariaLabelForSelectionColumn = _a.ariaLabelForSelectionColumn, indentWidth = _a.indentWidth, viewport = _a.viewport, onColumnClick = _a.onColumnClick, onColumnContextMenu = _a.onColumnContextMenu, _c = _a.onRenderColumnHeaderTooltip, onRenderColumnHeaderTooltip = _c === void 0 ? this._onRenderColumnHeaderTooltip : _c, styles = _a.styles, theme = _a.theme;
        var _d = this.state, isAllSelected = _d.isAllSelected, columnResizeDetails = _d.columnResizeDetails, isSizing = _d.isSizing, groupNestingDepth = _d.groupNestingDepth, isAllCollapsed = _d.isAllCollapsed, columnReorderProps = _d.columnReorderProps;
        var showCheckbox = selectAllVisibility !== SelectAllVisibility.none;
        var isCheckboxHidden = selectAllVisibility === SelectAllVisibility.hidden;
        if (!this._dragDropHelper && columnReorderProps) {
            this._dragDropHelper = new DragDropHelper({
                selection: {
                    getSelection: function () {
                        return;
                    }
                },
                minimumPixelsForDrag: this.props.minimumPixelsForDrag
            });
        }
        var frozenColumnCountFromStart = columnReorderProps && columnReorderProps.frozenColumnCountFromStart ? columnReorderProps.frozenColumnCountFromStart : 0;
        var frozenColumnCountFromEnd = columnReorderProps && columnReorderProps.frozenColumnCountFromEnd ? columnReorderProps.frozenColumnCountFromEnd : 0;
        this._classNames = getClassNames(styles, {
            theme: theme,
            isAllSelected: isAllSelected,
            isSelectAllHidden: selectAllVisibility === SelectAllVisibility.hidden,
            isResizingColumn: !!columnResizeDetails && isSizing,
            isSizing: isSizing,
            isAllCollapsed: isAllCollapsed,
            isCheckboxHidden: isCheckboxHidden
        });
        var classNames = this._classNames;
        var isRTL = getRTL();
        return (React.createElement(FocusZone, { role: "row", "aria-label": ariaLabel, className: classNames.root, componentRef: this._rootComponent, ref: this._onRootRef, onMouseMove: this._onRootMouseMove, "data-automationid": "DetailsHeader", style: { minWidth: viewport ? viewport.width : 0 }, direction: FocusZoneDirection.horizontal },
            showCheckbox
                ? [
                    React.createElement("div", { key: "__checkbox", className: classNames.cellIsCheck, "aria-labelledby": this._id + "-check", onClick: !isCheckboxHidden ? this._onSelectAllClicked : undefined, "aria-colindex": 1, role: 'columnheader', "aria-hidden": isCheckboxHidden ? true : undefined }, onRenderColumnHeaderTooltip({
                        hostClassName: css(classNames.checkTooltip),
                        id: this._id + "-checkTooltip",
                        setAriaDescribedBy: false,
                        content: ariaLabelForSelectAllCheckbox,
                        children: (React.createElement(DetailsRowCheck, { id: this._id + "-check", "aria-label": ariaLabelForSelectionColumn, "aria-describedby": ariaLabelForSelectAllCheckbox && !this.props.onRenderColumnHeaderTooltip ? this._id + "-checkTooltip" : undefined, "data-is-focusable": !isCheckboxHidden, isHeader: true, selected: isAllSelected, anySelected: false, canSelect: !isCheckboxHidden, className: classNames.check }))
                    }, this._onRenderColumnHeaderTooltip)),
                    ariaLabelForSelectAllCheckbox && !this.props.onRenderColumnHeaderTooltip ? (React.createElement("label", { key: "__checkboxLabel", id: this._id + "-checkTooltip", className: classNames.accessibleLabel }, ariaLabelForSelectAllCheckbox)) : null
                ]
                : null,
            groupNestingDepth > 0 && this.props.collapseAllVisibility === CollapseAllVisibility.visible ? (React.createElement("div", { className: classNames.cellIsGroupExpander, onClick: this._onToggleCollapseAll, "data-is-focusable": true },
                React.createElement(Icon, { className: classNames.collapseButton, iconName: isRTL ? 'ChevronLeftMed' : 'ChevronRightMed' }))) : null,
            React.createElement(GroupSpacer, { indentWidth: indentWidth, count: groupNestingDepth - 1 }),
            columns.map(function (column, columnIndex) {
                var _isDraggable = columnReorderProps
                    ? columnIndex >= frozenColumnCountFromStart && columnIndex < columns.length - frozenColumnCountFromEnd
                    : false;
                return [
                    columnReorderProps &&
                        (_isDraggable || columnIndex === columns.length - frozenColumnCountFromEnd) &&
                        _this._renderDropHint(columnIndex),
                    React.createElement(DetailsColumn, { column: column, key: column.key, columnIndex: (showCheckbox ? 2 : 1) + columnIndex, parentId: _this._id, isDraggable: _isDraggable, updateDragInfo: _this._updateDragInfo, dragDropHelper: _this._dragDropHelper, onColumnClick: onColumnClick, onColumnContextMenu: onColumnContextMenu, 
                        // Do not render tooltips by default, but allow for override via props.
                        onRenderColumnHeaderTooltip: _this.props.onRenderColumnHeaderTooltip, isDropped: _this._onDropIndexInfo.targetIndex === columnIndex, cellStyleProps: _this.props.cellStyleProps }),
                    _this._renderColumnDivider(columnIndex)
                ];
            }),
            columnReorderProps && frozenColumnCountFromEnd === 0 && this._renderDropHint(columns.length),
            isSizing && (React.createElement(Layer, null,
                React.createElement("div", { className: classNames.sizingOverlay, onMouseMove: this._onSizerMouseMove, onMouseUp: this._onSizerMouseUp })))));
    };
    /** Set focus to the active thing in the focus area. */
    DetailsHeaderBase.prototype.focus = function () {
        return Boolean(this._rootComponent.current && this._rootComponent.current.focus());
    };
    DetailsHeaderBase.prototype._getHeaderDragDropOptions = function () {
        var options = {
            selectionIndex: 1,
            context: { data: this, index: 0 },
            canDrag: function () { return false; },
            canDrop: function () { return true; },
            onDragStart: function () { return undefined; },
            updateDropState: this._updateDroppingState,
            onDrop: this._onDrop,
            onDragEnd: function () { return undefined; },
            onDragOver: this._onDragOver
        };
        return options;
    };
    DetailsHeaderBase.prototype._updateDroppingState = function (newValue, event) {
        if (this._draggedColumnIndex >= 0 && event.type !== 'drop') {
            if (!newValue) {
                this._resetDropHints();
            }
        }
    };
    DetailsHeaderBase.prototype._isValidCurrentDropHintIndex = function () {
        return this._currentDropHintIndex >= 0;
    };
    DetailsHeaderBase.prototype._onDragOver = function (item, event) {
        if (this._draggedColumnIndex >= 0) {
            event.stopPropagation();
            this._computeDropHintToBeShown(event.clientX);
        }
    };
    DetailsHeaderBase.prototype._onDrop = function (item, event) {
        var columnReorderProps = this.state.columnReorderProps;
        // Target index will not get changed if draggeditem is after target item.
        if (this._draggedColumnIndex >= 0 && event) {
            var targetIndex = this._draggedColumnIndex > this._currentDropHintIndex ? this._currentDropHintIndex : this._currentDropHintIndex - 1;
            var isValidDrop = false;
            event.stopPropagation();
            if (this._isValidCurrentDropHintIndex()) {
                isValidDrop = true;
                this._onDropIndexInfo.sourceIndex = this._draggedColumnIndex;
                this._onDropIndexInfo.targetIndex = targetIndex;
            }
            if (isValidDrop) {
                if (columnReorderProps && columnReorderProps.onColumnDrop) {
                    var dragDropDetails = {
                        draggedIndex: this._draggedColumnIndex,
                        targetIndex: targetIndex
                    };
                    columnReorderProps.onColumnDrop(dragDropDetails);
                }
                else if (columnReorderProps && columnReorderProps.handleColumnReorder) {
                    columnReorderProps.handleColumnReorder(this._draggedColumnIndex, targetIndex);
                }
            }
        }
        this._resetDropHints();
        this._dropHintDetails = {};
        this._draggedColumnIndex = -1;
    };
    /**
     * @returns whether or not the "Select All" checkbox column is hidden.
     */
    DetailsHeaderBase.prototype._isCheckboxColumnHidden = function () {
        var _a = this.props, selectionMode = _a.selectionMode, checkboxVisibility = _a.checkboxVisibility;
        return selectionMode === SelectionMode.none || checkboxVisibility === CheckboxVisibility.hidden;
    };
    DetailsHeaderBase.prototype._updateDragInfo = function (props, event) {
        var columnReorderProps = this.state.columnReorderProps;
        var itemIndex = props.itemIndex;
        if (itemIndex >= 0) {
            // Column index is set based on the checkbox
            this._draggedColumnIndex = this._isCheckboxColumnHidden() ? itemIndex - 1 : itemIndex - 2;
            this._getDropHintPositions();
            if (columnReorderProps && columnReorderProps.onColumnDragStart) {
                columnReorderProps.onColumnDragStart(true);
            }
        }
        else if (event && this._draggedColumnIndex >= 0) {
            this._resetDropHints();
            this._draggedColumnIndex = -1;
            this._dropHintDetails = {};
            if (columnReorderProps && columnReorderProps.onColumnDragEnd) {
                var columnDragEndLocation = this._isEventOnHeader(event);
                columnReorderProps.onColumnDragEnd({ dropLocation: columnDragEndLocation }, event);
            }
        }
    };
    DetailsHeaderBase.prototype._resetDropHints = function () {
        if (this._currentDropHintIndex >= 0) {
            this._updateDropHintElement(this._dropHintDetails[this._currentDropHintIndex].dropHintElementRef, 'none');
            this._currentDropHintIndex = Number.MIN_SAFE_INTEGER;
        }
    };
    DetailsHeaderBase.prototype._updateDropHintElement = function (element, displayProperty) {
        element.childNodes[1].style.display = displayProperty;
        element.childNodes[0].style.display = displayProperty;
    };
    DetailsHeaderBase.prototype._liesBetween = function (target, left, right) {
        return getRTL() ? target <= left && target >= right : target >= left && target <= right;
    };
    DetailsHeaderBase.prototype._isBefore = function (a, b) {
        return getRTL() ? a >= b : a <= b;
    };
    DetailsHeaderBase.prototype._isAfter = function (a, b) {
        return getRTL() ? a <= b : a >= b;
    };
    DetailsHeaderBase.prototype._isEventOnHeader = function (event) {
        if (this._rootElement) {
            var clientRect = this._rootElement.getBoundingClientRect();
            if (event.clientX > clientRect.left &&
                event.clientX < clientRect.right &&
                event.clientY > clientRect.top &&
                event.clientY < clientRect.bottom) {
                return ColumnDragEndLocation.header;
            }
        }
    };
    DetailsHeaderBase.prototype._renderColumnDivider = function (columnIndex) {
        var _a = this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
        var column = columns[columnIndex];
        var onRenderDivider = column.onRenderDivider;
        return onRenderDivider
            ? onRenderDivider({ column: column, columnIndex: columnIndex }, this._renderColumnSizer)
            : this._renderColumnSizer({ column: column, columnIndex: columnIndex });
    };
    DetailsHeaderBase.prototype._renderDropHint = function (dropHintIndex) {
        var classNames = this._classNames;
        return (React.createElement("div", { key: 'dropHintKey', className: classNames.dropHintStyle, id: "columnDropHint_" + dropHintIndex },
            React.createElement(Icon, { key: "dropHintCaretKey", "aria-hidden": true, "data-is-focusable": false, "data-sizer-index": dropHintIndex, className: classNames.dropHintCaretStyle, iconName: 'CaretUpSolid8' }),
            React.createElement("div", { key: "dropHintLineKey", "aria-hidden": true, "data-is-focusable": false, "data-sizer-index": dropHintIndex, className: classNames.dropHintLineStyle })));
    };
    /**
     * double click on the column sizer will auto ajust column width
     * to fit the longest content among current rendered rows.
     *
     * @private
     * @param {number} columnIndex (index of the column user double clicked)
     * @param {React.MouseEvent} ev (mouse double click event)
     */
    DetailsHeaderBase.prototype._onSizerDoubleClick = function (columnIndex, ev) {
        var _a = this.props, onColumnAutoResized = _a.onColumnAutoResized, _b = _a.columns, columns = _b === void 0 ? NO_COLUMNS : _b;
        if (onColumnAutoResized) {
            onColumnAutoResized(columns[columnIndex], columnIndex);
        }
    };
    DetailsHeaderBase.prototype._onSelectionChanged = function () {
        var isAllSelected = !!this.props.selection && this.props.selection.isAllSelected();
        if (this.state.isAllSelected !== isAllSelected) {
            this.setState({
                isAllSelected: isAllSelected
            });
        }
    };
    DetailsHeaderBase.prototype._onToggleCollapseAll = function () {
        var onToggleCollapseAll = this.props.onToggleCollapseAll;
        var newCollapsed = !this.state.isAllCollapsed;
        this.setState({
            isAllCollapsed: newCollapsed
        });
        if (onToggleCollapseAll) {
            onToggleCollapseAll(newCollapsed);
        }
    };
    DetailsHeaderBase.defaultProps = {
        selectAllVisibility: SelectAllVisibility.visible,
        collapseAllVisibility: CollapseAllVisibility.visible
    };
    return DetailsHeaderBase;
}(BaseComponent));
export { DetailsHeaderBase };
function getLegacyColumnReorderProps(columnReorderOptions) {
    return tslib_1.__assign({}, columnReorderOptions, { onColumnDragEnd: undefined });
}
function stopPropagation(ev) {
    ev.stopPropagation();
}
//# sourceMappingURL=DetailsHeader.base.js.map