using Earthblend.Tts.Common.Core.Enumerations;
using System;
using System.Collections.Generic;
using System.Text;

namespace Earthblend.Tts.Common.Core.Statics
{
    public static class VariableUtil
    {
        public const String VisualStudio = @"C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.exe";

        public struct GlobalFields
        {
            public const String VisualFilteredDataItems = "VisualFilteredDataItems";
            public const String FilteredDataItems = "FilteredDataItems";
            public const String DataItems = "DataItems";
            public const String VirtualCanvasDataItems = "VirtualCanvasDataItems";

            public const String FilteredWorldDataItems = "FilteredWorldDataItems";
            public const String SelectedWorldDataItem = "SelectedWorldDataItem";
            public const String FilteredCanvasDataItems = "FilteredCanvasDataItems";
            public const String SelectedCanvasDataItem = "SelectedCanvasDataItem";
            public const String SelectedGroupCount = "SelectedGroupCount";
            public const String FilteredTriangleDataItems = "FilteredTriangleDataItems";
            public const String FilteredVirtualEquationElements = "FilteredVirtualEquationElements";
            public const String FilteredSegments = "FilteredSegments";
            public const String FilteredCanvasDataItemCaptions = "FilteredCanvasDataItemCaptions";
            public const String VirtualEquationElements = "VirtualEquationElements";

            public const String Main = "Main";
            public const String Axis = "Axis";
            public const String WireFrame = "WireFrame";
            public const String AxisNumbers = "AxisNumbers";
            public const String Grids = "Grids";
            public const String RibbonText = "RibbonText";
            public const String Segments = "Segments";
            public const String Squares = "Squares";
            public const String Arrows = "Arrows";
            public const String CompilerPlot = "CompilerPlot";
            public const String SelectionAugment = "SelectionAugment";

        }

        public static List<MathSymbolType> SymbolTypes = new List<MathSymbolType>()
        {
            // MathSymbolType.Actinide
            //,MathSymbolType.AlkaliMetal
            //,MathSymbolType.AlkalineEarth
            //,MathSymbolType.NonMetal
            //,MathSymbolType.NobleGas
            //,MathSymbolType.SuperHeavy
            //,MathSymbolType.Theoretical
            //,MathSymbolType.TransitionMetal
            //,MathSymbolType.BasicMetal
            //,MathSymbolType.Lanthanide
            //,MathSymbolType.Halogen
            //,MathSymbolType.SemiMetal
        };

        private static String MakeSubscript(int value)
        {
            StringBuilder sb = new StringBuilder();

            foreach (var c in value.ToString())
            {
                switch (c)
                {
                    case '0': sb.Append("₀"); break;
                    case '1': sb.Append("₁"); break;
                    case '2': sb.Append("₂"); break;
                    case '3': sb.Append("₃"); break;
                    case '4': sb.Append("₄"); break;
                    case '5': sb.Append("₅"); break;
                    case '6': sb.Append("₆"); break;
                    case '7': sb.Append("₇"); break;
                    case '8': sb.Append("₈"); break;
                    case '9': sb.Append("₉"); break;
                }
            }

            return sb.ToString();
        }

        static VariableUtil()
        {
            //KnownVariables.Add("Z" + i); //500
            foreach (var letter in KnownUpperCaseLetters)
                for (int i = 0; i < 500; i++)
                {
                    KnownVariables.Add(letter + i);
                    KnownVariables.Add(letter.ToLower() + i);
                }

            //KnownVariables.Add("ASub" + i);
            foreach (var letter in KnownUpperCaseLetters)
                for (int i = 0; i < 10; i++)
                    KnownVariables.Add(letter + "Sub" + i);

            //₀,₁,₂,₃,₄,₅,₆,₇,₈,₉
            //foreach(var letter in KnownUpperCaseLetters)
            //    foreach (var subscript in VariableUtil.KnownSubscripts)
            //    {
            //        KnownVariables.Add(letter + subscript.Key);
            //    }
            //    

            var subscripts = new Dictionary<int, String>()
            {
                { 0, "₀"  }, { 1,"₁"   }, { 2,"₂"   }, { 3,"₃"   }, { 4,"₄"   },
                { 5, "₅"  }, { 6,"₆"   }, { 7,"₇"   }, { 8,"₈"   }, { 9,"₉"   },
                { 10,"₁₀" }, { 11,"₁₁" }, { 12,"₁₂" }, { 13,"₁₃" }, { 14,"₁₄" },
                { 15,"₁₅" }, { 16,"₁₆" }, { 17,"₁₇" }, { 18,"₁₈" }, { 19,"₁₉" },
                { 20,"₂₀" }, { 21,"₂₁" }, { 22,"₂₂" }, { 23,"₂₃" }, { 24,"₂₄" },
                { 25,"₂₅" }, { 26,"₂₆" }, { 27,"₂₇" }, { 28,"₂₈" }, { 29,"₂₉" },
                { 30,"₃₀" }, { 31,"₃₁" }, { 32,"₃₂" }, { 33,"₃₃" }, { 34,"₃₄" },
                { 35,"₃₅" }, { 36,"₃₆" }, { 37,"₃₇" }, { 38,"₃₈" }, { 39,"₃₉" },
                { 40,"₄₀" }, { 41,"₄₁" }, { 42,"₄₂" }, { 43,"₄₃" }, { 44,"₄₄" },
                { 45,"₄₅" }, { 46,"₄₆" }, { 47,"₄₇" }, { 48,"₄₈" }, { 49,"₄₉" },
                { 50,"₅₀" },
            };

            for (int i = 51; i <= 1000; i++)
                subscripts.Add(i, MakeSubscript(i));

            for (int i = 0; i <= 1000; i++)
            {
                String str = i.ToString();
                StringBuilder sb = new StringBuilder();
                foreach (char c in str)
                {
                    int n = Convert.ToInt32(c.ToString());
                    sb.Append(subscripts[n]);
                }
                Subscripts.Add(subscripts[i], i);
                KnownSubscripts.Add(sb.ToString(), "Sub" + i.ToString());
            }
        }

        public static Dictionary<String, int> Alphabet = new Dictionary<String, int>() { { "A", 0 }, { "B", 1 }, { "C", 2 }, { "D", 3 }, { "E", 4 }, { "F", 5 }, { "G", 6 }, { "H", 7 }, { "I", 8 }, { "J", 9 }, { "K", 10 }, { "L", 11 }, { "M", 12 }, { "N", 13 }, { "O", 14 }, { "P", 15 }, { "Q", 16 }, { "R", 17 }, { "S", 18 }, { "T", 19 }, { "U", 20 }, { "V", 21 }, { "W", 22 }, { "X", 23 }, { "Y", 24 }, { "Z", 25 }, };
        public static Dictionary<Char, int> AlphabetChar = new Dictionary<Char, int>() { { 'A', 0 }, { 'B', 1 }, { 'C', 2 }, { 'D', 3 }, { 'E', 4 }, { 'F', 5 }, { 'G', 6 }, { 'H', 7 }, { 'I', 8 }, { 'J', 9 }, { 'K', 10 }, { 'L', 11 }, { 'M', 12 }, { 'N', 13 }, { 'O', 14 }, { 'P', 15 }, { 'Q', 16 }, { 'R', 17 }, { 'S', 18 }, { 'T', 19 }, { 'U', 20 }, { 'V', 21 }, { 'W', 22 }, { 'X', 23 }, { 'Y', 24 }, { 'Z', 25 }, };
        public static Dictionary<String, int> Constant = new Dictionary<String, int>() { { "π", 0 } };
        public static Dictionary<Char, int> ConstantChar = new Dictionary<Char, int>() { { 'π', 0 } };

        public static IList<String> KnownVariables = new List<String>()
        {
            "PW", "PH", "PD",
            "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",
        };

        public static Dictionary<String, int> Subscripts = new Dictionary<string, int>();

        //Perhaps make the int an Ascii value?
        public static Dictionary<String, int> KnownUpperCaseLetterDictionary = new Dictionary<string, int>()
        {
            { "A",1},
            { "B",1},
            { "C",1},
            { "D",1},
            { "E",1},
            { "F",1},
            { "G",1},
            { "H",1},
            { "I",1},
            { "J",1},
            { "K",1},
            { "L",1},
            { "M",1},
            { "N",1},
            { "O",1},
            { "P",1},
            { "Q",1},
            { "R",1},
            { "S",1},
            { "T",1},
            { "U",1},
            { "V",1},
            { "W",1},
            { "X",1},
            { "Y",1},
            { "Z",1},

            //"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", 
        };

        public static IList<String> KnownUpperCaseLetters = new List<String>() { "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", };
        public static IList<String> KnownLowerCaseLetters = new List<String>() { "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", };
        public static IList<String> KnownOperators = new List<String>() { "+", "-", "/", "*", "=", "<", ">", "!", "√" };
        public static IList<String> KnownConstants = new List<String>() { "π", };
        public static Dictionary<Char, Char> KnownPowers = new Dictionary<Char, Char>()
        {
            { '⁰', '0' },
            { '¹', '1' },
            { '²', '2' },
            { '³', '3' },
            { '⁴', '4' },
            { '⁵', '5' },
            { '⁶', '6' },
            { '⁷', '7' },
            { '⁸', '8' },
            { '⁹', '9' },
        };
        public static Dictionary<String, String> KnownSubscriptTranslationTable = new Dictionary<String, String>()
        {
            { "a","ₐ"  },
            { "e","ₑ"  },
            { "h","ₕ"  },
            { "i","ᵢ"  },
            { "j","ⱼ"  },
            { "k","ₖ"  },
            { "l","ₗ"  },
            { "m","ₘ"  },
            { "n","ₙ"  },
            { "o","ₒ"  },
            { "p","ₚ"  },
            { "r","ᵣ"  },
            { "s","ₛ"  },
            { "t","ₜ"  },
            { "u","ᵤ"  },
            { "v","ᵥ"  },

        };
        public static IList<String> AlphaSuperscripts = new List<String>() { "ⁿ", "ᴺ" };
        public static Dictionary<String, String> AlphaSuperscriptTable = new Dictionary<String, String>()
        {
            { "ⁿ", "n" },
            { "ᴺ", "N" },
        };
        public static Dictionary<String, String> KnownSubscripts = new Dictionary<String, String>()
        {
            { "ₐ", "Suba" },
            { "ₑ", "Sube" },
            { "ₕ", "Subh" },
            { "ᵢ", "Subi" },
            { "ⱼ", "Subj" },
            { "ₖ", "Subk" },
            { "ₗ", "Subl" },
            { "ₘ", "Subm" },
            { "ₙ", "Subn" },
            { "ₒ", "Subo" },
            { "ₚ", "Subp" },
            { "ᵣ", "Subr" },
            { "ₛ", "Subs" },
            { "ₜ", "Subt" },
            { "ᵤ", "Subu" },
            { "ᵥ", "Subv" },
        };

        public static Dictionary<String, String> KnownSubscriptsTable = new Dictionary<String, String>()
        {
            { "₀", "0" },
            { "₁", "1" },
            { "₂", "2" },
            { "₃", "3" },
            { "₄", "4" },
            { "₅", "5" },
            { "₆", "6" },
            { "₇", "7" },
            { "₈", "8" },
            { "₉", "9" },
        };

        public static Dictionary<Char, Char> KnownSuperscriptsTableChar = new Dictionary<Char, Char>()
        {
            { '⁰', '0' },
            { '¹', '1' },
            { '²', '2' },
            { '³', '3' },
            { '⁴', '4' },
            { '⁵', '5' },
            { '⁶', '6' },
            { '⁷', '7' },
            { '⁸', '8' },
            { '⁹', '9' },
        };
        public static Dictionary<Char, Char> KnownSubscriptsTableChar = new Dictionary<Char, Char>()
        {
            { '₀', '0' },
            { '₁', '1' },
            { '₂', '2' },
            { '₃', '3' },
            { '₄', '4' },
            { '₅', '5' },
            { '₆', '6' },
            { '₇', '7' },
            { '₈', '8' },
            { '₉', '9' },
        };

        public static Dictionary<Char, String> KnownSuperscripts = new Dictionary<Char, String>()
        {
            { '⁰', "Sup0" },
            { '¹', "Sup1" },
            { '²', "Sup2" },
            { '³', "Sup3" },
            { '⁴', "Sup4" },
            { '⁵', "Sup5" },
            { '⁶', "Sup6" },
            { '⁷', "Sup7" },
            { '⁸', "Sup8" },
            { '⁹', "Sup9" },
            { 'ᴬ',"A" },
            { 'ᴮ',"B"},

            { 'ᴰ',"D"},
            { 'ᴱ',"E"},

            { 'ᴳ',"G"},
            { 'ᴴ',"H"},
            { 'ᴵ',"I"},
            { 'ᴶ',"J"},
            { 'ᴷ',"K"},
            { 'ᴸ',"L"},
            { 'ᴹ',"M"},
            { 'ᴺ',"N"},
            { 'ᴼ',"O"},
            { 'ᴾ',"P"},

            { 'ᴿ',"R"},

            { 'ᵀ',"T"},
            { 'ᵁ',"U"},
            { 'ⱽ',"V"},
            { 'ᵂ',"W"},
        };
        public static Dictionary<String, String> KnownSuperscriptsTable = new Dictionary<String, String>()
        {
            { "⁰", "0" },
            { "¹", "1" },
            { "²", "2" },
            { "³", "3" },
            { "⁴", "4" },
            { "⁵", "5" },
            { "⁶", "6" },
            { "⁷", "7" },
            { "⁸", "8" },
            { "⁹", "9" },
            { "¹⁰", "10" },
            { "¹¹", "11" },
            { "¹²", "12" },
            { "¹³", "13" },
            { "¹⁴", "14" },
            { "¹⁵", "15" },
            { "¹⁶", "16" },
            { "¹⁷", "17" },
            { "¹⁸", "18" },
            { "¹⁹", "19" },
            { "²⁰", "20" },
            { "²¹", "21" },
            { "²²", "22" },
            { "²³", "23" },
            { "²⁴", "24" },
            { "²⁵", "25" },
            { "²⁶", "26" },
            { "²⁷", "27" },
            { "²⁸", "28" },
            { "²⁹", "29" },
            { "³⁰", "30" },
            { "³¹", "31" },
            { "³²", "32" },
            { "³³", "33" },
            { "³⁴", "34" },
            { "³⁵", "35" },
            { "³⁶", "36" },
            { "³⁷", "37" },
            { "³⁸", "38" },
            { "³⁹", "39" },
            { "⁴⁰", "40" },
            { "⁴¹", "41" },
            { "⁴²", "42" },
            { "⁴³", "43" },
            { "⁴⁴", "44" },
            { "⁴⁵", "45" },
            { "⁴⁶", "46" },
            { "⁴⁷", "47" },
            { "⁴⁸", "48" },
            { "⁴⁹", "49" },
            { "⁵⁰", "50" },



            { "ᴬ","A" },
            { "ᴮ","B"},

            { "ᴰ","D"},
            { "ᴱ","E"},

            { "ᴳ","G"},
            { "ᴴ","H"},
            { "ᴵ","I"},
            { "ᴶ","J"},
            { "ᴷ","K"},
            { "ᴸ","L"},
            { "ᴹ","M"},
            { "ᴺ","N"},
            { "ᴼ","O"},
            { "ᴾ","P"},

            { "ᴿ","R"},

            { "ᵀ","T"},
            { "ᵁ","U"},
            { "ⱽ","V"},
            { "ᵂ","W"},
        };


        public static String TranslateSuperscript(String str)
        {
            String target = String.Empty;

            switch (str)
            {
                case "⁰": target = "0"; break;
                case "¹": target = "1"; break;
                case "²": target = "2"; break;
                case "³": target = "3"; break;
                case "⁴": target = "4"; break;
                case "⁵": target = "5"; break;
                case "⁶": target = "6"; break;
                case "⁷": target = "7"; break;
                case "⁸": target = "8"; break;
                case "⁹": target = "9"; break;
                case "ᴬ": target = "A"; break;
                case "ᴮ": target = "B"; break;

                case "ᴰ": target = "D"; break;
                case "ᴱ": target = "E"; break;

                case "ᴳ": target = "G"; break;
                case "ᴴ": target = "H"; break;
                case "ᴵ": target = "I"; break;
                case "ᴶ": target = "J"; break;
                case "ᴷ": target = "K"; break;
                case "ᴸ": target = "L"; break;
                case "ᴹ": target = "M"; break;
                case "ᴺ": target = "N"; break;
                case "ᴼ": target = "O"; break;
                case "ᴾ": target = "P"; break;

                case "ᴿ": target = "R"; break;

                case "ᵀ": target = "T"; break;
                case "ᵁ": target = "U"; break;
                case "ⱽ": target = "V"; break;
                case "ᵂ": target = "W"; break;



            }
            return target;
        }

        public static String ReverseTranslateSuperscriptForInput(String str)
        {
            String target = String.Empty;

            switch (str)
            {
                case "0": target = "⁰"; break;
                case "1": target = "¹"; break;
                case "2": target = "²"; break;
                case "3": target = "³"; break;
                case "4": target = "⁴"; break;
                case "5": target = "⁵"; break;
                case "6": target = "⁶"; break;
                case "7": target = "⁷"; break;
                case "8": target = "⁸"; break;
                case "9": target = "⁹"; break;
            }
            return target;
        }

        public static String ConvertSubscript(Char c)
        {
            String target = String.Empty;

            switch (c)
            {
                case '₀': target = "0"; break;
                case '₁': target = "1"; break;
                case '₂': target = "2"; break;
                case '₃': target = "3"; break;
                case '₄': target = "4"; break;
                case '₅': target = "5"; break;
                case '₆': target = "6"; break;
                case '₇': target = "7"; break;
                case '₈': target = "8"; break;
                case '₉': target = "9"; break;
            }
            return target;
        }

        public static String ReverseTranslateSubscriptForInput(String str)
        {
            String target = String.Empty;

            switch (str)
            {
                case "0": target = "₀"; break;
                case "1": target = "₁"; break;
                case "2": target = "₂"; break;
                case "3": target = "₃"; break;
                case "4": target = "₄"; break;
                case "5": target = "₅"; break;
                case "6": target = "₆"; break;
                case "7": target = "₇"; break;
                case "8": target = "₈"; break;
                case "9": target = "₉"; break;
            }
            return target;
        }

        public static String ReverseTranslateSubscript(String str)
        {
            String target = String.Empty;

            switch (str)
            {
                case "0": target = "₀"; break;
                case "1": target = "₁"; break;
                case "2": target = "₂"; break;
                case "3": target = "₃"; break;
                case "4": target = "₄"; break;
                case "5": target = "₅"; break;
                case "6": target = "₆"; break;
                case "7": target = "₇"; break;
                case "8": target = "₈"; break;
                case "9": target = "₉"; break;

                case "10": target = "₁₀"; break;
                case "11": target = "₁₁"; break;
                case "12": target = "₁₂"; break;
                case "13": target = "₁₃"; break;
                case "14": target = "₁₄"; break;
                case "15": target = "₁₅"; break;
                case "16": target = "₁₆"; break;
                case "17": target = "₁₇"; break;
                case "18": target = "₁₈"; break;
                case "19": target = "₁₉"; break;
                case "20": target = "₂₀"; break;
                case "21": target = "₂₁"; break;
                case "22": target = "₂₂"; break;
                case "23": target = "₂₃"; break;
                case "24": target = "₂₄"; break;
                case "25": target = "₂₅"; break;
                case "26": target = "₂₆"; break;
                case "27": target = "₂₇"; break;
                case "28": target = "₂₈"; break;
                case "29": target = "₂₉"; break;
                case "30": target = "₃₀"; break;
                case "31": target = "₃₁"; break;
                case "32": target = "₃₂"; break;
                case "33": target = "₃₃"; break;
                case "34": target = "₃₄"; break;
                case "35": target = "₃₅"; break;
                case "36": target = "₃₆"; break;
                case "37": target = "₃₇"; break;
                case "38": target = "₃₈"; break;
                case "39": target = "₃₉"; break;
                case "40": target = "₄₀"; break;
                case "41": target = "₄₁"; break;
                case "42": target = "₄₂"; break;
                case "43": target = "₄₃"; break;
                case "44": target = "₄₄"; break;
                case "45": target = "₄₅"; break;
                case "46": target = "₄₆"; break;
                case "47": target = "₄₇"; break;
                case "48": target = "₄₈"; break;
                case "49": target = "₄₉"; break;
                case "50": target = "₅₀"; break;

            }
            return target;
        }

    }
}