"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Toolbar = exports.FlyoutMenuChildItem = exports.getIconStyle = exports.getEnabled = exports.TOOLBAR_BACKGROUND_COLOR = exports.DEFAULT_TOOLBAR_SIZE = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var type_guards_1 = require("../utils/type-guards");
var context_1 = require("./context");
var string_1 = require("../utils/string");
var icon_1 = require("./icon");
var core_1 = require("@blueprintjs/core");
var constants_1 = require("../constants");
exports.DEFAULT_TOOLBAR_SIZE = 29;
exports.TOOLBAR_BACKGROUND_COLOR = "#f0f0f0";
// Custom type guard to workaround: https://github.com/microsoft/TypeScript/issues/39879
function isNumeric(arg) {
    return typeof (arg) == 'number';
}
// Size is based on the default toolbar height of 29 (with base image icon size of 16x16)
// This ratio will help "scale" SVG icons to match
var SVG_SIZE_RATIO = 16 / exports.DEFAULT_TOOLBAR_SIZE;
function getSelected(item) {
    var sel = item.selected;
    if (sel != null) {
        if (typeof sel === 'function') {
            return sel();
        }
        else {
            return sel;
        }
    }
    return false;
}
function getEnabled(item) {
    var en = item.enabled;
    if (en != null) {
        if (typeof en === 'function') {
            return en();
        }
        else {
            return en;
        }
    }
    return true;
}
exports.getEnabled = getEnabled;
var OpacityIcon = React.memo(function (_a) {
    var opacity = _a.opacity, icon = _a.icon, iconSize = _a.iconSize;
    return React.createElement(core_1.Icon, { style: { opacity: opacity }, icon: icon, iconSize: iconSize });
});
function getIconElement(item, enabled, size) {
    var iconStyle = getIconStyle(enabled, size);
    if (item.iconClass || item.icon) {
        return React.createElement(icon_1.ImageIcon, { style: iconStyle, url: item.icon, spriteClass: item.iconClass });
    }
    else if (item.bpIconName) {
        var opacity = iconStyle.opacity; //For SVG, we only care about opacity
        return React.createElement(OpacityIcon, { opacity: opacity, icon: item.bpIconName, iconSize: size * SVG_SIZE_RATIO });
    }
    else {
        return React.createElement(React.Fragment, null);
    }
}
function getFlyoutIconElement(isFlownOut, size) {
    return React.createElement(core_1.Icon, { icon: isFlownOut ? "chevron-up" : "chevron-down", iconSize: size * SVG_SIZE_RATIO });
}
function getTooltip(item) {
    var tt = item.tooltip;
    if (tt != null) {
        if (typeof tt === 'function') {
            return tt();
        }
        else {
            return tt;
        }
    }
    return string_1.STR_EMPTY;
}
function getIconStyle(enabled, height) {
    var imgStyle = {
        verticalAlign: "middle",
        lineHeight: height
    };
    return imgStyle;
}
exports.getIconStyle = getIconStyle;
function getItemStyle(enabled, selected, size, isMouseOver, vertical) {
    var pad = ((size - 16) / 2);
    var vertPad = 6;
    var style = {
        display: vertical === true ? "block" : "inline-block",
        //height: height,
        paddingLeft: pad,
        paddingRight: pad,
        paddingTop: vertPad,
        paddingBottom: vertPad
    };
    if ((isMouseOver === true && enabled === true) || selected) {
        style.borderWidth = 1;
        style.paddingLeft = pad - 1; //To compensate for border
        style.paddingRight = pad - 1; //To compensate for border
        style.paddingTop = vertPad - 1; //To compensate for border
        style.paddingBottom = vertPad - 1; //To compensate for border
    }
    return style;
}
function getToolbarSeparatorItemStyle(vertical) {
    var style = {
        display: vertical === true ? "block" : "inline-block"
    };
    if (vertical === true) {
        style.paddingTop = 2;
        style.paddingBottom = -2;
        style.marginLeft = 0;
        style.marginRight = 0;
    }
    else {
        style.paddingTop = 0;
        style.paddingBottom = 0;
        style.marginLeft = 2;
        style.marginRight = -2;
    }
    return style;
}
function getMenuItemStyle(enabled, selected, height, isMouseOver) {
    var pad = ((height - 16) / 2);
    var vertPad = 6;
    var style = {
        //height: height,
        paddingLeft: pad,
        paddingRight: pad,
        paddingTop: vertPad,
        paddingBottom: vertPad
    };
    if (enabled && (isMouseOver === true || selected)) {
        style.cursor = "pointer";
        style.border = "1px solid rgb(153, 181, 202)";
        style.paddingLeft = pad - 1; //To compensate for border
        style.paddingRight = pad - 1; //To compensate for border
        style.paddingTop = vertPad - 1; //To compensate for border
        style.paddingBottom = vertPad - 1; //To compensate for border
    }
    return style;
}
var FlyoutMenuChildItem = function (props) {
    var item = props.item;
    var _a = React.useState(false), isMouseOver = _a[0], setIsMouseOver = _a[1];
    var onClick = function () {
        var _a, _b;
        if (getEnabled(item)) {
            (_a = item.invoke) === null || _a === void 0 ? void 0 : _a.call(item);
            (_b = props.onInvoked) === null || _b === void 0 ? void 0 : _b.call(props);
        }
    };
    var onMouseLeave = function () {
        setIsMouseOver(false);
    };
    var onMouseEnter = function () {
        setIsMouseOver(true);
    };
    var height = exports.DEFAULT_TOOLBAR_SIZE;
    var selected = getSelected(item);
    var enabled = getEnabled(item);
    var tt = getTooltip(item);
    var style = getMenuItemStyle(enabled, selected, height, isMouseOver);
    var iconEl = getIconElement(item, enabled, height);
    return React.createElement("li", { className: "noselect flyout-menu-child-item", title: tt, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick },
        React.createElement("div", { style: style },
            iconEl,
            " ",
            item.label));
};
exports.FlyoutMenuChildItem = FlyoutMenuChildItem;
var ComponentFlyoutItem = function (props) {
    var size = props.size, item = props.item, vertical = props.vertical, isFlownOut = props.isFlownOut;
    var toolbarCtx = React.useContext(context_1.ToolbarContext);
    var _a = React.useState(false), isMouseOver = _a[0], setIsMouseOver = _a[1];
    var onClick = function (e) {
        e.preventDefault();
        var flyoutId = item.flyoutId, componentName = item.componentName, componentProps = item.componentProps;
        var newState = !!!isFlownOut;
        if (newState) {
            var rect = e.currentTarget.getBoundingClientRect();
            var metrics = {
                posX: rect.left,
                posY: rect.top,
                width: rect.width,
                height: rect.height,
                vertical: vertical
            };
            toolbarCtx.openComponent(flyoutId, metrics, componentName, componentProps);
        }
        else {
            toolbarCtx.closeComponent(flyoutId);
        }
        return false;
    };
    var onMouseLeave = function () {
        setIsMouseOver(false);
    };
    var onMouseEnter = function () {
        setIsMouseOver(true);
    };
    var selected = getSelected(item);
    var enabled = getEnabled(item);
    var style = getItemStyle(enabled, selected, size, isMouseOver, vertical);
    var label = item.label;
    if (vertical === true) {
        label = React.createElement("div", { className: "rotated-text" },
            React.createElement("span", { className: "rotated-text__inner rotated-text-ccw" }, item.label));
    }
    var ttip = getTooltip(item);
    var iconEl = getIconElement(item, enabled, size);
    return React.createElement("div", { className: "noselect toolbar-flyout-btn ".concat(selected ? "selected-item" : "", " ").concat(isMouseOver ? "mouse-over" : ""), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick, style: style, title: ttip },
        React.createElement("div", { "data-flyout-id": "flyout-".concat(item.flyoutId) },
            iconEl,
            " ",
            label,
            " ",
            getFlyoutIconElement(isFlownOut, size)));
};
var FlyoutMenuReferenceItem = function (props) {
    var size = props.size, menu = props.menu, vertical = props.vertical, isFlownOut = props.isFlownOut;
    var toolbarCtx = React.useContext(context_1.ToolbarContext);
    var _a = React.useState(false), isMouseOver = _a[0], setIsMouseOver = _a[1];
    var onClick = function (e) {
        e.preventDefault();
        var newState = !!!isFlownOut;
        if (newState) {
            var rect = e.currentTarget.getBoundingClientRect();
            var metrics = {
                posX: rect.left,
                posY: rect.top,
                width: rect.width,
                height: rect.height,
                vertical: vertical
            };
            toolbarCtx.openFlyout(menu.flyoutId, metrics);
        }
        else {
            toolbarCtx.closeFlyout(menu.flyoutId);
        }
        return false;
    };
    var onMouseLeave = function () {
        setIsMouseOver(false);
    };
    var onMouseEnter = function () {
        setIsMouseOver(true);
    };
    var selected = getSelected(menu);
    var enabled = getEnabled(menu);
    var style = getItemStyle(enabled, selected, size, isMouseOver, vertical);
    var label = menu.label;
    if (vertical === true) {
        label = React.createElement("div", { className: "rotated-text" },
            React.createElement("span", { className: "rotated-text__inner rotated-text-ccw" }, menu.label));
    }
    var align = menu.flyoutAlign;
    if (!align) {
        align = (vertical === true) ? "right bottom" : "bottom right";
    }
    var ttip = getTooltip(menu);
    var iconEl = getIconElement(menu, enabled, size);
    return React.createElement("div", { className: "noselect toolbar-flyout-btn ".concat(selected ? "selected-item" : "", " ").concat(isMouseOver ? "mouse-over" : ""), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick, style: style, title: ttip },
        React.createElement("div", { "data-flyout-id": "flyout-".concat(menu.flyoutId) },
            iconEl,
            " ",
            label,
            " ",
            getFlyoutIconElement(isFlownOut, size)));
};
var ToolbarSeparator = function (props) {
    var style = getToolbarSeparatorItemStyle(props.vertical);
    if (props.vertical === true) {
        return React.createElement("div", { className: "noselect toolbar-separator-vertical", style: style });
    }
    else {
        return React.createElement("div", { className: "noselect toolbar-separator-horizontal", style: style }, constants_1.NBSP);
    }
};
var ToolbarButton = function (props) {
    var height = props.height, item = props.item, vertical = props.vertical, hideVerticalLabels = props.hideVerticalLabels;
    var _a = React.useState(false), isMouseOver = _a[0], setIsMouseOver = _a[1];
    var onMouseLeave = function () {
        setIsMouseOver(false);
    };
    var onMouseEnter = function () {
        setIsMouseOver(true);
    };
    var onClick = function (e) {
        e.preventDefault();
        var item = props.item;
        var enabled = getEnabled(item);
        if (enabled && item.invoke) {
            item.invoke();
        }
        return false;
    };
    var selected = getSelected(item);
    var enabled = getEnabled(item);
    var style = getItemStyle(enabled, selected, height, isMouseOver, vertical);
    var ttip = null;
    if (typeof (item.tooltip) == 'function') {
        ttip = item.tooltip();
    }
    else {
        ttip = item.tooltip;
    }
    if (!enabled) {
        style.opacity = 0.3;
    }
    var iconEl = getIconElement(item, enabled, height);
    return React.createElement("div", { className: "noselect toolbar-btn ".concat(selected ? "selected-item" : "", " ").concat((isMouseOver && enabled) ? "mouse-over" : ""), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, style: style, title: ttip, onClick: onClick },
        iconEl,
        " ",
        (vertical == true && hideVerticalLabels == true) ? null : item.label);
};
/**
 * A generic toolbar component
 * @param props
 */
var Toolbar = function (props) {
    var containerStyle = props.containerStyle, containerClass = props.containerClass, childItems = props.childItems, vertical = props.vertical, hideVerticalLabels = props.hideVerticalLabels, flyoutStates = props.flyoutStates, onOpenFlyout = props.onOpenFlyout, onCloseFlyout = props.onCloseFlyout, onOpenComponent = props.onOpenComponent, onCloseComponent = props.onCloseComponent;
    var openFlyout = function (id, metrics) { return onOpenFlyout === null || onOpenFlyout === void 0 ? void 0 : onOpenFlyout(id, metrics); };
    var closeFlyout = function (id) { return onCloseFlyout === null || onCloseFlyout === void 0 ? void 0 : onCloseFlyout(id); };
    var openComponent = function (id, metrics, name, props) { return onOpenComponent === null || onOpenComponent === void 0 ? void 0 : onOpenComponent(id, metrics, name, props); };
    var closeComponent = function (id) { return onCloseComponent === null || onCloseComponent === void 0 ? void 0 : onCloseComponent(id); };
    var height = exports.DEFAULT_TOOLBAR_SIZE;
    if (containerStyle) {
        var ch = containerStyle.height;
        if (isNumeric(ch)) {
            height = ch;
        }
    }
    var providerImpl = {
        openFlyout: openFlyout,
        closeFlyout: closeFlyout,
        openComponent: openComponent,
        closeComponent: closeComponent
    };
    return React.createElement(context_1.ToolbarContext.Provider, { value: providerImpl },
        React.createElement("div", { style: containerStyle, className: "has-flyout noselect ".concat(containerClass) }, childItems.map(function (item, index) {
            if ((0, type_guards_1.isComponentFlyout)(item)) {
                var isFlownOut = flyoutStates && !!flyoutStates[item.flyoutId];
                return React.createElement(ComponentFlyoutItem, { key: index, size: height, item: item, vertical: vertical, isFlownOut: isFlownOut });
            }
            else if ((0, type_guards_1.isMenuRef)(item)) {
                var isFlownOut = flyoutStates && !!flyoutStates[item.flyoutId];
                return React.createElement(FlyoutMenuReferenceItem, { key: index, size: height, menu: item, vertical: vertical, isFlownOut: isFlownOut });
            }
            else if (item.isSeparator === true) {
                return React.createElement(ToolbarSeparator, { key: index, size: height, vertical: vertical });
            }
            else {
                return React.createElement(ToolbarButton, { key: index, height: height, item: item, vertical: vertical, hideVerticalLabels: hideVerticalLabels });
            }
        })));
};
exports.Toolbar = Toolbar;
//# sourceMappingURL=toolbar.js.map