
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 MPosVietnamEncoder
    {
        public byte[] getVietnamEncodingData(string data, MPosCodePage CodePage = MPosCodePage.MPOS_CODEPAGE_TCVN)
        {
            switch(CodePage)
            {
                case MPosCodePage.MPOS_CODEPAGE_TCVN:
                case MPosCodePage.MPOS_CODEPAGE_TCVN_CAPTIAL:
                    return unicodeToTCVN3(data);
                case MPosCodePage.MPOS_CODEPAGE_VISCII:
                    return unicodeToVISCII(data);
            }
            return null;
        }
        private byte[] unicodeToVISCII(string dataToPrint)
        {
            byte[] visciiArray = {
               0xC0,0xC4,0xC3,0xC1,0x80,0x83,0x87,0xC8,0xCB,0x88,0xC9,0x89,0x8E,0xCC,0x9B,0xCE,
               0xCD,0x98,0xD2,0x99,0xA0,0xD3,0x9A,0x93,0x96,0x97,0xB3,0x95,0x94,0xD9,0x9C,0x9D,
               0xC5,0xC2,0xCA,0xD4,0xB4,0xBF,0xD0,0xE5,0xE2,0xEA,0xF4,0xBD,0xDF,0xF0,0x82,
               0xE0,0xE4,0xE3,0xE1,0xD5,0x02,0xA2,0xC6,0xC7,0xA1,0x05,
               0x81,0x85,0x86,0x06,0x84,0x8B,0xA3,0xA5,0xA6,0xE7,0xA4,0xA7,0xE8,0x8C,0xEB,0xA8,
               0xE9,0xA9,0xAB,0xAC,0xAD,0xAA,0xAE,0xEC,0xEF,0x8D,0x8A,0x90,0xEE,0xED,0xB8,0xF2,
               0x91,0xF6,0xF5,0xF3,0xF7,0xB0,0xB1,0xB2,0xAF,0xB5,0xB6,0xB7,0xDE,0xBE,0xFE,0xF9,
               0x92,0xFC,0xFB,0xFA,0xF8,0xD7,0xD8,0xE6,0xD1,0xF1,0xCF,0xD6,0xDB,0xFD,0xDC,0x8F,
               0xDA,0x9E,0xBB,0xBC,0xFF,
               0xBA,0xB9,0x9F,0xDD
            };

            char[] unicodeArray = {
                (char)0x00C0,(char)0x1EA2,(char)0x00C3,(char)0x00C1,(char)0x1EA0,(char)0x1EB6,(char)0x1EAC,(char)0x00C8,(char)0x1EBA,(char)0x1EBC,(char)0x00C9,(char)0x1EB8,(char)0x1EC6,(char)0x00CC,(char)0x1EC8,(char)0x0128,
                (char)0x00CD,(char)0x1ECA,(char)0x00D2,(char)0x1ECE,(char)0x00D5,(char)0x00D3,(char)0x1ECC,(char)0x1ED8,(char)0x1EDC,(char)0x1EDE,(char)0x1EE0,(char)0x1EDA,(char)0x1EE2,(char)0x00D9,(char)0x1EE6,(char)0x0168,
                (char)0x0102,(char)0x00C2,(char)0x00CA,(char)0x00D4,(char)0x01A0,(char)0x01AF,(char)0x0110,(char)0x0103,(char)0x00E2,(char)0x00EA,(char)0x00F4,(char)0x01A1,(char)0x01B0,(char)0x0111,(char)0x1EB0,
                (char)0x00E0,(char)0x1EA3,(char)0x00E3,(char)0x00E1,(char)0x1EA1,(char)0x1EB2,(char)0x1EB1,(char)0x1EB3,(char)0x1EB5,(char)0x1EAF,(char)0x1EB4,
                (char)0x1EAE,(char)0x1EA6,(char)0x1EA8,(char)0x1EAA,(char)0x1EA4,(char)0x1EC0,(char)0x1EB7,(char)0x1EA7,(char)0x1EA9,(char)0x1EAB,(char)0x1EA5,(char)0x1EAD,(char)0x00E8,(char)0x1EC2,(char)0x1EBB,(char)0x1EBD,
                (char)0x00E9,(char)0x1EB9,(char)0x1EC1,(char)0x1EC3,(char)0x1EC5,(char)0x1EBF,(char)0x1EC7,(char)0x00EC,(char)0x1EC9,(char)0x1EC4,(char)0x1EBE,(char)0x1ED2,(char)0x0129,(char)0x00ED,(char)0x1ECB,(char)0x00F2,
                (char)0x1ED4,(char)0x1ECF,(char)0x00F5,(char)0x00F3,(char)0x1ECD,(char)0x1ED3,(char)0x1ED5,(char)0x1ED7,(char)0x1ED1,(char)0x1ED9,(char)0x1EDD,(char)0x1EDF,(char)0x1EE1,(char)0x1EDB,(char)0x1EE3,(char)0x00F9,
                (char)0x1ED6,(char)0x1EE7,(char)0x0169,(char)0x00FA,(char)0x1EE5,(char)0x1EEB,(char)0x1EED,(char)0x1EEF,(char)0x1EE9,(char)0x1EF1,(char)0x1EF3,(char)0x1EF7,(char)0x1EF9,(char)0x00FD,(char)0x1EF5,(char)0x1ED0,
                (char)0x00DA,(char)0x1EE4,(char)0x1EEA,(char)0x1EEC,(char)0x1EEE,
                (char)0x1EE8,(char)0x1EF0,(char)0x1EF2,(char)0x00DD
            };

            int charLength = dataToPrint.Length;
            byte[] encodedCharArray = new byte[charLength + 1];

            // Initialize
            encodedCharArray[charLength] = 0x00;  // NULL
            for (int i = 0; i < charLength; i++){
                encodedCharArray[i] = 0x3F; // QUESTION MARK
                if (dataToPrint[i] <= 0x7F)
                    encodedCharArray[i] = (byte)dataToPrint[i];
            }

            // Character Mapping
            for (int i = 0; i < charLength; i++){
                for (int j = 0; j < unicodeArray.Length; j++){
                    if (unicodeArray[j] == dataToPrint[i])
                        encodedCharArray[i] = visciiArray[j];
                }
            }
            return encodedCharArray;
        }
        private byte[] unicodeToTCVN3(string dataToPrint)
        {
            byte[] tcvn3Array = {
               0xB5,0xB6,0xB7,0xB8,0xB9,0x3F,0xCB,0xCC,0xCE,0xCF,0xD0,0xD1,0xD6,0xD7,0xD8,0xDC,
               0xDD,0xDE,0xDF,0xE1,0xE2,0xE3,0xE4,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF1,0xF2,
               0xA1,0xA2,0xAA,0xAB,0xAC,0xAD,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xBB,
               0xB5,0xB6,0xB7,0xB8,0xB9,0x3F,0xBB,0xBC,0xBD,0xBE,0x3F,
               0x3F,0x3F,0x3F,0x3F,0x3F,0xD2,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xD3,0xCE,0xCF,
               0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD4,0xD5,0xE5,0xDC,0xDD,0xDE,0xDF,
               0x3F,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
               0x3F,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xE8,
               0xF3,0xF4,0xF5,0xF6,0xF7,
               0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE
            };

            char[] unicodeArray = {
                (char)0x00C0,(char)0x1EA2,(char)0x00C3,(char)0x00C1,(char)0x1EA0,(char)0x1EB6,(char)0x1EAC,(char)0x00C8,(char)0x1EBA,(char)0x1EBC,(char)0x00C9,(char)0x1EB8,(char)0x1EC6,(char)0x00CC,(char)0x1EC8,(char)0x0128,
                (char)0x00CD,(char)0x1ECA,(char)0x00D2,(char)0x1ECE,(char)0x00D5,(char)0x00D3,(char)0x1ECC,(char)0x1ED8,(char)0x1EDC,(char)0x1EDE,(char)0x1EE0,(char)0x1EDA,(char)0x1EE2,(char)0x00D9,(char)0x1EE6,(char)0x0168,
                (char)0x0102,(char)0x00C2,(char)0x00CA,(char)0x00D4,(char)0x01A0,(char)0x01AF,(char)0x0110,(char)0x0103,(char)0x00E2,(char)0x00EA,(char)0x00F4,(char)0x01A1,(char)0x01B0,(char)0x0111,(char)0x1EB0,
                (char)0x00E0,(char)0x1EA3,(char)0x00E3,(char)0x00E1,(char)0x1EA1,(char)0x1EB2,(char)0x1EB1,(char)0x1EB3,(char)0x1EB5,(char)0x1EAF,(char)0x1EB4,
                (char)0x1EAE,(char)0x1EA6,(char)0x1EA8,(char)0x1EAA,(char)0x1EA4,(char)0x1EC0,(char)0x1EB7,(char)0x1EA7,(char)0x1EA9,(char)0x1EAB,(char)0x1EA5,(char)0x1EAD,(char)0x00E8,(char)0x1EC2,(char)0x1EBB,(char)0x1EBD,
                (char)0x00E9,(char)0x1EB9,(char)0x1EC1,(char)0x1EC3,(char)0x1EC5,(char)0x1EBF,(char)0x1EC7,(char)0x00EC,(char)0x1EC9,(char)0x1EC4,(char)0x1EBE,(char)0x1ED2,(char)0x0129,(char)0x00ED,(char)0x1ECB,(char)0x00F2,
                (char)0x1ED4,(char)0x1ECF,(char)0x00F5,(char)0x00F3,(char)0x1ECD,(char)0x1ED3,(char)0x1ED5,(char)0x1ED7,(char)0x1ED1,(char)0x1ED9,(char)0x1EDD,(char)0x1EDF,(char)0x1EE1,(char)0x1EDB,(char)0x1EE3,(char)0x00F9,
                (char)0x1ED6,(char)0x1EE7,(char)0x0169,(char)0x00FA,(char)0x1EE5,(char)0x1EEB,(char)0x1EED,(char)0x1EEF,(char)0x1EE9,(char)0x1EF1,(char)0x1EF3,(char)0x1EF7,(char)0x1EF9,(char)0x00FD,(char)0x1EF5,(char)0x1ED0,
                (char)0x00DA,(char)0x1EE4,(char)0x1EEA,(char)0x1EEC,(char)0x1EEE,
                (char)0x1EE8,(char)0x1EF0,(char)0x1EF2,(char)0x1EF6,(char)0x1EF8,(char)0x00DD,(char)0x1EF4
            };

            int charLength = dataToPrint.Length;

            byte[] encodedCharArray = new byte[charLength + 1];

            // Initialize
            encodedCharArray[charLength] = 0x00;  // NULL
            for (int i = 0; i < charLength; i++){
                encodedCharArray[i] = 0x3F; // QUESTION MARK
                if (dataToPrint[i] <= 0x7F)
                    encodedCharArray[i] = (byte)dataToPrint[i];

            }

            // Character Mapping
            for (int i = 0; i < charLength; i++){
                for (int j = 0; j < unicodeArray.Length; j++){
                    if (unicodeArray[j] == dataToPrint[i])
                        encodedCharArray[i] = tcvn3Array[j];
                }
            }

            return encodedCharArray;
        }
    }
}
