using System;

namespace Quik.Media
{
    public abstract class QImage : IDisposable
    {
        public abstract int Width { get; }
        public abstract int Height { get; }
        public abstract int Depth { get; }
        public abstract QImageFormat InternalFormat { get; }
        public virtual int MipMapLevels => 0;
        public virtual bool Premultiplied => false;

        public abstract void LockBits2d(out QImageLock imageLock, QImageLockOptions options);
        public abstract void LockBits3d(out QImageLock imageLock, QImageLockOptions options);
        public abstract void LockBits3d(out QImageLock imageLock, QImageLockOptions options, int depth);
        public abstract void UnlockBits();

        // IDisposable
        private bool isDisposed = false;
        private void DisposePrivate(bool disposing)
        {
            if (isDisposed) return;

            Dispose(disposing);

            isDisposed = true;
        }
        protected virtual void Dispose(bool disposing) { }
        public void Dispose() => DisposePrivate(true);
    }

    public struct QImageLockOptions
    {
        public QImageFormat Format { get; }
        public bool Premultiply { get; }
        public int MipLevel { get; }
        public static QImageLockOptions Default { get; } = new QImageLockOptions(QImageFormat.RgbaU8, true, 0);

        public QImageLockOptions(QImageFormat format, bool premultiply, int level)
        {
            Format = format;
            Premultiply = premultiply;
            MipLevel = level;
        }
    }

    public struct QImageLock
    {
        public QImageFormat Format { get; }
        public int Width { get; }
        public int Height { get; }
        public int Depth { get; }
        public IntPtr ImagePtr { get; }

        public QImageLock(QImageFormat format, int width, int height, int depth, IntPtr ptr)
        {
            Format = format;
            Width = width;
            Height = height;
            Depth = depth;
            ImagePtr = ptr;
        }
    }
}