using System;
using System.Text;
using DotNetty.Buffers;
namespace dotNetty_kcp
{
    /// 
    /// Computes a CRC32 checksum.
    /// 
    /// Based on 
    public static class Crc32
    {
        readonly static uint[] Table = CreateTable();
        static Crc32()
        {
        }
//        /// 
//        /// Compute the checksum of a UTF8 text.
//        /// 
//        /// Text to calculate
//        /// Checksum
//        public static int ComputeChecksum(string text)
//        {
//            return ComputeChecksum(text, Encoding.UTF8);
//        }
//
//        /// 
//        /// Compute the checksum of a text using a specific encoding.
//        /// 
//        /// Text to calculate
//        /// Text encoding
//        /// Checksum
//        public static int ComputeChecksum(string text, Encoding encoding)
//        {
//            if (string.IsNullOrEmpty(text)) return 0;
//            byte[] bytes = encoding.GetBytes(text);
//            return ComputeChecksum(bytes);
//        }
        /// 
        /// Compute the checksum of a binary buffer.
        /// 
        /// Buffer to calculate
        /// 
        public static int ComputeChecksum(sbyte[] bytes)
        {
            uint crc = 0xffffffff;
            for (int i = 0; i < bytes.Length; i++)
            {
                byte index = (byte) (((crc) & 0xff) ^ bytes[i]);
                crc = (crc >> 8) ^ Table[index];
            }
            return unchecked((int) ~crc);
        }
        /// 
        /// Compute the checksum of a binary buffer.
        /// 
        /// Buffer to calculate
        /// 
        public static uint ComputeChecksum(IByteBuffer byteBuffer,int offset,int lenth)
        {
            var crc = 0xffffffff;
            lenth += offset;
            for (var i = offset; i < lenth; i++)
            {
                var index = (byte) (((crc) & 0xff) ^ byteBuffer.GetByte(i));
                crc = (crc >> 8) ^ Table[index];
            }
            return ~crc;
        }
        static uint[] CreateTable()
        {
            const uint poly = 0xedb88320;
            var table = new uint[256];
            uint temp = 0;
            for (uint i = 0; i < table.Length; ++i)
            {
                temp = i;
                for (int j = 8; j > 0; --j)
                {
                    if ((temp & 1) == 1)
                    {
                        temp = (uint) ((temp >> 1) ^ poly);
                    }
                    else
                    {
                        temp >>= 1;
                    }
                }
                table[i] = temp;
            }
            return table;
        }
    }
}