using System;
using System.Collections.Generic;
using System.Text;
using CommonUI.Gemo;
using CommonLang.Concurrent;

namespace CommonUI.Display
{

    public enum FontStyle
    {
        STYLE_PLAIN = 0,
        STYLE_BOLD = 1,
        STYLE_ITALIC = 2,
        STYLE_UNDERLINED = 4,
        STYLE_BOLD_UNDERLINED = 5,
        STYLE_ITALIC_UNDERLINED = 6,
        STYLE_BOLD_ITALIC = 7,
        STYLE_BOLD_ITALIC_UNDERLINED = 8
    }

    public abstract class TextLayer : IDisposable
    {
        public static uint DefaultDisableTextColorRGBA = 0x808080FF;

        private static AtomicLong s_RefCount = new AtomicLong(0);
        private static AtomicLong s_AliveCount = new AtomicLong(0);
        public static long RefCount { get { return s_RefCount.Value; } }
        public static long AliveCount { get { return s_AliveCount.Value; } }
        private bool m_disposed = false;

        protected string mText = "";

        protected uint mFontColorRGBA = 0xffffffff;
        protected uint mBorderColorRGBA = 0x000000ff;
        protected int mBorderTime = 8;
        protected Size2D mExpectSize = null;
        protected int mFontSize;
        protected FontStyle mFontStyle;
        protected Size2D mBounds = new Size2D();
        protected bool isDirty = true;

        protected bool isEnable = true;

        public TextLayer(string t, int size, FontStyle style = FontStyle.STYLE_PLAIN)
        {
            s_RefCount++;
            s_AliveCount++;
            this.mText = t;
            this.mFontSize = Math.Max(1, size);
            this.mFontStyle = style;
        }
        ~TextLayer()
        {
            s_RefCount--;
        }
        public void Dispose()
        {
            if (m_disposed) { return; }
            Disposing();
            m_disposed = true;
            s_AliveCount--;
        }
        protected abstract void Disposing();


        public bool IsEnable
        {
            get { return isEnable; }
            set
            {
                if (this.isEnable != value)
                {
                    this.isEnable = value;
                    this.isDirty = true;
                }
            }
        }

        public Size2D ExpectSize
        {
            get { return mExpectSize; }
            set
            {
                if (!value.Equals(mExpectSize))
                { 
                    this.mExpectSize = value; 
                    this.isDirty = true; 
                }
            }
        }

        public string Text
        {
            get { return mText; }
            set
            {
                if (!value.Equals(this.mText))
                {
                    this.mText = value;
                    this.isDirty = true;
                }
            }
        }

        public int FontSize
        {
            set
            {
                value = Math.Max(1, value);
                if (mFontSize != value)
                {
                    mFontSize = value;
                    this.isDirty = true;
                }
            }
            get { return mFontSize; }
        }

        public FontStyle TextFontStyle
        {
            set
            {
                if (mFontStyle != value)
                {
                    mFontStyle = value;
                    this.isDirty = true;
                }
            }
            get { return mFontStyle; }
        }

        public uint FontColor
        {
            get { return mFontColorRGBA; }
            set
            {
                if (this.mFontColorRGBA != value)
                {
                    this.mFontColorRGBA = value;
                    this.isDirty = true;
                }
            }
        }

        public uint BorderColor
        {
            get
            {
                return mBorderColorRGBA;
            }
            set
            {
                if (this.mBorderColorRGBA != value)
                {
                    this.mBorderColorRGBA = value;
                    this.isDirty = true;
                }
            }
        }

        public int BorderTime
        {
            get { return mBorderTime; }
            set
            {
                if (this.mBorderTime != value)
                {
                    this.mBorderTime = value;
                    this.isDirty = true;
                }
            }
        }
        
        public float Width
        {
            get { return mBounds.width; }
        }

        public float Height
        {
            get { return mBounds.height; }
        }

        public void SetFontColor(int rgb, float alpha = 1.0f)
        {
            uint uc = (uint)((rgb & 0xffffff) | (int)Math.Min(alpha * 255, 255));
            FontColor = (uc);
        }

        public void SetFontColor(uint rgba)
        {
            FontColor = rgba;
        }

        public void SetBorderColor(int rgb, int alpha = 0xff)
        {
            uint uc = (uint)((rgb & 0xffffff) | (int)Math.Min(alpha * 255, 255));
            BorderColor = (uc);
        }

        abstract public Image GetBuffer();
        
    }
}