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

var jsxRuntime = require('preact/jsx-runtime');
var compat = require('preact/compat');
var hooks = require('preact/hooks');
var useVisEvents = require('./useVisEvents-eb36d5e5.js');
var mergeProps = require('./mergeProps-e3da7237.js');
var layoutUtils = require('./layoutUtils-c2c02501.js');
var useLegendDnd = require('./useLegendDnd-d44ffd3c.js');
var useLegendContextMenu = require('./useLegendContextMenu-d8d7169f.js');
var useItemFocus = require('./useItemFocus-0c5fbee7.js');
var Flex = require('./Flex-da9f223a.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 useTextDimensions = require('./useTextDimensions-b94e8899.js');
var TrackResizeContainer = require('./TrackResizeContainer-96619aba.js');
var hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css = require('./hooks/PRIVATE_useVisDnd/themes/VisDndStyles.css.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, sections) {
    const { sectionIdx, itemIdx } = itemInfo;
    if (sectionIdx == -1 && itemIdx == -1) {
        const itemsLength = sections[sections.length - 1].items.length;
        return sections[sections.length - 1].items[itemsLength - 1];
    }
    return sections[sectionIdx].items[itemIdx];
}
function getNextItemInfo(itemInfo, sections) {
    let { itemIdx, sectionIdx } = itemInfo;
    if (sectionIdx == -1 && itemIdx == -1) {
        return {
            itemIdx: sections[sections.length - 1].items.length - 1,
            sectionIdx: sections.length - 1
        };
    }
    itemIdx += 1;
    const itemsLength = sections[sectionIdx].items.length;
    if (itemIdx >= itemsLength) {
        if (sectionIdx === sections.length - 1) {
            itemIdx = itemInfo.itemIdx;
        }
        else {
            sectionIdx += 1;
            itemIdx = 0;
        }
    }
    const item = sections[sectionIdx].items[itemIdx]; //TODO : Work for better fix instead of adding 'as LegendItem<D>'
    if (item?.actionable !== 'off') {
        return { itemIdx, sectionIdx };
    }
    return getNextItemInfo({ itemIdx, sectionIdx }, sections);
}
function getPrevItemInfo(itemInfo, sections) {
    let { itemIdx, sectionIdx } = itemInfo;
    if (sectionIdx == -1 && itemIdx == -1) {
        (itemIdx = sections[sections.length - 1].items.length - 1), (sectionIdx = sections.length - 1);
    }
    itemIdx -= 1;
    if (itemIdx < 0) {
        if (sectionIdx === 0) {
            itemIdx = 0;
        }
        else {
            itemIdx = sections[sectionIdx - 1].items.length - 1;
            sectionIdx -= 1;
        }
    }
    const item = sections[sectionIdx].items[itemIdx]; //TODO : Work for better fix instead of adding 'as LegendItem<D>'
    if (item?.actionable !== 'off') {
        return { itemIdx, sectionIdx };
    }
    return getPrevItemInfo({ itemIdx, sectionIdx }, sections);
}
/**
 * Returns utils functions for navigation in simple sectional legend.
 * @param items
 * @returns
 */
function getSectionalNavUtils(sections) {
    return {
        getItem: (itemInfo) => {
            return getItem(itemInfo, sections);
        },
        getDetailFromInfo: (itemInfo) => {
            if (!itemInfo || sections.length === 0) {
                return { itemId: undefined, sectionId: undefined, data: undefined };
            }
            const item = getItem(itemInfo, sections);
            const sectionId = sections[itemInfo.sectionIdx].id;
            return {
                itemId: item.id,
                sectionId: sectionId,
                data: sections[itemInfo.sectionIdx].items[itemInfo.itemIdx]
            };
        },
        getPrevItemInfo: (itemInfo) => {
            return getPrevItemInfo(itemInfo, sections);
        },
        getNextItemInfo: (itemInfo) => {
            return getNextItemInfo(itemInfo, sections);
        }
    };
}

/**
 * @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 getSectionalLegendLayoutInfo = ({ width, getTextDimensions, resolvedVars, rootRef, orientation, legendFontStylesObj = {}, symbolWidth, symbolHeight, sections }) => {
    let maxWidth = 0;
    let maxHeight = 0;
    let totalWidth = 0;
    const containerWidth = width;
    if (!rootRef.current || !Object.keys(resolvedVars).length || !getTextDimensions) {
        return;
    }
    const unitLength = parseFloat(resolvedVars['unit']);
    let currentRowWidth = 0;
    let maxRowWidth = 0;
    const isSectionWrappedArray = [];
    const isLegendWrappedArray = [];
    const itemsPerRowArray = [];
    let legendHeight = 0;
    const paddingTop = 0.75 * unitLength;
    // const paddingBottom = 1.5 * unitLength;
    sections.forEach((section, index) => {
        let isSectionWrapped = false;
        let isLegendWrapped = false;
        let totalSectionalWidth;
        let rowsAndCol;
        // getTextDimensions calculating text height as +6 from orignal size
        const titleDims = getTextDimensions(section.title, { fontWeight: '600' });
        //0.5 is adjustment made as getTextdimensions is not calculating correct height
        const titleHeight = titleDims.height + paddingTop + 0.5;
        const titlePaddingStart = 3;
        const titleWidth = titleDims.width + titlePaddingStart;
        const { maxItemWidth, maxItemHeight, horizontalSectionWidth } = getMaxWidth(section.items, unitLength, getTextDimensions, legendFontStylesObj, symbolWidth, symbolHeight);
        let initialNumberOfItemsPerRow = section.items.length;
        const rowGap = 4 * unitLength;
        if (titleWidth + horizontalSectionWidth < containerWidth) {
            totalSectionalWidth = horizontalSectionWidth + titleWidth;
            if (currentRowWidth !== 0 &&
                currentRowWidth + rowGap + totalSectionalWidth < containerWidth &&
                !isLegendWrappedArray[index - 1]) {
                currentRowWidth = currentRowWidth + totalSectionalWidth + rowGap;
            }
            else {
                currentRowWidth = totalSectionalWidth;
                legendHeight += Math.max(titleHeight, maxItemHeight);
                if (index !== 0) {
                    legendHeight += rowGap;
                }
            }
        }
        else {
            isSectionWrapped = true;
            totalSectionalWidth = horizontalSectionWidth;
            const rowPadding = 0.4 * unitLength;
            if (horizontalSectionWidth > containerWidth) {
                isLegendWrapped = true;
                currentRowWidth = 0;
                initialNumberOfItemsPerRow = Math.floor(containerWidth / maxItemWidth);
                rowsAndCol = useLegendDnd.getSectionGridNums(section.items.length, initialNumberOfItemsPerRow);
                if (rowsAndCol.itemsPerCol && rowsAndCol.itemsPerRow) {
                    legendHeight += titleHeight + 2 * (maxItemHeight + rowPadding) + 2 * paddingTop;
                    currentRowWidth = rowsAndCol.itemsPerRow * maxItemWidth;
                    if (rowsAndCol.itemsPerCol > 2) {
                        //here padding gets added to top and bottom
                        legendHeight += (rowsAndCol.itemsPerCol - 2) * (maxItemHeight + 2 * rowPadding);
                    }
                }
            }
            else {
                currentRowWidth = totalSectionalWidth;
                legendHeight += maxItemHeight + titleHeight + 2 * paddingTop;
                if (index !== 0) {
                    legendHeight += rowGap;
                }
            }
        }
        maxRowWidth = Math.max(currentRowWidth, maxRowWidth);
        totalWidth += horizontalSectionWidth;
        maxWidth = Math.max(maxWidth, maxItemWidth);
        maxHeight = maxItemHeight;
        isSectionWrappedArray.push(isSectionWrapped);
        isLegendWrappedArray.push(isLegendWrapped);
        itemsPerRowArray.push(orientation === 'vertical' ? 1 : Math.max(1, initialNumberOfItemsPerRow));
    });
    const legendLayoutInfo = {
        maxRowWidth: Math.ceil(maxRowWidth),
        legendHeight,
        totalWidth,
        maxItemWidth: Math.min(maxWidth, containerWidth),
        maxItemHeight: Math.ceil(maxHeight),
        itemsPerRowArray,
        isSectionWrappedArray,
        isLegendWrappedArray
    };
    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;
    const symbolPadding = unitLength * 1.5;
    if (symbolWidth) {
        itemSymbolWidth = symbolPadding + symbolWidth;
    }
    else {
        //below expression is simplified as, itemSymbolWidth = marginLeft + marginRight + width
        itemSymbolWidth = 4 * unitLength;
    }
    const paddingTop = 1.7 * unitLength;
    const defaultSymbolHeight = 2.5 * unitLength;
    if (symbolHeight) {
        // symbolHeight/defaultSymbolHeight + paddingTopBottom
        itemSymbolHeight = symbolHeight + paddingTop;
    }
    else {
        itemSymbolHeight = defaultSymbolHeight + paddingTop;
    }
    const paddingLeftRight = 2.5 * unitLength;
    items?.forEach((item) => {
        const legendItem = item;
        const { width, height } = getTextDimensions(legendItem.text, legendFontStylesObj);
        //itemTextWidth = paddingLeft + paddingRight + width
        const itemTextWidth = paddingLeftRight + 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 };
};

/**
 * A Sectional Legend allows grouping of legend items in sections with a specific title.
 */
const SectionalLegend = compat.forwardRef(({ orientation = 'horizontal', sectionTitleHAlign = 'start', sections, isReadOnly = true, onItemAction, onItemHover, onItemFocus, testId, contextMenuConfig, hideAndShowBehavior = 'off', hoverBehavior = 'none', valign = 'top', halign = 'start', ...props }, ref = null) => {
    return (jsxRuntime.jsx(TrackResizeContainer.TrackResizeContainer, { width: '100%', height: '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, _height) {
            const testIdProps = useTestId.useTestId(testId);
            const rootRef = hooks.useRef(null);
            const isTestEnv = testIdProps['data-testid'] !== undefined;
            const rootDimsRef = hooks.useRef();
            const { resolvedVars, cssContent } = useCssVars.useCssVars(useLegendDnd.legendVars);
            const { getItem, getDetailFromInfo, getPrevItemInfo, getNextItemInfo } = getSectionalNavUtils(sections);
            const legendFontStylesObj = useLegendDnd.getLegendTextStyle({
                fontStyle: props.textFontStyle,
                fontSize: props.textFontSize?.toString(),
                fontWeight: props.textFontWeight?.toString(),
                fontFamily: props.textFontFamily
            }, resolvedVars);
            const { textMeasureContent, getTextDimensions } = useTextDimensions.useTextDimensions();
            const isLegendItemActionable = useLegendDnd.getIsLegendItemActionable(sections, isReadOnly, true);
            const hasData = sections.length > 0;
            const layoutInfo = getSectionalLegendLayoutInfo({
                width,
                rootRef,
                getTextDimensions,
                resolvedVars,
                orientation,
                legendFontStylesObj,
                symbolWidth: props.symbolWidth,
                symbolHeight: props.symbolHeight,
                sections
            });
            const { touchResponse, touchResponseStyle } = useVisTouchResponse.useVisTouchResponse({ type: 'touchStart' });
            const { focusedItemInfo, hoveredItemInfo, onContextMenuDismissed, activeId, eventsProps } = useVisEvents.useVisEvent(touchResponse, !isReadOnly, isLegendItemActionable, useLegendDnd.getKeyUpHandler, getDetailFromInfo, getPrevItemInfo, getNextItemInfo, onItemAction, onItemHover, onItemFocus, useLegendDnd.isEqualItem, useLegendDnd.getItemInfo, { itemIdx: 0, sectionIdx: 0 });
            const { focusedItemRef } = useItemFocus.useItemFocus(focusedItemInfo);
            const text = useLegendDnd.getDatatipText(sections, getItem, focusedItemInfo, hoveredItemInfo);
            const [datatipDisabled, setDatatipDisabled] = hooks.useState(false);
            const { datatipContent, datatipProps: { 'aria-describedby': datatipAriaDescribedby, ...datatipProps } } = useLegendContextMenu.useLegendDatatip({
                text,
                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.useSectionalLegendContextMenu({
                rootRef,
                contextMenuConfig: hasData ? contextMenuConfig : undefined,
                focusedItemInfo,
                sections,
                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,
                sections,
                setDragOver,
                setDatatipDisabled,
                itemDraggable: props.itemDraggable
            });
            const mergedProps = mergeProps.mergeProps(eventsProps, datatipProps, contextMenuProps, dndProps);
            const titleStyle = {
                fontFamily: props.sectionTitleFontFamily,
                fontSize: props.sectionTitleFontSize,
                color: props.sectionTitleColor,
                fontStyle: props.sectionTitleFontStyle,
                fontWeight: props.sectionTitleFontWeight,
                textDecoration: props.sectionTitleTextDecoration
            };
            const { sectionalLegendBaseStyles, renderedLegendStyle } = PRIVATE_BaseLegend_themes_LegendStyles_css.styles;
            const isHoriz = orientation === 'horizontal';
            hooks.useImperativeHandle(ref, () => ({
                _getPreferredSize: (_width, _height) => {
                    const legendLayoutInfo = getSectionalLegendLayoutInfo({
                        width: _width,
                        getTextDimensions,
                        resolvedVars,
                        rootRef,
                        orientation,
                        legendFontStylesObj,
                        symbolWidth: props.symbolWidth,
                        symbolHeight: props.symbolHeight,
                        sections
                    });
                    if (legendLayoutInfo) {
                        return {
                            width: legendLayoutInfo?.maxRowWidth,
                            height: legendLayoutInfo?.legendHeight
                        };
                    }
                    else {
                        return;
                    }
                }
            }), [getTextDimensions, legendFontStylesObj, resolvedVars]);
            return (jsxRuntime.jsxs("div", { ref: rootRef, tabIndex: isReadOnly ? undefined : 0, role: "application", class: classNames.classNames([
                    sectionalLegendBaseStyles,
                    renderedLegendStyle,
                    dragOver
                        ? hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css.styles.dndDragOverHTMLStyle
                        : dragOver === false
                            ? hooks_PRIVATE_useVisDnd_themes_VisDndStyles_css.styles.dndRejectedStyle
                            : undefined
                ]), draggable: draggable, style: touchResponseStyle, ...testIdProps, ...ariaProps, ...mergedProps, "aria-activedescendant": activeId, children: [jsxRuntime.jsx(Flex.Flex, { direction: isHoriz ? 'row' : 'column', wrap: 'wrap', gap: '4x', children: sections.map((section, index) => {
                            const labelledById = !isReadOnly ? layoutUtils.getRandomId() : '';
                            const isWrappedSection = layoutInfo
                                ? layoutInfo.isSectionWrappedArray[index]
                                : false;
                            const flexDirection = !isHoriz || isWrappedSection ? 'column' : 'row';
                            const alignItems = !isHoriz || isWrappedSection ? 'start' : 'center';
                            const { itemsPerCol, itemsPerRow } = useLegendDnd.getSectionGridNums(section.items.length, layoutInfo?.itemsPerRowArray[index]);
                            return (jsxRuntime.jsxs(Flex.Flex, { align: alignItems, direction: flexDirection, maxWidth: '100%', justify: 'start', wrap: "wrap", children: [jsxRuntime.jsx(useLegendContextMenu.LegendText, { text: section.title, ...titleStyle, type: "title", id: labelledById, align: sectionTitleHAlign }), jsxRuntime.jsx(useLegendContextMenu.BaseLegend, { ...props, focusedItemRef: focusedItemRef, labelledBy: labelledById, sectionIdx: index, items: section.items, orientation: orientation, itemsPerRow: itemsPerRow, itemsPerCol: itemsPerCol, itemWidth: layoutInfo?.isLegendWrappedArray[index]
                                            ? layoutInfo?.maxItemWidth
                                            : undefined, isReadOnly: isReadOnly, focusedItemInfo: focusedItemInfo, hoveredItemInfo: hoveredItemInfo, activeId: activeId, hideAndShowBehavior: hideAndShowBehavior, hoverBehavior: hoverBehavior, isTestEnv: isTestEnv })] }));
                        }) }), datatipContent, textMeasureContent, cssContent, contextMenuContent, dndContent] }));
        } }));
});

exports.SectionalLegend = SectionalLegend;
//# sourceMappingURL=SectionalLegend-ea2ac46d.js.map
