import { utilities } from '@cornerstonejs/core';
import ToolModes from '../../enums/ToolModes';
const { DefaultHistoryMemo } = utilities.HistoryMemo;
class BaseTool {
    static { this.defaults = {
        configuration: {
            strategies: {},
            defaultStrategy: undefined,
            activeStrategy: undefined,
            strategyOptions: {},
        },
    }; }
    constructor(toolProps, defaultToolProps) {
        const mergedDefaults = BaseTool.mergeDefaultProps(BaseTool.defaults, defaultToolProps);
        const initialProps = utilities.deepMerge(mergedDefaults, toolProps);
        const { configuration = {}, supportedInteractionTypes, toolGroupId, } = initialProps;
        this.toolGroupId = toolGroupId;
        this.supportedInteractionTypes = supportedInteractionTypes || [];
        this.configuration = Object.assign({}, configuration);
        this.mode = ToolModes.Disabled;
    }
    static mergeDefaultProps(defaultProps = {}, additionalProps) {
        if (!additionalProps) {
            return defaultProps;
        }
        return utilities.deepMerge(defaultProps, additionalProps);
    }
    get toolName() {
        return this.getToolName();
    }
    getToolName() {
        return this.constructor.toolName;
    }
    applyActiveStrategy(enabledElement, operationData) {
        const { strategies, activeStrategy } = this.configuration;
        return strategies[activeStrategy]?.call(this, enabledElement, operationData);
    }
    applyActiveStrategyCallback(enabledElement, operationData, callbackType, ...extraArgs) {
        const { strategies, activeStrategy } = this.configuration;
        if (!strategies[activeStrategy]) {
            throw new Error(`applyActiveStrategyCallback: active strategy ${activeStrategy} not found, check tool configuration or spellings`);
        }
        return strategies[activeStrategy][callbackType]?.call(this, enabledElement, operationData, ...extraArgs);
    }
    setConfiguration(newConfiguration) {
        this.configuration = utilities.deepMerge(this.configuration, newConfiguration);
    }
    setActiveStrategy(strategyName) {
        this.setConfiguration({ activeStrategy: strategyName });
    }
    getTargetImageData(targetId) {
        if (targetId.startsWith('imageId:')) {
            const imageId = targetId.split('imageId:')[1];
            const imageURI = utilities.imageIdToURI(imageId);
            let viewports = utilities.getViewportsWithImageURI(imageURI);
            if (!viewports || !viewports.length) {
                return;
            }
            viewports = viewports.filter((viewport) => {
                return viewport.getCurrentImageId() === imageId;
            });
            if (!viewports || !viewports.length) {
                return;
            }
            return viewports[0].getImageData();
        }
        else if (targetId.startsWith('volumeId:')) {
            const volumeId = utilities.getVolumeId(targetId);
            const viewports = utilities.getViewportsWithVolumeId(volumeId);
            if (!viewports || !viewports.length) {
                return;
            }
            return viewports[0].getImageData();
        }
        else if (targetId.startsWith('videoId:')) {
            const imageURI = utilities.imageIdToURI(targetId);
            const viewports = utilities.getViewportsWithImageURI(imageURI);
            if (!viewports || !viewports.length) {
                return;
            }
            return viewports[0].getImageData();
        }
        else {
            throw new Error('getTargetIdImage: targetId must start with "imageId:" or "volumeId:"');
        }
    }
    getTargetId(viewport) {
        const targetId = viewport.getViewReferenceId?.();
        if (targetId) {
            return targetId;
        }
        throw new Error('getTargetId: viewport must have a getViewReferenceId method');
    }
    undo() {
        this.doneEditMemo();
        DefaultHistoryMemo.undo();
    }
    redo() {
        DefaultHistoryMemo.redo();
    }
    static createZoomPanMemo(viewport) {
        const state = {
            pan: viewport.getPan(),
            zoom: viewport.getZoom(),
        };
        const zoomPanMemo = {
            restoreMemo: () => {
                const currentPan = viewport.getPan();
                const currentZoom = viewport.getZoom();
                viewport.setZoom(state.zoom);
                viewport.setPan(state.pan);
                viewport.render();
                state.pan = currentPan;
                state.zoom = currentZoom;
            },
        };
        DefaultHistoryMemo.push(zoomPanMemo);
        return zoomPanMemo;
    }
    doneEditMemo() {
        if (this.memo?.commitMemo?.()) {
            DefaultHistoryMemo.push(this.memo);
        }
        this.memo = null;
    }
}
BaseTool.toolName = 'BaseTool';
export default BaseTool;
