using PlcSiemens.O;
using PlcSiemens.Protocol.Common;
using PlcSiemens.Protocol.Szl;

namespace PlcSiemens.ProtocolHandle
{
    public class SzlHandle : IPacketHandle
    {
        public SzlCmd SzlCmd { get; set; }
        public SzlRequest SzlRequestFirst { get; set; }
        public SzlRequest SzlRequestNext { get; set; }
        public SzlResponse SzlResponseFirst { get; set; }
        public SzlNextResponse SzlNextResponseNext { get; set; }

        public ResultCode ResultCode
        {
            get;
            set;
        }

        public void Handle(IIsoSender sender)
        {
            var first = true;
            byte seq = 0x00;
            bool done = false;

            do
            {
                if (first)
                {
                    SzlRequestFirst.First = true;
                    SzlRequestFirst.Seq = seq;
                    SzlRequestFirst.ID = SzlCmd.ID;
                    SzlRequestFirst.Index = SzlCmd.Index;

                    SzlResponseFirst = sender.IsoSend<SzlRequest, SzlResponse>(SzlRequestFirst);

                    if (SzlResponseFirst == null) return;

                    ResultCode = SzlResponseFirst.Data.Ret;
                    if (SzlResponseFirst.Params.Err == ResultCode.OK)
                    {
                        if (SzlResponseFirst.Data.Ret == ResultCode.OKFF)
                        {
                            done = (SzlResponseFirst.Params.Rsvd & 0x00FF) == 0;
                            seq = SzlResponseFirst.Params.Seq;
                        }
                    }
                }
                else
                {
                    SzlRequestNext = new SzlRequest();
                    SzlRequestNext.First = false;
                    SzlRequestNext.Seq = seq;
                    SzlRequestNext.ID = SzlCmd.ID;
                    SzlRequestNext.Index = SzlCmd.Index;

                    SzlNextResponseNext = sender.IsoSend<SzlRequest, SzlNextResponse>(SzlRequestNext);

                    if (SzlNextResponseNext == null) return;

                    ResultCode = SzlResponseFirst.Data.Ret;
                    if (SzlNextResponseNext.Params.Err == ResultCode.OK)
                    {
                        if (SzlNextResponseNext.Data.Ret == ResultCode.OKFF)
                        {
                            done = (SzlNextResponseNext.Params.Rsvd & 0x00FF) == 0;
                            seq = SzlNextResponseNext.Params.Seq;

                            SzlResponseFirst.Data.AddNextData(SzlNextResponseNext.Data.Data, SzlNextResponseNext.Data.DLen);
                        }
                    }
                }
                first = false;
            } while (!done && ResultCode == ResultCode.OKFF);

            if (ResultCode == ResultCode.OKFF) ResultCode = ResultCode.OK;
        }

        public SzlHandle()
        {
            ResultCode = ResultCode.Unknown;
            SzlRequestFirst = new SzlRequest();
            SzlCmd = SzlInfo.ReadSzlAll;
        }
    }
}
