using System.Collections.Generic;
using System.IO;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Win32;
using FooEditEngine;
using FooEditEngine.Windows;
using FooEditor.Properties;

namespace FooEditor
{
    public class Config
    {
        static private Config _instance;

        public const string RegAppPath = "Software\\FooProject\\FooEditor";
        const string SyntaxDefinitionPath = RegAppPath + "\\SytaxDefinition";

        public string FontName,GrepPath;
        public float FontSize;
        public int Height, Width,MaxBackupCount , TabStops,AutoSaveCount;
        public bool WordRap,DrawLine,UrlMark,DrawLineNumber;
        public ColorTable Token2Color;
        
        private Config()
        {
            this.RecentFile = new RecentFileCollection();
            this.DontLoadPlugins = new List<string>();
            this.SyntaxDefinitions = new Dictionary<string, string>();
            this.Token2Color = new ColorTable();
        }

        static public Config GetInstance()
        {
            if (_instance == null)
                _instance = new Config();
            return _instance;
        }

        public static string ApplicationFolder
        {
            get
            {
                return Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData),Resources.AppName);
            }
        }

        public int RecentMaxCount
        {
            get { return this.RecentFile.MaxCount; }
            set { this.RecentFile.MaxCount = value; }
        }

        internal RecentFileCollection RecentFile
        {
            get;
            private set;
        }
        
        public Dictionary<string, string> SyntaxDefinitions
        {
            get;
            private set;
        }

        public List<string> DontLoadPlugins
        {
            get;
            private set;
        }

        public void Load()
        {
            RegistryKey regkey = Registry.CurrentUser.CreateSubKey(RegAppPath);
            
            this.FontName = (string)regkey.GetValue("FontName", SystemFonts.DialogFont.Name);
            this.FontSize = float.Parse((string)regkey.GetValue("FontSize", SystemFonts.DialogFont.Size.ToString()));
            this.Height = (int)regkey.GetValue("Height",480);
            this.Width = (int)regkey.GetValue("Width", 640);
            this.MaxBackupCount = (int)regkey.GetValue("MaxBackupCount", 4);
            this.RecentMaxCount = (int)regkey.GetValue("RecentCount", 4);
            this.WordRap = bool.Parse((string)regkey.GetValue("WordRap","false"));
            this.DrawLine = bool.Parse((string)regkey.GetValue("DrawLine", "true"));
            this.UrlMark = bool.Parse((string)regkey.GetValue("UrlMark", "false"));
            this.DrawLineNumber = bool.Parse((string)regkey.GetValue("DrawLineNumber", "false"));
            this.AutoSaveCount = (int)regkey.GetValue("AutoSaveCount", 0);
            string[] temp = (string[])regkey.GetValue("RecentFile", new string[0]);
            this.RecentFile.AddRange(temp);
            temp = (string[])regkey.GetValue("DontLoadPlugin", new string[0]);
            this.DontLoadPlugins.AddRange(temp);
            this.TabStops = (int)regkey.GetValue("TabStops", 4);
            this.GrepPath = (string)regkey.GetValue("GrepPath", Application.StartupPath + "\\FooGrep.EXE");
            this.Token2Color.Fore = ColorTranslator.FromOle((int)regkey.GetValue("ForeColor", ColorTranslator.ToOle(SystemColors.WindowText)));
            this.Token2Color.Back = ColorTranslator.FromOle((int)regkey.GetValue("BackColor", ColorTranslator.ToOle(SystemColors.Control)));
            this.Token2Color.LineMarker = ColorTranslator.FromOle((int)regkey.GetValue("MarkerColor", ColorTranslator.ToOle(Color.LightGray)));
            this.Token2Color.Comment = ColorTranslator.FromOle((int)regkey.GetValue("CommentColor", ColorTranslator.ToOle(Color.Green)));
            this.Token2Color.Keyword1 = ColorTranslator.FromOle((int)regkey.GetValue("Keyword1Color", ColorTranslator.ToOle(Color.Blue)));
            this.Token2Color.Keyword2 = ColorTranslator.FromOle((int)regkey.GetValue("Keyword2Color", ColorTranslator.ToOle(Color.DarkCyan)));
            this.Token2Color.Literal = ColorTranslator.FromOle((int)regkey.GetValue("LiteralColor", ColorTranslator.ToOle(Color.Brown)));
            this.Token2Color.Control = ColorTranslator.FromOle((int)regkey.GetValue("ControlColor", ColorTranslator.ToOle(Color.Gray)));
            this.Token2Color.URL = ColorTranslator.FromOle((int)regkey.GetValue("URLColor", ColorTranslator.ToOle(Color.Blue)));
            this.Token2Color.Hilight = ColorTranslator.FromOle((int)regkey.GetValue("HilightColor", ColorTranslator.ToOle(SystemColors.Highlight)));
            regkey.Close();

            regkey = Registry.CurrentUser.OpenSubKey(SyntaxDefinitionPath);
            if (regkey == null)
                regkey = SetDefalutSytax();
            string[] names = regkey.GetValueNames();
            this.SyntaxDefinitions.Clear();
            foreach (string name in names)
                if (name != "")
                    this.SyntaxDefinitions.Add(name, (string)regkey.GetValue(name));
            regkey.Close();

            return;
        }
        public void Save()
        {
            RegistryKey regkey = Registry.CurrentUser.CreateSubKey(RegAppPath);
            regkey.SetValue("FontName", this.FontName);
            regkey.SetValue("FontSize", this.FontSize);
            regkey.SetValue("Height", this.Height);
            regkey.SetValue("Width", this.Width);
            regkey.SetValue("MaxBackupCount", this.MaxBackupCount);
            regkey.SetValue("RecentCount", this.RecentMaxCount);
            regkey.SetValue("WordRap", this.WordRap);
            regkey.SetValue("DrawLine", this.DrawLine);
            regkey.SetValue("RecentFile", this.RecentFile.ToArray());
            regkey.SetValue("DontLoadPlugin", this.DontLoadPlugins.ToArray());
            regkey.SetValue("TabStops", this.TabStops);
            regkey.SetValue("UrlMark", this.UrlMark);
            regkey.SetValue("GrepPath", this.GrepPath);
            regkey.SetValue("AutoSaveCount", this.AutoSaveCount);
            regkey.SetValue("ForeColor", ColorTranslator.ToOle(this.Token2Color.Fore));
            regkey.SetValue("BackColor", ColorTranslator.ToOle(this.Token2Color.Back));
            regkey.SetValue("MarkerColor", ColorTranslator.ToOle(this.Token2Color.LineMarker));
            regkey.SetValue("CommentColor", ColorTranslator.ToOle(this.Token2Color.Comment));
            regkey.SetValue("Keyword1Color", ColorTranslator.ToOle(this.Token2Color.Keyword1));
            regkey.SetValue("Keyword2Color", ColorTranslator.ToOle(this.Token2Color.Keyword2));
            regkey.SetValue("LiteralColor", ColorTranslator.ToOle(this.Token2Color.Literal));
            regkey.SetValue("ControlColor", ColorTranslator.ToOle(this.Token2Color.Control));
            regkey.SetValue("URLColor", ColorTranslator.ToOle(this.Token2Color.URL));
            regkey.SetValue("HilightColor", ColorTranslator.ToOle(this.Token2Color.Hilight));
            regkey.SetValue("DrawLineNumber", this.DrawLineNumber);
            regkey.Close();

            regkey =  Registry.CurrentUser.CreateSubKey(SyntaxDefinitionPath);
            foreach (KeyValuePair<string, string> kv in SyntaxDefinitions)
                regkey.SetValue(kv.Key, kv.Value);
            regkey.Close();            
        }

        private RegistryKey SetDefalutSytax()
        {
            RegistryKey regkey = Registry.CurrentUser.CreateSubKey(SyntaxDefinitionPath);
            regkey.SetValue("clang.xml", ".+\\.(c|cpp|cs)$");
            regkey.SetValue("css.xml", ".+\\.(css)$");
            regkey.SetValue("html.xml", ".+\\.(htm|html|xhtml)$");
            regkey.SetValue("javascript.xml", ".+\\.(js)$");
            regkey.SetValue("php.xml", ".+\\.(php)$");
            regkey.SetValue("python.xml", ".+\\.(py)$");
            regkey.SetValue("ruby.xml", ".+\\.(rb)$");
            regkey.SetValue("vb.xml", ".+\\.(vb|vbs)$");
            regkey.SetValue("perl.xml", ".+\\.(pl)$");
            regkey.SetValue("java.xml", ".+\\.(java)$");
            regkey.SetValue("xml.xml", ".+\\.(xml)$");
            return regkey;
        }
    }
}
