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

namespace skyscraper5.Skyscraper.Text.Encodings
{
    [SkyscraperEncoding("dvb-iso-6937")]
    class dvb_iso_6937 : SkyscraperBaseEncoding8
    {
        protected override char[] Decrypt(byte[] preprocessed)
        {
            StringBuilder resultBuilder = new StringBuilder();
            for (int i = 0; i < preprocessed.Length; i++)
            {
                if (preprocessed[i] <= 0x7e)
                {
                    AsciiTable.GetAsciiChar(preprocessed[i], resultBuilder);
                    continue;
                }
                switch (preprocessed[i])
                {
                    case 0x7f: break;
                    case 0xa0: resultBuilder.Append('\u00a0'); break;
                    case 0xa1: resultBuilder.Append('¡'); break;
                    case 0xa2: resultBuilder.Append('¢'); break;
                    case 0xa3: resultBuilder.Append('£'); break;
                    case 0xa4: resultBuilder.Append('$'); break;
                    case 0xa5: resultBuilder.Append('¥'); break;
                    case 0xa6: resultBuilder.Append('#'); break;
                    case 0xa7: resultBuilder.Append('§'); break;
                    case 0xa8: resultBuilder.Append('¤'); break;
                    case 0xa9: resultBuilder.Append('‘'); break;
                    case 0xaa: resultBuilder.Append('“'); break;
                    case 0xab: resultBuilder.Append('«'); break;
                    case 0xac: resultBuilder.Append('←'); break;
                    case 0xad: resultBuilder.Append('↑'); break;
                    case 0xae: resultBuilder.Append('→'); break;
                    case 0xaf: resultBuilder.Append('↓'); break;
                    case 0xb0: resultBuilder.Append('°'); break;
                    case 0xb1: resultBuilder.Append('¡'); break;
                    case 0xb2: resultBuilder.Append('²'); break;
                    case 0xb3: resultBuilder.Append('³'); break;
                    case 0xb4: resultBuilder.Append('×'); break;
                    case 0xb5: resultBuilder.Append('µ'); break;
                    case 0xb6: resultBuilder.Append('¶'); break;
                    case 0xb7: resultBuilder.Append('·'); break;
                    case 0xb8: resultBuilder.Append('÷'); break;
                    case 0xb9: resultBuilder.Append('’'); break;
                    case 0xba: resultBuilder.Append('”'); break;
                    case 0xbb: resultBuilder.Append('»'); break;
                    case 0xbc: resultBuilder.Append('¼'); break;
                    case 0xbd: resultBuilder.Append('½'); break;
                    case 0xbe: resultBuilder.Append('¾'); break;
                    case 0xbf: resultBuilder.Append('¿'); break;
                    case 0xc0: break;
                    case 0xc1:
                        i++;
                        int j = preprocessed.Length;
                        if (i == j)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('À'); break;
                            case 0x45: resultBuilder.Append('È'); break;
                            case 0x49: resultBuilder.Append('Ì'); break;
                            case 0x4f: resultBuilder.Append('Ò'); break;
                            case 0x55: resultBuilder.Append('Ù'); break;
                            case 0x61: resultBuilder.Append('à'); break;
                            case 0x65: resultBuilder.Append('è'); break;
                            case 0x69: resultBuilder.Append('ì'); break;
                            case 0x6f: resultBuilder.Append('ò'); break;
                            case 0x75: resultBuilder.Append('ù'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc2:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Á'); break;
                            case 0x43: resultBuilder.Append('Ć'); break;
                            case 0x45: resultBuilder.Append('É'); break;
                            case 0x49: resultBuilder.Append('Í'); break;
                            case 0x4c: resultBuilder.Append('Ĺ'); break;
                            case 0x4e: resultBuilder.Append('Ń'); break;
                            case 0x4f: resultBuilder.Append('Ó'); break;
                            case 0x52: resultBuilder.Append('Ŕ'); break;
                            case 0x53: resultBuilder.Append('Ś'); break;
                            case 0x55: resultBuilder.Append('Ú'); break;
                            case 0x59: resultBuilder.Append('Ý'); break;
                            case 0x5a: resultBuilder.Append('Ź'); break;
                            case 0x61: resultBuilder.Append('á'); break;
                            case 0x63: resultBuilder.Append('ć'); break;
                            case 0x65: resultBuilder.Append('é'); break;
                            case 0x67: resultBuilder.Append('ģ'); break;
                            case 0x69: resultBuilder.Append('í'); break;
                            case 0x6c: resultBuilder.Append('ĺ'); break;
                            case 0x6e: resultBuilder.Append('ń'); break;
                            case 0x6f: resultBuilder.Append('ó'); break;
                            case 0x72: resultBuilder.Append('ŕ'); break;
                            case 0x73: resultBuilder.Append('ś'); break;
                            case 0x75: resultBuilder.Append('ú'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc3:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Â'); break;
                            case 0x43: resultBuilder.Append('Ĉ'); break;
                            case 0x45: resultBuilder.Append('Ê'); break;
                            case 0x47: resultBuilder.Append('Ĝ'); break;
                            case 0x48: resultBuilder.Append('Ĥ'); break;
                            case 0x49: resultBuilder.Append('Î'); break;
                            case 0x4a: resultBuilder.Append('Ĵ'); break;
                            case 0x4f: resultBuilder.Append('Ô'); break;
                            case 0x53: resultBuilder.Append('Ŝ'); break;
                            case 0x55: resultBuilder.Append('Û'); break;
                            case 0x57: resultBuilder.Append('Ŵ'); break;
                            case 0x59: resultBuilder.Append('Ŷ'); break;
                            case 0x61: resultBuilder.Append('â'); break;
                            case 0x63: resultBuilder.Append('ĉ'); break;
                            case 0x65: resultBuilder.Append('ê'); break;
                            case 0x67: resultBuilder.Append('ĝ'); break;
                            case 0x68: resultBuilder.Append('ĥ'); break;
                            case 0x69: resultBuilder.Append('î'); break;
                            case 0x6a: resultBuilder.Append('ĵ'); break;
                            case 0x6f: resultBuilder.Append('ô'); break;
                            case 0x73: resultBuilder.Append('ŝ'); break;
                            case 0x75: resultBuilder.Append('û'); break;
                            case 0x77: resultBuilder.Append('ŵ'); break;
                            case 0x79: resultBuilder.Append('ŷ'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc4:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Ã'); break;
                            case 0x49: resultBuilder.Append('Ĩ'); break;
                            case 0x4e: resultBuilder.Append('Ñ'); break;
                            case 0x4f: resultBuilder.Append('Õ'); break;
                            case 0x55: resultBuilder.Append('Ũ'); break;
                            case 0x61: resultBuilder.Append('ã'); break;
                            case 0x69: resultBuilder.Append('ĩ'); break;
                            case 0x6e: resultBuilder.Append('ñ'); break;
                            case 0x6f: resultBuilder.Append('õ'); break;
                            case 0x75: resultBuilder.Append('ũ'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc5:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Ā'); break;
                            case 0x45: resultBuilder.Append('Ē'); break;
                            case 0x49: resultBuilder.Append('Ī'); break;
                            case 0x4f: resultBuilder.Append('Ō'); break;
                            case 0x55: resultBuilder.Append('Ū'); break;
                            case 0x61: resultBuilder.Append('ā'); break;
                            case 0x65: resultBuilder.Append('ē'); break;
                            case 0x69: resultBuilder.Append('ī'); break;
                            case 0x6f: resultBuilder.Append('ō'); break;
                            case 0x75: resultBuilder.Append('ū'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc6:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Ă'); break;
                            case 0x47: resultBuilder.Append('Ğ'); break;
                            case 0x55: resultBuilder.Append('Ŭ'); break;
                            case 0x61: resultBuilder.Append('ă'); break;
                            case 0x67: resultBuilder.Append('ğ'); break;
                            case 0x75: resultBuilder.Append('ŭ'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc7:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x43: resultBuilder.Append('Ċ'); break;
                            case 0x45: resultBuilder.Append('Ė'); break;
                            case 0x47: resultBuilder.Append('Ġ'); break;
                            case 0x49: resultBuilder.Append('İ'); break;
                            case 0x5a: resultBuilder.Append('Ż'); break;
                            case 0x63: resultBuilder.Append('ċ'); break;
                            case 0x65: resultBuilder.Append('ė'); break;
                            case 0x67: resultBuilder.Append('ġ'); break;
                            case 0x7a: resultBuilder.Append('ż'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc8:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Ä'); break;
                            case 0x45: resultBuilder.Append('Ë'); break;
                            case 0x49: resultBuilder.Append('Ï'); break;
                            case 0x4f: resultBuilder.Append('Ö'); break;
                            case 0x55: resultBuilder.Append('Ü'); break;
                            case 0x59: resultBuilder.Append('Ÿ'); break;
                            case 0x61: resultBuilder.Append('ä'); break;
                            case 0x65: resultBuilder.Append('ë'); break;
                            case 0x69: resultBuilder.Append('ï'); break;
                            case 0x6f: resultBuilder.Append('ö'); break;
                            case 0x75: resultBuilder.Append('ü'); break;
                            case 0x79: resultBuilder.Append('ÿ'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xc9: break;
                    case 0xca:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Å'); break;
                            case 0x55: resultBuilder.Append('Ů'); break;
                            case 0x61: resultBuilder.Append('å'); break;
                            case 0x75: resultBuilder.Append('ů'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xcb:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x43: resultBuilder.Append('Ç'); break;
                            case 0x47: resultBuilder.Append('Ģ'); break;
                            case 0x4b: resultBuilder.Append('Ķ'); break;
                            case 0x4c: resultBuilder.Append('Ļ'); break;
                            case 0x4e: resultBuilder.Append('Ņ'); break;
                            case 0x52: resultBuilder.Append('Ŗ'); break;
                            case 0x53: resultBuilder.Append('Ş'); break;
                            case 0x54: resultBuilder.Append('Ţ'); break;
                            case 0x63: resultBuilder.Append('ç'); break;
                            case 0x6b: resultBuilder.Append('ķ'); break;
                            case 0x6c: resultBuilder.Append('ļ'); break;
                            case 0x6e: resultBuilder.Append('ņ'); break;
                            case 0x72: resultBuilder.Append('ŗ'); break;
                            case 0x73: resultBuilder.Append('ş'); break;
                            case 0x74: resultBuilder.Append('ţ'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xcc:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x30: resultBuilder.Append("0̲"); break;
                            case 0x31: resultBuilder.Append("1̲"); break;
                            case 0x32: resultBuilder.Append("2̲"); break;
                            case 0x33: resultBuilder.Append("3̲"); break;
                            case 0x34: resultBuilder.Append("4̲"); break;
                            case 0x35: resultBuilder.Append("5̲"); break;
                            case 0x36: resultBuilder.Append("6̲"); break;
                            case 0x37: resultBuilder.Append("7̲"); break;
                            case 0x38: resultBuilder.Append("8̲"); break;
                            case 0x39: resultBuilder.Append("9̲"); break;
                            case 0x61: resultBuilder.Append("a̲"); break;
                            case 0x62: resultBuilder.Append("b̲"); break;
                            case 0x63: resultBuilder.Append("c̲"); break;
                            case 0x64: resultBuilder.Append("d̲"); break;
                            case 0x65: resultBuilder.Append("e̲"); break;
                            case 0x66: resultBuilder.Append("f̲"); break;
                            case 0x67: resultBuilder.Append("g̲"); break;
                            case 0x68: resultBuilder.Append("h̲"); break;
                            case 0x69: resultBuilder.Append("i̲"); break;
                            case 0x6a: resultBuilder.Append("j̲"); break;
                            case 0x6b: resultBuilder.Append("k̲"); break;
                            case 0x6c: resultBuilder.Append("l̲"); break;
                            case 0x6d: resultBuilder.Append("m̲"); break;
                            case 0x6e: resultBuilder.Append("n̲"); break;
                            case 0x6f: resultBuilder.Append("o̲"); break;
                            case 0x70: resultBuilder.Append("p̲"); break;
                            case 0x71: resultBuilder.Append("q̲"); break;
                            case 0x72: resultBuilder.Append("r̲"); break;
                            case 0x73: resultBuilder.Append("s̲"); break;
                            case 0x74: resultBuilder.Append("t̲"); break;
                            case 0x75: resultBuilder.Append("u̲"); break;
                            case 0x76: resultBuilder.Append("v̲"); break;
                            case 0x77: resultBuilder.Append("w̲"); break;
                            case 0x78: resultBuilder.Append("x̲"); break;
                            case 0x79: resultBuilder.Append("y̲"); break;
                            case 0x7a: resultBuilder.Append("z̲"); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xcd:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x4f: resultBuilder.Append('Ő'); break;
                            case 0x55: resultBuilder.Append('Ű'); break;
                            case 0x6f: resultBuilder.Append('ő'); break;
                            case 0x75: resultBuilder.Append('ű'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xce:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch(preprocessed[i])
                        {
                            case 0x41: resultBuilder.Append('Ą'); break;
                            case 0x45: resultBuilder.Append('Ę'); break;
                            case 0x49: resultBuilder.Append('Į'); break;
                            case 0x55: resultBuilder.Append('Ų'); break;
                            case 0x61: resultBuilder.Append('ą'); break;
                            case 0x65: resultBuilder.Append('ę'); break;
                            case 0x69: resultBuilder.Append('į'); break;
                            case 0x75: resultBuilder.Append('ų'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xcf:
                        i++;
                        if (i == preprocessed.Length)
                            break;
                        switch (preprocessed[i])
                        {
                            case 0x43: resultBuilder.Append('Č'); break;
                            case 0x44: resultBuilder.Append('Ď'); break;
                            case 0x45: resultBuilder.Append('Ě'); break;
                            case 0x4c: resultBuilder.Append('Ľ'); break;
                            case 0x4e: resultBuilder.Append('Ň'); break;
                            case 0x52: resultBuilder.Append('Ř'); break;
                            case 0x53: resultBuilder.Append('Š'); break;
                            case 0x54: resultBuilder.Append('Ť'); break;
                            case 0x5a: resultBuilder.Append('Ž'); break;
                            case 0x63: resultBuilder.Append('č'); break;
                            case 0x64: resultBuilder.Append('d'); break;
                            case 0x65: resultBuilder.Append('ě'); break;
                            case 0x6c: resultBuilder.Append('ľ'); break;
                            case 0x6e: resultBuilder.Append('ň'); break;
                            case 0x72: resultBuilder.Append('ř'); break;
                            case 0x73: resultBuilder.Append('š'); break;
                            case 0x74: resultBuilder.Append('ť'); break;
                            case 0x7a: resultBuilder.Append('ž'); break;
                            default:
                                i--;
                                break;
                        }
                        break;
                    case 0xd0: resultBuilder.Append('―'); break;
                    case 0xd1: resultBuilder.Append('¹'); break;
                    case 0xd2: resultBuilder.Append('®'); break;
                    case 0xd3: resultBuilder.Append('©'); break;
                    case 0xd4: resultBuilder.Append('™'); break;
                    case 0xd5: resultBuilder.Append('♪'); break;
                    case 0xd6: resultBuilder.Append('¬'); break;
                    case 0xd7: resultBuilder.Append('¦'); break;
                    case 0xd8: break;
                    case 0xd9: break;
                    case 0xda: break;
                    case 0xdb: break;
                    case 0xdc: resultBuilder.Append('⅛'); break;
                    case 0xdd: resultBuilder.Append('⅜'); break;
                    case 0xde: resultBuilder.Append('⅝'); break;
                    case 0xdf: resultBuilder.Append('⅞'); break;
                    case 0xe0: resultBuilder.Append('Ω'); break;
                    case 0xe1: resultBuilder.Append('Æ'); break;
                    case 0xe2: resultBuilder.Append('Đ'); break;
                    case 0xe3: resultBuilder.Append('ª'); break;
                    case 0xe4: resultBuilder.Append('Ħ'); break;
                    case 0xe5: break;
                    case 0xe6: resultBuilder.Append('Ĳ'); break;
                    case 0xe7: resultBuilder.Append('Ŀ'); break;
                    case 0xe8: resultBuilder.Append('Ł'); break;
                    case 0xe9: resultBuilder.Append('Ø'); break;
                    case 0xea: resultBuilder.Append('Œ'); break;
                    case 0xeb: resultBuilder.Append('°'); break;
                    case 0xec: resultBuilder.Append('Þ'); break;
                    case 0xed: resultBuilder.Append('Ŧ'); break;
                    case 0xee: resultBuilder.Append('Ŋ'); break;
                    case 0xef: resultBuilder.Append('ŉ'); break;
                    case 0xf0: resultBuilder.Append('ĸ'); break;
                    case 0xf1: resultBuilder.Append('æ'); break;
                    case 0xf2: resultBuilder.Append('đ'); break;
                    case 0xf3: resultBuilder.Append('ð'); break;
                    case 0xf4: resultBuilder.Append('ħ'); break;
                    case 0xf5: resultBuilder.Append('ı'); break;
                    case 0xf6: resultBuilder.Append('ĳ'); break;
                    case 0xf7: resultBuilder.Append('ŀ'); break;
                    case 0xf8: resultBuilder.Append('ł'); break;
                    case 0xf9: resultBuilder.Append('ų'); break;
                    case 0xfa: resultBuilder.Append('œ'); break;
                    case 0xfb: resultBuilder.Append('ß'); break;
                    case 0xfc: resultBuilder.Append('þ'); break;
                    case 0xfd: resultBuilder.Append('ŧ'); break;
                    case 0xfe: resultBuilder.Append('ŋ'); break;
                    case 0xff: resultBuilder.Append('\u00ad'); break;
                    default:
                        byte m = preprocessed[i];
                        throw new NotImplementedException(String.Format("0x{0:X2}", m));
                }
            }

            return resultBuilder.ToString().ToCharArray();
        }
    }
}
