/* @oracle/oraclejet-preact: undefined */
'use strict';

var jsxRuntime = require('preact/jsx-runtime');
var hooks = require('preact/hooks');
var useLegendContextMenu = require('./useLegendContextMenu-d8d7169f.js');
var useVisEvents = require('./useVisEvents-eb36d5e5.js');
var useLegendDnd = require('./useLegendDnd-d44ffd3c.js');
var mergeProps = require('./mergeProps-e3da7237.js');
var useItemFocus = require('./useItemFocus-0c5fbee7.js');
var PRIVATE_BaseLegend_themes_LegendStyles_css = require('./PRIVATE_BaseLegend/themes/LegendStyles.css.js');
var useCssVars = require('./useCssVars-99ce6e96.js');
var classNames = require('./classNames-c14c6ef3.js');
var useTestId = require('./useTestId-32c35bff.js');
var useVisTouchResponse = require('./useVisTouchResponse-376e11d5.js');
var stringUtils = require('./stringUtils-4e4a6b2b.js');
var compat = require('preact/compat');
var TrackResizeContainer = require('./TrackResizeContainer-96619aba.js');
var useTextDimensions = require('./useTextDimensions-b94e8899.js');
var hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css = require('./hooks/PRIVATE_useVisDnd/themes/VisDndStyles.css.js');
var LegendRendered = require('./LegendRendered-c12152bc.js');

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
function getItem(itemInfo, items) {
    const { itemIdx } = itemInfo;
    if (itemIdx == -1) {
        return items[items.length - 1];
    }
    return items[itemIdx];
}
function getNextItemInfo(itemInfo, items) {
    let itemIdx = itemInfo.itemIdx;
    if (itemIdx == -1) {
        itemIdx = items.length - 1;
    }
    itemIdx = Math.min(items.length - 1, itemIdx + 1);
    if (items[itemIdx].actionable !== 'off') {
        return { sectionIdx: 0, itemIdx };
    }
    else if (itemIdx === items.length - 1) {
        itemIdx = itemIdx - 1;
        return { sectionIdx: 0, itemIdx };
    }
    return getNextItemInfo({ sectionIdx: 0, itemIdx }, items);
}
function getPrevItemInfo(itemInfo, items) {
    let itemIdx = itemInfo.itemIdx;
    if (itemIdx == -1) {
        itemIdx = items.length - 1;
    }
    itemIdx = Math.max(0, itemIdx - 1);
    if (items[itemIdx].actionable !== 'off') {
        return { sectionIdx: 0, itemIdx };
    }
    return getPrevItemInfo({ sectionIdx: 0, itemIdx }, items);
}
/**
 * Returns utils functions for navigation in simple legend.
 * @param items
 * @returns
 */
function getLegendNavUtils(items) {
    return {
        getItem: (itemInfo) => {
            return getItem(itemInfo, items);
        },
        getDetailFromInfo: (itemInfo) => {
            if (!itemInfo || items.length === 0) {
                return { itemId: undefined, data: undefined };
            }
            const item = getItem(itemInfo, items);
            return { itemId: item.id, data: item };
        },
        getPrevItemInfo: (itemInfo) => {
            return getPrevItemInfo(itemInfo, items);
        },
        getNextItemInfo: (itemInfo) => {
            return getNextItemInfo(itemInfo, items);
        }
    };
}

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
const getLinearLegendLayoutInfo = ({ width, getTextDimensions, resolvedVars, orientation, legendFontStylesObj = {}, symbolWidth, items }) => {
    let maxWidth = 0;
    let maxHeight = 0;
    let totalWidth = 0;
    let isWrapped = false;
    const containerWidth = width;
    if (!Object.keys(resolvedVars).length || !getTextDimensions) {
        return;
    }
    const unitLength = parseFloat(resolvedVars['unit']);
    const { maxItemWidth, maxItemHeight, horizontalSectionWidth } = getMaxWidth(items, unitLength, getTextDimensions, legendFontStylesObj, symbolWidth);
    totalWidth = horizontalSectionWidth;
    maxWidth = maxItemWidth;
    maxHeight = maxItemHeight;
    isWrapped = horizontalSectionWidth > containerWidth;
    const legendLayoutInfo = {
        totalWidth,
        maxItemWidth: Math.min(maxWidth, containerWidth),
        maxItemHeight: maxHeight,
        itemsPerRow: orientation === 'vertical' ? 1 : Math.max(1, Math.floor(containerWidth / maxWidth)),
        isWrapped
    };
    return legendLayoutInfo;
};
/**
 * Returns maximum of the width among the items in a section of legend also return the width of the entire section.
 * @param items Legend items array
 * @param unitLength Base  element
 * @param getTextDimensions Text width measurement function
 * @param legendFontStylesObj Legend text font style properties object
 * @param symbolWidth Width of legend symbol
 *
 * @returns
 */
const getMaxWidth = (items, unitLength, getTextDimensions, legendFontStylesObj, symbolWidth, symbolHeight) => {
    let maxItemWidth = 0;
    let maxItemHeight = 0;
    let horizontalSectionWidth = 0;
    let itemSymbolWidth = 0;
    let itemSymbolHeight = 0;
    if (symbolWidth) {
        itemSymbolWidth = unitLength * 1.5 + symbolWidth;
    }
    else {
        //itemSymbolWidth = marginLeft + marginRight + width below expression is simplified
        itemSymbolWidth = 4 * unitLength;
    }
    if (symbolHeight) {
        // symbolHeight/defaultSymbolHeight + symbolPaddingTopBottom
        itemSymbolHeight = symbolHeight + unitLength * 1.7;
    }
    else {
        // symbolHeight/defaultSymbolHeight + symbolPaddingTopBottom
        itemSymbolHeight = 2.5 * unitLength + unitLength * 1.7;
    }
    items?.forEach((item) => {
        const legendItem = item;
        const { width, height } = getTextDimensions(legendItem.text, legendFontStylesObj);
        //itemTextWidth = paddingLeft + paddingRight + width
        const itemTextWidth = unitLength * 2.5 + width;
        //horizontalSectionWidth = total width of the section
        horizontalSectionWidth += itemSymbolWidth + itemTextWidth;
        maxItemWidth = Math.max(maxItemWidth, itemSymbolWidth + itemTextWidth);
        maxItemHeight = Math.max(maxItemHeight, height, itemSymbolHeight);
    });
    return { maxItemWidth, maxItemHeight, horizontalSectionWidth };
};
function _getPreferredSize(_width, _height, items, resolvedVars, orientation, legendFontStylesObj, symbolWidth, symbolHeight, getTextDimensions) {
    if (!getTextDimensions) {
        return undefined;
    }
    const layoutInfo = getLinearLegendLayoutInfo({
        width: _width,
        getTextDimensions,
        resolvedVars,
        orientation,
        legendFontStylesObj,
        symbolWidth: symbolWidth,
        symbolHeight: symbolHeight,
        items
    });
    const { itemsPerCol, itemsPerRow } = useLegendDnd.getGridNums(items.length, layoutInfo, orientation);
    const unitLength = parseFloat(resolvedVars['unit']);
    const preferredWidth = Math.min(_width, itemsPerCol === 1
        ? layoutInfo.totalWidth
        : itemsPerRow
            ? layoutInfo.maxItemWidth * itemsPerRow
            : layoutInfo.totalWidth);
    const paddingLegendItems = 0.8 * unitLength;
    const paddingLegendTopBottom = 1.5 * unitLength;
    const legendHeight = itemsPerCol
        ? layoutInfo.maxItemHeight * itemsPerCol +
            (itemsPerCol - 1) * paddingLegendItems +
            paddingLegendTopBottom
        : layoutInfo.maxItemHeight + paddingLegendTopBottom;
    const preferredHeight = Math.min(_height, legendHeight);
    return { width: Math.ceil(preferredWidth), height: Math.ceil(preferredHeight) };
}

/**
 * A legend displays an interactive description of symbols, colors, etc., used in graphical information representations.
 */
const Legend = compat.forwardRef(({ orientation = 'horizontal', items, isReadOnly = true, onItemAction, onItemHover, onItemFocus, testId, contextMenuConfig, hideAndShowBehavior = 'off', hoverBehavior = 'none', halign = 'start', valign = 'top', ...props }, ref = null) => {
    // Use the context
    const { isGetPreferredSizeReady, width, height } = hooks.useContext(LegendRendered.LegendRenderedContext);
    const { textMeasureContent, getTextDimensions } = useTextDimensions.useTextDimensions();
    const { resolvedVars, cssContent } = useCssVars.useCssVars(useLegendDnd.legendVars);
    const legendFontStylesObj = useLegendDnd.getLegendTextStyle({
        fontStyle: props.textFontStyle,
        fontSize: props.textFontSize?.toString(),
        fontWeight: props.textFontWeight?.toString(),
        fontFamily: props.textFontFamily
    }, resolvedVars);
    const rootRef = hooks.useRef(null);
    compat.useImperativeHandle(ref, () => ({
        _getPreferredSize: (_width, _height) => {
            return _getPreferredSize(_width, _height, items, resolvedVars, orientation, legendFontStylesObj, props.symbolWidth, props.symbolHeight, getTextDimensions);
        }
    }), [
        getTextDimensions,
        resolvedVars,
        orientation,
        legendFontStylesObj,
        props.symbolWidth,
        props.symbolHeight,
        items
    ]);
    if (getTextDimensions &&
        resolvedVars['unit'] != undefined &&
        resolvedVars['fontSize'] != undefined) {
        isGetPreferredSizeReady?.(true);
    }
    const testIdProps = useTestId.useTestId(testId);
    const isTestEnv = testIdProps['data-testid'] !== undefined;
    const rootDimsRef = hooks.useRef();
    const { getItem, getDetailFromInfo, getPrevItemInfo, getNextItemInfo } = getLegendNavUtils(items);
    const isLegendItemActionable = useLegendDnd.getIsLegendItemActionable(items, isReadOnly);
    const hasData = items.length > 0;
    const legendKeyUpHandler = (triggerOnAction, updatefocusedItemInfo, focusedItemInfo) => useLegendDnd.getKeyUpHandler(triggerOnAction, updatefocusedItemInfo, focusedItemInfo, props.hiddenIds != null);
    const { touchResponse, touchResponseStyle } = useVisTouchResponse.useVisTouchResponse({
        type: 'touchStart'
    });
    const { focusedItemInfo, hoveredItemInfo, onContextMenuDismissed, activeId, eventsProps } = useVisEvents.useVisEvent(touchResponse, !isReadOnly, isLegendItemActionable, legendKeyUpHandler, getDetailFromInfo, getPrevItemInfo, getNextItemInfo, onItemAction, onItemHover, onItemFocus, useLegendDnd.isEqualItem, useLegendDnd.getItemInfo, { itemIdx: 0, sectionIdx: 0 }, props.hiddenIds != null);
    const { focusedItemRef } = useItemFocus.useItemFocus(focusedItemInfo);
    const datatipText = useLegendDnd.getDatatipText(items, getItem, focusedItemInfo, hoveredItemInfo);
    const [datatipDisabled, setDatatipDisabled] = hooks.useState(false);
    const { datatipContent, datatipProps: { 'aria-describedby': datatipAriaDescribedby, ...datatipProps } } = useLegendContextMenu.useLegendDatatip({
        text: datatipText,
        rootDimsRef,
        focusedItemInfo,
        focusedItemRef,
        touchResponse,
        isDisabled: datatipDisabled
    });
    const ariaProps = useLegendDnd.getAriaProps(isReadOnly, props['aria-label'], props.hiddenIds, stringUtils.merge([props['aria-describedby'], datatipAriaDescribedby]), props['aria-labelledby']);
    const { contextMenuContent, contextMenuProps } = useLegendContextMenu.useLegendContextMenu({
        rootRef,
        contextMenuConfig: hasData ? contextMenuConfig : undefined,
        focusedItemInfo,
        items,
        isReadOnly,
        onContextMenuDismissed
    });
    const [dragOver, setDragOver] = hooks.useState();
    const { draggable, dndProps, dndContent } = useLegendDnd.useLegendDnd({
        onDrag: props.onDrag,
        onDragStart: props.onDragStart,
        onDragEnd: props.onDragEnd,
        onDragEnter: props.onDragEnter,
        onDragLeave: props.onDragLeave,
        onDragOver: props.onDragOver,
        onDrop: props.onDrop,
        items,
        setDragOver,
        setDatatipDisabled,
        itemDraggable: props.itemDraggable
    });
    const mergedProps = mergeProps.mergeProps(eventsProps, datatipProps, contextMenuProps, dndProps);
    const { legendStyle, renderedLegendStyle } = PRIVATE_BaseLegend_themes_LegendStyles_css.styles;
    return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isGetPreferredSizeReady && (jsxRuntime.jsx(TrackResizeContainer.TrackResizeContainer, { width: width ? `${width}px` : '100%', height: height ? `${height}px` : '100%', class: classNames.classNames([
                    PRIVATE_BaseLegend_themes_LegendStyles_css.styles.flexStyle,
                    PRIVATE_BaseLegend_themes_LegendStyles_css.styles[`${halign}HAlign`],
                    PRIVATE_BaseLegend_themes_LegendStyles_css.styles[`${valign}VAlign`]
                ]), children: function _(width) {
                    const layoutInfo = hooks.useMemo(() => getLinearLegendLayoutInfo({
                        width,
                        getTextDimensions,
                        resolvedVars,
                        orientation,
                        legendFontStylesObj,
                        symbolWidth: props.symbolWidth,
                        symbolHeight: props.symbolHeight,
                        items
                    }), [width]);
                    const { itemsPerCol, itemsPerRow } = useLegendDnd.getGridNums(items.length, layoutInfo);
                    return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { ref: rootRef, tabIndex: isReadOnly ? undefined : 0, role: "application", draggable: draggable, class: classNames.classNames([
                                    legendStyle,
                                    renderedLegendStyle,
                                    dragOver
                                        ? hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css.styles.dndDragOverHTMLStyle
                                        : dragOver === false
                                            ? hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css.styles.dndRejectedStyle
                                            : undefined
                                ]), style: touchResponseStyle, ...testIdProps, ...ariaProps, ...mergedProps, "aria-activedescendant": activeId, children: jsxRuntime.jsx(useLegendContextMenu.BaseLegend, { ...props, focusedItemRef: focusedItemRef, items: items, isReadOnly: isReadOnly, orientation: orientation, sectionIdx: 0, itemsPerRow: itemsPerRow, itemsPerCol: itemsPerCol, itemWidth: layoutInfo?.isWrapped ? layoutInfo?.maxItemWidth : undefined, focusedItemInfo: focusedItemInfo, hoveredItemInfo: hoveredItemInfo, activeId: activeId, hideAndShowBehavior: hideAndShowBehavior, hoverBehavior: hoverBehavior, isTestEnv: isTestEnv }) }), datatipContent, contextMenuContent, dndContent] }));
                } })), textMeasureContent, cssContent] }));
});

exports.Legend = Legend;
//# sourceMappingURL=Legend-7e72e911.js.map
