import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';
import imageIdToURI from '../../utilities/imageIdToURI';
import VoxelManager from '../../utilities/VoxelManager';
import { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';
import cache from '../cache';
export class ImageVolume {
    constructor(props) {
        this._imageIdsIndexMap = new Map();
        this._imageURIsIndexMap = new Map();
        this.cornerstoneImageMetaData = null;
        this.isPreScaled = false;
        this.numTimePoints = null;
        this.numFrames = null;
        const { imageIds, scaling, dimensions, spacing, origin, direction, dataType, volumeId, referencedVolumeId, metadata, referencedImageIds, additionalDetails, voxelManager, numberOfComponents, } = props;
        if (!dataType) {
            throw new Error('Data type is required, please provide a data type as string such as "Uint8Array", "Float32Array", etc.');
        }
        let { imageData } = props;
        this.imageIds = imageIds;
        this.volumeId = volumeId;
        this.metadata = metadata;
        this.dimensions = dimensions;
        this.spacing = spacing;
        this.origin = origin;
        this.direction = direction;
        this.dataType = dataType;
        this.vtkOpenGLTexture = vtkStreamingOpenGLTexture.newInstance();
        this.vtkOpenGLTexture.setVolumeId(volumeId);
        this.voxelManager =
            voxelManager ??
                VoxelManager.createImageVolumeVoxelManager({
                    dimensions,
                    imageIds,
                    numberOfComponents,
                });
        this.numVoxels =
            this.dimensions[0] * this.dimensions[1] * this.dimensions[2];
        if (!imageData) {
            imageData = vtkImageData.newInstance();
            imageData.setDimensions(dimensions);
            imageData.setSpacing(spacing);
            imageData.setDirection(direction);
            imageData.setOrigin(origin);
        }
        imageData.set({
            dataType: dataType,
            voxelManager: this.voxelManager,
            id: volumeId,
            numberOfComponents: numberOfComponents || 1,
        });
        imageData.set({
            hasScalarVolume: false,
        });
        this.imageData = imageData;
        this.numFrames = this._getNumFrames();
        this._reprocessImageIds();
        if (scaling) {
            this.scaling = scaling;
        }
        if (referencedVolumeId) {
            this.referencedVolumeId = referencedVolumeId;
        }
        if (referencedImageIds) {
            this.referencedImageIds = referencedImageIds;
        }
        if (additionalDetails) {
            this.additionalDetails = additionalDetails;
        }
    }
    get sizeInBytes() {
        return this.voxelManager.sizeInBytes;
    }
    get imageIds() {
        return this._imageIds;
    }
    set imageIds(newImageIds) {
        this._imageIds = newImageIds;
        this._reprocessImageIds();
    }
    _reprocessImageIds() {
        this._imageIdsIndexMap.clear();
        this._imageURIsIndexMap.clear();
        this._imageIds.forEach((imageId, i) => {
            const imageURI = imageIdToURI(imageId);
            this._imageIdsIndexMap.set(imageId, i);
            this._imageURIsIndexMap.set(imageURI, i);
        });
    }
    isDynamicVolume() {
        return this.numTimePoints > 1;
    }
    getImageIdIndex(imageId) {
        return this._imageIdsIndexMap.get(imageId);
    }
    getImageIdByIndex(imageIdIndex) {
        return this._imageIds[imageIdIndex];
    }
    getImageURIIndex(imageURI) {
        return this._imageURIsIndexMap.get(imageURI);
    }
    load(callback) {
    }
    destroy() {
        this.imageData.delete();
        this.imageData = null;
        this.voxelManager.clear();
        this.vtkOpenGLTexture.releaseGraphicsResources();
        this.vtkOpenGLTexture.delete();
    }
    invalidate() {
        for (let i = 0; i < this.imageIds.length; i++) {
            this.vtkOpenGLTexture.setUpdatedFrame(i);
        }
        this.imageData.modified();
    }
    modified() {
        this.imageData.modified();
        this.vtkOpenGLTexture.modified();
        this.numFrames = this._getNumFrames();
    }
    removeFromCache() {
        cache.removeVolumeLoadObject(this.volumeId);
    }
    getScalarDataLength() {
        return this.voxelManager.getScalarDataLength();
    }
    _getNumFrames() {
        if (!this.isDynamicVolume()) {
            return this.imageIds.length;
        }
        return this.numTimePoints;
    }
    imageIdIndexToFrameIndex(imageIdIndex) {
        return imageIdIndex % this.numFrames;
    }
    getCornerstoneImages() {
        const { imageIds } = this;
        return imageIds.map((imageId) => {
            return cache.getImage(imageId);
        });
    }
}
export default ImageVolume;
