"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getActiveValue = void 0;
const get_bullet_spec_1 = require("./get_bullet_spec");
const get_panel_dimensions_1 = require("./get_panel_dimensions");
const constants_1 = require("../../../common/constants");
const create_selector_1 = require("../../../state/create_selector");
const get_active_pointer_position_1 = require("../../../state/selectors/get_active_pointer_position");
const common_1 = require("../../../utils/common");
const constants_2 = require("../renderer/canvas/constants");
const spec_1 = require("../spec");
const theme_1 = require("../theme");
const angular_1 = require("../utils/angular");
exports.getActiveValue = (0, create_selector_1.createCustomCachedSelector)([get_active_pointer_position_1.getActivePointerPosition, get_panel_dimensions_1.getPanelDimensions, get_bullet_spec_1.getBulletSpec], (pointer, dimensions, spec) => {
    if (!pointer)
        return null;
    const { x, y } = pointer;
    const rowIndex = Math.ceil(y / dimensions.panel.height) - 1;
    const columnIndex = Math.ceil(x / dimensions.panel.width) - 1;
    const activePanel = dimensions.rows?.[rowIndex]?.[columnIndex];
    if (!activePanel)
        return null;
    const relativePointer = {
        x: x - activePanel.panel.x,
        y: y - activePanel.panel.y,
    };
    const valueDetails = getPanelValue(activePanel, relativePointer, spec);
    if (!valueDetails || !(0, common_1.isFiniteNumber)(valueDetails.value))
        return null;
    return {
        ...valueDetails,
        rowIndex,
        columnIndex,
        panel: activePanel,
    };
});
function getPanelValue(panel, pointer, spec) {
    const { graphArea, scale } = panel;
    const [min, max] = (0, common_1.sortNumbers)(scale.domain());
    const isWithinDomain = (0, common_1.isBetween)(min, max);
    switch (spec.subtype) {
        case spec_1.BulletSubtype.circle:
        case spec_1.BulletSubtype.halfCircle:
        case spec_1.BulletSubtype.twoThirdsCircle: {
            const { radius } = (0, angular_1.getAngledChartSizing)(graphArea.size, spec.subtype);
            const center = {
                x: graphArea.center.x,
                y: radius + constants_2.TARGET_SIZE / 2,
            };
            const { x, y } = pointer;
            const normalizedPointer = {
                x: x - center.x - graphArea.origin.x - theme_1.GRAPH_PADDING.left,
                y: y - center.y - graphArea.origin.y - theme_1.GRAPH_PADDING.top,
            };
            const distance = Math.sqrt(Math.pow(normalizedPointer.x, 2) + Math.pow(normalizedPointer.y, 2));
            const outerLimit = radius + constants_2.BULLET_SIZE / 2 + constants_2.HOVER_SLOP;
            const innerLimit = radius - constants_2.BULLET_SIZE / 2 - constants_2.HOVER_SLOP;
            if (distance <= outerLimit && distance >= innerLimit) {
                const angleOffset = normalizedPointer.x < 0 && normalizedPointer.y > 0 ? -constants_1.TAU : 0;
                const angle = Math.atan2(normalizedPointer.y, normalizedPointer.x) + angleOffset;
                const value = scale.invert(angle);
                const snapValue = spec.tickSnapStep ? (0, common_1.roundTo)(value, spec.tickSnapStep) : value;
                if (isWithinDomain(snapValue)) {
                    return {
                        value,
                        snapValue,
                        color: panel.colorScale(snapValue).hex(),
                        pixelValue: angle,
                    };
                }
            }
            break;
        }
        case spec_1.BulletSubtype.horizontal: {
            const yCenterOffset = Math.abs(pointer.y - graphArea.origin.y - constants_2.TARGET_SIZE / 2);
            if (yCenterOffset > constants_2.TARGET_SIZE / 2 + constants_2.HOVER_SLOP)
                return;
            const relativeX = pointer.x - theme_1.GRAPH_PADDING.left;
            const [min, max] = scale.range();
            if (relativeX < min || relativeX > max)
                break;
            const value = panel.scale.invert(relativeX);
            const snapValue = spec.tickSnapStep ? (0, common_1.roundTo)(value, spec.tickSnapStep) : value;
            if (isWithinDomain(snapValue)) {
                return {
                    value,
                    snapValue,
                    color: panel.colorScale(snapValue).hex(),
                    pixelValue: relativeX,
                };
            }
            break;
        }
        case spec_1.BulletSubtype.vertical: {
            const xCenterOffset = Math.abs(pointer.x - graphArea.center.x - theme_1.GRAPH_PADDING.left);
            if (xCenterOffset > constants_2.TARGET_SIZE / 2 + constants_2.HOVER_SLOP)
                return;
            const relativeY = panel.panel.height - pointer.y - theme_1.GRAPH_PADDING.bottom;
            const [min, max] = scale.range();
            if (relativeY < min || relativeY > max)
                break;
            const value = panel.scale.invert(relativeY);
            const snapValue = spec.tickSnapStep ? (0, common_1.roundTo)(value, spec.tickSnapStep) : value;
            if (isWithinDomain(snapValue)) {
                return {
                    value,
                    snapValue,
                    color: panel.colorScale(snapValue).hex(),
                    pixelValue: relativeY,
                };
            }
            break;
        }
        default:
            return;
    }
}
//# sourceMappingURL=get_active_value.js.map