/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Picker
 */
import "./ListPicker.scss";
import classnames from "classnames";
import * as React from "react";
import { PopupItem } from "@itwin/components-react";
import { Columns, GroupColumn, Panel, Title, } from "@itwin/components-react/internal";
import { Icon, SearchBox } from "@itwin/core-react";
import { ToolbarDragInteractionContext } from "../toolbar/DragInteraction.js";
import { UiFramework } from "../UiFramework.js";
import { SvgChevronDown, SvgChevronRight, SvgList, } from "@itwin/itwinui-icons-react";
/** Enum for the list picker item type
 * @beta
 */
export var ListItemType;
(function (ListItemType) {
    ListItemType[ListItemType["Item"] = 0] = "Item";
    ListItemType[ListItemType["Separator"] = 1] = "Separator";
    ListItemType[ListItemType["Container"] = 2] = "Container";
})(ListItemType || (ListItemType = {}));
/** List Picker Item React component
 * @beta
 */
export class ListPickerItem extends React.PureComponent {
    /** Renders ListPickerItem */
    render() {
        const itemClassName = classnames("ListPicker-item", this.props.isActive && "is-active", this.props.isFocused && "is-focused", this.props.className);
        // TODO - if cut off, show a title
        const title = this.props.label && this.props.label.length > 25
            ? this.props.label
            : undefined;
        return (
        // eslint-disable-next-line jsx-a11y/click-events-have-key-events
        React.createElement("div", { className: itemClassName, onClick: this.props.onClick, role: "button", tabIndex: -1 },
            React.createElement("div", { className: "label", title: title }, this.props.label)));
    }
}
/** Expandable Section React component
 * @beta
 */
export class ExpandableSection extends React.PureComponent {
    /** Creates an ExpandableSection */
    constructor(props) {
        super(props);
        this.state = { expanded: !!this.props.expanded };
    }
    /** @internal */
    async componentDidUpdate(prevProps) {
        if (this.props.expanded !== prevProps.expanded) {
            this.setState({ expanded: true });
        }
    }
    _onClick = () => {
        this.setState((prevState) => ({ expanded: !prevState.expanded }));
    };
    /** Renders ExpandableSection */
    render() {
        const className = classnames("nz-toolbar-item-expandable-group-group", this.props.className);
        const icon = this.state.expanded ? (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(Icon, { iconSpec: React.createElement(SvgChevronDown, null) })) : (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(Icon, { iconSpec: React.createElement(SvgChevronRight, null) }));
        return (React.createElement(Panel, { className: className, style: this.props.style, key: this.props.title },
            React.createElement("div", { onClick: this._onClick, className: this.state.expanded
                    ? "ListPickerInnerContainer-header-expanded"
                    : "ListPickerInnerContainer-header", role: "button", tabIndex: -1, "aria-expanded": this.state.expanded },
                React.createElement("div", { className: "ListPickerInnerContainer-header-content" },
                    React.createElement("div", { className: "ListPickerInnerContainer-expander" }, icon),
                    React.createElement("div", { className: "ListPickerInnerContainer-title" }, this.props.title))),
            this.state.expanded ? (React.createElement(GroupColumn, null, this.props.children)) : (React.createElement("div", null))));
    }
}
/** @beta */
export function getListPanel(props) {
    const expandSingleSection = () => {
        const populatedContainers = props.items.filter((item) => {
            return (item.type === ListItemType.Container && item.children.length !== 0);
        });
        return populatedContainers.length === 1;
    };
    const listItemToElement = (item, itemIndex) => {
        switch (item.type) {
            case ListItemType.Item:
                return (React.createElement(ListPickerItem, { ...props, key: itemIndex.toString(), label: item.name, isActive: item.enabled, onClick: () => {
                        props.setEnabled(item, !item.enabled);
                    } }));
            case ListItemType.Separator:
                return (React.createElement("div", { key: itemIndex.toString(), className: "ListPicker-separator" }));
            case ListItemType.Container:
                if (item.children.length !== 0) {
                    return (React.createElement(ExpandableSection, { key: itemIndex.toString(), title: item.name, className: "ListPickerInnerContainer", expanded: props.expanded === true
                            ? !expandSingleSection()
                            : expandSingleSection() },
                        React.createElement(GroupColumn, null, item.children.map(listItemToElement))));
                }
                else {
                    return React.createElement("div", { key: itemIndex.toString() });
                }
            default:
                return React.createElement("div", { key: itemIndex.toString() });
        }
    };
    return (React.createElement(Panel, { className: "ListPickerContainer" },
        React.createElement(Title, null, props.title),
        props.searchBox && props.onSearchValueChange && (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(SearchBox, { className: "ListPickerSearchBox", onValueChanged: props.onSearchValueChange })),
        React.createElement(Columns, null,
            React.createElement(GroupColumn, { className: "ListPicker-column" }, props.items.map(listItemToElement)))));
}
/**
 * List picker toolbar popup item.
 * Used to provide an expandable list of items to enable/disable items.
 * @beta
 */
function ListPickerPopupItem(props) {
    const icon = props.icon ??
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        (props.iconSpec ? (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        typeof props.iconSpec === "string" ? (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(Icon, { iconSpec: props.iconSpec })) : (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement("i", { className: "icon uifw-item-svg-icon" }, props.iconSpec))) : (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(Icon, { iconSpec: React.createElement(SvgList, null) })));
    return (React.createElement(ToolbarDragInteractionContext.Consumer, null, (isEnabled) => {
        return props.panelOnly === true ? (getListPanel(props)) : (
        // eslint-disable-next-line @typescript-eslint/no-deprecated
        React.createElement(PopupItem, { className: "ListPicker-button", hideIndicator: isEnabled, icon: icon, title: props.title, panel: getListPanel(props) }));
    }));
}
/**
 * List Picker that lets the user pick from a list of items to enable/disable
 * It also provides options to enable all, disable all and invert selection
 * @beta
 */
export class ListPicker extends React.Component {
    static get Key_All() {
        return -3;
    }
    static get Key_None() {
        return -2;
    }
    static get Key_Invert() {
        return -1;
    }
    static get Key_Separator() {
        return -4;
    }
    /** Creates a ListPicker */
    constructor(props) {
        super(props);
    }
    // Creates an array of items containing the separator and special requests (all, none, invert)
    createItems(items) {
        const newItems = [];
        // Create special buttons (All/None/Invert)
        if (this.props.enableAllFunc) {
            let allEnabled = true;
            items.map((item) => {
                allEnabled = allEnabled && item.enabled;
            });
            newItems.push({
                key: ListPicker.Key_All,
                name: UiFramework.translate("pickerButtons.all"),
                enabled: allEnabled,
                type: ListItemType.Item,
            });
        }
        if (this.props.disableAllFunc) {
            let allDisabled = false;
            items.map((item) => {
                allDisabled = allDisabled || item.enabled;
            });
            newItems.push({
                key: ListPicker.Key_None,
                name: UiFramework.translate("pickerButtons.none"),
                enabled: !allDisabled,
                type: ListItemType.Item,
            });
        }
        if (this.props.invertFunc) {
            newItems.push({
                key: ListPicker.Key_Invert,
                name: UiFramework.translate("pickerButtons.invert"),
                enabled: false,
                type: ListItemType.Item,
            });
        }
        if (this.props.enableAllFunc ||
            this.props.disableAllFunc ||
            this.props.invertFunc) {
            newItems.push({
                key: ListPicker.Key_Separator,
                name: UiFramework.translate("pickerButtons.separator"),
                enabled: false,
                type: ListItemType.Separator,
            });
        }
        // Push items
        items.map((item) => {
            newItems.push(item);
        });
        return newItems;
    }
    /**
     * Checks if item is a special item.
     * @param item Item to check
     */
    isSpecialItem(item) {
        return (item.key === ListPicker.Key_All ||
            item.key === ListPicker.Key_Invert ||
            item.key === ListPicker.Key_None ||
            item.type !== ListItemType.Item ||
            item.key === ListPicker.Key_Separator);
    }
    // Handle enabling/disabling the items
    // This will call the this.props.setEnabled function to provide the parent with a chance to process it
    _setEnabled = (item, enabled) => {
        if (this.isSpecialItem(item)) {
            switch (item.key) {
                case ListPicker.Key_All: {
                    if (this.props.enableAllFunc)
                        this.props.enableAllFunc();
                    return;
                }
                case ListPicker.Key_None: {
                    if (this.props.disableAllFunc)
                        this.props.disableAllFunc();
                    return;
                }
                case ListPicker.Key_Invert: {
                    if (this.props.invertFunc)
                        this.props.invertFunc();
                    return;
                }
            }
        }
        // Call on parent to do processing of the item
        this.props.setEnabled(item, enabled);
    };
    /** Renders ListPicker */
    render() {
        return (React.createElement(ListPickerPopupItem, { ...this.props, title: this.props.title, setEnabled: this._setEnabled, onExpanded: this.props.onExpanded, items: this.createItems(this.props.items), 
            // eslint-disable-next-line @typescript-eslint/no-deprecated
            iconSpec: this.props.iconSpec, icon: this.props.icon }));
    }
}
//# sourceMappingURL=ListPicker.js.map