using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace ExWeb
{
    public partial class Mod_Inline : Mod
    {
        static int[] CharClass = new int[]
        {
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 00 000 
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 10 016
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 20 032
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 30 048
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 40 064
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 50 080
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 60 096
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 70 112
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 80 128
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 90 144
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // A0 160
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // B0 176
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // C0 192
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // D0 208
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // E0 224
            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1   // F0 240
        };
        static bool Show16BitChars = false;
        static bool Show8BitChars = true;
        static bool ShowIBMchars = false;

        public static string ToHex1(int b)
        {
            string HexChars = "0123456789abcdef";
            return HexChars[b].ToString();
        }
        public static string ToHex(byte b)
        {
            return ToHex1(b / 16) + ToHex1(b % 16);
        }
        public static string ToHex(int b)
        {
            return ToHex((byte)(b / 256)) + ToHex((byte)(b % 256));
        }
        public static string ToHex(string s)
        {
            string HexChars = "";
            for (int i = 0; i < s.Length; i++)
            {
                HexChars += "0x" + ToHex((byte)s[i]) + " ";
            }
            return HexChars;
        }
        private static byte[] GetBuffer(string s)
        {
            byte[] buffer = new byte[s.Length * 2];
            for (int i = 0; i < s.Length; i++)
            {
                int b;
                try
                {
                    b = char.ConvertToUtf32(s, i);
                }
                catch
                {
                    b = 65635;
                }
                buffer[2 * i] = (byte)(b / 256);
                buffer[2 * i + 1] = (byte)(b % 256);
            }
            return buffer;
        }
        public static string ToChar(int b)
        {
            if (b < 32) return (ShowIBMchars ? "ɚ" + ToHex1(b) + ";" : "·");
            else return ((char)b).ToString();
        }
        public static string ToUtf8(byte[] b)
        {
            if (((int)b[0] * 256 + (int)b[1]) < 32) return (ShowIBMchars ? "ɚ" + ToHex1((char)b[1]) + ";" : "·");
            else return (new UTF8Encoding()).GetString(b);
        }
        public static string DumpText(string Text)
        {
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Text);
            return Dump(buffer);
        }
        public static string Dump(string FilePathAbsolute)
        {
            FileInfo fi = new FileInfo(FilePathAbsolute);
            int FileLength = (int)(fi.Length % 65536);
            BinaryReader binReader = new BinaryReader(File.Open(FilePathAbsolute, FileMode.Open, FileAccess.Read));
            byte[] buffer = new byte[FileLength];
            int ReadBytes = binReader.Read(buffer, 0, FileLength);
            binReader.Close();
            return Dump(buffer);
        }
        public static string Highlight(string Text, bool HighlightControls, bool HighlightForeign)
        {
            if (HighlightControls) return "<span class='HexCtrl'>" + Text + "</span>";
            else if (HighlightForeign) return "<span class='Hex8'>" + Text + "</span>";
            else return Text;
        }
        public static string Highlight(string Text, byte ToDisplay)
        {
            bool HighlightControls = false;
            bool HighlightForeign = false;
            if (ToDisplay < 32) HighlightControls = true;
            if (ToDisplay > 127) HighlightForeign = true;
            return Highlight(Text, HighlightControls, HighlightForeign);
        }
        public static string Dump(byte[] b)
        {
            string s = "";
            int PageCount = b.Length / 256; if (b.Length % 256 != 0) PageCount++;
            if (PageCount > 16) PageCount = 16;
            for (int p = 0; p < PageCount; p++)
            {
                s += "<span class='HexContent'>" + ToHex((byte)p) + "</span><span class='HexCaption'> 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f" + (Show8BitChars ? "  0123456789abcdef" : "") + (Show16BitChars ? "  01234567" : "") + "</span>\r\n";
                for (int r = 0; r < 16; r++)
                {
                    string prefix = "<span class='HexCaption'>" + ToHex1(r) + "0</span> ";
                    string line_hex = "";
                    string line_char = "";
                    string line_char2 = "";
                    byte[] line_char20 = { 0, 0 };
                    for (int c = 0; c < 16; c++)
                    {
                        int index = p * 256 + r * 16 + c;
                        if (index == b.Length)
                        {
                            line_hex = line_hex.PadRight(16 * 3, ' ');
                            line_char = line_char + "".PadRight(16 - c, ' ');
                            s += prefix + line_hex + (Show8BitChars ? " " + Untag(line_char) : "") + (Show16BitChars ? "  " + Untag(line_char2) : "") + "\r\n";
                            goto for_end;
                        }
                        byte ToDisplay = b[index];
                        string strHex = ToHex(ToDisplay);
                        string strChar = ToChar(ToDisplay);
                        line_hex += Highlight(strHex, ToDisplay) + " ";
                        line_char += Highlight(Untag(strChar), ToDisplay);
                        line_char20[index % 2] = ToDisplay;
                        if (index % 2 == 1)
                        {
                            line_char2 += Untag(ToUtf8(line_char20));
                        }
                    }
                    s += prefix + line_hex + (Show8BitChars ? " " + line_char : "") + (Show16BitChars ? "  " + line_char2 : "") + "\r\n";
                }
                s += "\r\n";
            }
        for_end:
            return s;
        }
    }
}