using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace InABox.Core
{
    public enum UnderlineType
    {
        None,
        Single,
        Double
    }
    
    public interface IDFLayoutTextControl
    {
        T GetStyleProperty<T>(string property, T defaultValue);

        void SetStyleProperty(string property, object? value);
    }

    public class DFLayoutTextStyle : EnclosedEntity
    {
        [EditorSequence(0)]
        [Caption("Italic", IncludePath = false)]
        [CheckBoxEditor]
        public bool IsItalic { get; set; } = false;

        [EditorSequence(1)]
        [CheckBoxEditor]
        [Caption("Bold", IncludePath = false)]
        public bool IsBold { get; set; } = false;

        [EditorSequence(2)]
        [EnumLookupEditor(typeof(UnderlineType))]
        [Caption("Underline", IncludePath = false)]
        public UnderlineType Underline { get; set; } = UnderlineType.None;

        [EditorSequence(3)]
        [Caption("Font Size", IncludePath = false)]
        [Comment("Font size in points.")]
        [DoubleEditor(ToolTip = "Font size in points. Set to 0 for the default size.")]
        public double FontSize { get; set; } = 0;

        [EditorSequence(4)]
        [Caption("Text Colour", IncludePath = false)]
        [ColorEditor]
        public string Foreground { get; set; } = "";

        [EditorSequence(5)]
        [Caption("Background Colour", IncludePath = false)]
        [ColorEditor]
        public string Background { get; set; } = "";

        [EditorSequence(6)]
        [Caption("Horz Alignment", IncludePath = false)]
        [EnumLookupEditor(typeof(DFLayoutAlignment))]
        public DFLayoutAlignment HorizontalTextAlignment { get; set; } = DFLayoutAlignment.Start;

        [EditorSequence(7)]
        [Caption("Vertical Alignment", IncludePath = false)]
        [EnumLookupEditor(typeof(DFLayoutAlignment))]
        public DFLayoutAlignment VerticalTextAlignment { get; set; } = DFLayoutAlignment.Middle;

        [EditorSequence(8)]
        [Caption("Allow Wrap?", IncludePath = false)]
        [CheckBoxEditor]
        public bool TextWrapping { get; set; } = true;
        
        [JsonIgnore]
        [NullEditor]
        [DoNotSerialize]
        public Color ForegroundColour { get => GetForegroundColour(); set => SetForegroundColour(value); }

        [JsonIgnore]
        [NullEditor]
        [DoNotSerialize]
        public Color BackgroundColour { get => GetBackgroundColour(); set => SetBackgroundColour(value); }

        public void LoadProperties(IDFLayoutTextControl control)
        {
            IsItalic = control.GetStyleProperty(nameof(IsItalic), false);
            IsBold = control.GetStyleProperty(nameof(IsBold), false);
            Underline = control.GetStyleProperty(nameof(Underline), UnderlineType.None);
            Foreground = control.GetStyleProperty(nameof(Foreground), "");
            Background = control.GetStyleProperty(nameof(Background), "");
            FontSize = control.GetStyleProperty(nameof(FontSize), 0.0);
            TextWrapping = control.GetStyleProperty(nameof(TextWrapping), true);
            HorizontalTextAlignment = control.GetStyleProperty(nameof(HorizontalTextAlignment), DFLayoutAlignment.Start);
            VerticalTextAlignment = control.GetStyleProperty(nameof(VerticalTextAlignment), DFLayoutAlignment.Middle);
        }
        public void SaveProperties(IDFLayoutTextControl control)
        {
            control.SetStyleProperty(nameof(IsItalic), IsItalic);
            control.SetStyleProperty(nameof(IsBold), IsBold);
            control.SetStyleProperty(nameof(Underline), Underline);
            control.SetStyleProperty(nameof(Foreground), Foreground);
            control.SetStyleProperty(nameof(Background), Background);
            control.SetStyleProperty(nameof(FontSize), FontSize);
            control.SetStyleProperty(nameof(TextWrapping), TextWrapping);
            control.SetStyleProperty(nameof(HorizontalTextAlignment), HorizontalTextAlignment);
            control.SetStyleProperty(nameof(VerticalTextAlignment), VerticalTextAlignment);
        }

        public Color GetForegroundColour() => ColourFromString(Foreground);
        public Color GetBackgroundColour() => ColourFromString(Background);

        public string SetForegroundColour(Color colour) => Foreground = ColourToString(colour);
        public string SetBackgroundColour(Color colour) => Background = ColourToString(colour);

        public static Color ColourFromString(string colour) => string.IsNullOrWhiteSpace(colour)
            ? Color.Empty
            : DFLayoutUtils.ConvertObjectToColour(colour) ?? Color.Empty;

        public static string ColourToString(Color colour) => colour == Color.Empty
            ? ""
            : colour.IsKnownColor ? colour.ToKnownColor().ToString() : $"#{colour.ToArgb():X4}";
    }
}
