using System;
using System.ComponentModel.Composition;
using System.Text;
using System.Text.RegularExpressions;
using FooEditEngine;
using FooEditEngine.Windows;
using StringFilter.Properties;
using FooEditor.Plugin;
using System.Windows.Forms;

namespace StringFilter
{
    [Export(typeof(IPlugin))]
    class Filter : IPlugin
    {
        Editor editor;
        #region IPlugin メンバー

        public void Initalize(Editor e)
        {
            this.editor = e;

            ToolStripMenuItem ItemNode = new ToolStripMenuItem(Resource.StringFilterMenuItem);
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToUpperMenuItem,null, ToUpper));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToLowerMenuItem,null, ToLower));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToEntityMenuItem,null, ToEntity));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToRealCharMenuItem,null, ToRealChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToHalfWidthChar,null, ToHalfWidthChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToFullWidthChar,null, ToFullWidthChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ExpandTabMenuItem,null, ExpandTab));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ExpandSpaceMenuItem,null, ExpandSpace));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.InsertQuotationMenuItem,null, InsertQuotation));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.IntendMenuItem,null, Intend));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.UnIntendMenuItem,null, UnIntend));
            ToolStripMenuItem item = (ToolStripMenuItem)e.RootMenuStrip.Items[1];
            item.DropDownItems.Add(new ToolStripSeparator());
            item.DropDownItems.Add(ItemNode);

            ItemNode = new ToolStripMenuItem(Resource.StringFilterMenuItem);
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToUpperMenuItem,null, ToUpper));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToLowerMenuItem,null, ToLower));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToEntityMenuItem,null, ToEntity));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToRealCharMenuItem,null, ToRealChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToHalfWidthChar,null, ToHalfWidthChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ToFullWidthChar,null, ToFullWidthChar));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ExpandTabMenuItem,null, ExpandTab));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.ExpandSpaceMenuItem,null, ExpandSpace));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.InsertQuotationMenuItem,null, InsertQuotation));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.IntendMenuItem,null, Intend));
            ItemNode.DropDownItems.Add(new ToolStripMenuItem(Resource.UnIntendMenuItem,null, UnIntend));
            e.ContextMenuStrip.Items.Add(new ToolStripSeparator());
            e.ContextMenuStrip.Items.Add(ItemNode);
        }

        public void ClosedApp()
        {
        }

        public void ShowConfigForm()
        {
        }
        #endregion

        void UnIntend(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;
            
            TextBox.SelectedText = RemoveLineHead(TextBox.SelectedText, "\t");
            TextBox.Refresh();
        }

        void Intend(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;
            
            TextBox.SelectedText = InsertLineHead(TextBox.SelectedText, "\t");
            TextBox.Refresh();
        }

        void InsertQuotation(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;
            
            TextBox.SelectedText = InsertLineHead(TextBox.SelectedText, ">");
            TextBox.Refresh();
        }

        void ToUpper(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;
            
            TextBox.SelectedText = TextBox.SelectedText.ToUpper();
            TextBox.Refresh();
        }

        void ToLower(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;
            
            TextBox.SelectedText = TextBox.SelectedText.ToLower();
            TextBox.Refresh();
        }

        void ToEntity(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;

            string[] oldVales = new string[] { "\"", "&", "<", ">" };
            string[] newVales = new string[] {"&quot;","&amp;","&lt;","&gt;" };

            TextBox.SelectedText = Replace(TextBox.SelectedText,oldVales,newVales);
            TextBox.Refresh();
        }

        void ToRealChar(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;

            string[] oldVales = new string[] { "&quot;", "&amp;", "&lt;", "&gt;" };
            string[] newVales = new string[] { "\"", "&", "<", ">" };

            TextBox.SelectedText = Replace(TextBox.SelectedText, oldVales, newVales);
            TextBox.Refresh();
        }

        void ToHalfWidthChar(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;

            string[] oldVales = new string[] { "１", "２", "３", "４", "５", "６", "７", "８", "９", "０",
                "！", "”", "＃", "＄", "％", "＆", "’", "（", "）", "－", "＾", "￥", "＠", "；", "：",
                "、", "。", "・", "「", "」", "＝", "～", "｜", "‘", "｛", "＋", "＊", "｝", "＜", "＞",
                "？", "＿", "Ａ", "Ｂ", "Ｃ", "Ｄ", "Ｅ", "Ｆ", "Ｇ", "Ｈ", "Ｉ", "Ｊ", "Ｋ", "Ｌ", "Ｍ", 
                "Ｎ", "Ｏ", "Ｐ", "Ｑ", "Ｒ", "Ｓ", "Ｔ", "Ｕ", "Ｖ", "Ｗ", "Ｘ", "Ｙ", "Ｚ", "ａ", "ｂ", 
                "ｃ", "ｄ", "ｅ", "ｆ", "ｇ", "ｈ", "ｉ", "ｊ", "ｋ", "ｌ", "ｍ", "ｎ", "ｏ", "ｐ", "ｑ", 
                "ｒ", "ｓ", "ｔ", "ｕ", "ｖ", "ｗ", "ｘ", "ｙ", "ｚ"
            };
            string[] newVales = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
                "!", "\"", "#", "$", "%", "&", "'", "(", ")", "-", "^", "\\", "@", ";", ":",
                ",", ".", "/", "[", "]", "=", "~", "|", "`", "{", "+", "*", "}", "<", ">",
                "?", "_", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", 
                "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", 
                "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", 
                "r", "s", "t", "u", "v", "w", "x", "y", "z"
            };

            TextBox.SelectedText = Replace(TextBox.SelectedText, oldVales, newVales);
            TextBox.Refresh();
        }

        void ToFullWidthChar(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;

            string[] oldVales = new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
                "!", "\"", "#", "$", "%", "&", "'", "(", ")", "-", "^", "\\", "@", ";", ":",
                ",", ".", "/", "[", "]", "=", "~", "|", "`", "{", "+", "*", "}", "<", ">",
                "?", "_", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", 
                "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", 
                "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", 
                "r", "s", "t", "u", "v", "w", "x", "y", "z"
            };
            string[] newVales = new string[] { "１", "２", "３", "４", "５", "６", "７", "８", "９", "０",
                "！", "”", "＃", "＄", "％", "＆", "’", "（", "）", "－", "＾", "￥", "＠", "；", "：",
                "、", "。", "・", "「", "」", "＝", "～", "｜", "‘", "｛", "＋", "＊", "｝", "＜", "＞",
                "？", "＿", "Ａ", "Ｂ", "Ｃ", "Ｄ", "Ｅ", "Ｆ", "Ｇ", "Ｈ", "Ｉ", "Ｊ", "Ｋ", "Ｌ", "Ｍ", 
                "Ｎ", "Ｏ", "Ｐ", "Ｑ", "Ｒ", "Ｓ", "Ｔ", "Ｕ", "Ｖ", "Ｗ", "Ｘ", "Ｙ", "Ｚ", "ａ", "ｂ", 
                "ｃ", "ｄ", "ｅ", "ｆ", "ｇ", "ｈ", "ｉ", "ｊ", "ｋ", "ｌ", "ｍ", "ｎ", "ｏ", "ｐ", "ｑ", 
                "ｒ", "ｓ", "ｔ", "ｕ", "ｖ", "ｗ", "ｘ", "ｙ", "ｚ"
            };

            TextBox.SelectedText = Replace(TextBox.SelectedText, oldVales, newVales);
            TextBox.Refresh();
        }

        void ExpandTab(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;

            if (TextBox.RectSelection)
                return;

            int TabStops = TextBox.TabStops;
            StringBuilder temp = new StringBuilder();
            int index = 0;
            string Text = TextBox.SelectedText;
            for (int i = 0; i < Text.Length; i++)
            {
                if (Text[i] == '\t')
                {
                    int tablen = TabStops - (index % TabStops);
                    for (int j = tablen; j > 0; j--)
                        temp.Append(' ');
                    index += tablen;
                }
                else
                {
                    temp.Append(Text[i]);
                    index++;
                }
                if (Text[i] == '\n')
                    index = 0;
            }
            TextBox.SelectedText = temp.ToString();
            TextBox.Refresh();
        }

        void ExpandSpace(object sender, EventArgs e)
        {
            FooTextBox TextBox = this.editor.TextBox;
            
            if (TextBox.RectSelection)
                return;

            Regex regex = new Regex(string.Format(" {{1,{0}}}", TextBox.TabStops));
            TextBox.SelectedText = regex.Replace(TextBox.SelectedText,"\t");
            TextBox.Refresh();
        }


        string InsertLineHead(string s, string str)
        {
            string[] lines = s.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            StringBuilder output = new StringBuilder();
            for (int i = 0; i < lines.Length; i++)
                output.AppendLine(str + lines[i]);
            return output.ToString();
        }

        string RemoveLineHead(string s, string str)
        {
            string[] lines = s.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            StringBuilder output = new StringBuilder();
            for (int i = 0; i < lines.Length; i++)
                if (lines[i].StartsWith(str))
                    output.AppendLine(lines[i].Substring(1));
                else
                    output.AppendLine(lines[i]);
            return output.ToString();
        }

        string Replace(string s, string[] oldValues, string[] newValues)
        {
            if (oldValues.Length != newValues.Length)
                throw new ArgumentException("oldValuesとnewValuesの数が一致しません");

            StringBuilder str = new StringBuilder(s);
            for (int i = 0; i < oldValues.Length; i++)
                str = str.Replace(oldValues[i], newValues[i]);
            return str.ToString();
        }
    }
}
