/* @oracle/oraclejet-preact: undefined */
import { g as getInfo } from './eventsUtils-e5fc62d5.js';
import './accUtils-ce2d6588.js';
import { i as inSpace } from './utils-43235750.js';
import { c as curveThroughPoints } from './pathUtils-1a478322.js';
import { colorSchemeVars } from './Common/themes/themeContract.css.js';
import { a as rgb, r as rgba } from './utils-a4102e03.js';
import { g as getGroupCenterCoord } from './layoutUtils-5d62f2b4.js';
import { u as useDnd } from './useDnd-c5ae190c.js';

/**
 * @license
 * Copyright (c) 2008 %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
/**
 * Returns a straight area path command.
 * @param {array} lineSegmentCoords Polyline top points array.
 * @param {array} bottomCoords Polyline bottom points array.
 * @return {string} Straight area path commands.
 */
function getStraightAreaPath(lineSegmentCoords, bottomCoords) {
    // Create the path data string
    let pathData;
    if (lineSegmentCoords.length > 0) {
        pathData =
            lineSegmentCoords
                .map((lineSegmentCoord, index) => {
                return `${index === 0 ? 'M' : 'L'} ${lineSegmentCoord[0]} ${lineSegmentCoord[1]}`;
            })
                .join(' ') +
                [...bottomCoords]
                    .reverse()
                    .map((bottomCoord) => {
                    return `L ${bottomCoord[0]} ${bottomCoord[1]}`;
                })
                    .join(' ') +
                'Z';
    }
    return pathData;
}
/**
 * Returns a curved area path command, based on cubic hermite splines, that goes through the points in the points array.
 * @param {array} lineSegmentCoords Polyline top points array.
 * @param {array} bottomCoords Polyline bottom points array.
 * @param {boolean} connectWithLine Whether the first point is reached using lineTo. Otherwise, moveTo is used.
 * @param {string} splineType The spline type.
 * @return {string} Curved area path commands.
 */
function getCurveAreaPath(lineSegmentCoords, bottomCoords, connectWithLine, splineType, isBottomSegmentCurved) {
    let pathData;
    if (lineSegmentCoords.length > 0) {
        if (!isBottomSegmentCurved) {
            pathData =
                curveThroughPoints(lineSegmentCoords, connectWithLine, splineType) +
                    [...bottomCoords]
                        .reverse()
                        .map((bottomCoord) => {
                        return `L ${bottomCoord[0]} ${bottomCoord[1]}`;
                    })
                        .join(' ') +
                    'Z';
        }
        else {
            pathData =
                curveThroughPoints(lineSegmentCoords, false, splineType) +
                    ' ' +
                    curveThroughPoints([...bottomCoords].reverse(), true, splineType) +
                    ' Z';
        }
    }
    return pathData;
}

/**
 * @license
 * Copyright (c) 2008 %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
const LABEL_OFFSET = 15;
function getCmdsForArea(lineSegmentCoords, bottomCoords, areaType, isHoriz, isBottomSegmentCurved) {
    if (areaType === 'straight') {
        return getStraightAreaPath(lineSegmentCoords, bottomCoords);
    }
    return getCurveAreaPath(lineSegmentCoords, bottomCoords, false, isHoriz ? 'mh' : 'mv', isBottomSegmentCurved);
}
function getCmdsForLine(lineSegmentCoords, lineType, isHoriz) {
    if (lineType === 'straight') {
        return lineSegmentCoords.join(' ');
    }
    return curveThroughPoints(lineSegmentCoords, false, isHoriz ? 'mh' : 'mv');
}
/**
 * Returns the cumulative series for stacked chart.
 */
function getCumulativeSeries(numSeries, numGroups, getDataItem, hiddenIds, isLog) {
    const series = Array(numSeries)
        .fill(numGroups)
        .map(() => {
        return new Array(numGroups);
    });
    for (let groupIndex = 0; groupIndex < numGroups; groupIndex += 1) {
        let prevValidTotal = undefined;
        for (let seriesIndex = 0; seriesIndex < numSeries; seriesIndex += 1) {
            const item = getDataItem(seriesIndex, groupIndex);
            if (!item ||
                hiddenIds?.has(item.id) ||
                (isLog && item.value !== undefined && item.value <= 0)) {
                series[seriesIndex][groupIndex] = undefined;
                continue;
            }
            if (seriesIndex > 0 && prevValidTotal != null) {
                const prev = series[seriesIndex - 1][groupIndex];
                if (prev != null) {
                    series[seriesIndex][groupIndex] = prev + item.value;
                }
                else {
                    series[seriesIndex][groupIndex] = prevValidTotal + item.value;
                }
            }
            else {
                series[seriesIndex][groupIndex] = item.value;
                prevValidTotal = item.value;
            }
        }
    }
    return series;
}
/**
 * Returns the series data.
 */
function getSeriesData(numSeries, numGroups, getDataItem, hiddenIds, isLog) {
    const series = [];
    for (let seriesIndex = 0; seriesIndex < numSeries; seriesIndex += 1) {
        const currentSeries = [];
        for (let groupIndex = 0; groupIndex < numGroups; groupIndex += 1) {
            const item = getDataItem(seriesIndex, groupIndex);
            if (!item ||
                hiddenIds?.has(item.id) ||
                (isLog && item.value !== undefined && item.value <= 0)) {
                continue;
            }
            currentSeries[groupIndex] =
                item.value !== undefined ? item.value : { x: item.x, y: item.y }; // TODO : Need fix for x as number
        }
        series.push(currentSeries);
    }
    return series;
}
/**
 * Returns the markertype order.
 */
function getMarkers() {
    return ['square', 'circle', 'diamond', 'plus', 'triangleDown', 'triangleUp'];
}
/**
 * Returns the marker fill and stroke depending on the state.
 */
function getMarkerFillAndStroke(// TODO : JET-62244 - Replace getMarkerFillAndStroke function with classes.
isMarkerDisplayed, isSelectionEnabled, isHovered, isFocused, isSelected, seriesColor, itemColor) {
    let fill;
    let stroke;
    let outerStroke;
    if (isSelectionEnabled) {
        if (isSelected) {
            if (isMarkerDisplayed) {
                // TODO: settle on one visual for selected markers: 
                // Selected effect when markers are turned on
                fill = itemColor || seriesColor;
                outerStroke = rgb(colorSchemeVars.palette.neutral[130]);
                stroke = rgb(colorSchemeVars.palette.neutral[0]);
            }
            else {
                // Selected effect when markers are not turned on
                fill = rgb(colorSchemeVars.palette.neutral[0]);
                if (isHovered || isFocused) {
                    stroke = itemColor || seriesColor;
                }
                else {
                    stroke = rgb(colorSchemeVars.palette.neutral[130]);
                }
            }
        }
        else if (isHovered || isFocused) {
            stroke = itemColor || seriesColor;
            fill = rgb(colorSchemeVars.palette.neutral[0]);
        }
        else {
            if (isMarkerDisplayed) {
                fill = itemColor || seriesColor;
                stroke = rgb(colorSchemeVars.palette.neutral[0]);
            }
            else {
                fill = rgba(colorSchemeVars.palette.neutral[0], 0);
                stroke = rgba(colorSchemeVars.palette.neutral[0], 0);
            }
        }
    }
    else if (isMarkerDisplayed) {
        fill = itemColor || seriesColor;
        stroke = rgb(colorSchemeVars.palette.neutral[0]);
    }
    else {
        stroke = isFocused ? itemColor || seriesColor : rgba(colorSchemeVars.palette.neutral[0], 0);
        fill = rgba(colorSchemeVars.palette.neutral[0], 0);
    }
    return { fill, stroke, outerStroke };
}
/**
 * Returns the coordinates of line or area based on orientation and size of the chart.
 */
function getLineAreaSegments(yScale, xScale, data, startIndex, endIndex, isHorizontal, isLog, groups, seriesIndex, getDataItem, timeAxisType, hasXYValues) {
    const segments = [];
    let currentPath = [];
    for (let groupIndex = startIndex; groupIndex < endIndex + 1; groupIndex += 1) {
        let item, value, valueX, valueY;
        if (hasXYValues) {
            item = data[groupIndex];
            valueX = item?.x;
            valueY = item?.y;
        }
        else {
            item = data[groupIndex];
            value = item;
        }
        if (item == null || (isLog && value <= 0 && valueX <= 0 && valueY <= 0)) {
            segments.push(currentPath);
            currentPath = [];
            continue;
        }
        let x, y;
        if (hasXYValues) {
            x = xScale.transform(valueX);
            y = yScale.transform(valueY);
        }
        else {
            x = isHorizontal
                ? yScale.transform(value)
                : getGroupCenterCoord(groups[groupIndex], groupIndex, xScale, getDataItem(seriesIndex, groupIndex), timeAxisType);
            y = isHorizontal
                ? getGroupCenterCoord(groups[groupIndex], groupIndex, xScale, getDataItem(seriesIndex, groupIndex), timeAxisType)
                : yScale.transform(value);
        }
        currentPath.push([x, y]);
        if (groupIndex === endIndex) {
            segments.push(currentPath);
        }
    }
    return segments;
}
/**
 * Returns the markertype order.
 */
function getLabelPosition(labelPosition, tx, ty, labelDims) {
    if (labelPosition === 'aboveMarker') {
        ty = ty - LABEL_OFFSET;
    }
    else if (labelPosition === 'belowMarker') {
        ty = ty + LABEL_OFFSET;
    }
    else if (labelPosition === 'afterMarker') {
        tx = tx + labelDims?.width / 2 + LABEL_OFFSET;
    }
    else if (labelPosition === 'beforeMarker') {
        tx = tx - labelDims?.width / 2 - LABEL_OFFSET;
    }
    return { x: tx, y: ty };
}
// JET-71237 optimize this function
const findSeriesGroupIndexFromId = (series, id, groups, getDataItem) => {
    for (let i = 0; i < series.length; i++) {
        for (let j = 0; j < groups.length; j++) {
            const item = getDataItem && getDataItem(i, j);
            if (item && item.id === id) {
                return {
                    seriesIndex: i,
                    groupIndex: j
                };
            }
        }
    }
    return {
        seriesIndex: 0,
        groupIndex: 0
    };
};

/**
 * @license
 * Copyright (c) %FIRST_YEAR% %CURRENT_YEAR%, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 * @ignore
 */
function getChartDragContext(target, groups, rootRef, event, selectedIds, series, getDataItem, groupDraggable, itemsDraggable) {
    //We search for the key using the target of the event
    const info = getInfo(rootRef, target);
    const seriesIndex = info ? info.seriesIndex : undefined;
    const groupIndex = info ? info.groupIndex : undefined;
    let context;
    if (seriesIndex !== undefined &&
        groupIndex !== undefined &&
        getDataItem?.(seriesIndex, groupIndex)) {
        const currentData = getDataItem(seriesIndex, groupIndex);
        if (itemsDraggable && itemsDraggable(currentData, seriesIndex, groupIndex) == 'on') {
            const data = [];
            if (selectedIds.size > 1 && selectedIds.has(currentData.id)) {
                const iterator = selectedIds.values();
                let current = iterator.next().value;
                while (current !== undefined) {
                    const { seriesIndex, groupIndex } = findSeriesGroupIndexFromId(series, current, groups, getDataItem);
                    data.push({
                        data: getDataItem(seriesIndex, groupIndex),
                        seriesIndex,
                        groupIndex
                    });
                    current = iterator.next().value;
                }
            }
            else {
                data.push({
                    data: getDataItem(seriesIndex, groupIndex),
                    seriesIndex,
                    groupIndex
                });
            }
            context = {
                items: data,
                type: 'items',
                event
            };
        }
    }
    else if (groupIndex !== undefined) {
        if (groupDraggable && groupDraggable(groups[groupIndex])) {
            context = {
                group: groups[groupIndex],
                groupIndex: groupIndex,
                type: 'xAxisTickLabel',
                event
            };
        }
    }
    return context;
}
function getChartDropContext(xSpace, ySpace, plotAreaSpace, event) {
    //We search for the key using the target of the event
    const offSetX = event.offsetX;
    const offSetY = event.offsetY;
    let context;
    if (inSpace(offSetX, offSetY, xSpace)) {
        context = {
            type: 'xAxis',
            x: offSetX - xSpace.x,
            event
        };
    }
    else if (inSpace(offSetX, offSetY, ySpace)) {
        context = {
            type: 'yAxis',
            y: offSetY - ySpace.y,
            event
        };
    }
    else if (inSpace(offSetX, offSetY, plotAreaSpace)) {
        context = {
            type: 'plotArea',
            x: offSetX - plotAreaSpace.x,
            y: offSetY - plotAreaSpace.y,
            event
        };
    }
    return context;
}
function isChartDraggable(series, groups, getDataItem, groupDraggable, itemsDraggable) {
    if (groupDraggable) {
        for (let i = 0; i < groups.length; i++) {
            if (groupDraggable(groups[i]) === 'on') {
                return true;
            }
        }
    }
    if (itemsDraggable && getDataItem) {
        for (let i = 0; i < groups.length; i++) {
            for (let j = 0; j < series.length; j++) {
                if (getDataItem(j, i) && itemsDraggable(getDataItem(j, i), j, i) === 'on') {
                    return true;
                }
            }
        }
    }
    return false;
}
function getDragImageElements(rootRef, context, event) {
    const elems = [];
    let elem;
    const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    const container = document.createElementNS('http://www.w3.org/2000/svg', 'g');
    let width;
    let height;
    if (context?.type === 'items') {
        const items = context.items;
        // only component specific
        for (let i = 0; i < items.length; i++) {
            elem = rootRef.current?.querySelector(`[data-oj-series-index="${items[i].seriesIndex}"][data-oj-group-index="${items[i].groupIndex}"]`);
            if (elem)
                elems.push(elem);
        }
    }
    else if (context?.type === 'xAxisTickLabel') {
        elem = rootRef.current?.querySelector(`[data-oj-group-index="${context?.groupIndex}"]`);
        if (elem)
            elems.push(elem);
    }
    if (elems.length > 0) {
        let minX = Infinity;
        let minY = Infinity;
        let maxX = -Infinity;
        let maxY = -Infinity;
        for (let i = 0; i < elems.length; i++) {
            const bbox = elems[i].getBBox();
            if (bbox.x < minX) {
                minX = bbox.x;
            }
            if (bbox.x + bbox.width > maxX) {
                maxX = bbox.x + bbox.width;
            }
            if (bbox.y < minY) {
                minY = bbox.y;
            }
            if (bbox.y + bbox.height > maxY) {
                maxY = bbox.y + bbox.height;
            }
        }
        // Call getComputedStyles for font on the rootref
        const styles = window.getComputedStyle(elems[0].parentElement);
        for (let i = 0; i < elems.length; i++) {
            elem = elems[i];
            const clone = elem.cloneNode(true);
            container.appendChild(clone);
        }
        container.setAttribute('transform', `translate(${-minX},${-minY})`);
        container.style.fontSize = styles.getPropertyValue('font-size');
        container.style.fontFamily = styles.getPropertyValue('font-family');
        container.style.textAnchor = styles.getPropertyValue('text-anchor');
        container.style.dominantBaseline = styles.getPropertyValue('dominant-baseline');
        width = maxX - minX;
        height = maxY - minY;
        svg.appendChild(container);
        return {
            image: svg,
            offSetX: event.offsetX - minX,
            offSetY: event.offsetY - minY,
            width,
            height
        };
    }
    return null;
}

const useChartDnd = ({ onDragStart, onDrag, onDragEnd, onDragEnter, onDragLeave, onDragOver, onDrop, rootRef, series, selectedIds, groups, getDataItem, groupDraggable, itemsDraggable, xSpace, ySpace, plotAreaSpace, setDragOver, setDatatipDisabled, onSelectionChange }) => {
    const draggable = isChartDraggable(series, groups, getDataItem, groupDraggable, itemsDraggable);
    const getDragContext = function (target, event) {
        return getChartDragContext(target, groups, rootRef, event, selectedIds, series, getDataItem, groupDraggable, itemsDraggable);
    };
    const getDropContext = function (event) {
        const context = getChartDropContext(xSpace, ySpace, plotAreaSpace, event);
        return context;
    };
    const getChartDragImage = function (props) {
        return getDragImageElements(rootRef, props.context, props.event);
    };
    const onPreDndStart = function (context) {
        if (context?.type === 'items') {
            const items = context.items;
            const ids = items.map((item) => item.data.id);
            const data = items.map((item) => item.data);
            onSelectionChange?.({ ids: [...ids], data: [...data] });
        }
    };
    const showDropEffect = function (context) {
        setDragOver({
            accepted: true,
            type: context.type
        });
    };
    const showRejectedDropEffect = function (context) {
        setDragOver({
            accepted: false,
            type: context.type
        });
    };
    const clearDropEffect = function () {
        setDragOver({
            accepted: undefined,
            type: ''
        });
    };
    const { dragProps, dropProps, content } = useDnd({
        onDragStart,
        onDrag,
        onDragEnd,
        onDragEnter,
        onDragLeave,
        onDragOver,
        onDrop,
        getDragContext,
        getDropContext,
        getDragImage: getChartDragImage,
        onPreDndStart,
        setDatatipDisabled,
        showRejectedDropEffect,
        showDropEffect,
        clearDropEffect
    });
    return {
        draggable: draggable,
        dndProps: draggable ? { ...dragProps, ...dropProps } : dropProps,
        dndContent: content
    };
};

export { getSeriesData as a, getLineAreaSegments as b, getCmdsForArea as c, getLabelPosition as d, getMarkerFillAndStroke as e, getCmdsForLine as f, getMarkers as g, getCumulativeSeries as h, useChartDnd as u };
//# sourceMappingURL=useChartDnd-fc7ba21c.js.map
