using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace code2html
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            for (int i = 0; i < 10; ++i)
            {
                colors[i] = Color.DarkBlue;
                fonts[i] = fontDialog1.Font;
            }
            colors[3] = Color.Blue;
            colors[8] = Color.Green;
            colors[9] = Color.DarkRed;
        }

        private bool m_bKeygroup = false;
        private Color[] colors = new Color[10];
        private Font[] fonts = new Font[10];
        private bool m_bCommentStyleExist = false;
        private bool m_bStringStyleExist = false;
        private string m_sCommentStart = "";
        private string m_sCommentEnd = "";
        private bool m_bMultiLineCommentOpen = false;
        private string m_sCommentSign = "";
        private char m_cEscapeChar = '.';

        private void BTN_SEARCH_SYN_Click(object sender, EventArgs e)
        {
            if (openSyntaxFileDialog.ShowDialog() == DialogResult.OK)
            {
                SynFileText.Text = openSyntaxFileDialog.FileName;

                //parse syntax file
                string[] Lines = System.IO.File.ReadAllLines(SynFileText.Text, ASCIIEncoding.ASCII);
                foreach (string str in Lines)
                {
                    str.Trim();
                    switch (str)
                    {
                        case "[keygroup1]":
                            goto case "[group1]";
                        case "[group1]":
                            group1btn.Enabled = true;
                            group1pBox.Enabled = true;
                            break;
                        case "[keygroup2]":
                            goto case "[group2]";
                        case "[group2]":
                            group2btn.Enabled = true;
                            group2pBox.Enabled = true;
                            break;
                        case "[keygroup3]":
                            goto case "[group3]";
                        case "[group3]":
                            group3btn.Enabled = true;
                            group3pBox.Enabled = true;
                            break;
                        case "[keygroup4]":
                            goto case "[group4]";
                        case "[group4]":
                            group4btn.Enabled = true;
                            group4pBox.Enabled = true;
                            break;
                        case "[keygroup5]":
                            goto case "[group5]";
                        case "[group5]":
                            group5btn.Enabled = true;
                            group5pBox.Enabled = true;
                            break;
                        case "[keygroup6]":
                            goto case "[group6]";
                        case "[group6]":
                            group6btn.Enabled = true;
                            group6pBox.Enabled = true;
                            break;
                        case "[keygroup7]":
                            goto case "[group7]";
                        case "[group7]":
                            group7btn.Enabled = true;
                            group7pBox.Enabled = true;
                            break;
                        case "[keygroup8]":
                            goto case "[group8]";
                        case "[group8]":
                            group8btn.Enabled = true;
                            group8pBox.Enabled = true;
                            break;
                    }
                }
            }
        }

        private void BTN_SEARCH_CODE_Click(object sender, EventArgs e)
        {
            if (openCodeFileDialog.ShowDialog() == DialogResult.OK)
            {
                CodeFileText.Text = openCodeFileDialog.FileName;
            }
        }

        private void BTN_CONVERT_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                 string[][] groups = new string[0][];
                 char[] Stringsigns = new char[0];
                 using (System.IO.StreamWriter sw = new System.IO.StreamWriter(saveFileDialog1.FileName))
                {
                    sw.WriteLine("<?xml version=\"1.0\" encoding=\"ISO-8859-15\" ?>");
                    sw.WriteLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
                    sw.WriteLine("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
                    sw.WriteLine("");
                    sw.WriteLine("\t<head>");
                    sw.WriteLine("\t\t<title>"+CodeFileText.Text+"</title>");
                    sw.WriteLine("\t\t<meta http-equiv=\"content-type\" content=\"text/html; charset=ISO-8859-15\" />");
                    sw.WriteLine("\t\t<style type=\"text/css\">");

                    //parse syntax file
                    string[] Lines = System.IO.File.ReadAllLines(SynFileText.Text, ASCIIEncoding.ASCII);
                    int i = 0;
                    foreach (string str in Lines)
                    {
                        str.Trim();
                        if (str.StartsWith("//"))
                            continue;
                        if (str == "") continue;
                        if (str == " ") continue;
                        if (str.StartsWith("Escapechar"))
                        {
                            m_cEscapeChar = (char)str.Substring(str.IndexOf(":") + 1)[0];
                            continue;
                        }
                        if (str.StartsWith("Commentsign"))
                        {
                            m_sCommentSign = str.Substring(str.IndexOf(":") + 1);
                            //write new Style
                            if (!m_bCommentStyleExist)
                            {
                                sw.WriteLine("\t\t\tvar.group9 {");
                                sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[8]) + ";");
                                sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[8]) + ";");
                                sw.WriteLine("\t\t\t}");
                                m_bCommentStyleExist = true;
                            }
                            continue;
                        }
                        if (str.StartsWith("Commentstart"))
                        {
                            m_sCommentStart = str.Substring(str.IndexOf(":") + 1);
                            //write new Style
                            if (!m_bCommentStyleExist)
                            {
                                sw.WriteLine("\t\t\tvar.group9 {");
                                sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[8]) + ";");
                                sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[8]) + ";");
                                sw.WriteLine("\t\t\t}");
                                m_bCommentStyleExist = true;
                            }
                            continue;
                        }
                        if (str.StartsWith("Commentend"))
                        {
                            m_sCommentEnd = str.Substring(str.IndexOf(":") + 1);
                            //write new Style
                            if (!m_bCommentStyleExist)
                            {
                                sw.WriteLine("\t\t\tvar.group9 {");
                                sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[8]) + ";");
                                sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[8]) + ";");
                                sw.WriteLine("\t\t\t}");
                                m_bCommentStyleExist = true;
                            }
                            continue;
                        }
                        if (str.StartsWith("Stringsign"))
                        {
                            Array.Resize(ref Stringsigns, Stringsigns.GetLength(0) + 1);
                            Stringsigns[Stringsigns.GetLength(0) - 1] = str[str.IndexOf(":") + 1];
                            //write new Style
                            if (!m_bStringStyleExist)
                            {
                                sw.WriteLine("\t\t\tvar.group10 {");
                                sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[9]) + ";");
                                sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[9]) + ";");
                                sw.WriteLine("\t\t\t}");
                                m_bStringStyleExist = true;
                            }
                            continue;
                        }
                        if (str.StartsWith("[group"))
                        {
                            Array.Resize(ref groups, groups.GetLength(0) + 1);
                            groups[groups.GetLength(0)-1] = new string[0];
                            //write new Style
                            sw.WriteLine("\t\t\tvar.group"+System.Convert.ToString(i+1)+" {");
                            sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[i]) + ";");
                            sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[i++]) + ";");
                            sw.WriteLine("\t\t\t}");
                            m_bKeygroup = false;
                            continue;
                        }
                        if (str.StartsWith("[keygroup"))
                        {
                            Array.Resize(ref groups, groups.GetLength(0) + 1);
                            groups[groups.GetLength(0) - 1] = new string[0];
                            //write new Style
                            sw.WriteLine("\t\t\tvar.group"+System.Convert.ToString(i+1)+" {");
                            sw.WriteLine("\t\t\t\tcolor:" + ColorConv(colors[i]) + ";");
                            sw.WriteLine("\t\t\t\tfont:" + FontConv(fonts[i++]) + ";");
                            sw.WriteLine("\t\t\t}");
                            m_bKeygroup = true;
                            continue;
                        }
                        string output = str + " ";
                        Array.Resize(ref groups[groups.GetLength(0) - 1], groups[groups.GetLength(0) - 1].GetLength(0) + 1);
                        groups[groups.GetLength(0) - 1][groups[groups.GetLength(0) - 1].GetLength(0) - 1] = output;
                        if (!m_bKeygroup)
                        {
                            output = str + "(";
                            Array.Resize(ref groups[groups.GetLength(0) - 1], groups[groups.GetLength(0) - 1].GetLength(0) + 1);
                            groups[groups.GetLength(0) - 1][groups[groups.GetLength(0) - 1].GetLength(0) - 1] = output;
                        }
                        else
                        {
                            output = str + ")";
                            Array.Resize(ref groups[groups.GetLength(0) - 1], groups[groups.GetLength(0) - 1].GetLength(0) + 1);
                            groups[groups.GetLength(0) - 1][groups[groups.GetLength(0) - 1].GetLength(0) - 1] = output;
                        }

                    }

                    sw.WriteLine("\t\t</style>");
                    sw.WriteLine("\t</head>");
                    sw.WriteLine("");
                    sw.WriteLine("\t<body>");
                    sw.WriteLine("\t\t<pre>");

                     //convert code file
                    Lines = System.IO.File.ReadAllLines(CodeFileText.Text, ASCIIEncoding.ASCII);
                    foreach (string str in Lines)
                    {
                        string output = str;

                        output = output.Replace("&", "&amp;");
                        output = output.Replace("<", "&lt;");
                        output = output.Replace(">", "&gt;");
                        output = output.Replace("ü", "&uuml;");
                        output = output.Replace("ä", "&auml;");
                        output = output.Replace("ö", "&ouml;");
                        output = output.Replace("ß", "&szlig;");

                        int commentidx = -1;
                        int iMultiLineCommentStart = -1;
                        int iMultiLineCommentEnd = -1;

                        if ((commentidx = output.IndexOf(m_sCommentSign)) != -1)
                        {
                            output = output.Insert(commentidx, "<var class=\"group9\">");
                            output = output.Insert(output.Length, "</var>");
                        }
                        if (commentidx == 0)
                            continue;

                        if ((iMultiLineCommentStart = output.IndexOf(m_sCommentStart)) > -1)
                        {
                            if (!((iMultiLineCommentStart > commentidx) && (commentidx>0)))
                            {
                                output = output.Insert(iMultiLineCommentStart, "<var class=\"group9\">");
                                m_bMultiLineCommentOpen = true;
                            }
                        }

                        if ((iMultiLineCommentEnd = output.IndexOf(m_sCommentEnd)) > -1)
                        {
                            output = output.Insert(iMultiLineCommentEnd + 2, "</var>");
                            m_bMultiLineCommentOpen = false;
                        }
                        if (!m_bMultiLineCommentOpen)
                        {
                            int stringidx = -1;
                            bool stringstart = true;
                            char stringstartchar = 'x';
                            int chars2add = 0;
                            int charcorrect = 0;
                            do
                            {
                                charcorrect += chars2add;
                                stringidx = output.IndexOfAny(Stringsigns, stringidx + 1 + chars2add);
             //                   if ((stringidx>0) && (output[stringidx - 1] == m_cEscapeChar))
             //                       continue;

                                if ((commentidx < 0) || ((commentidx > -1) && ((stringidx + 1) < (commentidx + charcorrect))))
                                if ((iMultiLineCommentEnd < 0) || ((iMultiLineCommentEnd>-1) && ((stringidx + 1)>iMultiLineCommentEnd)))
                                {
                                    if (stringidx > -1)
                                    {
                                        chars2add = 0;
                                        if (stringstart)
                                        {
                                            stringstartchar = output[stringidx];
                                            output = output.Insert(stringidx, "<var class=\"group10\">");
                                            chars2add = 21;
                                            stringstart = false;
                                        }
                                        else
                                        {
                                            if(stringstartchar==output[stringidx])
                                            {
                                                output = output.Insert(stringidx + 1, "</var>");
                                                chars2add = 6;
                                                stringstart = true;
                                            }
                                        }
                                    }
                                }

                        } while (stringidx > -1 && stringidx+chars2add+1 < output.Length);


                            int cnt = 0;
                            foreach (string[] groupwords in groups)
                            {
                                cnt++;
                                int curridx = -1;
                                foreach(string word in groupwords)
                                    if ((curridx = str.IndexOf(word)) != -1)
                                        if ((curridx==0) || ((curridx>0) && (str[curridx-1]==' ' || str[curridx-1]=='(')))
                                            if ((commentidx < 0) || ((commentidx > -1) && ((curridx + 1) < commentidx)))
                                                if ((iMultiLineCommentEnd < 0) || ((iMultiLineCommentEnd > -1) && ((curridx + 1) > iMultiLineCommentEnd)))
                                                    output = output.Replace(word.Substring(0, word.Length - 1), "<var class=\"group" + cnt.ToString() + "\">" + word.Substring(0, word.Length - 1) + "</var>");
                            }
                        }
                        sw.WriteLine(output);
                    }

                    sw.WriteLine("\t\t</pre>");
                    sw.WriteLine("\t</body>");
                    sw.WriteLine("</html>");
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (fontDialog1.ShowDialog() == DialogResult.OK)
                fonts[0] = fontDialog1.Font;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if (colorDialog1.ShowDialog() == DialogResult.OK)
                group1pBox.BackColor = colors[0] = colorDialog1.Color;
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (fontDialog2.ShowDialog() == DialogResult.OK)
                fonts[1] = fontDialog2.Font;
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            if (colorDialog2.ShowDialog() == DialogResult.OK)
                group2pBox.BackColor = colors[1] = colorDialog2.Color;
        }
        private void button3_Click(object sender, EventArgs e)
        {
            if (fontDialog3.ShowDialog() == DialogResult.OK)
                fonts[2] = fontDialog3.Font;
        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {
            if (colorDialog3.ShowDialog() == DialogResult.OK)
                group3pBox.BackColor = colors[2] = colorDialog3.Color;
        }
        private void button4_Click(object sender, EventArgs e)
        {
            if (fontDialog4.ShowDialog() == DialogResult.OK)
                fonts[3] = fontDialog4.Font;
        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {
            if (colorDialog4.ShowDialog() == DialogResult.OK)
                group4pBox.BackColor = colors[3] = colorDialog4.Color;
        }
        private void button5_Click(object sender, EventArgs e)
        {
            if (fontDialog5.ShowDialog() == DialogResult.OK)
                fonts[4] = fontDialog5.Font;
        }

        private void pictureBox5_Click(object sender, EventArgs e)
        {
            if (colorDialog5.ShowDialog() == DialogResult.OK)
                group5pBox.BackColor = colors[4] = colorDialog5.Color;
        }
        private void button6_Click(object sender, EventArgs e)
        {
            if (fontDialog6.ShowDialog() == DialogResult.OK)
                fonts[5] = fontDialog6.Font;
        }

        private void pictureBox6_Click(object sender, EventArgs e)
        {
            if (colorDialog6.ShowDialog() == DialogResult.OK)
                group6pBox.BackColor = colors[5] = colorDialog6.Color;
        }
        private void button7_Click(object sender, EventArgs e)
        {
            if (fontDialog7.ShowDialog() == DialogResult.OK)
                fonts[6] = fontDialog7.Font;
        }

        private void pictureBox7_Click(object sender, EventArgs e)
        {
            if (colorDialog7.ShowDialog() == DialogResult.OK)
                group7pBox.BackColor = colors[6] = colorDialog7.Color;
        }
        private void button8_Click(object sender, EventArgs e)
        {
            if (fontDialog8.ShowDialog() == DialogResult.OK)
                fonts[7] = fontDialog8.Font;
        }

        private void pictureBox8_Click(object sender, EventArgs e)
        {
            if (colorDialog8.ShowDialog() == DialogResult.OK)
                group8pBox.BackColor = colors[7] = colorDialog8.Color;
        }
        private void button9_Click(object sender, EventArgs e)
        {
            if (fontDialog9.ShowDialog() == DialogResult.OK)
                fonts[8] = fontDialog9.Font;
        }

        private void pictureBox9_Click(object sender, EventArgs e)
        {
            if (colorDialog9.ShowDialog() == DialogResult.OK)
                group9pBox.BackColor = colors[8] = colorDialog9.Color;
        }
        private void button10_Click(object sender, EventArgs e)
        {
            if (fontDialog10.ShowDialog() == DialogResult.OK)
                fonts[9] = fontDialog10.Font;
        }

        private void pictureBox10_Click(object sender, EventArgs e)
        {
            if (colorDialog10.ShowDialog() == DialogResult.OK)
                group10pBox.BackColor = colors[9] = colorDialog10.Color;
        }

        private string ColorConv(Color Color2Convert)
        {
            return "#" + String.Format("{0:x2}",Color2Convert.R) +
                         String.Format("{0:x2}",Color2Convert.G) +
                         String.Format("{0:x2}",Color2Convert.B);
        }

        private string FontConv(Font Font2Convert)
        {
            string Output = "";

            if (Font2Convert.Italic)
                Output += "italic ";
            if (Font2Convert.Bold)
                Output += "bold ";
            Output += Font2Convert.SizeInPoints.ToString().Replace(",", ".") + "pt ";
            Output += "\"" + Font2Convert.Name.ToString() + "\"";
            return Output;
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            About myAbout = new About();
            myAbout.ShowDialog();
        }
    }
}