//  
//   Rebex Sample Code License
// 
//   Copyright 2025, REBEX CR s.r.o.
//   All rights reserved.
//   https://www.rebex.net/
// 
//   Permission to use, copy, modify, and/or distribute this software for any
//   purpose with or without fee is hereby granted.
// 
//   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
//   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
//   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
//   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
//   OTHER DEALINGS IN THE SOFTWARE.
// 

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

namespace Rebex.Samples
{
    public static class Colorize
    {
        private static readonly Dictionary<string, string> Keywords;
        private static readonly Dictionary<string, string> Classes;

        static Colorize()
        {
            #region Add keywords and class names
            
            Keywords = new Dictionary<string, string>();
            Keywords.Add("string", null);
            Keywords.Add("int", null);
            Keywords.Add("for", null);
            Keywords.Add("foreach", null);
            
            Classes= new Dictionary<string, string>();
            Classes.Add("MessageBox", null);
            Classes.Add("Scripting", null);
            
            #endregion
        }

        public static void SetCode(RichTextBox textBox, string code)
        {
            textBox.Clear();

            if (code == null)
            {
                textBox.SelectionColor = Color.Red;
                textBox.AppendText("Code not available.");
                return;
            }

            textBox.SelectionColor = Color.Black;

            int start;
            start = code.IndexOf("static void Execute"); if (start < 0) return;
            start = code.IndexOf('{', start); if (start < 0) return;
            start = code.IndexOf('\n', start); if (start < 0) return;
            int end = code.IndexOf("// end of script", start); if (end < 0) return;

            code = code.Substring(start, end - start).Trim();
            code = code.Replace("\t\t\t", ""); // remove leading 3xTAB
            code = code.Replace("            ", ""); // remove leading 12xSPACE

            int pos = 0;
            while (pos < code.Length)
            {
                bool isWord = char.IsLetterOrDigit(code[pos]);
                bool isComment = false;
                bool isString = false;

                int n = pos + 1;
                while (n < code.Length)
                {
                    char c = code[n];
                    if (char.IsLetterOrDigit(c) != isWord)
                        break;

                    if (c == '/' && code[n - 1] == '/')
                    {
                        isComment = true;
                        n--;
                        break;
                    }

                    if (c == '"')
                    {
                        isString = true;
                        break;
                    }

                    n++;
                }

                string chunk = code.Substring(pos, n - pos);
                if (isWord)
                {
                    if (Keywords.ContainsKey(chunk))
                        textBox.SelectionColor = Color.Blue;
                    else if (Classes.ContainsKey(chunk))
                        textBox.SelectionColor = Color.DarkCyan;
                    else
                        textBox.SelectionColor = Color.Black;

                    textBox.AppendText(chunk);
                }
                else
                {
                    textBox.SelectionColor = Color.Black;
                    textBox.AppendText(chunk);
                }

                pos = n;

                if (isComment)
                {
                    n = code.IndexOf('\n', pos); if (n < 0) n = code.Length;

                    chunk = code.Substring(pos, n - pos + 1);
                    textBox.SelectionColor = Color.DarkGreen;
                    textBox.AppendText(chunk);
                    pos = n + 1;
                }

                if (isString)
                {
                    n = code.IndexOf('"', pos + 1); if (n < 0) n = code.Length;

                    chunk = code.Substring(pos, n - pos + 1);
                    textBox.SelectionColor = Color.Brown;
                    textBox.AppendText(chunk);
                    pos = n + 1;
                }
            }
        }
    }
}
