/// <summary>
        /// Returns the names of all characters + all alias in the passed in array
        /// </summary>
        /// <param name="characters"></param>
        /// <returns></returns>
        public static string[] GetAllCharacterNames(CharacterInDialogClass[] characters, gender testGender)
        {
            if (characters == null)
            {
                throw new Exception("GetAllCharacterNames You must pass in a valid character array");
            }

            ArrayList names = new ArrayList();
            foreach (CharacterInDialogClass character in characters)
            {
                if (character == null)
                {
                    throw new Exception("GetAllCharacterNames - somehow you have an invalid character in your list. Did you forget to iterate the [x] indexer when assigning characters?");
                }
                if (character.Gender == testGender || testGender == gender.any)
                {
                    string[] _names = character.GetNames();

                    foreach (string name in _names)
                    {
                        names.Add(name);
                    }
                }
            }
            if (names.Count <= 0)
            {
                //throw new Exception("GetAllCharacterNames - no names in character list!?");
                // this might be valid sometimes (i.e., no female names)
            }

            string[] allnames = new string[names.Count];
            names.CopyTo(allnames);

            return allnames;
        }
        /// <summary>
        /// returns a regex expression that can be used
        /// to filter a string for the presence of any of these names
        /// </summary>
        /// <param name="characters"></param>
        /// <returns></returns>
        public static string GetRegexForNames(CharacterInDialogClass[] characters)
        {
            string sResult = "";
            string[] names = GetAllCharacterNames(characters, gender.any);
            foreach (string s in names)
            {
                string sMultiple = "";

                if (sResult != "")
                {
                    sMultiple = "|";
                }
                sResult = String.Format("{0}{1}\\b{2}\\b", sResult, sMultiple, s);
            }
            return sResult;
        }
 /// <summary>
 /// go through the arry and find maximum tilt
 /// </summary>
 /// <param name="characters"></param>
 /// <returns></returns>
 public static string GetMostLikelyName(CharacterInDialogClass[] characters, gender sex)
 {
     int nMax = -1;
     string sName = "";
     foreach (CharacterInDialogClass character in characters)
     {
         // we can searcha ll as well
         if (character.Tilt > nMax && (character.Gender == sex || sex == gender.any) )
         {
             nMax = character.Tilt;
             sName = character.Name;
         }
     }
     return sName;
 }
        /// <summary>
        /// Goes througha nd looks for a match for the alias
        /// , returning the first found
        /// case insensitive
        /// Will return directly if sAlias = name
        /// </summary>
        /// <param name="characters"></param>
        public static string GetNameFromAlias(string sAlias, CharacterInDialogClass[] characters)
        {
            if (sAlias == null || sAlias == "")
            {
                //throw new Exception("Alias null or blank");
                return ""; // t his is actually okay, just means there were no alias
            }
            if (characters == null || characters.Length <= 0)
            {
                throw new Exception("No characters");
            }
            string sAliasCheck = sAlias.ToLower();
            foreach (CharacterInDialogClass character in characters)
            {

                if (character.Name.ToLower() == sAliasCheck)
                {
                    return sAlias;
                }

                if (character.Alias != null)
                {
                    foreach (string s in character.Alias)
                    {
                        if (s.ToLower() == sAliasCheck)
                        {
                            // an alias matched, return the name
                            return character.Name;
                        }
                    }
                }
            }
            return sAlias; // if not match return myself
        }
        private void bInput_Click(object sender, EventArgs e)
        {
            // for testing paste will be collector

            CharacterInDialogClass[] characters = new CharacterInDialogClass[5];

                characters[0] = new CharacterInDialogClass();
                characters[0].Name = "Izzy";
                characters[0].Alias = new string[2] { "Isabel", "Mosh" };
                characters[0].Gender = CharacterInDialogClass.gender.female;
                characters[0].Tilt = 75;

                characters[1] = new CharacterInDialogClass();
                characters[1].Name = "Commander";
                characters[1].Alias = new string[3] { "Meredith", "Ferguson", "Ferguson's" };
                characters[1].Gender = CharacterInDialogClass.gender.female;
                characters[1].Tilt = 50;

                characters[2] = new CharacterInDialogClass();
                characters[2].Name = "Rutger";
                characters[2].Alias = new string[2] { "Dr.", "doctor" };
                characters[2].Gender = CharacterInDialogClass.gender.male;
                characters[2].Tilt = 75;

                characters[3] = new CharacterInDialogClass();
                characters[3].Name = "Alex";

                characters[3].Gender = CharacterInDialogClass.gender.male;
                characters[3].Tilt = 25;

                characters[4] = new CharacterInDialogClass();
                characters[4].Name = "Janice";

                characters[4].Gender = CharacterInDialogClass.gender.female;
                characters[4].Tilt = 40;

            writethink.LoadTextStringIntoDatabase(textBoxInput.Text, characters);
            writethink.view = new DataView(writethink.table);
        }
        /// <summary>
        /// sets up the list of buttons
        /// </summary>
        /// <param name="characters"></param>
        public bool Setup(CharacterInDialogClass[] _characters, DataView _view, string version)
        {
            panelForDialog.Visible = false;
            panelForGrammar.Visible = false;

            System.Windows.Forms.ToolTip  tt= new System.Windows.Forms.ToolTip();
            tt.SetToolTip(ButtonVersion, Loc.Instance.GetString ("Press this button to record that you have proofread the entire layout. This will record a transaction for you."));

            ButtonVersion.Text =  version;
            if (null == _characters)
            {
                MessageBox.Show("There were no characters marked with colors. Exiting the Dialog Review.");
                return false;
            }
            view = _view;
            characters = _characters;
            foreach (CharacterInDialogClass character in characters)
            {
              /*  Button newButton = new Button();
                newButton.FlatStyle = FlatStyle.Popup;
                newButton.Text = character.Name;
                newButton.Dock = DockStyle.Top;
                newButton.Click += new EventHandler(newButton_Click);
                newButton.Text = newButton.Text + " (" + CountLines(character.Name) + ")";*/
               Button newButton = CreateAButton(character.Name + " (" + CountLines(character.Name) + ")",Color.LightBlue);

                panelButtons.Controls.Add(newButton);
                newButton.Tag = character.Name;

                newButton = null;

            }
            panelButtons.Dock = DockStyle.Fill;
            return true;
        }
        /// <summary>
        /// loads text into the database as oppose to LoadTextIntoDatabase which
        /// takes a file
        /// 
        /// 
        /// </summary>
        /// <param name="sTextString"></param>
        /// <param name="rtf">CUT: if passed in will attempt to do character matching by color (Experimental Spetember 2011)</param>
        /// <param name="KeepTable"> if true we don't rebuild the TABLE, for use with color matching</param>
        /// <param name="OverrideCharacter">Name of the character to override, with color matching system</param>
        /// <param name="_characters"></param>
        /// <returns></returns>
        public DataTable LoadTextStringIntoDatabase(string sText, CharacterInDialogClass[] _characters, string OverrideCharacter, bool KeepTable)
        {
            timer = DateTime.Now;

            this.characters = _characters;
            // Hving null characters is okay, though it will produce almost meaningless results
             if (characters == null)
            {
                 // create a simple character array with one entry
                this.characters = new CharacterInDialogClass[1];
                this.characters[0] = new CharacterInDialogClass();
                this.characters[0].Name = "default";
             //   throw new Exception("Need character information to parse dialog");
            }

            sText = CleanupImportString(sText);

            if (sText == null)
            {
                throw new Exception("text string was null");
            }

            if (false == KeepTable)
            {
                table = new DataTable();
                DataColumn auto = new DataColumn("ID", typeof(int));

                auto.AutoIncrement = true;
                auto.AutoIncrementSeed = 1;// DateTime.Now.Millisecond;
                auto.AutoIncrementStep = 1;
                table.Columns.Add(auto);
                table.PrimaryKey = new DataColumn[] { auto };

                DataColumn text = new DataColumn("Text");
                table.Columns.Add(text);

                table.Columns.Add("Confidence", typeof(double));

                table.Columns.Add("dialog", typeof(bool), "Text Like '%\"%'");
                table.Columns.Add("contraction", typeof(bool), "Text Like '%\'\'%'");
                table.Columns.Add("hesaidshesaid");
                DataColumn charLen = new DataColumn("charLen", typeof(int), "Len(Text)");

                table.Columns.Add(charLen);
                DataColumn wordLen = new DataColumn("wordLen", typeof(int));// "Len(Text)/5");
                table.Columns.Add(wordLen);

                table.Columns.Add("ispassive", typeof(bool));
                table.Columns.Add("isfragment", typeof(bool));
                table.Columns.Add("syllables", typeof(int));
                table.Columns.Add("startswithverb", typeof(bool)); // August 2012
                table.Columns.Add("hidelinebyline", typeof(bool)); // November 2012 - to hide during a line by line search
            } // keep table

            // precleanup: convert quotes
            sText = ReplaceFunkyQuotesWithNormal(sText);

               // a regex with some handling for abbreviations

              //    Regex.Split(sText, @"(?<=['""A-Za-z0-9][\.\!\?])\s+(?=[A-Z])");
                //worked but flawed

            // this is suppose to be faster (using compiled with a constant string)
                Regex splitter = new Regex(@"(?:(?<=\.|\!|\?)(?<!Mr\.|\...|Dr\.)(?<!U\.S\.A\.)\s+(?=[A-Z]))", RegexOptions.Compiled);

                string[] lines = splitter.Split(sText);

            /* Nope, won't work, doesn't match
                if ("" != rtf)
                {
                    rtflines = splitter.Split(rtf); // september 2011 (color coding)
                }
            */

            // * Parse # 2 - now we extract dialog
            ArrayList lines2 = ParseEachLine(lines);

            //ArrayList lines2 = new ArrayList(lines);

            // we have to do 2 loops
            // the first loop removes blanks
            for (int deletepass = lines2.Count - 1; deletepass > -1; deletepass--)
            {
                lines2[deletepass] = lines2[deletepass].ToString().Replace("bbb.", "");
                lines2[deletepass] = lines2[deletepass].ToString().Replace("bbb", "");
                lines2[deletepass] = lines2[deletepass].ToString().Trim();
                if (lines2[deletepass].ToString() == "" || lines2[deletepass].ToString() == " ")
                {
                    lg.Instance.Line("WriteThink->LoadTextStringIntoDatabase", ProblemType.MESSAGE, lines2[deletepass].ToString() + " deleting");
                    lines2.Remove(lines2[deletepass]);

                }
            }
            // tried doing a dialog regex but realized that
            // failed too because they would neve rmatch
            // because the strings are split in one but not the other based on periods

            // set up knowledge table
            // ToDo: Should be loading from file
            if (false == KeepTable)
            {
                BuildAITables();
            }

            int nCount = -1;

            // Major pass; primarily grabbing Speaker but also passive and stuff
            foreach (string s in lines2)
            {
                nCount++;

                /* My attempt a COLOR PASS: Ignore this until I get back to it. I don't think I want to dit
                // september 2011
              //  move this code to where dialog is
                if (true)
                {
                    int indexofrtf = rtf.IndexOf(s.Replace("\"", "").Trim()); // remove quote marks because they are removed
                    string rtf_temp = "";
                    if (indexofrtf > -1)
                    {
                        rtf_temp = rtf.Substring(indexofrtf-4, s.Length + 4);
                    }
                }*/

                string snewline = s;
                //  string snewline = s.Replace("bbb.", "");
                //  snewline = snewline.Replace("bbb", "");
              //  if (snewline != "" && snewline != " ")  no longer needed, we do this in a seperate loop
                {

                    // add core string to datatable
                    DataRow row = table.NewRow();
                    row["hidelinebyline"] = false;
                    row["Text"] = snewline;
                    row["hesaidshesaid"] = "none";
                    row["isfragment"] = IsFragment(snewline);
                    row["wordLen"] = GetWordCount(snewline);

                    bool bIsDialog = snewline.IndexOf("\"") > -1;

                    row["ispassive"] = IsPassive(snewline, bIsDialog);
                    double confidence = 0.0;
                    string sPrevious = "";
                    string sNext = "";
                    string sBeforeSpeaker = "";

                    if (Layout.LayoutDetails.Instance.WordSystemInUse.IsVerb(FirstWords(snewline, 1)))
                    {
                        row["startswithverb"] = true;
                    }
                    else
                    {
                        row["startswithverb"] = false;
                    }

                    // * Code for the color coding
                    if ("" != OverrideCharacter)
                    {
                        // we don't do the next section
                        // if we are overriding a character we ASSUME
                        // we passed dialog in.
                        row["hesaidshesaid"] = OverrideCharacter;
                        confidence = 1.0;
                    }
                    else

                    // don't calculate hesaid unless there is actual dialog
                    if (bIsDialog == true)
                    {
                        if (nCount > 0)
                        {
                            // don't grab lines looking for context if they were dialog lines

                            sPrevious = lines2[nCount - 1].ToString();
                            if (sPrevious.IndexOf("\"") > -1)
                            {
                                sPrevious = ""; //
                            }
                            sBeforeSpeaker = table.Rows[table.Rows.Count - 1]["hesaidshesaid"].ToString();

                        }
                        if (nCount < lines2.Count - 1)
                        {

                            sNext = lines2[nCount + 1].ToString();
                            if (sNext.IndexOf("\"") > -1)
                            {
                                sNext = ""; //
                            }

                        }
                        row["hesaidshesaid"] = GetSpeaker(snewline, sPrevious, sNext, sBeforeSpeaker, out confidence);
                    }
                    row["Confidence"] = confidence;
                    row["syllables"] = GetSyllables(snewline);
                    table.Rows.Add(row);
                    row = null;
                }
            }
            return table;
        }
 public DataTable LoadTextStringIntoDatabase(string sText, CharacterInDialogClass[] _characters)
 {
     return LoadTextStringIntoDatabase(sText, _characters, "", false);
 }
        /// <summary>
        /// Loadsa a file  into database
        /// </summary>
        /// <param name="sTextFile"></param>
        /// <returns></returns>
        public DataTable LoadTextIntoDatabase(string sTextFile, CharacterInDialogClass[] _characters)
        {
            if (File.Exists(sTextFile) == false)
            {
                throw new Exception(String.Format("File {0} does not exist."));
            }

            // load the text into one giant string

            // the encoding is important because it gets rid of characters
            StreamReader file = new StreamReader(sTextFile, System.Text.Encoding.Default);
            string sText = "";
            if (file != null)
            {
                string sLine = file.ReadLine();
                while (sLine != null)
                {
                   // sLine = CleanupImportString(sLine); moved this into LoadTextInto
                    if (sLine == "" || sLine == " ")
                    {
                        sLine = " bbb. "; // need to insert this to have proper parabreaks
                    }
                    sText = sText + sLine;
                    sLine = file.ReadLine();
                }
            }

            file.Close();

            return LoadTextStringIntoDatabase(sText, _characters);
        }