using System;
using System.Drawing;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Reflection;
using FooEditor.Properties;
using FooEditor.Plugin;

namespace FooEditor
{
    public delegate void ConfigChangeEventHandler(object sender,EventArgs e);

    public partial class ConfigForm : Form
    {
        Dictionary<string, string> tempSyntaxDef;
        List<string> DontLoadPlugins;

        public ConfigForm(IEnumerable<IPlugin> plugins)
        {
            InitializeComponent();
            
            this.ConfigChangeEvent += new ConfigChangeEventHandler((s,e)=>{});
                        
            this.tempSyntaxDef = new Dictionary<string, string>();
            this.DontLoadPlugins = new List<string>();

            foreach (IPlugin plugin in plugins)
            {
                AssemblyName asm = plugin.GetType().Assembly.GetName();
                PluginListViewItem item = new PluginListViewItem(asm.Name,asm.Version.ToString(),Path.GetFileName(asm.CodeBase),plugin);
                this.listView1.Items.Add(item);
            }

            this.button7.Enabled = false;
            this.button8.Enabled = false;
        }

        public event ConfigChangeEventHandler ConfigChangeEvent;

        private void ConfigForm_Load(object sender, EventArgs e)
        {
            Config cfg = Config.GetInstance();

            this.checkBox3.Checked = cfg.DrawLine;
            this.checkBox4.Checked = cfg.UrlMark;
            this.numericUpDown2.Value = cfg.TabStops;
            this.checkBox6.Checked = cfg.WordRap;
            this.checkBox7.Checked = cfg.DrawLineNumber;

            this.numericUpDown4.Value = cfg.MaxBackupCount;
            this.numericUpDown1.Value = cfg.RecentMaxCount;
            this.numericUpDown5.Value = cfg.AutoSaveCount;
            
            foreach (string s in cfg.SyntaxDefinitions.Keys)
            {
                this.listBox1.Items.Add(s);
                this.tempSyntaxDef.Add(s, cfg.SyntaxDefinitions[s]);
            }

            this.numericUpDown3.Value = (int)cfg.FontSize;
            foreach (var font in FontFamily.Families)
            {
                this.comboBox2.Items.Add(font.Name);
                if (font.Name == cfg.FontName)
                    this.comboBox2.SelectedItem = font.Name;
            }

            this.colorComboBox1.SelectedColor = cfg.Token2Color.Fore;
            this.colorComboBox2.SelectedColor = cfg.Token2Color.Back;
            this.colorComboBox3.SelectedColor = cfg.Token2Color.Comment;
            this.colorComboBox4.SelectedColor = cfg.Token2Color.Literal;
            this.colorComboBox5.SelectedColor = cfg.Token2Color.Keyword1;
            this.colorComboBox6.SelectedColor = cfg.Token2Color.Keyword2;
            this.colorComboBox7.SelectedColor = cfg.Token2Color.Control;
            this.colorComboBox8.SelectedColor = cfg.Token2Color.URL;
            this.colorComboBox9.SelectedColor = cfg.Token2Color.Hilight;
            this.colorComboBox10.SelectedColor = cfg.Token2Color.LineMarker;

            foreach (var str in cfg.DontLoadPlugins)
            {
                this.DontLoadPlugins.Add(str);

                string pluginName = Path.GetFileNameWithoutExtension(str);
                if (this.listView1.Items.ContainsKey(pluginName) == false)
                {
                    PluginListViewItem item = new PluginListViewItem(pluginName, string.Empty, str, null);
                    this.listView1.Items.Add(item);
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Config cfg = Config.GetInstance();

            cfg.DrawLine = this.checkBox3.Checked;
            cfg.UrlMark = this.checkBox4.Checked;
            cfg.TabStops = (int)this.numericUpDown2.Value;
            cfg.WordRap = this.checkBox6.Checked;
            cfg.DrawLineNumber = this.checkBox7.Checked;

            cfg.MaxBackupCount = (int)this.numericUpDown4.Value;
            cfg.RecentMaxCount = (int)this.numericUpDown1.Value;
            cfg.AutoSaveCount = (int)this.numericUpDown5.Value;

            SaveSyntaxDef();
            cfg.SyntaxDefinitions.Clear();
            foreach (KeyValuePair<string, string> kv in this.tempSyntaxDef)
                cfg.SyntaxDefinitions.Add(kv.Key, kv.Value);

            cfg.Token2Color.Fore = this.colorComboBox1.SelectedColor;
            cfg.Token2Color.Back = this.colorComboBox2.SelectedColor;
            cfg.Token2Color.Comment = this.colorComboBox3.SelectedColor;
            cfg.Token2Color.Literal = this.colorComboBox4.SelectedColor;
            cfg.Token2Color.Keyword1 = this.colorComboBox5.SelectedColor;
            cfg.Token2Color.Keyword2 = this.colorComboBox6.SelectedColor;
            cfg.Token2Color.Control = this.colorComboBox7.SelectedColor;
            cfg.Token2Color.URL = this.colorComboBox8.SelectedColor;
            cfg.Token2Color.Hilight = this.colorComboBox9.SelectedColor;
            cfg.Token2Color.LineMarker = this.colorComboBox10.SelectedColor;
            cfg.FontName = (string)this.comboBox2.SelectedItem;
            cfg.FontSize = (float)this.numericUpDown3.Value;

            if (cfg.DontLoadPlugins.Count != this.DontLoadPlugins.Count)
                MessageBox.Show(Resources.ShouldBeReboot);

            cfg.DontLoadPlugins.Clear();
            foreach (var str in this.DontLoadPlugins)
                cfg.DontLoadPlugins.Add(str);

            this.ConfigChangeEvent(this, new EventArgs());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.button3_Click(sender, e);
            this.Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Config cfg = Config.GetInstance();

            cfg.RecentFile.Clear();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            string key = (string)this.listBox1.SelectedItem;

            if (key == null)
            {
                this.textBox1.Text = string.Empty;
                this.textBox2.Text = string.Empty;
                return;
            }

            SaveSyntaxDef();

            this.textBox1.Text = key;
            this.textBox2.Text = this.tempSyntaxDef[key];
        }

        private void button5_Click(object sender, EventArgs e)
        {
            string key = Resources.DocumentModeNewItem + this.tempSyntaxDef.Count;
            this.tempSyntaxDef.Add(key, "");
            this.listBox1.Items.Add(key);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            string key = (string)this.listBox1.SelectedItem;
            this.tempSyntaxDef.Remove(key);
            this.listBox1.Items.Remove(key);
        }
        void SaveSyntaxDef()
        {
            string key = this.textBox1.Text;
            string value = this.textBox2.Text;
            if (key != string.Empty && value != string.Empty)
                this.tempSyntaxDef[key] = value;
        }

        private void button9_Click(object sender, EventArgs e)
        {
            if (this.listView1.SelectedItems == null || this.listView1.SelectedItems.Count == 0)
                return;
            PluginListViewItem item = (PluginListViewItem)this.listView1.SelectedItems[0];
            IPlugin plugin = item.plugin;

            plugin.ShowConfigForm();
        }

        private void listView1_DoubleClick(object sender, EventArgs e)
        {
            this.button9_Click(this.button9, null);
        }

        private void button7_Click(object sender, EventArgs e)
        {
            if (this.listView1.SelectedItems == null || this.listView1.SelectedItems.Count == 0)
                return;
            PluginListViewItem item = (PluginListViewItem)this.listView1.SelectedItems[0];

            this.DontLoadPlugins.Remove(item.fileName);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            if (this.listView1.SelectedItems == null || this.listView1.SelectedItems.Count == 0)
                return;
            PluginListViewItem item = (PluginListViewItem)this.listView1.SelectedItems[0];

            if (this.DontLoadPlugins.Contains(item.fileName) == false)
                this.DontLoadPlugins.Add(item.fileName);
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.listView1.SelectedItems == null || this.listView1.SelectedItems.Count == 0)
                return;

            PluginListViewItem item = (PluginListViewItem)this.listView1.SelectedItems[0];
            if (this.DontLoadPlugins.Contains(item.fileName))
            {
                this.button7.Enabled = true;
                this.button8.Enabled = false;
            }
            else
            {
                this.button7.Enabled = false;
                this.button8.Enabled = true;
            }
        }
    }

    class PluginListViewItem : ListViewItem
    {
        public PluginListViewItem(string name, string version, string fileName, IPlugin plugin)
            : base(name)
        {
            this.Name = name;
            this.SubItems.Add(version);
            this.SubItems.Add(fileName);
            this.Tag = (object)plugin;
        }

        public string version
        {
            get { return this.SubItems[1].Text; }
        }

        public string fileName
        {
            get { return this.SubItems[2].Text; }
        }

        public IPlugin plugin
        {
            get { return (IPlugin)this.Tag; }
        }
    }
}
