using ModernGUI.Controls;
using System.Windows.Forms;

namespace ModernGUI
{
    public class SkinManager
    {
        //Singleton instance
        private static SkinManager _instance;

        //Forms to control
        private readonly List<ModernGUI.Controls.Form> _formsToManage = new List<ModernGUI.Controls.Form>();


        public delegate void OnThemeChanged(ColorSchemes NewColorScheme);
        public OnThemeChanged ThemeChanged;

        public delegate void OnSchemeChanged(bool DarkMode);
        public OnSchemeChanged DarkModeChanged;

        //Theme
        private Themes _theme;
        public Themes Theme
        {
            get { return _theme; }
            set
            {
                _theme = value;
                UpdateBackgrounds();
                if (_theme == Themes.LIGHT)
                {
                    DarkModeChanged?.Invoke(false);
                }
                else
                {
                    DarkModeChanged?.Invoke(true);
                }
            }
        }

        private ColorScheme _colorScheme;
        public ColorScheme ColorScheme
        {
            get { return _colorScheme; }
            set
            {

                _colorScheme = value;
                UpdateBackgrounds();
                ThemeChanged?.Invoke(_colorScheme.CurrentScheme);
            }
        }

        public enum Themes : byte
        {
            LIGHT,
            DARK
        }

        #region Divider Colors
        //Divider Color
        private static readonly Color DIVIDERS_BLACK = Color.FromArgb(31, 0, 0, 0);
        private static readonly Brush DIVIDERS_BLACK_BRUSH = new SolidBrush(DIVIDERS_BLACK);
        private static readonly Color DIVIDERS_WHITE = Color.FromArgb(31, 255, 255, 255);
        private static readonly Brush DIVIDERS_WHITE_BRUSH = new SolidBrush(DIVIDERS_WHITE);
        #endregion

        #region Text
        // Text
        private static readonly Color PRIMARY_TEXT_BLACK = Color.FromArgb(222, 0, 0, 0);
        private static readonly Brush PRIMARY_TEXT_BLACK_BRUSH = new SolidBrush(PRIMARY_TEXT_BLACK);
        public static Color SECONDARY_TEXT_BLACK = Color.FromArgb(138, 0, 0, 0);
        public static Brush SECONDARY_TEXT_BLACK_BRUSH = new SolidBrush(SECONDARY_TEXT_BLACK);
        private static readonly Color DISABLED_OR_HINT_TEXT_BLACK = Color.FromArgb(66, 0, 0, 0);
        private static readonly Brush DISABLED_OR_HINT_TEXT_BLACK_BRUSH = new SolidBrush(DISABLED_OR_HINT_TEXT_BLACK);
        private static readonly Color PRIMARY_TEXT_WHITE = Color.FromArgb(255, 255, 255, 255);// Color.FromArgb(255, 255, 255, 255);
        private static readonly Brush PRIMARY_TEXT_WHITE_BRUSH = new SolidBrush(PRIMARY_TEXT_WHITE);
        public static Color SECONDARY_TEXT_WHITE = Color.FromArgb(179, 255, 255, 255);
        public static Brush SECONDARY_TEXT_WHITE_BRUSH = new SolidBrush(SECONDARY_TEXT_WHITE);
        private static readonly Color DISABLED_OR_HINT_TEXT_WHITE = Color.FromArgb(77, 255, 255, 255);
        private static readonly Brush DISABLED_OR_HINT_TEXT_WHITE_BRUSH = new SolidBrush(DISABLED_OR_HINT_TEXT_WHITE);

        private static readonly Color TEXT_HIGH_EMPHASIS_LIGHT = Color.FromArgb(222, 255, 255, 255); // Alpha 87%
        private static readonly Brush TEXT_HIGH_EMPHASIS_LIGHT_BRUSH = new SolidBrush(TEXT_HIGH_EMPHASIS_LIGHT);
        private static readonly Color TEXT_HIGH_EMPHASIS_DARK = Color.FromArgb(222, 0, 0, 0); // Alpha 87%
        private static readonly Brush TEXT_HIGH_EMPHASIS_DARK_BRUSH = new SolidBrush(TEXT_HIGH_EMPHASIS_DARK);

        private static readonly Color TEXT_HIGH_EMPHASIS_LIGHT_NOALPHA = Color.FromArgb(255, 255, 255, 255); // Alpha 100%
        private static readonly Brush TEXT_HIGH_EMPHASIS_LIGHT_NOALPHA_BRUSH = new SolidBrush(TEXT_HIGH_EMPHASIS_LIGHT_NOALPHA);
        private static readonly Color TEXT_HIGH_EMPHASIS_DARK_NOALPHA = Color.FromArgb(255, 0, 0, 0); // Alpha 100%
        private static readonly Brush TEXT_HIGH_EMPHASIS_DARK_NOALPHA_BRUSH = new SolidBrush(TEXT_HIGH_EMPHASIS_DARK_NOALPHA);

        private static readonly Color TEXT_MEDIUM_EMPHASIS_LIGHT = Color.FromArgb(153, 255, 255, 255); // Alpha 60%
        private static readonly Brush TEXT_MEDIUM_EMPHASIS_LIGHT_BRUSH = new SolidBrush(TEXT_MEDIUM_EMPHASIS_LIGHT);
        private static readonly Color TEXT_MEDIUM_EMPHASIS_DARK = Color.FromArgb(153, 0, 0, 0); // Alpha 60%
        private static readonly Brush TEXT_MEDIUM_EMPHASIS_DARK_BRUSH = new SolidBrush(TEXT_MEDIUM_EMPHASIS_DARK);

        private static readonly Color TEXT_DISABLED_OR_HINT_LIGHT = Color.FromArgb(97, 255, 255, 255); // Alpha 38%
        private static readonly Brush TEXT_DISABLED_OR_HINT_LIGHT_BRUSH = new SolidBrush(TEXT_DISABLED_OR_HINT_LIGHT);
        private static readonly Color TEXT_DISABLED_OR_HINT_DARK = Color.FromArgb(97, 0, 0, 0); // Alpha 38%
        private static readonly Brush TEXT_DISABLED_OR_HINT_DARK_BRUSH = new SolidBrush(TEXT_DISABLED_OR_HINT_DARK);

        public Color TextHighEmphasisColor => Theme == Themes.LIGHT ? TEXT_HIGH_EMPHASIS_DARK : TEXT_HIGH_EMPHASIS_LIGHT;
        public Brush TextHighEmphasisBrush => Theme == Themes.LIGHT ? TEXT_HIGH_EMPHASIS_DARK_BRUSH : TEXT_HIGH_EMPHASIS_LIGHT_BRUSH;
        public Color TextHighEmphasisNoAlphaColor => Theme == Themes.LIGHT ? TEXT_HIGH_EMPHASIS_DARK_NOALPHA : TEXT_HIGH_EMPHASIS_LIGHT_NOALPHA;
        public Brush TextHighEmphasisNoAlphaBrush => Theme == Themes.LIGHT ? TEXT_HIGH_EMPHASIS_DARK_NOALPHA_BRUSH : TEXT_HIGH_EMPHASIS_LIGHT_NOALPHA_BRUSH;
        public Color TextMediumEmphasisColor => Theme == Themes.LIGHT ? TEXT_MEDIUM_EMPHASIS_DARK : TEXT_MEDIUM_EMPHASIS_LIGHT;
        public Brush TextMediumEmphasisBrush => Theme == Themes.LIGHT ? TEXT_MEDIUM_EMPHASIS_DARK_BRUSH : TEXT_MEDIUM_EMPHASIS_LIGHT_BRUSH;
        public Color TextDisabledOrHintColor => Theme == Themes.LIGHT ? TEXT_DISABLED_OR_HINT_DARK : TEXT_DISABLED_OR_HINT_LIGHT;
        public Brush TextDisabledOrHintBrush => Theme == Themes.LIGHT ? TEXT_DISABLED_OR_HINT_DARK_BRUSH : TEXT_DISABLED_OR_HINT_LIGHT_BRUSH;
        #endregion

        #region Checkbox Color
        // Checkbox colors
        private static readonly Color CHECKBOX_OFF_LIGHT = Color.FromArgb(138, 0, 0, 0);
        private static readonly Brush CHECKBOX_OFF_LIGHT_BRUSH = new SolidBrush(CHECKBOX_OFF_LIGHT);
        private static readonly Color CHECKBOX_OFF_DISABLED_LIGHT = Color.FromArgb(66, 0, 0, 0);
        private static readonly Brush CHECKBOX_OFF_DISABLED_LIGHT_BRUSH = new SolidBrush(CHECKBOX_OFF_DISABLED_LIGHT);

        private static readonly Color CHECKBOX_OFF_DARK = Color.FromArgb(179, 255, 255, 255);
        private static readonly Brush CHECKBOX_OFF_DARK_BRUSH = new SolidBrush(CHECKBOX_OFF_DARK);
        private static readonly Color CHECKBOX_OFF_DISABLED_DARK = Color.FromArgb(77, 255, 255, 255);
        private static readonly Brush CHECKBOX_OFF_DISABLED_DARK_BRUSH = new SolidBrush(CHECKBOX_OFF_DISABLED_DARK);

        #endregion

        #region Raised button

        //Raised button
        private static readonly Color RAISED_BUTTON_BACKGROUND = Color.FromArgb(255, 255, 255, 255);
        private static readonly Brush RAISED_BUTTON_BACKGROUND_BRUSH = new SolidBrush(RAISED_BUTTON_BACKGROUND);
        private static readonly Color RAISED_BUTTON_TEXT_LIGHT = PRIMARY_TEXT_WHITE;
        private static readonly Brush RAISED_BUTTON_TEXT_LIGHT_BRUSH = new SolidBrush(RAISED_BUTTON_TEXT_LIGHT);
        private static readonly Color RAISED_BUTTON_TEXT_DARK = PRIMARY_TEXT_BLACK;
        private static readonly Brush RAISED_BUTTON_TEXT_DARK_BRUSH = new SolidBrush(RAISED_BUTTON_TEXT_DARK);

        #endregion

        #region Flat button

        //Flat button
        private static readonly Color FLAT_BUTTON_BACKGROUND_HOVER_LIGHT = Color.FromArgb(20.PercentageToColorComponent(), 0x999999.ToColor());
        private static readonly Brush FLAT_BUTTON_BACKGROUND_HOVER_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_HOVER_LIGHT);
        private static readonly Color FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT = Color.FromArgb(40.PercentageToColorComponent(), 0x999999.ToColor());
        private static readonly Brush FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT);
        private static readonly Color FLAT_BUTTON_DISABLEDTEXT_LIGHT = Color.FromArgb(26.PercentageToColorComponent(), 0x000000.ToColor());
        private static readonly Brush FLAT_BUTTON_DISABLEDTEXT_LIGHT_BRUSH = new SolidBrush(FLAT_BUTTON_DISABLEDTEXT_LIGHT);
        private static readonly Color FLAT_BUTTON_BACKGROUND_HOVER_DARK = Color.FromArgb(15.PercentageToColorComponent(), 0xCCCCCC.ToColor());
        private static readonly Brush FLAT_BUTTON_BACKGROUND_HOVER_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_HOVER_DARK);
        private static readonly Color FLAT_BUTTON_BACKGROUND_PRESSED_DARK = Color.FromArgb(25.PercentageToColorComponent(), 0xCCCCCC.ToColor());
        private static readonly Brush FLAT_BUTTON_BACKGROUND_PRESSED_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_BACKGROUND_PRESSED_DARK);
        private static readonly Color FLAT_BUTTON_DISABLEDTEXT_DARK = Color.FromArgb(30.PercentageToColorComponent(), 0xFFFFFF.ToColor());
        private static readonly Brush FLAT_BUTTON_DISABLEDTEXT_DARK_BRUSH = new SolidBrush(FLAT_BUTTON_DISABLEDTEXT_DARK);

        #endregion

        #region ContextMenuStrip

        //ContextMenuStrip
        private static readonly Color CMS_BACKGROUND_LIGHT_HOVER = Color.FromArgb(255, 238, 238, 238);
        private static readonly Brush CMS_BACKGROUND_HOVER_LIGHT_BRUSH = new SolidBrush(CMS_BACKGROUND_LIGHT_HOVER);
        private static readonly Color CMS_BACKGROUND_DARK_HOVER = Color.FromArgb(38, 204, 204, 204);
        private static readonly Brush CMS_BACKGROUND_HOVER_DARK_BRUSH = new SolidBrush(CMS_BACKGROUND_DARK_HOVER);

        #endregion

        #region Application background

        //Application background
        private static readonly Color BACKGROUND_LIGHT = Color.FromArgb(255, 255, 255, 255);
        private static Brush BACKGROUND_LIGHT_BRUSH = new SolidBrush(BACKGROUND_LIGHT);
        private static readonly Color BACKGROUND_DARK = Color.FromArgb(255, 51, 51, 51);
        private static Brush BACKGROUND_DARK_BRUSH = new SolidBrush(BACKGROUND_DARK);

        #endregion

        #region Application action bar

        //Application action bar
        public readonly Color ACTION_BAR_TEXT = Color.FromArgb(255, 255, 255, 255);
        public readonly Brush ACTION_BAR_TEXT_BRUSH = new SolidBrush(Color.FromArgb(255, 255, 255, 255));
        public readonly Color ACTION_BAR_TEXT_SECONDARY = Color.FromArgb(153, 255, 255, 255);
        public readonly Brush ACTION_BAR_TEXT_SECONDARY_BRUSH = new SolidBrush(Color.FromArgb(153, 255, 255, 255));

        #endregion

        #region DataGridview Background
        //DataGridview Background
        public readonly Color DATAGRIDVIEW_BACKGROUND_LIGHT = Color.FromArgb(245, 245, 245);
        public readonly Color DATAGRIDVIEW_BACKGROUND_DARK = Color.FromArgb(189, 189, 189);
        #endregion

        #region Generic back colors - for user controls

        // Generic back colors - for user controls
        private static readonly Color BACKGROUND_ALTERNATIVE_LIGHT = Color.FromArgb(10, 0, 0, 0);
        private static readonly Brush BACKGROUND_ALTERNATIVE_LIGHT_BRUSH = new SolidBrush(BACKGROUND_ALTERNATIVE_LIGHT);
        private static readonly Color BACKGROUND_ALTERNATIVE_DARK = Color.FromArgb(10, 255, 255, 255);
        private static readonly Brush BACKGROUND_ALTERNATIVE_DARK_BRUSH = new SolidBrush(BACKGROUND_ALTERNATIVE_DARK);
        private static readonly Color BACKGROUND_HOVER_LIGHT = Color.FromArgb(20, 0, 0, 0);
        private static readonly Brush BACKGROUND_HOVER_LIGHT_BRUSH = new SolidBrush(BACKGROUND_HOVER_LIGHT);
        private static readonly Color BACKGROUND_HOVER_DARK = Color.FromArgb(20, 255, 255, 255);
        private static readonly Brush BACKGROUND_HOVER_DARK_BRUSH = new SolidBrush(BACKGROUND_HOVER_DARK);
        private static readonly Color BACKGROUND_HOVER_RED = Color.FromArgb(255, 255, 0, 0);
        private static readonly Brush BACKGROUND_HOVER_RED_BRUSH = new SolidBrush(BACKGROUND_HOVER_RED);
        private static readonly Color BACKGROUND_DOWN_RED = Color.FromArgb(255, 255, 84, 54);
        private static readonly Brush BACKGROUND_DOWN_RED_BRUSH = new SolidBrush(BACKGROUND_DOWN_RED);
        private static readonly Color BACKGROUND_FOCUS_LIGHT = Color.FromArgb(30, 0, 0, 0);
        private static readonly Brush BACKGROUND_FOCUS_LIGHT_BRUSH = new SolidBrush(BACKGROUND_FOCUS_LIGHT);
        private static readonly Color BACKGROUND_FOCUS_DARK = Color.FromArgb(30, 255, 255, 255);
        private static readonly Brush BACKGROUND_FOCUS_DARK_BRUSH = new SolidBrush(BACKGROUND_FOCUS_DARK);
        private static readonly Color BACKGROUND_DISABLED_LIGHT = Color.FromArgb(25, 0, 0, 0);
        private static readonly Brush BACKGROUND_DISABLED_LIGHT_BRUSH = new SolidBrush(BACKGROUND_DISABLED_LIGHT);
        private static readonly Color BACKGROUND_DISABLED_DARK = Color.FromArgb(25, 255, 255, 255);
        private static readonly Brush BACKGROUND_DISABLED_DARK_BRUSH = new SolidBrush(BACKGROUND_DISABLED_DARK);

        public Color BackgroundColor => Theme == Themes.LIGHT ? BACKGROUND_LIGHT : BACKGROUND_DARK;
        public Brush BackgroundBrush => Theme == Themes.LIGHT ? BACKGROUND_LIGHT_BRUSH : BACKGROUND_DARK_BRUSH;
        public Color BackgroundAlternativeColor => Theme == Themes.LIGHT ? BACKGROUND_ALTERNATIVE_LIGHT : BACKGROUND_ALTERNATIVE_DARK;
        public Brush BackgroundAlternativeBrush => Theme == Themes.LIGHT ? BACKGROUND_ALTERNATIVE_LIGHT_BRUSH : BACKGROUND_ALTERNATIVE_DARK_BRUSH;
        public Color BackgroundDisabledColor => Theme == Themes.LIGHT ? BACKGROUND_DISABLED_LIGHT : BACKGROUND_DISABLED_DARK;
        public Brush BackgroundDisabledBrush => Theme == Themes.LIGHT ? BACKGROUND_DISABLED_LIGHT_BRUSH : BACKGROUND_DISABLED_DARK_BRUSH;
        public Color BackgroundHoverColor => Theme == Themes.LIGHT ? BACKGROUND_HOVER_LIGHT : BACKGROUND_HOVER_DARK;
        public Brush BackgroundHoverBrush => Theme == Themes.LIGHT ? BACKGROUND_HOVER_LIGHT_BRUSH : BACKGROUND_HOVER_DARK_BRUSH;
        public Color BackgroundHoverRedColor => Theme == Themes.LIGHT ? BACKGROUND_HOVER_RED : BACKGROUND_HOVER_RED;
        public Brush BackgroundHoverRedBrush => Theme == Themes.LIGHT ? BACKGROUND_HOVER_RED_BRUSH : BACKGROUND_HOVER_RED_BRUSH;
        public Brush BackgroundDownRedBrush => Theme == Themes.LIGHT ? BACKGROUND_DOWN_RED_BRUSH : BACKGROUND_DOWN_RED_BRUSH;
        public Color BackgroundFocusColor => Theme == Themes.LIGHT ? BACKGROUND_FOCUS_LIGHT : BACKGROUND_FOCUS_DARK;
        public Brush BackgroundFocusBrush => Theme == Themes.LIGHT ? BACKGROUND_FOCUS_LIGHT_BRUSH : BACKGROUND_FOCUS_DARK_BRUSH;

        #endregion

        #region ComboBox

        //ComboBox
        private static readonly Color SWITCH_OFF_DISABLED_THUMB_LIGHT = Color.FromArgb(255, 230, 230, 230);
        private static readonly Color SWITCH_OFF_DISABLED_THUMB_DARK = Color.FromArgb(255, 150, 150, 150);
        private static readonly Color DIVIDERS_ALTERNATIVE_LIGHT = Color.FromArgb(153, 255, 255, 255); // Alpha 60%
        private static readonly Brush DIVIDERS_ALTERNATIVE_LIGHT_BRUSH = new SolidBrush(DIVIDERS_ALTERNATIVE_LIGHT);
        private static readonly Color DIVIDERS_ALTERNATIVE_DARK = Color.FromArgb(153, 0, 0, 0); // Alpha 60%
        private static readonly Brush DIVIDERS_ALTERNATIVE_DARK_BRUSH = new SolidBrush(DIVIDERS_ALTERNATIVE_DARK);

        public Brush DividersAlternativeBrush => Theme == Themes.LIGHT ? DIVIDERS_ALTERNATIVE_DARK_BRUSH : DIVIDERS_ALTERNATIVE_LIGHT_BRUSH;
        public Color SwitchOffDisabledThumbColor => Theme == Themes.LIGHT ? SWITCH_OFF_DISABLED_THUMB_LIGHT : SWITCH_OFF_DISABLED_THUMB_DARK;

        #endregion

        #region Get Color/Brush Methods

        public Color GetPrimaryTextColor()
        {
            return Theme == Themes.LIGHT ? PRIMARY_TEXT_BLACK : PRIMARY_TEXT_WHITE;
        }

        public Brush GetPrimaryTextBrush()
        {
            return Theme == Themes.LIGHT ? PRIMARY_TEXT_BLACK_BRUSH : PRIMARY_TEXT_WHITE_BRUSH;
        }

        public Color GetSecondaryTextColor()
        {
            return Theme == Themes.LIGHT ? SECONDARY_TEXT_BLACK : SECONDARY_TEXT_WHITE;
        }

        public Brush GetSecondaryTextBrush()
        {
            return Theme == Themes.LIGHT ? SECONDARY_TEXT_BLACK_BRUSH : SECONDARY_TEXT_WHITE_BRUSH;
        }

        public Color GetDisabledOrHintColor()
        {
            return Theme == Themes.LIGHT ? DISABLED_OR_HINT_TEXT_BLACK : DISABLED_OR_HINT_TEXT_WHITE;
        }

        public Brush GetDisabledOrHintBrush()
        {
            return Theme == Themes.LIGHT ? DISABLED_OR_HINT_TEXT_BLACK_BRUSH : DISABLED_OR_HINT_TEXT_WHITE_BRUSH;
        }

        public Color GetDividersColor()
        {
            return Theme == Themes.LIGHT ? DIVIDERS_BLACK : DIVIDERS_WHITE;
        }

        public Brush GetDividersBrush()
        {
            return Theme == Themes.LIGHT ? DIVIDERS_BLACK_BRUSH : DIVIDERS_WHITE_BRUSH;
        }

        public Color GetCheckboxOffColor()
        {
            return Theme == Themes.LIGHT ? CHECKBOX_OFF_LIGHT : CHECKBOX_OFF_DARK;
        }

        public Brush GetCheckboxOffBrush()
        {
            return Theme == Themes.LIGHT ? CHECKBOX_OFF_LIGHT_BRUSH : CHECKBOX_OFF_DARK_BRUSH;
        }

        public Color GetCheckBoxOffDisabledColor()
        {
            return Theme == Themes.LIGHT ? CHECKBOX_OFF_DISABLED_LIGHT : CHECKBOX_OFF_DISABLED_DARK;
        }

        public Brush GetCheckBoxOffDisabledBrush()
        {
            return Theme == Themes.LIGHT ? CHECKBOX_OFF_DISABLED_LIGHT_BRUSH : CHECKBOX_OFF_DISABLED_DARK_BRUSH;
        }

        public Brush GetRaisedButtonBackgroundBrush()
        {
            return RAISED_BUTTON_BACKGROUND_BRUSH;
        }

        public Brush GetRaisedButtonTextBrush(bool primary)
        {
            return primary ? RAISED_BUTTON_TEXT_LIGHT_BRUSH : RAISED_BUTTON_TEXT_DARK_BRUSH;
        }

        public Color GetFlatButtonHoverBackgroundColor()
        {
            return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_HOVER_LIGHT : FLAT_BUTTON_BACKGROUND_HOVER_DARK;
        }

        public Brush GetFlatButtonHoverBackgroundBrush()
        {
            return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_HOVER_LIGHT_BRUSH : FLAT_BUTTON_BACKGROUND_HOVER_DARK_BRUSH;
        }

        public Color GetFlatButtonPressedBackgroundColor()
        {
            return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT : FLAT_BUTTON_BACKGROUND_PRESSED_DARK;
        }

        public Brush GetFlatButtonPressedBackgroundBrush()
        {
            return Theme == Themes.LIGHT ? FLAT_BUTTON_BACKGROUND_PRESSED_LIGHT_BRUSH : FLAT_BUTTON_BACKGROUND_PRESSED_DARK_BRUSH;
        }

        public Brush GetFlatButtonDisabledTextBrush()
        {
            return Theme == Themes.LIGHT ? FLAT_BUTTON_DISABLEDTEXT_LIGHT_BRUSH : FLAT_BUTTON_DISABLEDTEXT_DARK_BRUSH;
        }

        public Brush GetCmsSelectedItemBrush()
        {
            return Theme == Themes.LIGHT ? CMS_BACKGROUND_HOVER_LIGHT_BRUSH : CMS_BACKGROUND_HOVER_DARK_BRUSH;
        }

        public Color GetApplicationBackgroundColor()
        {
            return Theme == Themes.LIGHT ? BACKGROUND_LIGHT : BACKGROUND_DARK;
        }


        private Dictionary<UserControl, Color> UserControlOriginalBackcolor = new Dictionary<UserControl, Color>();
        public Color GetUserControlBackgroundColor(UserControl userControl)
        {

            if (Theme == Themes.DARK)
            {

                if (!UserControlOriginalBackcolor.ContainsKey(userControl))
                {
                    //PanelOriginalBackcolor.Remove(userControl);
                    UserControlOriginalBackcolor.Add(userControl, userControl.BackColor);
                }

                return BACKGROUND_DARK;
            }
            else
            {
                if (UserControlOriginalBackcolor.ContainsKey(userControl))
                {
                    return UserControlOriginalBackcolor[userControl];
                }
                else
                {
                    return userControl.BackColor;
                }
            }


        }

        private Dictionary<System.Windows.Forms.Panel, Color> PanelOriginalBackcolor = new Dictionary<System.Windows.Forms.Panel, Color>();
        public Color GetPanelBackgroundColor(System.Windows.Forms.Panel userControl)
        {
            if (Theme == Themes.DARK)
            {

                if (!PanelOriginalBackcolor.ContainsKey(userControl) )
                {
                    //PanelOriginalBackcolor.Remove(userControl);
                    PanelOriginalBackcolor.Add(userControl, userControl.BackColor);
                }

                return BACKGROUND_DARK;
            }
            else
            {
                if (PanelOriginalBackcolor.ContainsKey(userControl))
                {
                    return PanelOriginalBackcolor[userControl];
                }
                else
                {
                    return userControl.BackColor;
                }
            }

        }
        public Color GetPanelBackgroundColor(ModernGUI.Controls.Panel userControl)
        {
            return GetPanelBackgroundColor((System.Windows.Forms.Panel)userControl);
        }
        private Dictionary<TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel, Color> HtmlPanelOriginalBackcolor = new Dictionary<TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel, Color>();
        public Color GetPanelBackgroundColor(TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel userControl)
        {
            if (Theme == Themes.DARK)
            {

                if (!HtmlPanelOriginalBackcolor.ContainsKey(userControl))
                {
                    //PanelOriginalBackcolor.Remove(userControl);
                    HtmlPanelOriginalBackcolor.Add(userControl, userControl.BackColor);
                }

                return BACKGROUND_DARK;
            }
            else
            {
                if (HtmlPanelOriginalBackcolor.ContainsKey(userControl))
                {
                    return HtmlPanelOriginalBackcolor[userControl];
                }
                else
                {
                    return userControl.BackColor;
                }
            }

        }
        public Color GetDataGridviewBackground()
        {
            return Theme == Themes.LIGHT ? DATAGRIDVIEW_BACKGROUND_LIGHT : DATAGRIDVIEW_BACKGROUND_DARK;
        }

        #endregion

        //Other constants
        public int FORM_PADDING = 14;

        //OpenSans font
        public OpenSans openSans;

        private SkinManager()
        {
            openSans = new OpenSans();
            Theme = Themes.LIGHT;
            ColorScheme = new ColorScheme(ColorSchemes.Indigo);
        }

        

        public static SkinManager Instance => _instance ?? (_instance = new SkinManager());

        public void AddFormToManage(ModernGUI.Controls.Form InForm)
        {
            _formsToManage.Add(InForm);
            UpdateBackgrounds();
        }

        public void RemoveFormToManage(ModernGUI.Controls.Form InForm)
        {
            _formsToManage.Remove(InForm);
        }

        private void UpdateBackgrounds()
        {
            var newBackColor = GetApplicationBackgroundColor();
            foreach (var _form in _formsToManage)
            {
                _form.BackColor = newBackColor;
                UpdateControl(_form, newBackColor);
            }
        }

        private void UpdateToolStrip(ToolStrip toolStrip, Color newBackColor)
        {
            if (toolStrip == null)
            {
                return;
            }

            toolStrip.BackColor = newBackColor;
            foreach (ToolStripItem control in toolStrip.Items)
            {
                control.BackColor = newBackColor;
                if (control is ModernGUI.Controls.ToolStripMenuItem && ((ModernGUI.Controls.ToolStripMenuItem)control).HasDropDown)
                {
                    //recursive call
                    UpdateToolStrip(((ModernGUI.Controls.ToolStripMenuItem)control).DropDown, newBackColor);
                }
            }
        }

        private void UpdateControl(Control controlToUpdate, Color newBackColor)
        {
            if (controlToUpdate == null)
            {
                return;
            }

            #region Contex Menu Strip
            if (controlToUpdate.ContextMenuStrip != null)
            {
                UpdateToolStrip(controlToUpdate.ContextMenuStrip, newBackColor);
            }
            #endregion

            #region Tab Control 

            ModernGUI.Controls.TabControl tabControl = null;

            if (controlToUpdate.GetType() == typeof(ModernGUI.Controls.TabControl))
            {
                tabControl = (ModernGUI.Controls.TabControl)controlToUpdate;
            }
            if (tabControl != null)
            {
                foreach (TabPage tabPage in tabControl.TabPages)
                {
                    tabPage.BackColor = newBackColor;
                }
            }

            #endregion
            
            #region DataGridview



            if (controlToUpdate is (ModernGUI.Controls.DataGridView))
            {

                SolidBrush brush = ((SolidBrush)GetFlatButtonPressedBackgroundBrush());

                ((ModernGUI.Controls.DataGridView)controlToUpdate).BackColor = GetDataGridviewBackground();

            }
            #endregion

            #region Divider
            if (controlToUpdate is Divider)
            {
                controlToUpdate.BackColor = newBackColor;
            }
            #endregion

            #region Calandar
            if (controlToUpdate is Calendar)
            {
                controlToUpdate.BackColor = Color.Black;
            }
            #endregion

            #region WPF Text box controlls
            if (controlToUpdate is (ModernGUI.Controls.WPF.WPFTextBox))
            {


                ((ModernGUI.Controls.WPF.WPFTextBox)controlToUpdate).BackColor = GetDataGridviewBackground();

            }

            if (controlToUpdate is (ModernGUI.Controls.WPF.WPFTextEditor))
            {


                ((ModernGUI.Controls.WPF.WPFTextEditor)controlToUpdate).BackColor = GetDataGridviewBackground();

            }

            #endregion

            #region HtmlPanel
            if (controlToUpdate is (TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel))
            {
                controlToUpdate.BackColor = GetPanelBackgroundColor((TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel)controlToUpdate);
            }

            #endregion

            if (controlToUpdate is (System.Windows.Forms.ComboBox))
            {
                //TODO: Needs implimentation

            }

            if (controlToUpdate is (System.Windows.Forms.Label))
            {
                ((System.Windows.Forms.Label)controlToUpdate).ForeColor = GetPrimaryTextColor();

               // ((System.Windows.Forms.Label)controlToUpdate).Font = openSans[12, OpenSans.Weight.Regular];
            }
    

            #region TableLayoutPanel
            if (controlToUpdate is TableLayoutPanel)
            {
                // controlToUpdate.BackColor = GetDividersColor();
                controlToUpdate.BackColor = newBackColor;
            }
            #endregion
            
            #region Navigation Menu

            if (controlToUpdate.GetType() == typeof(ModernGUI.Controls.NavigtionMenu))
            {
                ((ModernGUI.Controls.NavigtionMenu)controlToUpdate).BackColor = _instance.ColorScheme.PrimaryColor;
                ((ModernGUI.Controls.NavigtionMenu)controlToUpdate).BackColor_Selected = ModernGUI.Shared.Drawing.HighlightColor(_instance.ColorScheme.PrimaryColor, 1.5f);
                ((ModernGUI.Controls.NavigtionMenu)controlToUpdate).BackColor_Hover = ControlPaint.Dark(_instance.ColorScheme.PrimaryColor);
                ((ModernGUI.Controls.NavigtionMenu)controlToUpdate).BackColor_Click = ControlPaint.Dark(_instance.ColorScheme.PrimaryColor);
                return; // This needs to return, beacuse this is a composite of panel controls and will be changded by the panel update 
            }
            if (controlToUpdate?.Parent?.GetType() == typeof(ModernGUI.Controls.NavigtionMenu))
            {
                return;
            }
            #endregion

            #region Panel

            if (controlToUpdate.GetType() == typeof(System.Windows.Forms.Panel))
            {
                if (controlToUpdate is System.Windows.Forms.Panel)
                {
                    controlToUpdate.BackColor = GetPanelBackgroundColor((System.Windows.Forms.Panel)controlToUpdate); //Color.FromArgb(newBackColor.ToArgb() ^ 0xffffff);
                }
            }
            if (controlToUpdate.GetType() == typeof(ModernGUI.Controls.Panel))
            {
                if (controlToUpdate is ModernGUI.Controls.Panel)
                {
                    controlToUpdate.BackColor = GetPanelBackgroundColor((ModernGUI.Controls.Panel)controlToUpdate); //Color.FromArgb(newBackColor.ToArgb() ^ 0xffffff);
                }
            }
            #endregion

            #region UserControl
            if (controlToUpdate is (System.Windows.Forms.UserControl))
            {
                controlToUpdate.BackColor = GetUserControlBackgroundColor((System.Windows.Forms.UserControl)controlToUpdate);
            }
            #endregion

            //recursive call
            foreach (Control control in controlToUpdate.Controls)
            {
                 UpdateControl(control, newBackColor);
            }

            controlToUpdate.Invalidate();
        }

    }
}
