/// <summary>
        /// Updates the data file commands from the HTML document within the supplied range 
        /// </summary>
        /// <param name="start">beginning command to save</param>
        /// <param name="count">last command to update </param>
        public void SaveCommandEditor(int start, int count)
        {
            UpdateDocument(new Action(delegate()
            { 
                for (int i = start; i <= count; i++)
                {
                    var elementname = String.Format("editcommand{0}", i);
                    var element = _GuiHost.Document.GetElementById(elementname);
                    if (element != null)
                    { 
                        int indexvalue = -1;
                        var command = InterpreterDataFile.Commands.FirstOrDefault(x => x.Index == i);
                        if (command == null)
                        {
                            command = new CommandData { Index = i };
                            InterpreterDataFile.Commands.Add(command);
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandname{0}", i)) != null)
                        {
                            command.Name = _GuiHost.GetAttribute(String.Format("commandname{0}", i), Attribs.Value);
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandtype{0}", i)) != null)
                        {
                            var typeofcommand = _GuiHost.GetAttribute(String.Format("commandtype{0}", i), Attribs.Value).ToString();
                            var commandtype = (MCODE_TYPE)Enum.Parse(typeof(MCODE_TYPE), typeofcommand);
                            command.Type = commandtype; 
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandsetbit1{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandsetbit1{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.Bit1 = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandstatebit1{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandstatebit1{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.State1 = indexvalue > 0;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandsetbit2{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandsetbit2{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.Bit2 = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandstatebit2{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandstatebit2{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.State2 = indexvalue > 0;
                            }
                        }

                        if (_GuiHost.Document.GetElementById(String.Format("commandsetdacbit{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandsetdacbit{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.Bit1 = indexvalue;
                            }
                        }

                        if (_GuiHost.Document.GetElementById(String.Format("commanddacscale{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commanddacscale{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.DacScale = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commanddacoffset{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commanddacoffset{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.DacOffset = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commanddacmin{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commanddacmin{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.DacMin = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commanddacmax{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commanddacmax{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.DacMax = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandthread{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandthread{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.Thread = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandvar{0}", i)) != null)
                        {
                            if (Int32.TryParse(_GuiHost.GetAttribute(String.Format("commandvar{0}", i), Attribs.Value), out indexvalue))
                            {
                                command.VAR = indexvalue;
                            }
                        }
                        if (_GuiHost.Document.GetElementById(String.Format("commandfilename{0}", i)) != null)
                        {
                            var filename = _GuiHost.GetAttribute(String.Format("commandfilename{0}", i), Attribs.Value).ToString();

                            command.FileName = filename;
                        }
                    }
                }
            }));
        }
        /// <summary>
        /// Generates the specific editor for a Mcode Action command based on its type
        /// </summary>
        /// <param name="command">command source to generate editor for</param>
        /// <param name="showindex">flag to determine whether or not to create a p element displaying the command index</param>
        /// <param name="editname">flag to determine whether the command name text is editable or not</param>
        /// <returns>html command editor</returns>
        public string GetEditorForCommand(CommandData command, bool showindex,  bool editname)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("<div class=\"editorforcommand\">");

            if (showindex)
            {
                sb.AppendLine(String.Format("<p class=\"commandlabel\" id=\"commandindexlabel{0}\">{0}</p>", command.Index));
            }

            if (editname)
            {
                sb.AppendLine("<p class=\"commanddescription\">Name:</p>");
                sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandname{0}\" value=\"{1}\"/>", command.Index, command.Name));
            }
            else
            {
                sb.AppendLine(String.Format("<p class=\"commandlabel\" id=\"commandnamelabel{0}\">{1} :</p>", command.Index, command.Name));
            } 


            //sb.AppendLine(String.Format("<select class=\"commandtype\" id=\"commandtype{0}\">", command.Index));
            //sb.AppendLine("<option isselected value=\"M_Action_None\">None</option>");
            //sb.AppendLine("<option value=\"M_Action_Setbit\">Set Bit</option>");
            //sb.AppendLine("<option value=\"M_Action_SetTwoBits\">Set 2 Bits</option>");
            //sb.AppendLine("<option value=\"M_Action_DAC\">DAC</option>");
            //sb.AppendLine("<option value=\"M_Action_Program\">Run Program</option>");
            //sb.AppendLine("<option value=\"M_Action_Program_wait\">Run/Wait</option>");
            //sb.AppendLine("<option value=\"M_Action_Program_wait_sync\">Run/Wait/Sync</option>");
            //sb.AppendLine("<option value=\"M_Action_Program_PC\">Run EXE</option>");
            //sb.AppendLine("<option value=\"M_Action_Callback\">User Callback</option>");
            //sb.AppendLine("<option value=\"M_Action_Waitbit\">Wait Bit</option>");
            //sb.AppendLine("</select>"); 

                                  
            switch (command.Type)
            {
                case MCODE_TYPE.M_Action_Setbit:
                    sb.AppendLine("<p class=\"commanddescription\">Set Bit</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandsetbit1{0}\" value=\"{1}\"/>", command.Index, command.Bit1));
                    sb.AppendLine("<p class=\"commanddescription\">to</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandstatebit1{0}\" value=\"{1}\"/>", command.Index, command.State1 ? 1 : 0));
                    break;
                case MCODE_TYPE.M_Action_SetTwoBits:
                    sb.AppendLine("<p class=\"commanddescription\">Set Bit</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandsetbit1{0}\" value=\"{1}\"/>", command.Index, command.Bit1));
                    sb.AppendLine("<p class=\"commanddescription\">to</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandstatebit1{0}\" value=\"{1}\"/>", command.Index, command.State1 ? 1 : 0));
                    sb.AppendLine("<p class=\"commanddescription\">and</p>");
                    sb.AppendLine("<p class=\"commanddescription\">Set Bit</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandsetbit2{0}\" value=\"{1}\"/>", command.Index, command.Bit2));
                    sb.AppendLine("<p class=\"commanddescription\">to</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandstatebit2{0}\" value=\"{1}\"/>", command.Index, command.State2 ? 1 : 0));
                    break;
                case MCODE_TYPE.M_Action_DAC:
                    sb.AppendLine("<p class=\"commanddescription\">Set DAC</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandsetdacbit{0}\" value=\"{1}\"/>", command.Index, command.Bit1));
                    sb.AppendLine("<p class=\"commanddescription\">scale</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commanddacscale{0}\" value=\"{1}\"/>", command.Index, command.DacScale));
                    sb.AppendLine("<p class=\"commanddescription\">offset</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commanddacoffset{0}\" value=\"{1}\"/>", command.Index, command.DacOffset));
                    sb.AppendLine("<p class=\"commanddescription\">min</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commanddacmin{0}\" value=\"{1}\"/>", command.Index, command.DacMin));
                    sb.AppendLine("<p class=\"commanddescription\">max</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commanddacmax{0}\" value=\"{1}\"/>", command.Index, command.DacMax));
                    break;
                case MCODE_TYPE.M_Action_Program:
                    sb.AppendLine("<p class=\"commanddescription\">Thread</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandthread{0}\" value=\"{1}\"/>", command.Index, command.Thread));
                    sb.AppendLine("<p class=\"commanddescription\">VAR</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandvar{0}\" value=\"{1}\"/>", command.Index, command.VAR));
                    sb.AppendLine("<p class=\"commanddescription\">File</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandfiletext\" id=\"commandfilename{0}\" value=\"{1}\"/>", command.Index, command.FileName));
                    sb.AppendLine(String.Format("<button class=\"commandbutton\" id=\"commandgetfilename{0}\" data-commandid=\"{0}\">{1}</button>", command.Index, "..."));
                    break;
                case MCODE_TYPE.M_Action_Program_wait:
                    sb.AppendLine("<p class=\"commanddescription\">Thread</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandthread{0}\" value=\"{1}\"/>", command.Index, command.Thread));
                    sb.AppendLine("<p class=\"commanddescription\">VAR</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandvar{0}\" value=\"{1}\"/>", command.Index, command.VAR));
                    sb.AppendLine("<p class=\"commanddescription\">File</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandfiletext\" id=\"commandfilename{0}\" value=\"{1}\"/>", command.Index, command.FileName));
                    sb.AppendLine(String.Format("<button class=\"commandbutton\" id=\"commandgetfilename{0}\" data-commandid=\"{0}\">{1}</button>", command.Index, "..."));
                    break;
                case MCODE_TYPE.M_Action_Program_wait_sync:
                    sb.AppendLine("<p class=\"commanddescription\">Thread</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandthread{0}\" value=\"{1}\"/>", command.Index, command.Thread));
                    sb.AppendLine("<p class=\"commanddescription\">VAR</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandtext\" id=\"commandvar{0}\" value=\"{1}\"/>", command.Index, command.VAR));
                    sb.AppendLine("<p class=\"commanddescription\">File</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandfiletext\" id=\"commandfilename{0}\" value=\"{1}\"/>", command.Index, command.FileName));
                    sb.AppendLine(String.Format("<button class=\"commandbutton\" id=\"commandgetfilename{0}\" data-commandid=\"{0}\">{1}</button>", command.Index, "..."));
                    break;
                case MCODE_TYPE.M_Action_Program_PC:
                    sb.AppendLine("<p class=\"commanddescription\">File</p>");
                    sb.AppendLine(String.Format("<input type=\"text\" class=\"commandfiletext\" id=\"commandfilename{0}\" value=\"{1}\"/>", command.Index, command.FileName));
                    sb.AppendLine(String.Format("<button class=\"commandbutton\" id=\"commandgetfilename{0}\" data-commandid=\"{0}\">{1}</button>", command.Index, "..."));
                    break;
                default:
                    break;
            }
            sb.AppendLine("</div>");
            return sb.ToString();
        }
 /// <summary>
 /// Transfers command data from the data file to the HTML within the supplied range of elements
 /// </summary>
 /// <param name="start">beginning command to load</param>
 /// <param name="count">last command to update</param>
 public void LoadCommandEditor(int start, int count)
 {
     bool needssave = false;
     UpdateDocument(new Action(delegate()
     {
         for (int i = start; i <= count; i++)
         {
             var elementname = String.Format("editcommand{0}", i);
             var element = _GuiHost.Document.GetElementById(elementname);
             if (element != null)
             {
                 var command = InterpreterDataFile.Commands.FirstOrDefault(x => x.Index == i);
                 if (command == null)
                 {
                     command = new CommandData { Index = i };
                     InterpreterDataFile.Commands.Add(command);
                     needssave = true;
                 }
                 var showindex = Convert.ToBoolean(_GuiHost.GetAttribute(elementname, Attribs.ShowCommandIndex));
                 var editname = Convert.ToBoolean(_GuiHost.GetAttribute(elementname, Attribs.EditCommandName));
                 if (!editname)
                 {
                     command.Name = _GuiHost.GetAttribute(elementname, Attribs.CommandName);
                 }
                 var editor = GetEditorForCommand(command, showindex, editname);
                 _GuiHost.SetElementHTML(elementname, editor);
    
               
                 _GuiHost.SetAttribute(string.Format("commandtype{0}", i), Attribs.Value, command.Type.ToString());
             } 
         }
     }));
     if (needssave)
     {
         SaveInterpreterData();
     }
 }