using PlcSiemens.O;
using PlcSiemens.Protocol.Common;
using System.Text;

namespace PlcSiemens.Protocol.ListBlocks
{
    public class DataBlockInfoDataResponse
    {
        public byte Ret { get; set; }
        public byte Size { get; set; }
        public ushort Length { get; set; }
        public byte CstB { get; set; }
        public BlockType BlkType { get; set; }
        public ushort CstW1 { get; set; }
        public ushort CstW2 { get; set; }
        public ushort CstPp { get; set; }
        public byte Unknown1 { get; set; }
        public byte BlkFlags { get; set; }
        public BlockLangType BlkLang { get; set; }
        public SubBlockType SubBlkType { get; set; }
        public ushort BlkNumber { get; set; }
        public uint LenLoadMem { get; set; }
        public byte[] BlkSec { get; set; }//[4]

        //public uint CodeTimeMs { get; set; }
        //public ushort CodeTimeDy { get; set; }
        //public uint IntfTimeMs { get; set; }
        //public ushort IntfTimeDy { get; set; }
        public System.DateTime CodeDateTime { get; set; }

        public System.DateTime IntfDateTime { get; set; }
        public ushort SbbLen { get; set; }
        public ushort AddLen { get; set; }
        public ushort LocDataLen { get; set; }
        public ushort Mc7Len { get; set; }
        public string Author { get; set; }//[8]
        public string Family { get; set; }//[8]
        public string Header { get; set; }//[8]
        public byte Version { get; set; }
        public byte Unknown2 { get; set; }
        public ushort BlkChksum { get; set; }
        public byte[] Resvd1 { get; set; }//[4]
        public byte[] Resvd2 { get; set; }//[4]

        private BlockType GetBlockType(SubBlockType subBlockType)
        {
            switch (subBlockType)
            {
                case SubBlockType.OB: return BlockType.OB;
                case SubBlockType.DB: return BlockType.DB;
                case SubBlockType.SDB: return BlockType.SDB;
                case SubBlockType.FC: return BlockType.FC;
                case SubBlockType.SFC: return BlockType.SFC;
                case SubBlockType.FB: return BlockType.FB;
                case SubBlockType.SFB: return BlockType.SFB;
                default: return 0;
            };
        }

        public void Build(ByteBuffer buffer)
        {
            Ret = buffer.PopByte();
            Size = buffer.PopByte();
            Length = buffer.PopUshort();
            CstB = buffer.PopByte();
            BlkType = (BlockType)buffer.PopByte();
            CstW1 = buffer.PopUshort();
            CstW2 = buffer.PopUshort();
            CstPp = buffer.PopUshort();
            Unknown1 = buffer.PopByte();
            BlkFlags = buffer.PopByte();
            BlkLang = (BlockLangType)buffer.PopByte();
            SubBlkType = (SubBlockType)buffer.PopByte();
            BlkType = GetBlockType(SubBlkType);//根据SunblockType

            BlkNumber = buffer.PopUshort();
            LenLoadMem = buffer.PopUint();
            BlkSec = buffer.PopBytes(4);// { get; set; }//[4]
            var codeTimeMs = buffer.PopUint();//毫秒时间
            var codeTimeDy = buffer.PopUshort();//天数 开始时间1984/1/1
            var intfTimeMs = buffer.PopUint();//毫秒时间
            var intfTimeDy = buffer.PopUshort();//天数 开始时间1984/1/1
            System.DateTime date = new System.DateTime(1984, 1, 1);
            CodeDateTime = date.AddDays(codeTimeDy).AddMilliseconds(codeTimeMs);
            IntfDateTime = date.AddDays(intfTimeDy).AddMilliseconds(intfTimeMs);
            SbbLen = buffer.PopUshort();
            AddLen = buffer.PopUshort();
            LocDataLen = buffer.PopUshort();
            Mc7Len = buffer.PopUshort();

            var author = buffer.PopBytes(8);//{ get; set; }//[8]
            var family = buffer.PopBytes(8);//{ get; set; }//[8]
            var header = buffer.PopBytes(8);//{ get; set; }//[8]
            Author = Encoding.UTF8.GetString(author).TrimEnd('\0');
            Family = Encoding.UTF8.GetString(family).TrimEnd('\0');
            Header = Encoding.UTF8.GetString(header).TrimEnd('\0');

            Version = buffer.PopByte();
            Unknown2 = buffer.PopByte();
            BlkChksum = buffer.PopUshort();
            Resvd1 = buffer.PopBytes(4);//{ get; set; }//[4]
            Resvd2 = buffer.PopBytes(4);// { get; set; }//[4]
        }

        /// <summary>Returns a string that represents the current object.</summary>
        /// <returns>A string that represents the current object.</returns>
        //public override string ToString()
        //{
        //    return $"Block Type   : {BlkType}\r\n" +
        //           $"Block Number : {BlkNumber}\r\n" +
        //           $"Block Lang   : {BlkLang}\r\n" +
        //           $"Block Flags  : {Convert.ToString(BlkFlags, 2).PadLeft(8,'0')}\r\n" +
        //           $"MC7 Size     : {Mc7Len}\r\n" +
        //           $"Load Size    : {LenLoadMem}\r\n" +
        //           $"Local Data   : {LocDataLen}\r\n" +
        //           $"SBB Length   : {SbbLen}\r\n" +
        //           $"CheckSum     : {BlkChksum.ToString("X4")}\r\n" +
        //           $"Version      : {(Version/16.0).ToString("F1")}\r\n" +
        //           $"Code Date    : {CodeDateTime}\r\n" +
        //           $"Intf.Date    : {IntfDateTime}\r\n" +
        //           $"Author       : {Author}\r\n" +
        //           $"Family       : {Family}\r\n" +
        //           $"Header       : {Header}";
        //}
    }
}
