var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
define(["require", "exports", "react", "../../Utilities", "./DetailsList.Props", "../../FocusZone", "../../Check", "../../Icon", "../../Layer", "../GroupedList/GroupSpacer", "../../utilities/selection/interfaces", "./DetailsHeader.scss"], function (require, exports, React, Utilities_1, DetailsList_Props_1, FocusZone_1, Check_1, Icon_1, Layer_1, GroupSpacer_1, interfaces_1, DetailsHeader_scss_1) {
    "use strict";
    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 INNER_PADDING = 16;
    var SelectAllVisibility;
    (function (SelectAllVisibility) {
        SelectAllVisibility[SelectAllVisibility["none"] = 0] = "none";
        SelectAllVisibility[SelectAllVisibility["hidden"] = 1] = "hidden";
        SelectAllVisibility[SelectAllVisibility["visible"] = 2] = "visible";
    })(SelectAllVisibility = exports.SelectAllVisibility || (exports.SelectAllVisibility = {}));
    var DetailsHeader = (function (_super) {
        __extends(DetailsHeader, _super);
        function DetailsHeader(props) {
            var _this = _super.call(this, props) || this;
            _this.state = {
                columnResizeDetails: null,
                groupNestingDepth: _this.props.groupNestingDepth,
                isAllCollapsed: _this.props.isAllCollapsed
            };
            _this._onToggleCollapseAll = _this._onToggleCollapseAll.bind(_this);
            _this._onSelectAllClicked = _this._onSelectAllClicked.bind(_this);
            return _this;
        }
        DetailsHeader.prototype.componentDidMount = function () {
            var selection = this.props.selection;
            this._events.on(selection, interfaces_1.SELECTION_CHANGE, this._onSelectionChanged);
            // We need to use native on this to avoid MarqueeSelection from handling the event before us.
            this._events.on(this.refs.root, 'mousedown', this._onRootMouseDown);
        };
        DetailsHeader.prototype.componentWillReceiveProps = function (newProps) {
            var groupNestingDepth = this.state.groupNestingDepth;
            if (newProps.groupNestingDepth !== groupNestingDepth) {
                this.setState({ groupNestingDepth: newProps.groupNestingDepth });
            }
        };
        DetailsHeader.prototype.render = function () {
            var _this = this;
            var _a = this.props, columns = _a.columns, ariaLabel = _a.ariaLabel, ariaLabelForSelectAllCheckbox = _a.ariaLabelForSelectAllCheckbox, selectAllVisibility = _a.selectAllVisibility;
            var _b = this.state, isAllSelected = _b.isAllSelected, columnResizeDetails = _b.columnResizeDetails, isSizing = _b.isSizing, groupNestingDepth = _b.groupNestingDepth, isAllCollapsed = _b.isAllCollapsed;
            return (React.createElement("div", { role: 'row', "aria-label": ariaLabel, className: Utilities_1.css('ms-DetailsHeader', DetailsHeader_scss_1.default.root, (_c = {},
                    _c['is-allSelected ' + DetailsHeader_scss_1.default.rootIsAllSelected] = isAllSelected,
                    _c['is-selectAllHidden ' + DetailsHeader_scss_1.default.rootIsSelectAllHidden] = selectAllVisibility === SelectAllVisibility.hidden,
                    _c['is-resizingColumn'] = !!columnResizeDetails && isSizing,
                    _c)), ref: 'root', onMouseMove: this._onRootMouseMove, "data-automationid": 'DetailsHeader' },
                React.createElement(FocusZone_1.FocusZone, { ref: 'focusZone', direction: FocusZone_1.FocusZoneDirection.horizontal },
                    React.createElement("div", { className: Utilities_1.css('ms-DetailsHeader-cellWrapper', DetailsHeader_scss_1.default.cellWrapper), role: 'columnheader' }, (selectAllVisibility === SelectAllVisibility.visible) ? (React.createElement("button", { type: 'button', className: Utilities_1.css('ms-DetailsHeader-cell is-check', DetailsHeader_scss_1.default.cell, DetailsHeader_scss_1.default.cellIsCheck), onClick: this._onSelectAllClicked, "aria-label": ariaLabelForSelectAllCheckbox, "aria-pressed": isAllSelected },
                        React.createElement(Check_1.Check, { checked: isAllSelected }))) : null),
                    groupNestingDepth > 0 ? (React.createElement("button", { type: 'button', className: Utilities_1.css('ms-DetailsHeader-cell', DetailsHeader_scss_1.default.cell), onClick: this._onToggleCollapseAll },
                        React.createElement(Icon_1.Icon, { className: Utilities_1.css('ms-DetailsHeader-collapseButton', DetailsHeader_scss_1.default.collapseButton, isAllCollapsed && ('is-collapsed ' + DetailsHeader_scss_1.default.collapseButtonIsCollapsed)), iconName: 'ChevronDown' }))) : (null),
                    GroupSpacer_1.GroupSpacer({ count: groupNestingDepth - 1 }),
                    columns.map(function (column, columnIndex) {
                        return (React.createElement("div", { key: column.key, className: Utilities_1.css('ms-DetailsHeader-cellWrapper', DetailsHeader_scss_1.default.cellWrapper), role: 'columnheader', "aria-sort": column.isSorted ? (column.isSortedDescending ? 'descending' : 'ascending') : 'none' },
                            React.createElement("button", { type: 'button', key: column.fieldName, disabled: column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.disabled, className: Utilities_1.css('ms-DetailsHeader-cell', DetailsHeader_scss_1.default.cell, column.headerClassName, (_a = {},
                                    _a['is-actionable ' + DetailsHeader_scss_1.default.cellIsActionable] = column.columnActionsMode !== DetailsList_Props_1.ColumnActionsMode.disabled,
                                    _a['is-empty ' + DetailsHeader_scss_1.default.cellIsEmpty] = !column.name,
                                    _a['is-icon-visible'] = column.isSorted || column.isGrouped || column.isFiltered,
                                    _a)), style: { width: column.calculatedWidth + INNER_PADDING }, onClick: _this._onColumnClick.bind(_this, column), onContextMenu: _this._onColumnContextMenu.bind(_this, column), "aria-haspopup": column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.hasDropdown, "aria-label": column.ariaLabel || column.name, "data-automationid": 'ColumnsHeaderColumn', "data-item-key": column.key },
                                column.isFiltered && (React.createElement(Icon_1.Icon, { className: DetailsHeader_scss_1.default.nearIcon, iconName: 'Filter' })),
                                column.isSorted && (React.createElement(Icon_1.Icon, { className: DetailsHeader_scss_1.default.nearIcon, iconName: column.isSortedDescending ? 'SortDown' : 'SortUp' })),
                                column.isGrouped && (React.createElement(Icon_1.Icon, { className: DetailsHeader_scss_1.default.nearIcon, iconName: 'GroupedDescending' })),
                                column.iconClassName && (React.createElement(Icon_1.Icon, { className: DetailsHeader_scss_1.default.nearIcon, iconName: column.iconClassName })),
                                column.name,
                                column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.hasDropdown && (React.createElement(Icon_1.Icon, { className: Utilities_1.css('ms-DetailsHeader-filterChevron', DetailsHeader_scss_1.default.filterChevron), iconName: 'ChevronDown' }))),
                            (column.isResizable) && (React.createElement("div", { "data-sizer-index": columnIndex, className: Utilities_1.css('ms-DetailsHeader-cell is-sizer', DetailsHeader_scss_1.default.cell, DetailsHeader_scss_1.default.cellIsSizer, (_b = {},
                                    _b['is-resizing ' + DetailsHeader_scss_1.default.cellIsResizing] = isSizing && columnResizeDetails.columnIndex === columnIndex,
                                    _b)), onDoubleClick: _this._onSizerDoubleClick.bind(_this, columnIndex) }))));
                        var _a, _b;
                    })),
                isSizing && (React.createElement(Layer_1.Layer, null,
                    React.createElement("div", { className: Utilities_1.css(isSizing && DetailsHeader_scss_1.default.sizingOverlay), onMouseMove: this._onSizerMouseMove, onMouseUp: this._onSizerMouseUp })))));
            var _c;
        };
        /** Set focus to the active thing in the focus area. */
        DetailsHeader.prototype.focus = function () {
            return this.refs.focusZone.focus();
        };
        /**
         * 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)
         */
        DetailsHeader.prototype._onSizerDoubleClick = function (columnIndex, ev) {
            var _a = this.props, onColumnAutoResized = _a.onColumnAutoResized, columns = _a.columns;
            if (onColumnAutoResized) {
                onColumnAutoResized(columns[columnIndex], columnIndex);
            }
        };
        /**
         * Called when the select all toggle is clicked.
         */
        DetailsHeader.prototype._onSelectAllClicked = function () {
            var selection = this.props.selection;
            selection.toggleAllSelected();
        };
        DetailsHeader.prototype._onRootMouseDown = function (ev) {
            var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
            var columnIndex = Number(columnIndexAttr);
            var columns = this.props.columns;
            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();
        };
        DetailsHeader.prototype._onRootMouseMove = function (ev) {
            var _a = this.state, columnResizeDetails = _a.columnResizeDetails, isSizing = _a.isSizing;
            if (columnResizeDetails && !isSizing && ev.clientX !== columnResizeDetails.originX) {
                this.setState({ isSizing: true });
            }
        };
        /**
         * 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)
         */
        DetailsHeader.prototype._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, columns = _a.columns;
            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 (Utilities_1.getRTL()) {
                    movement = -movement;
                }
                onColumnResized(columns[columnResizeDetails.columnIndex], columnResizeDetails.columnMinWidth + movement);
            }
        };
        /**
         * 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)
         */
        DetailsHeader.prototype._onSizerMouseUp = function (ev) {
            var _a = this.props, columns = _a.columns, onColumnIsSizingChanged = _a.onColumnIsSizingChanged;
            var columnResizeDetails = this.state.columnResizeDetails;
            this.setState({
                columnResizeDetails: null,
                isSizing: false
            });
            if (onColumnIsSizingChanged) {
                onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], false);
            }
        };
        DetailsHeader.prototype._onSelectionChanged = function () {
            var isAllSelected = this.props.selection.isAllSelected();
            if (this.state.isAllSelected !== isAllSelected) {
                this.setState({
                    isAllSelected: isAllSelected
                });
            }
        };
        DetailsHeader.prototype._onColumnClick = function (column, ev) {
            var onColumnClick = this.props.onColumnClick;
            if (column.onColumnClick) {
                column.onColumnClick(ev, column);
            }
            if (onColumnClick) {
                onColumnClick(ev, column);
            }
        };
        DetailsHeader.prototype._onColumnContextMenu = function (column, ev) {
            var onColumnContextMenu = this.props.onColumnContextMenu;
            if (column.onContextMenu) {
                column.onColumnContextMenu(column, ev);
            }
            if (onColumnContextMenu) {
                onColumnContextMenu(column, ev);
            }
        };
        DetailsHeader.prototype._onToggleCollapseAll = function () {
            var onToggleCollapseAll = this.props.onToggleCollapseAll;
            var newCollapsed = !this.state.isAllCollapsed;
            this.setState({
                isAllCollapsed: newCollapsed
            });
            if (onToggleCollapseAll) {
                onToggleCollapseAll(newCollapsed);
            }
        };
        return DetailsHeader;
    }(Utilities_1.BaseComponent));
    DetailsHeader.defaultProps = {
        isSelectAllVisible: SelectAllVisibility.visible
    };
    __decorate([
        Utilities_1.autobind
    ], DetailsHeader.prototype, "_onSelectAllClicked", null);
    __decorate([
        Utilities_1.autobind
    ], DetailsHeader.prototype, "_onRootMouseDown", null);
    __decorate([
        Utilities_1.autobind
    ], DetailsHeader.prototype, "_onRootMouseMove", null);
    __decorate([
        Utilities_1.autobind
    ], DetailsHeader.prototype, "_onSizerMouseMove", null);
    __decorate([
        Utilities_1.autobind
    ], DetailsHeader.prototype, "_onSizerMouseUp", null);
    exports.DetailsHeader = DetailsHeader;
});

//# sourceMappingURL=DetailsHeader.js.map
