
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WinRT.BxlComponent.Plugin.BxlMpXamarinSDK.Abstractions
{
    internal class MPosFarsiEncoder
    {
        public byte[] getFarsiEncodingData(string data, MPosCodePage CodePage = MPosCodePage.MPOS_CODEPAGE_FARSI_II)
        {
            if (CodePage == MPosCodePage.MPOS_CODEPAGE_FARSI_II)
                return unicodeToIranforEng(data);
            else
                return unicodeToIran(data);
        }
        private byte[] getReverseBytes(byte[] data)
        {
            byte[] reverseBytes = new byte[data.Length];
            for (int i = data.Length - 1; i >= 0; i--)
                reverseBytes[data.Length - 1 - i] = data[i];
            return reverseBytes;
        }
        private int getLineCount(string str)
        {
            if (str == null)
                return 0;
            if (str == string.Empty)
                return 0;
            int index = -1;
            int count = 0;
            while (-1 != (index = str.IndexOf(Environment.NewLine, index + 1)))
                count++;

            return count + 1;
        }
        private byte[] getFarsiEncodingBytes(string characters, bool reverse)
        {
            char[] charArray    = characters.ToCharArray();
            byte[] charBytes    = new byte[charArray.Length];

            // Unicode Table : http://www.utf8-chartable.de/unicode-utf8-table.pl?start=1280&number=1024
            for (int i = 0; i < charArray.Length; i++)
            {
                bool Monfasel_Pre = true;
                bool Monfasel_Post = true;

                switch (charArray[i])
                {
                    case (char)0x7F: //Space
                        charBytes[i] = 0x7F;
                        break;
                    case (char)0x0627:
                        charBytes[i] = 0x90;
                        if (i + 1 != charArray.Length){
                            if (!isMonfaselCharacter(charArray[i + 1]) && !isEnglish(charArray[i + 1]))
                                charBytes[i] = 0x91;
                        }
                        break;
                    case (char)0x0628:
                        charBytes[i] = 0x92;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x92 : (byte)0x93;
                        break;
                    case (char)0x067E:
                        charBytes[i] = 0x94;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x94 : (byte)0x95;
                        break;
                    case (char)0x062A:
                        charBytes[i] = 0x96;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x96 : (byte)0x97;
                        break;
                    case (char)0x062B:
                        charBytes[i] = 0x98;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x98 : (byte)0x99;
                        break;
                    case (char)0x062C:
                        charBytes[i] = 0x9A;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x9A : (byte)0x9B;
                        break;
                    case (char)0x0686:
                        charBytes[i] = 0x9C;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x9C : (byte)0x9D;
                        break;
                    case (char)0x062D:
                        charBytes[i] = 0x9E;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0x9E : (byte)0x9F;
                        break;
                    case (char)0x062E:
                        charBytes[i] = 0xA0;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xA0 : (byte)0xA1;
                        break;

                    case (char)0x062F:      charBytes[i] = 0xA2;    break;
                    case (char)0x0630:      charBytes[i] = 0xA3;    break;
                    case (char)0x0631:      charBytes[i] = 0xA4;    break;
                    case (char)0x0632:      charBytes[i] = 0xA5;    break;
                    case (char)0x0698:      charBytes[i] = 0xA6;    break;

                    case (char)0x0633:
                        charBytes[i] = 0xA7;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xA7 : (byte)0xA8;
                        break;
                    case (char)0x0634:
                        charBytes[i] = 0xA9;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xA9 : (byte)0xAA;
                        break;
                    case (char)0x0635:
                        charBytes[i] = 0xAB;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xAB : (byte)0xAC;
                        break;
                    case (char)0x0636:
                        charBytes[i] = 0xAD;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xAD : (byte)0xAE;
                        break;
                    case (char)0x0637:  charBytes[i] = 0xAF;    break;
                    case (char)0x0638:  charBytes[i] = 0xE0;    break;
                    case (char)0x0639:
                        if (i + 1 != charArray.Length){
                            if (!isMonfaselCharacter(charArray[i + 1]) && !isEnglish(charArray[i + 1]))
                                Monfasel_Pre = false;
                        }

                        if (i - 1 >= 0){
                            if (!isSpace_Or_English(charArray[i - 1]))
                                Monfasel_Post = false;
                        }

                        if (Monfasel_Pre == true && Monfasel_Post == true)
                            charBytes[i] = 0xE1;
                        else if (Monfasel_Pre == false && Monfasel_Post == true)
                            charBytes[i] = 0xE2;
                        else if (Monfasel_Pre == true && Monfasel_Post == false)
                            charBytes[i] = 0xE4;
                        else if (Monfasel_Pre == false && Monfasel_Post == false)
                            charBytes[i] = 0xE3;
                        break;
                    case (char)0x063A:
                        if (i + 1 != charArray.Length){
                            if (!isMonfaselCharacter(charArray[i + 1]) && !isEnglish(charArray[i + 1]))
                                Monfasel_Pre = false;
                        }

                        if (i - 1 >= 0){
                            if (!isSpace_Or_English(charArray[i - 1]))
                                Monfasel_Post = false;
                        }

                        if (Monfasel_Pre == true && Monfasel_Post == true)
                            charBytes[i] = 0xE5;
                        else if (Monfasel_Pre == false && Monfasel_Post == true)
                            charBytes[i] = 0xE6;
                        else if (Monfasel_Pre == true && Monfasel_Post == false)
                            charBytes[i] = 0xE8;
                        else if (Monfasel_Pre == false && Monfasel_Post == false)
                            charBytes[i] = 0xE7;
                        break;
                    case (char)0x0641:
                        charBytes[i] = 0xE9;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xE9 : (byte)0xEA;
                        break;
                    case (char)0x0642:
                        charBytes[i] = 0xEB;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xEB : (byte)0xEC;
                        break;
                    case (char)0x06A9:
                        charBytes[i] = 0xED;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xED : (byte)0xEE;
                        break;
                    case (char)0x06AF:
                        charBytes[i] = 0xEF;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xEF : (byte)0xF0;
                        break;
                    case (char)0x0644:
                        charBytes[i] = 0xF1;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xF1 : (byte)0xF3;
                        break;
                    case (char)0x0645:
                        charBytes[i] = 0xF4;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xF4 : (byte)0xF5;
                        break;
                    case (char)0x0646:
                        charBytes[i] = 0xF6;
                        if ((i - 1) >= 0)
                            charBytes[i] = isSpace_Or_English(charArray[i - 1]) == true ? (byte)0xF6 : (byte)0xF7;
                        break;
                    case (char)0x0648:
                        charBytes[i] = 0xF8;
                        break;

                    case (char)0x0647:
                        if (i + 1 != charArray.Length){
                            if (!isMonfaselCharacter(charArray[i + 1]) && !isEnglish(charArray[i + 1]))
                                Monfasel_Pre = false;
                        }
                        if (i - 1 >= 0){
                            if(!isSpace_Or_English(charArray[i - 1]))
                                Monfasel_Post = false;
                        }

                        if (Monfasel_Pre == true && Monfasel_Post == true)          charBytes[i] = 0xF9;
                        else if (Monfasel_Pre == false && Monfasel_Post == true)    charBytes[i] = 0xF9;
                        else if (Monfasel_Pre == true && Monfasel_Post == false)    charBytes[i] = 0xFB;
                        else if (Monfasel_Pre == false && Monfasel_Post == false)   charBytes[i] = 0xFA;
                        break;

                    case (char)0x06CC:
                        if (i + 1 != charArray.Length){
                            if (!isMonfaselCharacter(charArray[i + 1]) && !isEnglish(charArray[i + 1]))
                                Monfasel_Pre = false;
                        }

                        if (i - 1 >= 0){
                            if (!isSpace_Or_English(charArray[i - 1]))
                                Monfasel_Post = false;
                        }

                        if (Monfasel_Pre == true && Monfasel_Post == true)          charBytes[i] = (byte)0xFC;
                        else if (Monfasel_Pre == false && Monfasel_Post == true)    charBytes[i] = (byte)0xFD;
                        else if (Monfasel_Pre == true && Monfasel_Post == false)    charBytes[i] = (byte)0xFE;
                        else if (Monfasel_Pre == false && Monfasel_Post == false)   charBytes[i] = (byte)0xFE;
                        break;

                    case (char)0x06F0:  charBytes[i] = 0x80;  break;  //0 Farsi
                    case (char)0x06F1:  charBytes[i] = 0x81;  break;  //1 Farsi
                    case (char)0x06F2:  charBytes[i] = 0x82;  break;  //2 Farsi
                    case (char)0x06F3:  charBytes[i] = 0x83;  break;  //3 Farsi
                    case (char)0x06F4:  charBytes[i] = 0x84;  break;  //4 Farsi
                    case (char)0x06F5:  charBytes[i] = 0x85;  break;  //5 Farsi
                    case (char)0x06F6:  charBytes[i] = 0x86;  break;  //6 Farsi
                    case (char)0x06F7:  charBytes[i] = 0x87;  break;  //7 Farsi
                    case (char)0x06F8:  charBytes[i] = 0x88;  break;  //8 Farsi
                    case (char)0x06F9:  charBytes[i] = 0x89;  break;  //9 Farsi
                    case (char)0x060C:  charBytes[i] = 0x8A;  break;
                    case (char)0x0640:  charBytes[i] = 0x8B;  break;
                    case (char)0x061F:  charBytes[i] = 0x8C;  break;
                    case (char)0x0622:  charBytes[i] = 0x8D;  break;
                    case (char)0x0626:  charBytes[i] = 0x8E;  break;
                    case (char)0x0621:  charBytes[i] = 0x8F;  break;
                    default:
                        charBytes[i] = (byte)charArray[i];
                        break;
                }
            }

            if (reverse == true)
                return getReverseBytes(charBytes);
            else
                return charBytes;
        }
        private bool isSpace_Or_English(char character)
        {
            if (character == ' ')
                return true;
            return isEnglish(character);
        }
        private bool isMonfaselCharacter(char character)
        {
            bool Monfasel = false;

            if (character == (char)0x0627)      Monfasel = true;  // ARABIC LETTER ALEF : ا
            else if (character == (char)0x62F)  Monfasel = true;  // ARABIC LETTER DAL : د
            else if (character == (char)0x6230) Monfasel = true;  // ARABIC LETTER THAL : ذ
            else if (character == (char)0x0631) Monfasel = true;  // ARABIC LETTER REH : ر
            else if (character == (char)0x0632) Monfasel = true;  // ARABIC LETTER ZAIN : ز
            else if (character == (char)0x0698) Monfasel = true;  // ARABIC LETTER JEH : ژ
            else
                Monfasel = false;

            return Monfasel;
        }
        private bool isEnglish(char character)
        {
            bool English = false;

            if (character >= 0x00 && character <= 0x7E)
                return true;

            switch (character)
            {
                //Farsi symbols and numbers
                case (char)0x060C:
                case (char)0x0640:
                case (char)0x061F:
                case (char)0x0622:
                case (char)0x0606:
                case (char)0x0621:
                case (char)0x06F0:
                case (char)0x06F1:
                case (char)0x06F2:
                case (char)0x06F3:
                case (char)0x06F4:
                case (char)0x06F5:
                case (char)0x06F6:
                case (char)0x06F7:
                case (char)0x06F8:
                case (char)0x06F9:
                    English = true;
                    break;
                default:
                    English = false;
                    break;
            }

            return English;
        }
        private bool isIsolated(char CH)
        {
            switch (CH)
            {
                case 'چ':
                case 'ج':
                case 'ح':
                case 'خ':
                case 'ه':
                case 'ع':
                case 'غ':
                case 'ف':
                case 'ق':
                case 'ث':
                case 'ص':
                case 'ض':
                case 'گ':
                case 'ک':
                case 'م':
                case 'ن':
                case 'ت':
                case 'ب':
                case 'ل':
                case 'ی':
                case 'س':
                case 'ش':
                case 'ئ':
                case 'ط':
                case 'ظ':
                    return false;
                default:
                    return true;
            }
        }
        public byte[] reverseforUnicodeToIran(byte[] B)
        {

            byte[] posNoReverseData = null;
            int cntNoReverseData = 0;
            //숫자, 대문자, 소문자, 콤마(,), 하이폰(-), 점(.) 몇개 있는지 
            //숫자를 특수기호(,-.:/)과 조합해서 쓸 경우 추가 (ex 17.00   1,234,567   463-400,   (+971) , 10% )
            for (int i = 0; i < B.Length; i++)
            {
                if ((B[i] >= 0x30 && B[i] <= 0x39)
                        || (B[i] >= 0x41 && B[i] <= 0x5A)
                        || (B[i] >= 0x61 && B[i] <= 0x7A)
                        || (B[i] == 0x2C)
                        || (B[i] == 0x2D)
                        || (B[i] == 0x2E)
                        || (B[i] == 0x3A)
                        || (B[i] == 0x2F)
                        || (B[i] == 0x28)
                        || (B[i] == 0x29)
                        || (B[i] == 0x40))
                {
                    if ((B[i] == 0x2C)
                            || (B[i] == 0x2D)
                            || (B[i] == 0x2E)
                            || (B[i] == 0x3A)
                            || (B[i] == 0x2F)
                            || (B[i] == 0x28)
                            || (B[i] == 0x29)
                            || (B[i] == 0x40))
                    {
                        if ((i != 0) && (i != B.Length - 1))
                        {
                            //(ex. 031-218-5550 www.bixolon.com)
                            if ((B[i - 1] >= 0x30 && B[i - 1] <= 0x39)
                                    || (B[i + 1] >= 0x30 && B[i + 1] <= 0x39)
                                    || (B[i - 1] >= 0x41 && B[i - 1] <= 0x5A)//choeun 2016.11.14
                                    || (B[i + 1] >= 0x41 && B[i + 1] <= 0x5A)
                                    || (B[i - 1] >= 0x61 && B[i - 1] <= 0x7A)//choeun 2016.11.14
                                    || (B[i + 1] >= 0x61 && B[i + 1] <= 0x7A)
                                    || B[i + 1] == 0x2B)
                            {//choeun 2016.11.14  ex.(+ 
                                cntNoReverseData++;
                            }
                        }

                    }
                    else
                    {
                        cntNoReverseData++;
                    }

                    //choeun 2016.11.14
                    //ex. Shop 331 Blooklyn mall
                }
                else if (B[i] == 0x20)
                {
                    if ((i != 0) && (i != B.Length - 1))
                    {
                        if ((B[i - 1] >= 0x30 && B[i - 1] <= 0x39)
                                || (B[i + 1] >= 0x30 && B[i + 1] <= 0x39)
                                || (B[i - 1] >= 0x41 && B[i - 1] <= 0x5A)//
                                || (B[i + 1] >= 0x41 && B[i + 1] <= 0x5A)
                                || (B[i - 1] >= 0x61 && B[i - 1] <= 0x7A)//
                                || (B[i + 1] >= 0x61 && B[i + 1] <= 0x7A))
                        {
                            cntNoReverseData++;
                        }
                    }
                    //ex. +971	
                }
                else if (B[i] == 0x2B)
                {
                    if ((i != 0) && (i != B.Length - 1))
                    {
                        if (/*(B[i-1] >= 0x30 && B[i-1] <= 0x39)
												||*/(B[i + 1] >= 0x30 && B[i + 1] <= 0x39))
                        {
                            cntNoReverseData++;
                        }
                    }
                }
            }
            //페르시아어만 있을 때 처리
            if (cntNoReverseData != 0)
            {
                //개수만큼 할당
                posNoReverseData = new byte[cntNoReverseData];
                int k = 0;
                //REVERSE 할 데이터의 위치를 배열에 저장
                for (int i = 0; i < B.Length; i++)
                {
                    if ((B[i] >= 0x30 && B[i] <= 0x39)
                            || (B[i] >= 0x41 && B[i] <= 0x5A)
                            || (B[i] >= 0x61 && B[i] <= 0x7A)
                            || (B[i] == 0x2C)
                            || (B[i] == 0x2D)
                            || (B[i] == 0x2E)
                            || (B[i] == 0x3A)
                            || (B[i] == 0x2F)
                            || (B[i] == 0x28)
                            || (B[i] == 0x29)
                            || (B[i] == 0x40))
                    {
                        if ((B[i] == 0x2C)
                                || (B[i] == 0x2D)
                                || (B[i] == 0x2E)
                                || (B[i] == 0x3A)
                                || (B[i] == 0x2F)
                                || (B[i] == 0x28)
                                || (B[i] == 0x29)
                                || (B[i] == 0x40))
                        {
                            if ((i != 0) && (i != B.Length - 1))
                            {
                                //(ex. 031-218-5550 www.bixolon.com)
                                if ((B[i - 1] >= 0x30 && B[i - 1] <= 0x39)
                                        || (B[i + 1] >= 0x30 && B[i + 1] <= 0x39)
                                        || (B[i - 1] >= 0x41 && B[i - 1] <= 0x5A)//choeun 2016.11.14
                                        || (B[i + 1] >= 0x41 && B[i + 1] <= 0x5A)
                                        || (B[i - 1] >= 0x61 && B[i - 1] <= 0x7A)//choeun 2016.11.14
                                        || (B[i + 1] >= 0x61 && B[i + 1] <= 0x7A)
                                        || B[i + 1] == 0x2B)
                                {//choeun 2016.11.14  ex.(+ 
                                    posNoReverseData[k] = (byte)i;
                                    k++;
                                }
                            }
                        }
                        else
                        {
                            posNoReverseData[k] = (byte)i;
                            k++;
                        }

                    }
                    //choeun 2016.11.14
                    //ex. Shop 331 Blooklyn mall
                    else if (B[i] == 0x20)
                    {
                        if ((i != 0) && (i != B.Length - 1))
                        {
                            if ((B[i - 1] >= 0x30 && B[i - 1] <= 0x39)
                                    || (B[i + 1] >= 0x30 && B[i + 1] <= 0x39)
                                    || (B[i - 1] >= 0x41 && B[i - 1] <= 0x5A)//
                                    || (B[i + 1] >= 0x41 && B[i + 1] <= 0x5A)
                                    || (B[i - 1] >= 0x61 && B[i - 1] <= 0x7A)//
                                    || (B[i + 1] >= 0x61 && B[i + 1] <= 0x7A))
                            {
                                posNoReverseData[k] = (byte)i;
                                k++;
                            }
                        }
                    }
                    //ex. +971	
                    else if (B[i] == 0x2B)
                    {
                        if ((i != 0) && (i != B.Length - 1))
                        {
                            if (/*(B[i-1] >= 0x30 && B[i-1] <= 0x39)
											||*/(B[i + 1] >= 0x30 && B[i + 1] <= 0x39))
                            {
                                posNoReverseData[k] = (byte)i;
                                k++;
                            }
                        }
                    }
                }
                //문자열의 처음과 끝 위치 저장
                int posStart = posNoReverseData[0];
                int posEnd = 0;
                byte[] reverseTemp = null;
                byte[] orgTemp = null;

                int p = 0;
                for (int i = 0; i < cntNoReverseData; i++)
                {
                    //데이터 끝인지 체크
                    if (p == posNoReverseData.Length - 1)
                    {
                        posEnd = (posNoReverseData[i] & 0xff);

                        orgTemp = new byte[posEnd - posStart + 1];
                        reverseTemp = new byte[posEnd - posStart + 1];

                        //원래 데이터를 임시로 저장
                        int pos = 0;
                        for (int j = posStart; j < posEnd + 1; j++)
                        {
                            orgTemp[pos] = B[j];
                            pos++;
                        }
                        //데이터를 거꾸로 변환하여 저장
                        for (int j = 0; j < posEnd - posStart + 1; j++)
                        {
                            reverseTemp[j] = orgTemp[posEnd - posStart - j];
                        }
                        //원래 데이터를 거꾸로 변환환 데이터로 치환
                        pos = 0;
                        for (int j = posStart; j < posEnd + 1; j++)
                        {
                            B[j] = reverseTemp[pos];
                            pos++;
                        }

                    }
                    else
                    {
                        if (((posNoReverseData[p + 1] & 0xff) - (posNoReverseData[p] & 0xff)) > 1)
                        {
                            posEnd = (posNoReverseData[i] & 0xff);

                            orgTemp = new byte[posEnd - posStart + 1];
                            reverseTemp = new byte[posEnd - posStart + 1];

                            //원래 데이터를 저장
                            int pos = 0;
                            for (int j = posStart; j < posEnd + 1; j++)
                            {
                                orgTemp[pos] = B[j];
                                pos++;
                            }
                            //데이터를 거꾸로 변환하여 저장
                            for (int j = 0; j < posEnd - posStart + 1; j++)
                            {
                                reverseTemp[j] = orgTemp[posEnd - posStart - j];
                            }
                            //원래 데이터를 거꾸로 변환환 데이터로 치환
                            pos = 0;
                            for (int j = posStart; j < posEnd + 1; j++){
                                B[j] = reverseTemp[pos];
                                pos++;
                            }

                            posStart = (posNoReverseData[i + 1] & 0xff);
                            p++;
                        }
                        else{
                            p++;
                        }
                    }

                }
            }

            byte[] Temp = new byte[B.Length];
            for (int i = 0; i < B.Length; i++)
                Temp[i] = B[B.Length - 1 - i];
            return Temp;
        }
        private byte[] unicodeToIran(string charData)
        {

		    char[] Input    = charData.ToCharArray();
		    byte[] Result   = new byte[charData.Length];

		    for(int i=0;i<charData.Length;i++)
		    {
			    //			if(Input[i]<0x0079)
			    if(Input[i] < 0x007B) //y, z 파싱 못함
				    Result[i]=(byte)Input[i];
			    else
			    {	
				    switch((ushort)Input[i])
				    {
				    case 0x06F0:    Result[i]=(byte)0x80;   break;
				    case 0x06F1:    Result[i]=(byte)0x81;   break;
				    case 0x06F2:    Result[i]=(byte)0x82;   break;
				    case 0x06F3:    Result[i]=(byte)0x83;   break;
				    case 0x06F4:    Result[i]=(byte)0x84;   break;
				    case 0x06F5:    Result[i]=(byte)0x85;   break;
				    case 0x06F6:    Result[i]=(byte)0x86;   break;
				    case 0x06F7:    Result[i]=(byte)0x87;   break;
				    case 0x06F8:    Result[i]=(byte)0x88;   break;
				    case 0x06F9:    Result[i]=(byte)0x89;   break;
                    case 0x060C:    Result[i]=(byte)0x8A;   break;
				    case 0x0640:    Result[i]=(byte)0x8B;   break;
				    case 0x061F:    Result[i]=(byte)0x8C;   break;
				    case 0x0622:    Result[i]=(byte)0x8D;   break;
				    case 0x0626:    Result[i]=(byte)0x8E;   break;
				    case 0x0621:    Result[i]=(byte)0x8F;   break;

				    case (0x0627)://الف
					    if(i == 0)
						    Result[i]=(byte)0x90;
					    else if(isIsolated(Input[i-1]))
						    Result[i]=(byte)0x90;
					    else
						    Result[i]=(byte)0x91;					
				    break;

				    case 0x0628://ب
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x92;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x92;		
					    else
						    Result[i]=(byte)0x93;	
				    break;

				    case (0x067E)://پ
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x94;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x94;					
					    else
						    Result[i]=(byte)0x95;				
				    break;

				    case (0x062A)://ت
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x96;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x96;					
					    else
						    Result[i]=(byte)0x97;				
				    break;

				    case (0x062B)://ث
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x98;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x98;					
					    else
						    Result[i]=(byte)0x99;				
				    break;

				    case (0x062C)://ج
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x9A;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x9A;					
					    else
						    Result[i]=(byte)0x9B;				
				    break;

				    case (0x0686)://چ
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x9C;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x9C;					
					    else
						    Result[i]=(byte)0x9D;				
				    break;

				    case (0x062D)://ح
					    if(i+1==charData.Length)
						    Result[i]=(byte)0x9E;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0x9E;					
					    else
						    Result[i]=(byte)0x9F;				
				    break;

				    case (0x062E)://خ
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xA0;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xA0;					
					    else
						    Result[i]=(byte)0xA1;				
				    break;

				    case 0x62F:     Result[i]=(byte)0xA2;   break;  //د
                    case 0x630:     Result[i]=(byte)0xA3;   break;  //ذ
                    case 0x0631:    Result[i]=(byte)0xA4;   break;  //ر
                    case 0x0632:    Result[i]=(byte)0xA5;   break;  //ز
                    case 0x0698:    Result[i]=(byte)0xA6;   break;  //ژ

                    case 0x0633:
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xA7;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xA7;					
					    else
						    Result[i]=(byte)0xA8;				
				    break;

				    case 0x0634://ش
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xA9;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xA9;					
					    else
						    Result[i]=(byte)0xAA;				
				    break;

				    case 0x0635://ص
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xAB;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xAB;					
					    else
						    Result[i]=(byte)0xAC;				
				    break;

				    case 0x0636://ض
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xAD;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xAD;					
					    else
						    Result[i]=(byte)0xAE;				
				    break;

				    case 0x0637:    Result[i]=(byte)0xAF;   break;  //ط
                    case 0x0638:    Result[i]=(byte)0xE0;   break;  //ظ					

                    case (0x0639)://ع
					    if(i+1==charData.Length && (i==0 || isIsolated(Input[i-1])))
						    Result[i]=(byte)0xE1;
					    else if(i+1==charData.Length && (i==0 || !isIsolated(Input[i-1])))
						    Result[i]=(byte)0xE2;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A)){
						    if(i==0 || isIsolated(Input[i-1]))
							    Result[i]=(byte)0xE1;
						    else
							    Result[i]=(byte)0xE2;
					    }
					    else{
						    if(i==0 || isIsolated(Input[i-1]))
							    Result[i]=(byte)0xE4;
						    else
							    Result[i]=(byte)0xE3;
					    }
				    break;

				    case (0x063A)://غ
					    if(i+1==charData.Length && (i==0 || isIsolated(Input[i-1])))
						    Result[i]=(byte)0xE5;
					    else if(i+1==charData.Length && (i==0 || !isIsolated(Input[i-1])))
						    Result[i]=(byte)0xE6;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A)){
						    if(i==0 || isIsolated(Input[i-1]))
							    Result[i]=(byte)0xE5;
						    else
							    Result[i]=(byte)0xE6;
					    }
					    else{
						    if(i==0 || isIsolated(Input[i-1]))

							    Result[i]=(byte)0xE8;
						    else
							    Result[i]=(byte)0xE7;
					    }
				    break;

				    case (0x0641)://ف
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xE9;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xE9;					
					    else
						    Result[i]=(byte)0xEA;				
				    break;

				    case (0x0642)://ق
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xEB;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xEB;					
					    else
						    Result[i]=(byte)0xEC;				
				    break;

				    case (0x06A9)://ک
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xED;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xED;					
					    else
						    Result[i]=(byte)0xEE;				
				    break;

				    case (0x06AF)://گ
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xEF;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xEF;					
					    else
						    Result[i]=(byte)0xF0;				
				    break;

				    case (0x0644)://ل
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xF1;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xF1;					
					    else
						    Result[i]=(byte)0xF3;				
				    break;

				    case (0x0645)://م
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xF4;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xF4;					
					    else
						    Result[i]=(byte)0xF5;				
				    break;

				    case (0x0646)://ن
					    if(i+1==charData.Length)
						    Result[i]=(byte)0xF6;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A))
						    Result[i]=(byte)0xF6;					
					    else
						    Result[i]=(byte)0xF7;				
				    break;

				    case (0x0648)://و					
					    Result[i]=(byte)0xF8;			
				    break;

				    case (0x0647)://ه
					    if(i+1==charData.Length && (i==0 || isIsolated(Input[i-1])))
						    Result[i]=(byte)0xF9;					
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A)){
						    if(i==0 || isIsolated(Input[i-1]))
							    Result[i]=(byte)0xF9;
						    else
							    Result[i]=(byte)0xF9;
					    }
					    else{
						    if(i==0 || isIsolated(Input[i-1]))

							    Result[i]=(byte)0xFB;
						    else
							    Result[i]=(byte)0xFA;
					    }
				    break;

				    case (0x06CC)://غ
					    if(i+1==charData.Length && (i==0 || isIsolated(Input[i-1])))
						    Result[i]=(byte)0xFC;
					    else if(i+1==charData.Length && (i==0 || !isIsolated(Input[i-1])))
						    Result[i]=(byte)0xFD;
					    else if((i+1!=charData.Length) && (Input[i+1]==(char)0x0020 || Input[i+1]==(char)0x000A)){
						    if(i==0 || isIsolated(Input[i-1]))
							    Result[i]=(byte)0xFC;
						    else
							    Result[i]=(byte)0xFD;
					    }
					    else{
						    if(i==0 || isIsolated(Input[i-1]))

							    Result[i]=(byte)0xFE;
						    else
							    Result[i]=(byte)0xFE;
					    }
				    break;

				    default:
					    break;
				    }
			    }
		    }
		    return reverseforUnicodeToIran(Result);
        }
        private byte[] unicodeToIranforEng(string charData)
        {
            /*
            int cntEnter = 0;
            for (int i = 0; i < data.Length - 1; i++){
                if (data.Substring(i, i + 1).CompareTo("\n") == 0)
                    cntEnter++;
            }
            */

            //string[] source = data.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
            string[] source = charData.Split(new char[] { '\n' }, StringSplitOptions.None);
            var matchQuery  = from word in source where word.Contains("\n") select word;
            var cntEnter    = matchQuery.Count();

            string[] temp_Lines = charData.Split('n');
            string[] str_Lines  = new string[cntEnter + 1];

            if (temp_Lines.Length == 0){
                for (int i = 0; i < str_Lines.Length; i++)
                    str_Lines[i] = "\n";
            }
            else{
                for (int i = 0; i < temp_Lines.Length; i++)
                    str_Lines[temp_Lines.Length - 1 - i] = temp_Lines[i];

                for (int i = 0; i < str_Lines.Length; i++)
                    if ((str_Lines[i].Length == 0))
                        str_Lines[i] = "\n";
            }

            MemoryStream memStream      = new MemoryStream();
            BinaryWriter binaryWriter   = new BinaryWriter(memStream);

            for (int l = 0; l < str_Lines.Length; l++)
            {
                string Txt_Send = str_Lines[l];
                string Sub_Str = "";
                bool English_Lang = false;
                bool Prev_English_Lang = false;
                char[] Chr_Send = Txt_Send.ToCharArray();
                byte[] Result = null;

                for (int i = Chr_Send.Length - 1; i >= 0; i--)
                {
                    MPosDebug.WriteLine("UnicodeToIranforEng : Chr_Send["+i+"] = " + string.Format("0x{0:X}", (uint)Chr_Send[i]));

                    if (Chr_Send[i] != ' ')
                    {
                        if (isEnglish(Chr_Send[i])){
                            English_Lang = true;
                            if (Prev_English_Lang == false)
                                Result = getFarsiEncodingBytes(Sub_Str, false);
                        }   
                        else{
                            English_Lang = false;
                            if (Prev_English_Lang == true)
                                Result = getFarsiEncodingBytes(Sub_Str, true);
                        }

                        if (Result != null){
                            binaryWriter.Write(Result);
                            Sub_Str = "";
                        }
                    }
                    else
                    {
                        for (int j = i - 1; j >= 0; j--)
                        {
                            if (Chr_Send[j] != ' ')
                            {
                                if (isEnglish(Chr_Send[j]) != English_Lang){
                                    Result = getFarsiEncodingBytes(Sub_Str, English_Lang);
                                    if (Result != null){
                                        binaryWriter.Write(Result);
                                        Sub_Str = "";
                                    }
                                    
                                }
                                else{
                                    break;
                                }
                            }
                        }
                    }

                    Sub_Str += Chr_Send[i];
                    Prev_English_Lang = English_Lang;

                    if (i == 0)
                    {
                        if (English_Lang == true)
                            Result = getFarsiEncodingBytes(Sub_Str, true);
                        else
                            Result = getFarsiEncodingBytes(Sub_Str, false);
                        if (Result != null)
                            binaryWriter.Write(Result);
                    }

                    Result = null;
                }
            }

            var resultData = memStream.ToArray();
            binaryWriter.Dispose();
            return resultData;
        }
    }
}
