import { Events } from '../enums';
import { StackViewport, VolumeViewport } from '../RenderingEngine';
import getVolumeViewportScrollInfo from './getVolumeViewportScrollInfo';
import snapFocalPointToSlice from './snapFocalPointToSlice';
import getEnabledElement from '../getEnabledElement';
import triggerEvent from './triggerEvent';
import eventTarget from '../eventTarget';
export default function scroll(viewport, options) {
    const enabledElement = getEnabledElement(viewport.element);
    if (!enabledElement) {
        throw new Error('Scroll::Viewport is not enabled (it might be disabled)');
    }
    if (viewport instanceof StackViewport &&
        viewport.getImageIds().length === 0) {
        throw new Error('Scroll::Stack Viewport has no images');
    }
    const { volumeId, delta, scrollSlabs } = options;
    if (viewport instanceof VolumeViewport) {
        scrollVolume(viewport, volumeId, delta, scrollSlabs);
    }
    else {
        const imageIdIndex = viewport.getCurrentImageIdIndex();
        if (imageIdIndex + delta >
            viewport.getImageIds().length - 1 ||
            imageIdIndex + delta < 0) {
            const eventData = {
                imageIdIndex,
                direction: delta,
            };
            triggerEvent(eventTarget, Events.STACK_SCROLL_OUT_OF_BOUNDS, eventData);
        }
        viewport.scroll(delta, options.debounceLoading, options.loop);
    }
}
export function scrollVolume(viewport, volumeId, delta, scrollSlabs = false) {
    const useSlabThickness = scrollSlabs;
    const { numScrollSteps, currentStepIndex, sliceRangeInfo } = getVolumeViewportScrollInfo(viewport, volumeId, useSlabThickness);
    if (!sliceRangeInfo) {
        return;
    }
    const { sliceRange, spacingInNormalDirection, camera } = sliceRangeInfo;
    const { focalPoint, viewPlaneNormal, position } = camera;
    const { newFocalPoint, newPosition } = snapFocalPointToSlice(focalPoint, position, sliceRange, viewPlaneNormal, spacingInNormalDirection, delta);
    viewport.setCamera({
        focalPoint: newFocalPoint,
        position: newPosition,
    });
    viewport.render();
    const desiredStepIndex = currentStepIndex + delta;
    const VolumeScrollEventDetail = {
        volumeId,
        viewport,
        delta,
        desiredStepIndex,
        currentStepIndex,
        numScrollSteps,
        currentImageId: viewport.getCurrentImageId(),
    };
    if ((desiredStepIndex > numScrollSteps || desiredStepIndex < 0) &&
        viewport.getCurrentImageId()) {
        triggerEvent(eventTarget, Events.VOLUME_VIEWPORT_SCROLL_OUT_OF_BOUNDS, VolumeScrollEventDetail);
    }
    else {
        triggerEvent(eventTarget, Events.VOLUME_VIEWPORT_SCROLL, VolumeScrollEventDetail);
    }
}
