using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace SerialDebug
{
    public class CSendParam
    {
        private SendParamFormat _Format;
        private SendParamMode _Mode;
        private int _DelayTime;
        private readonly string _Data;
        private readonly byte[] _DataBytes = null;

        public CSendParam(SendParamFormat format, SendParamMode mode, int delayTime, byte[] data, int startIndex, int count)
        {
            _Format = format;
            _Mode = mode;
            _DelayTime = delayTime;
            _Data = string.Empty;
            if (data != null)
            {
                _DataBytes = new byte[count];
                Array.Copy(data, startIndex, _DataBytes, 0, count);

                if (Format == SendParamFormat.Hex)
                {
                    _Data = BitConverter.ToString(_DataBytes).Replace('-', ' ').TrimEnd(new char[] { ' ' });
                }
                else
                {
                    _Data = System.Text.ASCIIEncoding.Default.GetString(_DataBytes);
                }
            }
        }

        public CSendParam(SendParamFormat format, SendParamMode mode, int delayTime, string data, bool trans = true)
        {
            _Format = format;
            _Mode = mode;
            _DelayTime = delayTime;
            _Data = data;

            switch (_Format)
            {
                case SendParamFormat.ASCII:
                    {
                        byte[] bytes = System.Text.ASCIIEncoding.Default.GetBytes(_Data);
                        if (trans)
                        {

                            List<byte> list = new List<byte>();
                            for (int i = 0; i < bytes.Length; i++)
                            {
                                if (bytes[i] == (byte)'\\')
                                {
                                    if ((i + 1) >= bytes.Length)
                                    {
                                        list.Add(bytes[i]);
                                        continue;
                                    }
                                    //\r    
                                    //后一个是r
                                    if (bytes[i + 1] == (byte)'r' || bytes[i + 1] == (byte)'R')
                                    {
                                        list.Add(0x0D);
                                        i++;//跳过一个
                                    }
                                    // \n
                                    else if (bytes[i + 1] == (byte)'n' || bytes[i + 1] == (byte)'N')
                                    {
                                        list.Add(0x0A);
                                        i++;//跳过一个
                                    }
                                    //\t 09
                                    else if (bytes[i + 1] == (byte)'t' || bytes[i + 1] == (byte)'T')
                                    {
                                        list.Add(0x09);
                                        i++;//跳过一个
                                    }
                                    //\v 0B
                                    else if (bytes[i + 1] == (byte)'v' || bytes[i + 1] == (byte)'V')
                                    {
                                        list.Add(0x0B);
                                        i++;//跳过一个
                                    }
                                    else if (bytes[i + 1] == (byte)'a' || bytes[i + 1] == (byte)'A')
                                    {
                                        list.Add(0x07);
                                        i++;//跳过一个
                                    }
                                    else if (bytes[i + 1] == (byte)'b' || bytes[i + 1] == (byte)'B')
                                    {
                                        list.Add(0x08);
                                        i++;//跳过一个
                                    }
                                    else if (bytes[i + 1] == (byte)'f' || bytes[i + 1] == (byte)'F')
                                    {
                                        list.Add(0x0C);
                                        i++;//跳过一个
                                    }
                                    else
                                    {
                                        list.Add(bytes[i]);
                                    }
                                }
                                else
                                {
                                    list.Add(bytes[i]);
                                }
                            }
                            _DataBytes = list.ToArray();
                        }
                        else
                        {
                            _DataBytes = bytes;
                        }
                    }
                    break;
                case SendParamFormat.Hex:

                    string inputText = Regex.Replace(_Data, @"[0-9A-Fa-f]{2}", "$0 ");
                    string[] strArray = inputText.Split(new string[] { ",", " ", "0x", ",0X", "，", "(", ")" }, StringSplitOptions.RemoveEmptyEntries);


                    StringBuilder sbOut = new StringBuilder();
                    foreach (string s in strArray)
                    {
                        sbOut.AppendFormat("{0:X2} ", Convert.ToByte(s, 16));
                    }
                    _Data = sbOut.ToString().TrimEnd(' ');


                    _DataBytes = Array.ConvertAll<string, byte>(strArray, new Converter<string, byte>(HexStringToByte));

                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 十六进制字符串转十进制。
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        byte HexStringToByte(string hexStr)
        {
            return Convert.ToByte(hexStr, 16);
        }

        public SendParamFormat Format
        {
            get { return _Format; }
            set { _Format = value; }
        }

        public SendParamMode Mode
        {
            get { return _Mode; }
            set { _Mode = value; }
        }

        public int DelayTime
        {
            get { return _DelayTime; }
            set { _DelayTime = value; }
        }

        public int DataLen
        {
            get
            {
                if (_DataBytes != null)
                {
                    return _DataBytes.Length;
                }
                else
                {
                    return 0;
                }
            }
        }

        public string Data
        {
            get { return _Data; }
        }

        public string HexString
        {
            get
            {
                return string.Format("{0} ", BitConverter.ToString(_DataBytes).Replace('-', ' '));
            }
        }

        public string ASCIIString
        {
            get { return System.Text.ASCIIEncoding.Default.GetString(_DataBytes); }
        }

        public string DecString
        {
            get
            {
                StringBuilder sb = new StringBuilder();

                foreach (byte b in _DataBytes)
                {
                    sb.AppendFormat("{0} ", Convert.ToInt32(b));
                }

                return sb.ToString();
            }

        }

        public byte[] DataBytes
        {
            get
            {
                return _DataBytes;
            }
        }


        public string ParameterString
        {
            get
            {
                return string.Format("{0}:{1}:{2}", (int)_Format, (int)_Mode, _DelayTime);
            }
        }
    }


    public enum SendParamFormat : int
    {
        ASCII = 0,
        Hex = 1
    }

    public enum SendParamMode : int
    {
        //SendDelayTime = 0,// 启动后延时发送
        SendAfterLastSend = 0,//上帧发送完成后
        SendAfterReceived = 1//接收到数据帧后
    }
}
