//////////////////////////////////////////////////////////////////////////
        private void WriteHtml(string Filename, ScriptObject Obj)
        {
            using (StreamWriter sw = new StreamWriter(Filename, false, GetEncodingByName(CmbHtmlOutputCodepage.Text)))
            {
                // header
                sw.WriteLine("<html>");
                sw.WriteLine("<meta http-equiv=\"Content-Language\" content=\"" + TxtTermLanguage.Text + "\">");
                sw.WriteLine("<meta name=\"GENERATOR\" content=\"WME DocMaker 2.0\">");
                sw.WriteLine("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + GetEncodingByName(CmbHtmlOutputCodepage.Text).WebName + "\">");
                sw.WriteLine("<title>" + Obj.Name + "</title>");
                sw.WriteLine("<link rel=\"stylesheet\" type=\"text/css\" href=\"../../styles.css\">");
                sw.WriteLine("</head>");
                sw.WriteLine();
                sw.WriteLine("<body>");

                sw.WriteLine("<!-- Generated on " + DateTime.Now.ToString() + ", settings file: " + CurrentFilename + " -->");
                sw.WriteLine();

                // title
                sw.WriteLine("<h3>" + Obj.Name + "</h3>");
                sw.WriteLine("<p>");
                sw.WriteLine(Obj.Desc);
                sw.WriteLine("</p>");
                sw.WriteLine();

                sw.WriteLine("<br>");
                sw.WriteLine();

                // methods
                WriteHtmlMethods(sw, Obj, false, true);
                WriteHtmlMethods(sw, Obj, false, false);
                WriteHtmlMethods(sw, Obj, true, false);

                // attributes
                WriteHtmlAttributes(sw, Obj, false);
                WriteHtmlAttributes(sw, Obj, true);

                // events
                WriteHtmlEvents(sw, Obj);

                // methods detailed
                int ConstructorCount = 0;
                foreach (ScriptMethod Method in Obj.Methods)
                {
                    if (Method.Constructor) ConstructorCount++;
                    string Suffix = "";
                    if (ConstructorCount > 0) Suffix = ConstructorCount.ToString();

                    WriteHtmlMethodDetailed(sw, Method, Method.Constructor?Suffix:"");
                }

                // footer
                sw.WriteLine();
                sw.WriteLine("</body>");
                sw.WriteLine();
                sw.WriteLine("</html>");
            }
        }
        //////////////////////////////////////////////////////////////////////////
        private ScriptObject ParseFile(string Filename)
        {
            ScriptObject Obj = new ScriptObject();
            Obj.BaseFilename = Path.GetFileNameWithoutExtension(Filename);

            List<string> Lines = new List<string>();
            ReadLines(Filename, ref Lines);

            ScriptItem CurrentItem = null;
            string CurrentGroup = "";
            bool InExample = false;
            string CurrentExample = "";

            foreach (string line in Lines)
            {
                string Token = GetToken(line);
                string Data = GetData(line);

                switch (Token)
                {
                    case "*tit":
                    case "*title":
                        if (Obj.Name != "") Obj.Name += "\n";
                        Obj.Name += Data;
                        break;

                    case "*cls":
                    case "*class":
                        Obj.NativeClass = Data;
                        break;

                    case "*des":
                    case "*desc":
                    case "*description":
                        if (CurrentItem != null)
                        {
                            if (CurrentItem.Desc != "") CurrentItem.Desc += "\n";
                            CurrentItem.Desc += Data;
                        }
                        else if(Obj!=null)
                        {
                            if (Obj.Desc != "") Obj.Desc += "\n";
                            Obj.Desc += Data;
                        }
                        break;

                    case "*grp":
                    case "*group":
                        CurrentGroup = Data;
                        break;

                    case "*met":
                    case "*method":
                    case "*con":
                        CurrentItem = new ScriptMethod();
                        Obj.Methods.Add((ScriptMethod)CurrentItem);

                        ((ScriptMethod)CurrentItem).Headers.Add(Data);
                        CurrentItem.Group = CurrentGroup;

                        if (Token.StartsWith("*c")) ((ScriptMethod)CurrentItem).Constructor = true;
                        break;

                    case "*mt2":
                    case "*met2":
                    case "*method2":
                    case "*con2":
                        if (CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            ((ScriptMethod)CurrentItem).Headers.Add(Data);
                        }
                        break;

                    case "*par":
                    case "*param":
                    case "*parameter":
                    case "*opt":
                    case "*optpar":
                        if (CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            string ParamName = GetToken(Data);
                            string ParamData = GetData(Data);

                            if (ParamName != "")
                            {
                                ScriptParameter Param = new ScriptParameter();
                                Param.Name = ParamName;
                                Param.Desc = ParamData;

                                if (Token.StartsWith("*o")) Param.Optional = true;

                                ((ScriptMethod)CurrentItem).Parameters.Add(Param);
                                //((ScriptMethod)CurrentItem).Parameters.Sort();

                            }
                        }
                        break;

                    case "*ret":
                    case "*return":
                        if (CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            ScriptMethod Mtd = (ScriptMethod)CurrentItem;
                            if (Mtd.Return != "") Mtd.Return += "\n";
                            Mtd.Return += Data;
                        }
                        break;

                    case "*rem":
                    case "*remark":
                        if (CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            ScriptMethod Mtd = (ScriptMethod)CurrentItem;
                            if (Mtd.Remark != "") Mtd.Remark += "\n";
                            Mtd.Remark += Data;
                        }
                        break;

                    case "*ex_start":
                        InExample = true;
                        CurrentExample = "";
                        break;

                    case "*ex_end":
                        InExample = false;
                        if (CurrentExample != "" && CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            ((ScriptMethod)CurrentItem).Examples.Add(CurrentExample);
                        }
                        CurrentExample = "";
                        break;

                    case "*atr":
                    case "*attr":
                    case "*attribute":
                    case "*gatr":
                    case "*gattr":
                    case "*gattribute":
                        CurrentItem = new ScriptAttribute();
                        Obj.Attributes.Add((ScriptAttribute)CurrentItem);

                        CurrentItem.Name = Data;
                        CurrentItem.Group = CurrentGroup;

                        if (Token.StartsWith("*g")) CurrentItem.IsGlobal = true;
                        break;

                    case "*ro":
                        if (CurrentItem != null && CurrentItem is ScriptAttribute)
                        {
                            ((ScriptAttribute)CurrentItem).ReadOnly = true;
                        }
                        break;

                    case "*glo":
                    case "*glob":
                    case "*global":
                        CurrentItem = new ScriptMethod();
                        Obj.Methods.Add((ScriptMethod)CurrentItem);

                        ((ScriptMethod)CurrentItem).Headers.Add(Data);
                        ((ScriptMethod)CurrentItem).IsGlobal = true;
                        CurrentItem.Group = CurrentGroup;
                        break;

                    case "*gl2":
                    case "*glo2":
                    case "*glob2":
                    case "*global2":
                        if (CurrentItem != null && CurrentItem is ScriptMethod)
                        {
                            ((ScriptMethod)CurrentItem).Headers.Add(Data);
                        }
                        break;

                    case "*evn":
                    case "*evt":
                    case "*event":
                        CurrentItem = new ScriptEvent();
                        Obj.Events.Add((ScriptEvent)CurrentItem);

                        CurrentItem.Name = Data;
                        CurrentItem.Group = CurrentGroup;
                        break;

                    default:
                        if (InExample && line != "")
                        {
                            if (CurrentExample != "") CurrentExample += "\n";
                            CurrentExample += line;
                        }
                        break;
                }

            }
            return Obj;
        }
        //////////////////////////////////////////////////////////////////////////
        public bool ReadXml(XmlDocument Doc, bool Append)
        {
            if (Objects == null || !Append) Objects = new List<ScriptObject>();

            XmlNode Root = Doc.DocumentElement;
            if (Root == null || Root.Name != "WmeDocs") return false;

            XmlNode Node = Root.FirstChild;
            while(Node!=null)
            {
                if(Node.Name=="ScriptObjects")
                {
                    Node = Node.FirstChild;
                    while (Node != null)
                    {
                        if(Node.Name=="ScriptObject")
                        {
                            ScriptObject Obj = new ScriptObject();
                            if (Obj.ReadXml(Node)) Objects.Add(Obj);
                        }
                        Node = Node.NextSibling;
                    }
                    break;
                }
                Node = Node.NextSibling;
            }
            return true;
        }
        //////////////////////////////////////////////////////////////////////////
        private void WriteHtmlAttributes(StreamWriter sw, ScriptObject Obj, bool Globals)
        {
            bool FoundType = false;
            foreach (ScriptAttribute Attr in Obj.Attributes)
            {
                if (Globals == Attr.IsGlobal)
                {
                    FoundType = true;
                    break;
                }
            }
            if (!FoundType) return;

            if (Globals)
                sw.WriteLine("<h4>" + TxtTermGlobalVariables.Text + "</h4>");
            else
                sw.WriteLine("<h4>" + TxtTermAttributes.Text + "</h4>");
            sw.WriteLine("<table border=\"2\" cellspacing=\"0\" cellpadding=\"2\" style=\"border-collapse: collapse\" bordercolor=\"#111111\">");

            string LastGroup = "";
            foreach (ScriptAttribute Attr in Obj.Attributes)
            {
                if (Attr.IsGlobal != Globals) continue;

                // group
                if (Attr.Group != LastGroup)
                {
                    sw.WriteLine("  <tr>");
                    sw.WriteLine("    <td nowrap width=\"25%\"><b>" + Attr.Group + "</b></td>");
                    sw.WriteLine("    <td></td>");
                    sw.WriteLine("  </tr>");
                    LastGroup = Attr.Group;
                }

                // attribute
                sw.WriteLine("  <tr>");
                sw.WriteLine("    <td nowrap width=\"25%\">" + Attr.Name + (Attr.ReadOnly ? " (" + TxtTermReadOnly.Text + ")" : "") + "</td>");
                sw.WriteLine("    <td>" + Attr.Desc + "</td>");
                sw.WriteLine("  </tr>");
            }
            sw.WriteLine("</table>");
            sw.WriteLine();
        }
        //////////////////////////////////////////////////////////////////////////
        private void WriteHtmlMethods(StreamWriter sw, ScriptObject Obj, bool Globals, bool Constructors)
        {
            bool FoundType = false;
            foreach (ScriptMethod Method in Obj.Methods)
            {
                if (!Globals && !Constructors && !Method.IsGlobal && !Method.Constructor)
                {
                    FoundType = true;
                    break;
                }
                if (Globals && Method.IsGlobal)
                {
                    FoundType = true;
                    break;
                }
                if (Constructors && Method.Constructor)
                {
                    FoundType = true;
                    break;
                }
            }
            if (!FoundType) return;

            // title
            if (Globals) sw.WriteLine("<h4>" + TxtTermGlobalFunctions.Text + "</h4>");
            else if (Constructors) sw.WriteLine("<h4>" + TxtTermConstructors.Text + "</h4>");
            else sw.WriteLine("<h4>" + TxtTermMethods.Text + "</h4>");
            sw.WriteLine("<table border=\"2\" cellspacing=\"0\" cellpadding=\"2\" style=\"border-collapse: collapse\" bordercolor=\"#111111\">");

            string LastGroup = "";
            int ConstructorCount = 0;
            foreach (ScriptMethod Method in Obj.Methods)
            {
                if (Globals && !Method.IsGlobal) continue;
                if (Constructors && !Method.Constructor) continue;
                if (!Constructors && !Globals && (Method.IsGlobal || Method.Constructor)) continue;

                if (Method.Constructor) ConstructorCount++;

                // group
                if (Method.Group != LastGroup)
                {
                    sw.WriteLine("  <tr>");
                    sw.WriteLine("    <td nowrap width=\"25%\"><b>" + Method.Group + "</b></td>");
                    sw.WriteLine("    <td></td>");
                    sw.WriteLine("  </tr>");
                    LastGroup = Method.Group;
                }

                // method
                string Suffix = "";
                if (ConstructorCount > 0) Suffix = ConstructorCount.ToString();

                string MethodName = GetBracketName(Method.Headers[0]);
                sw.WriteLine("  <tr>");
                sw.WriteLine("    <td nowrap width=\"25%\"><a href=\"#" + MethodName + Suffix + "\">" + MethodName + "</a></td>");
                sw.WriteLine("    <td>" + Method.Desc + "</td>");
                sw.WriteLine("  </tr>");
            }

            sw.WriteLine("</table>");
            sw.WriteLine("");
        }
        //////////////////////////////////////////////////////////////////////////
        private void WriteHtmlEvents(StreamWriter sw, ScriptObject Obj)
        {
            if (Obj.Events.Count > 0)
            {
                sw.WriteLine("<h4>" + TxtTermEvents.Text + "</h4>");
                sw.WriteLine("<table border=\"2\" cellspacing=\"0\" cellpadding=\"2\" style=\"border-collapse: collapse\" bordercolor=\"#111111\">");

                string LastGroup = "";
                foreach (ScriptEvent Event in Obj.Events)
                {
                    // group
                    if (Event.Group != LastGroup)
                    {
                        sw.WriteLine("  <tr>");
                        sw.WriteLine("    <td nowrap width=\"25%\"><b>" + Event.Group + "</b></td>");
                        sw.WriteLine("    <td></td>");
                        sw.WriteLine("  </tr>");
                        LastGroup = Event.Group;
                    }

                    // event
                    sw.WriteLine("  <tr>");
                    sw.WriteLine("    <td nowrap width=\"25%\">" + Event.Name + "</td>");
                    sw.WriteLine("    <td>" + Event.Desc + "</td>");
                    sw.WriteLine("  </tr>");
                }
                sw.WriteLine("</table>");
                sw.WriteLine();
            }
        }