/// <summary>
 /// English letters, numbers and punctuation characters are ignored. This checks if the ch is an ignored character.
 /// </summary>
 /// <param name="ch">The character to be checked for skipping</param>
 /// <returns>True if the character should be ignored, false if it should not be ignored.</returns>
 internal static bool IsIgnoredCharacter(char ch)
 {
     return(char.IsPunctuation(ch) ||
            char.IsNumber(ch) ||
            char.IsLower(ch) ||
            char.IsUpper(ch) ||
            char.IsSymbol(ch) ||
            !ArabicTable.IsIsolatedForm(ch));
 }
    /// <summary>
    /// Converts a string to a form in which the sting will be displayed correctly for arabic text.
    /// </summary>
    /// <param name="str">String to be converted. Example: "Aaa"</param>
    /// <returns>Converted string. Example: "aa aaa A" without the spaces.</returns>
    internal static string FixLine(string str)
    {
        List <TashkeelLocation> tashkeelLocation;

        string originString = RemoveTashkeel(str, out tashkeelLocation);

        char[] lettersOrigin = originString.ToCharArray();
        char[] lettersFinal  = originString.ToCharArray();


        for (int i = 0; i < lettersOrigin.Length; i++)
        {
            lettersOrigin[i] = (char)ArabicTable.Convert(lettersOrigin[i]);
        }

        for (int i = 0; i < lettersOrigin.Length; i++)
        {
            bool skip = false;

            // For special Lam Letter connections.
            if (lettersOrigin[i] == (char)IsolatedArabicLetters.Lam && i < lettersOrigin.Length - 1)
            {
                skip = FixSpecialLam(lettersOrigin, i, lettersFinal);
            }

            if (!IsIgnoredCharacter(lettersOrigin[i]))
            {
                if (IsMiddleLetter(lettersOrigin, i))
                {
                    lettersFinal[i] = (char)(lettersOrigin[i] + 3);
                }
                else if (IsFinishingLetter(lettersOrigin, i))
                {
                    lettersFinal[i] = (char)(lettersOrigin[i] + 1);
                }
                else if (IsLeadingLetter(lettersOrigin, i))
                {
                    lettersFinal[i] = (char)(lettersOrigin[i] + 2);
                }
            }

            if (skip)
            {
                i++;
            }

            //chaining numbers to hindu
            if (useHinduNumbers && lettersOrigin[i] >= 0x0030 && lettersOrigin[i] <= 0x0039)
            {
                lettersFinal[i] = (char)(lettersOrigin[i] + 0x0630);
            }
        }



        //Return the Tashkeel to their places.
        if (showTashkeel)
        {
            lettersFinal = ReturnTashkeel(lettersFinal, tashkeelLocation);
        }


        List <char> list = new List <char>();

        List <char> numberList = new List <char>();

        for (int i = lettersFinal.Length - 1; i >= 0; i--)
        {
            if (char.IsPunctuation(lettersFinal[i]) && i > 0 && i < lettersFinal.Length - 1 &&
                (char.IsPunctuation(lettersFinal[i - 1]) || char.IsPunctuation(lettersFinal[i + 1])))
            {
                if (lettersFinal[i] == '(')
                {
                    list.Add(')');
                }
                else if (lettersFinal[i] == ')')
                {
                    list.Add('(');
                }
                else if (lettersFinal[i] == '<')
                {
                    list.Add('>');
                }
                else if (lettersFinal[i] == '>')
                {
                    list.Add('<');
                }
                else if (lettersFinal[i] == '[')
                {
                    list.Add(']');
                }
                else if (lettersFinal[i] == ']')
                {
                    list.Add('[');
                }
                else if (lettersFinal[i] != 0xFFFF)
                {
                    list.Add(lettersFinal[i]);
                }
            }
            // For cases where english words and arabic are mixed. This allows for using arabic, english and numbers in one sentence.
            else if (lettersFinal[i] == ' ' && i > 0 && i < lettersFinal.Length - 1 &&
                     (char.IsLower(lettersFinal[i - 1]) || char.IsUpper(lettersFinal[i - 1]) || char.IsNumber(lettersFinal[i - 1])) &&
                     (char.IsLower(lettersFinal[i + 1]) || char.IsUpper(lettersFinal[i + 1]) || char.IsNumber(lettersFinal[i + 1])))

            {
                numberList.Add(lettersFinal[i]);
            }

            else if (char.IsNumber(lettersFinal[i]) || char.IsLower(lettersFinal[i]) ||
                     char.IsUpper(lettersFinal[i]) || char.IsSymbol(lettersFinal[i]) ||
                     char.IsPunctuation(lettersFinal[i]))            // || lettersFinal[i] == '^') //)
            {
                if (lettersFinal[i] == '(')
                {
                    numberList.Add(')');
                }
                else if (lettersFinal[i] == ')')
                {
                    numberList.Add('(');
                }
                else if (lettersFinal[i] == '<')
                {
                    numberList.Add('>');
                }
                else if (lettersFinal[i] == '>')
                {
                    numberList.Add('<');
                }
                else if (lettersFinal[i] == '[')
                {
                    list.Add(']');
                }
                else if (lettersFinal[i] == ']')
                {
                    list.Add('[');
                }
                else
                {
                    numberList.Add(lettersFinal[i]);
                }
            }
            else if ((lettersFinal[i] >= (char)0xD800 && lettersFinal[i] <= (char)0xDBFF) ||
                     (lettersFinal[i] >= (char)0xDC00 && lettersFinal[i] <= (char)0xDFFF))
            {
                numberList.Add(lettersFinal[i]);
            }
            else
            {
                if (numberList.Count > 0)
                {
                    for (int j = 0; j < numberList.Count; j++)
                    {
                        list.Add(numberList[numberList.Count - 1 - j]);
                    }
                    numberList.Clear();
                }
                if (lettersFinal[i] != 0xFFFF)
                {
                    list.Add(lettersFinal[i]);
                }
            }
        }
        if (numberList.Count > 0)
        {
            for (int j = 0; j < numberList.Count; j++)
            {
                list.Add(numberList[numberList.Count - 1 - j]);
            }
            numberList.Clear();
        }

        // Moving letters from a list to an array.
        lettersFinal = new char[list.Count];
        for (int i = 0; i < lettersFinal.Length; i++)
        {
            lettersFinal[i] = list[i];
        }


        str = new string(lettersFinal);
        return(str);
    }