using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace arDev
{
    public  partial class MasterK
    { 
        public sRecvMessage Parse_RecvBuffer(byte[] buffer)
        {
            sRecvMessage frame = new sRecvMessage();
            frame.Clear();
            frame.Message = string.Empty;
            if(buffer==null)
            {
                frame.Message = "null buffer";
                return frame;
            }
            frame.FullString = System.Text.Encoding.Default.GetString(buffer);
            if (buffer == null || buffer.Length < 5)
            {
                frame.Message = "No Buffer";
                errorMessage = frame.Message;
                return frame;
            }
            //buffer copy
            frame.Buffer = new byte[buffer.Length];
            buffer.CopyTo(frame.Buffer, 0);
            if ((buffer[0] != 0x06 && buffer[0] != 0x15) || buffer[buffer.Length - 1] != 0x03)
            {
                frame.Message = "No STX,ETX";
                errorMessage = frame.Message;
                return frame;
            }
            try
            {
                frame.checksum = new byte[2];
                frame.isCSError = false;// !CheckCrc(buffer);
                frame.Device = System.Text.Encoding.Default.GetString(buffer, 1, 2);
                frame.Command = (char)buffer[3];
                frame.CmdType = System.Text.Encoding.Default.GetString(buffer, 4, 2);
                //쓰기명령은 데이터가 없다.
                if (frame.Command == 'W')
                {
                    frame.BlockCount = 0;
                    frame.DataLen = 0;
                    frame.Data = null;
                }
                else
                {
                    if (!frame.isNAK)
                    {
                        frame.BlockCount = Convert.ToInt32(System.Text.Encoding.Default.GetString(buffer, 6, 2), 16);
                        frame.DataLen = Convert.ToInt32(System.Text.Encoding.Default.GetString(buffer, 8, 2), 16);
                        int stringDataLen = frame.BlockCount * frame.DataLen * 2;
                        if (frame.FullString.Length < stringDataLen + 10)
                        {
                            frame.BlockCount = 0;
                            frame.Data = string.Empty;
                            errorMessage = "Frame length Error:" + frame.FullString;
                        }
                        else
                        {
                            frame.Data = frame.FullString.Substring(10, stringDataLen); //, 10, DataBufferLen);
                        }
                    }
                }  
            } catch(Exception ex)   //180706
            {
                frame.BlockCount = 0;
                errorMessage = ex.Message;
            }
             
            if (frame.isError && errorMessage == "") errorMessage = "Recvbuffer Has Error";
            return frame;
        }
        public sSendMessage Parse_SendBuffer(byte[] buffer)
        {
            sSendMessage msg = new sSendMessage();
            msg.Clear();
            msg.Message = string.Empty;
            if (buffer == null || buffer.Length < 5)
            {
                msg.Message = "No Buffer";
                errorMessage = msg.Message;
                return msg;
            }
            //buffer copy
            msg.Buffer = new byte[buffer.Length];
            msg.Strbuffer = System.Text.Encoding.Default.GetString(buffer);
            buffer.CopyTo(msg.Buffer, 0);
            if ((buffer[0] != wSTX) || buffer[buffer.Length - 1] != wETX)
            {
                msg.Message = "No STX,ETX";
                errorMessage = msg.Message;
                return msg;
            }
            msg.checksum = new byte[2];
            msg.isCSError = false;// !CheckCrc(buffer);
            msg.Device = System.Text.Encoding.Default.GetString(buffer, 1, 2);
            msg.Command = (char)buffer[3];
            if (msg.Command == 'R')
            {
                msg.CmdType = msg.Strbuffer.Substring(4, 2);
                msg.DeviceLength = int.Parse(msg.Strbuffer.Substring( 6, 2));
                msg.VarName = msg.Strbuffer.Substring( 8, msg.DeviceLength);
                msg.DataLen = int.Parse(msg.Strbuffer.Substring( 8 + msg.DeviceLength, 2));
            } else if (msg.Command == 'W')
            {
                msg.CmdType = System.Text.Encoding.Default.GetString(buffer, 4, 2);
                if(msg.CmdType == "SB")
                {
                    //블록수가 없다.
                    msg.NumberofBlock = 0;
                    msg.DeviceLength = int.Parse(msg.Strbuffer.Substring(6, 2));
                    msg.VarName = msg.Strbuffer.Substring(8, msg.DeviceLength);
                    msg.DataLen = Convert.ToByte(msg.Strbuffer.Substring(8 + msg.DeviceLength, 2),16);
                    int remain = msg.Strbuffer.Length - 2 - 10 - msg.DeviceLength+1;
                    msg.Data = msg.Strbuffer.Substring(10 + msg.DeviceLength, remain);
                }
                else
                {
                    msg.NumberofBlock = int.Parse(msg.Strbuffer.Substring(6, 2));
                    msg.DeviceLength = int.Parse(msg.Strbuffer.Substring(8, 2));
                    msg.VarName = msg.Strbuffer.Substring(10, msg.DeviceLength);
                    msg.Data = msg.Strbuffer.Substring(10 + msg.DeviceLength, 2);
                    msg.DataLen = (int)(msg.Data.Length / 2.0);
                }
                
            }
            return msg;
        }
        /// 
        /// 수신된 데이터를 분석하고 관련 메세지를 생성합니다.
        /// 
        /// 
        /// 
        [Description("")]
        protected void Run_RelayPortData(ref sRecvMessage message)
        {
            if (message.isNAK) return; //req nak process
            if (message.Command == 'R')
            {
                if (message.CmdType == "SB")
                {
                    var Port = lastSendMessage.VarName.Substring(1, 1);
                    var DataType = lastSendMessage.VarName.Substring(2, 1);
                    //int DataLen = 0;
                    //if (DataType == "W") DataLen = 16;
                    switch (Port)
                    {
                        case "P": //relay
                            //들어온값이 16진수 문자형태이므로 숫자로 변경
                            var InBufferStrH = message.Data.Substring(0, 8);
                            var InBufferStrL = message.Data.Substring(8, 8);
                            var OtBufferStrH = message.Data.Substring(16, 8);
                            var OtBufferStrL = message.Data.Substring(24, 8);
                            Int32 numvalueHI = Convert.ToInt32(InBufferStrL, 16);
                            Int32 numvalueLI = Convert.ToInt32(InBufferStrH, 16);
                            Int32 numvalueHO = Convert.ToInt32(OtBufferStrL, 16);
                            Int32 numvalueLO = Convert.ToInt32(OtBufferStrH, 16);
                            var bufHI = BitConverter.GetBytes(numvalueHI).ToArray();
                            var bufLI = BitConverter.GetBytes(numvalueLI).ToArray();
                            var bufHO = BitConverter.GetBytes(numvalueHO).ToArray();
                            var bufLO = BitConverter.GetBytes(numvalueLO).ToArray();
                            System.Collections.BitArray b = new System.Collections.BitArray(new byte[] { bufLI[2], bufLI[3], bufLI[0], bufLI[1] });
                            for (int i = 0; i < b.Length; i++)
                            {
                                this._valueI[i] = b.Get(i);
                                if (OldvalueI[i] != this._valueI[i])
                                {
                                    try
                                    {
                                        if (IOValueChanged != null)
                                            IOValueChanged(this, new IOValueEventArgs(eIOPINDIR.INPUT, i, OldvalueI[i], _valueI[i]));
                                    }
                                    catch (Exception ex)
                                    {
                                        if (IOErrorMessage != null)
                                            IOErrorMessage(this, new MessageEventArgs(true, ex.Message));
                                    }
                                    this.OldvalueI[i] = this._valueI[i];
                                }
                            }
                            System.Collections.BitArray bO = new System.Collections.BitArray(new byte[] { bufLO[2], bufLO[3], bufLO[0], bufLO[1] });
                            for (int i = 0; i < bO.Length; i++)
                            {
                                this._valueO[i] = bO.Get(i);
                                if (OldvalueO[i] != this._valueO[i])
                                {
                                    try
                                    {
                                        if (IOValueChanged != null)
                                            IOValueChanged(this, new IOValueEventArgs(eIOPINDIR.OUTPUT, i, OldvalueO[i], _valueO[i]));
                                    }
                                    catch (Exception ex)
                                    {
                                        if (IOErrorMessage != null)
                                            IOErrorMessage(this, new MessageEventArgs(true, ex.Message));
                                    }
                                    this.OldvalueO[i] = this._valueO[i];
                                }
                            }
                            break;
                    }
                }
            }
        }
    }
}