using DicomObjects;
using DicomObjects.Enums;
using DicomObjects.Internal;
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace MyHTJ2KCodec
{
    internal class MyHTJ2KDecoder : DicomObjects.Codecs.IDecompressor
    {
        [DllImport("OpenJPHWrapper.dll")]
        public static extern IntPtr Create();

        [DllImport("OpenJPHWrapper.dll")]
        public static extern IntPtr Decompress(IntPtr wrapper, byte[] compressedData, IntPtr dataSize, string photometricInterpretation,
            IntPtr planarConfig, out IntPtr decompressedSize);
        public void Decompress(DicomObjects.Codecs.DecompressionArguments args)
        {
            IntPtr wrapper = Create();

            byte[] compressedData;
            using (MemoryStream ms = new MemoryStream())
            {
                args.SourceStream.CopyTo(ms);
                compressedData = ms.ToArray();
            }

            IntPtr dataSize = (IntPtr)compressedData.Length;
            string photometricInterpretation = args.PhotometricInterpretation;
            IntPtr planarConfig = (IntPtr)args.Planarconfig;

            IntPtr decompressedDataPtr = Decompress(wrapper, compressedData, dataSize, photometricInterpretation, planarConfig, out IntPtr decompressedSizePtr);

            if (decompressedDataPtr == IntPtr.Zero)
                throw new Exception("Decompression failed: returned NULL pointer");

            int decompressedSize = decompressedSizePtr.ToInt32();
            byte[] decompressedData = new byte[decompressedSize];
            Marshal.Copy(decompressedDataPtr, decompressedData, 0, decompressedSize);
            Buffer.BlockCopy(decompressedData, 0, args.DestinationArray, 0, decompressedSize);
        }

        public string DecompressedPhotometricInterpretation(DicomDataSet parent)
        {
            return parent[Keyword.PhotometricInterpretation].Value.ToString();
        }

        public bool NeedsPlanarConfigTransform
        {
            get { return false; }
        }

        public object LockObject()
        {
            return this;
        }

        public PixelRequest BestRequest(float Zoom, RequestType Sync, DicomDataSet parent, int Frame)
        {
            throw new NotImplementedException();
        }

        public DecompressStatus DecompressState(PixelRequest Request)
        {
            throw new NotImplementedException();
        }

        public ProgressiveStatus DownloadStatus(PixelRequest Request)
        {
            throw new NotImplementedException();
        }

        public int CalculatedFrameCount()
        {
            throw new NotImplementedException();
        }

    }
}

