using System;

namespace Quik.Media
{
    /// <summary>
    /// Abstract class that represents a font.
    /// </summary>
    public abstract class QFont : IDisposable
    {
        public abstract FontInfo Info { get; }
        public string Family => Info.Family;
        public FontStyle Style => Info.Style;

        public abstract bool HasRune(int rune);
        public abstract QFontPage RasterizePage(int codepage, float size, in FontRasterizerOptions options);
        public QFontPage RasterizePage(int codepage, float size) => RasterizePage(codepage, size, FontRasterizerOptions.Default);

        // 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 FontRasterizerOptions
    {
        public float Resolution { get; set; }
        public bool Sdf { get; set; }

        public static readonly FontRasterizerOptions Default = new FontRasterizerOptions()
        {
            Resolution = 96.0f,
            Sdf        = true
        };
    }

    public class QFontPage : IDisposable
    {
        public QFont Font { get; }
        public int CodePage { get; }
        public float Size { get; }
        public virtual QImage Image { get; } = null;
        public virtual QGlyphMetrics[] Metrics { get; } = Array.Empty<QGlyphMetrics>();

        public FontRasterizerOptions Options { get; }
        public float Resolution => Options.Resolution;
        public bool Sdf => Options.Sdf;

        public void Dispose() => DisposeInternal(false);

        protected QFontPage(QFont font, int codepage, float size, in FontRasterizerOptions options)
        {
            Font = font;
            CodePage = codepage;
            Size = size;
            Options = options;
        }
        public QFontPage(QFont font, int codepage, float size, in FontRasterizerOptions options, QImage image, QGlyphMetrics[] metrics)
            : this(font, codepage, size, options)
        {
            Image = image;
            Metrics = metrics;
        }

        private bool isDisposed = false;
        private void DisposeInternal(bool disposing)
        {
            if (isDisposed) return;

            Dispose(disposing);
            isDisposed = true;
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                Image?.Dispose();
            }
        }
    }
}