//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.ComponentModel;
//using System.Threading;
//using COMM;
//using System.Runtime.Remoting.Messaging;
//using AR;

//namespace Project.Device
//{
//    public class Xbee_OLD : arDev.arRS232
//    {
//        public Xbee_OLD()
//        {

//        }

//        public string buffer = string.Empty;
//        public System.Text.StringBuilder newbuffer = new StringBuilder();
//        protected override bool CustomParser(byte[] buf, out byte[] remainBuffer)
//        {
//            //일반 kit 명령은 0x02 kit번호, kit값 0x03 
//            //상태 명령은 0x04 메세지데이터 0x05            

//            Console.WriteLine("custom parse len=" + buf.Length.ToString());

//            List<byte> sparebuffer = new List<byte>();
//            Boolean bComplete = false;
//            for (int i = 0; i < buf.Length; i++)
//            {
//                var incomByte = buf[i];
//                if (bComplete == true) sparebuffer.Add(incomByte);
//                else
//                {
//                    if (findSTX == false)
//                    {
//                        if (incomByte != 0x02)
//                        {
//                            //버리는데이터
//                        }
//                        else
//                        {
//                            findSTX = true;
//                            tempBuffer.Clear();
//                            tempBuffer.Add(incomByte);
//                        }
//                    }
//                    else
//                    {
//                        tempBuffer.Add(incomByte);

//                        if (incomByte == 0x03)
//                        {
//                            //데이터가 맞게 수신됨
//                            LastReceiveBuffer = tempBuffer.ToArray();
//                            bComplete = true;
//                            findSTX = false;
//                        }
//                        else if (tempBuffer.Count > 30)
//                        {
//                            tempBuffer.Clear();
//                            findSTX = false;
//                        }
//                    }
//                }
//            }
//            remainBuffer = sparebuffer.ToArray();
//            return bComplete;
//        }


//        public override bool ProcessRecvData(byte[] data)
//        {
//            var kitno = (char)(data[1]);
//            var kitval = (char)(data[2]);
//            NewMsgEvent(kitno, kitval);
//            return true;
//        }

//        public void NewMsgEvent(char kitNo, char kitVal)
//        {
//            //대상위치 확인
//            ePosition kitPos = ePosition.NONE;
//            if (kitNo == '9') kitPos = ePosition.QC;
//            else if (kitNo == '1') kitPos = ePosition.F1;
//            else if (kitNo == '2') kitPos = ePosition.F2;
//            else if (kitNo == '3') kitPos = ePosition.F3;
//            else if (kitNo == '4') kitPos = ePosition.F4;
//            else
//            {
//                if (kitNo == '0') return;
//                PUB.log.Add($"비허가 키트번호 무시 번호={kitNo},값={kitVal}");
//                return;
//            }

//            //if (kitNo=  'F')
//            //{
//            //    PUB.Speak("알 수 없는 키트번호 입니다");
//            //    PUB.logsys.Add($"키트번호별위치확인실패 값={kitNo}");
//            //    return;
//            //}

//            //(ePosition)int.Parse(kitNo.ToString());
//            PUB.logxbee.Add(string.Format("Xbee:newMsgEvent:{0},{1}=>{2}", kitNo, kitVal, kitPos));
//            if (PUB.CheckManualChargeMode() == false)
//            {
//                PUB.log.Add($"수동 충전 중이라 콜 기능을 취소 합니다");
//                return;
//            }

//            bool FixButton = kitPos == ePosition.NONE;
//            if (kitPos == ePosition.NONE)
//            {
//                if (kitVal == '1') kitPos = ePosition.QC;
//                else if (kitVal == '2') kitPos = ePosition.CHARGE;
//                else if (kitVal == '4') kitPos = ePosition.QC;
//                //else if (kitVal == '3') kitPos = ePosition.QA;
//                else
//                {
//                    PUB.log.Add($"AGV버튼 이벤트 실행 값:{kitVal} 취소");
//                    return;
//                }
//                kitVal = '1'; //버튼은 무조건 ON상태로 한다
//            }

//            //자동상태가 아니라면 오류처리
//            if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false || PUB.sm.Step != StateMachine.eSMStep.RUN)
//            {
//                PUB.log.AddE("'자동실행' 상태가 아니므로 콜/취소 작업을 할 수 없습니다 콜:" + kitPos.ToString() + ",값=" + kitVal.ToString());
//                PUB.Speak(Lang.자동운전상태가아닙니다);
//                return;
//            }

//            //충전기를 제외하고 '1'의 값은 호출을 원하는값이다.('0'=취소)
//            if (kitVal == '1')
//            {
//                //qA혹은 Pack 에서 해당 버튼을 눌렀을때의 처리방법
//                //if (PUB.Result.CurrentPos == ePosition.QA && kitPos == ePosition.QA)
//                //{
//                //    PUB.logsys.AddE("QA위치에서 QA버튼을 눌렀음 명령 취소함");
//                //    PUB.Speak("현재 위치는 QA 입니다.");
//                //    return;
//                //}

//                //상/하차 작업중이 아니라면 콜을 받는다
//                if (PUB.sm.RunStep != StateMachine.ERunStep.GOUP && PUB.sm.RunStep != StateMachine.ERunStep.GODOWN)
//                {
//                    //call을 받으려면 대상위 (2=QC,3,4,5,6,7)
//                    //콜을 요청하는 곳 (2=QC,3=FVI-1,4,5,6,7==FVI-5)
//                    //1번은 충전기

//                    //콜버튼으로 대상위치를 다시 결정한다.
//                    //대상번호는 콜번호에서 +2을 하면 된다.
//                    //대상번호 PK=1,QA2=2,QA1=3,QC=4
//                    //QC의경우 콜Kit번호는 2이므로, 이동대상은 +2인 4가 되어야 함
//                    //콜번호와 RFID대상번호는 2의 오차가 발생함, 현재 설치된 RFID를 모두 변경할 수 없어서 이렇게 운용함


//                    RaiseMessage(MessageType.Normal, string.Format("CALL확정 Kit={0},대상위치={1}", kitNo, kitPos));

//                    PUB.AGV.data.CallNo = int.Parse(kitNo.ToString());
//                    PUB.AGV.data.CallString = kitNo.ToString();

//                    PUB.Result.CommandKit = kitNo;
//                    PUB.Result.TargetPos = kitPos;
//                    SendToKit(kitNo, '1', (PUB.IsCanCALL() ? '1' : '0'));  //콜확정을 클라이언트에 알림

//                    PUB.Speak(kitPos.ToString() + Lang.위치로이동합니다);

//                    //상태머신을 변경한다 (충전 OFF상태로 간다, 충전상태가 아니면 바로 이동하게됨)                    
//                    //Pub.sm.ResetRunStep();
//                    //Pub.sm.setNewStep(StateMachine.eSMStep.RUN);

//                    //qa, pack 은 하차 전용이다
//                    PUB.sm.ClearRunStep();
//                    PUB.sm.SetNewRunStep(StateMachine.ERunStep.GOUP);
//                    PUB.sm.SetNewStep(StateMachine.eSMStep.RUN);
//                }
//                else if (PUB.sm.RunStep == StateMachine.ERunStep.GODOWN && VAR.BOOL[eVarBool.WAIT_COVER_DOWN] == false && VAR.BOOL[eVarBool.WAIT_COVER_UP] == false)
//                {
//                    //하차중에 받을 수 있게하자 (단 FVi1 이하일때에는 무시하자) 230710 - 김수곤
//                    if (PUB.Result.TargetPos == ePosition.QC && PUB.Result.CurrentPos < ePosition.F1)
//                    {
//                        PUB.log.Add($"하차중이지만 FVI #1 아래에 있으니 콜을 취소 합니다");
//                        SendToKit(kitNo, '0', '0');
//                        RaiseMessage(MessageType.Normal, $"QC 추가 콜이지만 위치가 #1번 이하이므로 취소 됩니다. Kit={kitNo},현재={PUB.Result.CurrentPos},대상={PUB.Result.TargetPos}");
//                    }
//                    else
//                    {
//                        RaiseMessage(MessageType.Normal, string.Format("CALL확정(추가) Kit={0},대상위치={1}", kitNo, kitPos));

//                        PUB.AGV.data.CallNo = int.Parse(kitNo.ToString());
//                        PUB.AGV.data.CallString = kitNo.ToString();

//                        PUB.Result.CommandKit = kitNo;
//                        PUB.Result.TargetPos = kitPos;

//                        SendToKit(kitNo, '1', (PUB.IsCanCALL() ? '1' : '0'));  //콜확정을 클라이언트에 알림

//                        PUB.Speak(kitPos.ToString() + Lang.위치로이동합니다);

//                        //상태머신을 변경한다 (충전 OFF상태로 간다, 충전상태가 아니면 바로 이동하게됨)                    
//                        //Pub.sm.ResetRunStep();
//                        //Pub.sm.setNewStep(StateMachine.eSMStep.RUN);

//                        //qa, pack 은 하차 전용이다
//                        PUB.sm.ClearRunStep();
//                        PUB.sm.SetNewRunStep(StateMachine.ERunStep.GOUP);
//                        PUB.sm.SetNewStep(StateMachine.eSMStep.RUN);
//                    }

//                }
//                //else if (PUB.sm.RunStep == StateMachine.ERunStep.GODOWN && PUB.Result.CurrentPos == ePosition.QA)
//                //{
//                //    RaiseMessage(MessageType.Normal, string.Format("CALL확정 Kit={0},대상위치={1}", kitNo, kitPos));

//                //    PUB.Result.CommandKit = kitNo;
//                //    PUB.Result.TargetPos = kitPos;
//                //    SendToKit(kitNo, '1');  //콜확정을 클라이언트에 알림

//                //    PUB.Speak(kitPos.ToString() + "위치로 이동 합니다");

//                //    //상태머신을 변경한다 (충전 OFF상태로 간다, 충전상태가 아니면 바로 이동하게됨)                    
//                //    //   Pub.sm.ResetRunStep();
//                //    //  Pub.sm.setNewStep(StateMachine.eSMStep.RUN);

//                //    //qa => pack 은 하차 전용이다
//                //    //QA에서 PACK이동시에는 바로 N극 멈춤 기능을 사용해도도된다.(자재가 있으며, 커버가 내려가 있으므로 느리게 동작해야함)
//                //    PUB.sm.ClearRunStep();
//                //    PUB.sm.SetNewRunStep(StateMachine.ERunStep.GODOWN);
//                //    PUB.sm.SetNewStep(StateMachine.ESMStep.RUN);

//                //    PUB.AGV.AGVMoveStop("xbee_newmsgevent", arDev.Narumi.eStopOpt.MarkStop);// (arDev.Narumi.eAgvCmd.MoveStop,.SetNextStop_Mark(true, "xbee godn,qa,pack");
//                //    PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Up);
//                //}
//                else if (PUB.Result.TargetPos == kitPos) ////현재 지정된 클라이언트가 또 눌렀다
//                {
//                    PUB.Result.TargetPos = kitPos;
//                    PUB.AGV.data.CallNo = int.Parse(kitNo.ToString());
//                    PUB.AGV.data.CallString = kitNo.ToString();

//                    //상차 대기 중이라면 커버를 자동 올려준다
//                    //이것은 QC만 가능하다
//                    //QC가 QA혹은 PACK으로 보낼때 사용함
//                    if (kitPos == ePosition.QC &&
//                        VAR.BOOL[eVarBool.FLAG_LIMITLOW] == true)
//                    {
//                        RaiseMessage(MessageType.Normal, "QC위치에서 자동으로 커버를 올립니다");
//                        //PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Up);
//                        PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.UP);
//                    }
//                    else
//                    {
//                        //커버대기상태라면 커버를 자동으로 처리해준다.
//                        if (PUB.sm.Step == StateMachine.eSMStep.RUN && (PUB.sm.RunStep == StateMachine.ERunStep.GOUP || PUB.sm.RunStep == StateMachine.ERunStep.GODOWN))
//                        {

//                            if (VAR.BOOL[eVarBool.WAIT_COVER_DOWN] == true)
//                            {
//                                //var ld = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LD);
//                                //var rd = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RD);
//                                //if (ld == false || rd == false)
//                                //{
//                                //    PUB.log.Add("사용자 콜버튼 추가 동작 - Z내림");
//                                //    PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Down);
//                                //    PUB.Speak(Lang.커버를내립니다);
//                                //}
//                            }
//                            else if (VAR.BOOL[eVarBool.WAIT_COVER_UP] == true)
//                            {
//                                //var lu = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_LU);
//                                //var ru = PUB.PLC.GetValueI(arDev.FakePLC.DIName.PINI_LIMIT_RU);

//                                //if (lu == false || ru == false)
//                                //{
//                                //    PUB.PLC.ZMot(arDev.FakePLC.ZMotDirection.Up);
//                                //    PUB.log.Add("사용자 콜버튼 추가 동작 - Z올림");
//                                //    PUB.Speak(Lang.커버를올립니다);
//                                //}
//                            }
//                            else RaiseMessage(MessageType.Normal, string.Format("이미 CALL이 확정되었습니다 No={0},Pos={1}", kitNo, kitPos));
//                        }
//                        else RaiseMessage(MessageType.Normal, string.Format("이미 CALL이 확정되었습니다 No={0},Pos={1}", kitNo, kitPos));
//                    }
//                    SendToKit(kitNo, '1', (PUB.IsCanCALL() ? '1' : '0'));  //콜확정을 클라이언트에 알림
//                }
//                else
//                {
//                    //다른대상이 이미 선택된 상태이므로 CANCEL 한다.
//                    SendToKit(kitNo, '0', (PUB.IsCanCALL() ? '1' : '0'));
//                    RaiseMessage(MessageType.Normal, string.Format("다른 CALL이 확정된 상태입니다. 요청KIT={2},확정KIT={0},위치={1}", PUB.Result.TargetPos - 2, PUB.Result.TargetPos, kitNo));
//                }
//            }
//            else if (kitVal == '0')  //캔슬버튼을 눌렀다
//            {
//                //목표번호가 캔슬버튼을 눌렀다
//                if (PUB.Result.TargetPos == kitPos)
//                {
//                    //상차가 완료되면 TargetPos 가 변경되어 ,더이상 해당 버튼으로는 취소하지 못한다
//                    PUB.AGV.data.CallNo = 0;
//                    PUB.AGV.data.CallString = "--";

//                    SendToKit(kitNo, '0', (PUB.IsCanCALL() ? '1' : '0'));
//                    RaiseMessage(MessageType.Normal, string.Format("콜 취소 Kit={0}", kitNo));
//                    if (PUB.sm.RunStep != StateMachine.ERunStep.GOHOME)
//                    {
//                        PUB.Result.CommandKit = kitNo;
//                        PUB.Result.TargetPos = ePosition.QC;
//                        PUB.sm.ClearRunStep();
//                        PUB.sm.SetNewRunStep(StateMachine.ERunStep.GOHOME);
//                        PUB.sm.SetNewStep(StateMachine.eSMStep.RUN);
//                        RaiseMessage(MessageType.Normal, string.Format("콜 취소로 인해 홈으로 이동합니다 Kit={0}", kitNo));
//                    }

//                }
//                else
//                {
//                    //다른놈이 취소 버튼을 눌렀다. ㅋㅋ
//                    //아무~ 의미 없다.
//                    SendToKit(kitNo, '0', (PUB.IsCanCALL() ? '1' : '0'));
//                    RaiseMessage(MessageType.Normal, string.Format("해당 콜취소는 유효하지 않습니다 요청KIT={0},확정KIT={1}", kitNo, PUB.Result.TargetPos - 2));
//                }
//            }
//            else if (kitVal == '2')  //BACKWORK시에만 이 값이 전송되게 한다
//            {
//                //QA 이동 명령
//                //발동조건 1. QC 위치에서 GOUP(대기 혹은 상차완료)상태일때 (일반적인경우)
//                //발동조건 2. QC 위치에서 IDLE 상태일때 (GOUP상태로 하지 않고 바로 싫어버린경우)
//                //발동조건 3. 충전중일때

//                //if (kitPos != ePosition.QC)
//                //{
//                //    RaiseMessage(MessageType.Error, $"back 버튼은 QC버튼만 사용 가능 합니다");
//                //    return;
//                //}

//                //if (kitPos == ePosition.QC && PUB.Result.CurrentPos != ePosition.QC)
//                //{
//                //    RaiseMessage(MessageType.Error, string.Format("QC의 QA버튼은 홈위치에 있어야 사용이 가능 합니다"));
//                //    return;
//                //}

//                ////명령송신은 QC로 고정한다
//                //PUB.Result.CommandKit = '2';
//                //PUB.Result.TargetPos = ePosition.QA;
//                //PUB.sm.ClearRunStep();
//                //PUB.sm.SetNewRunStep(StateMachine.ERunStep.GODOWN);
//                //PUB.sm.SetNewStep(StateMachine.ESMStep.RUN);
//                //RaiseMessage(MessageType.Normal, string.Format("후진하차 모드 대상위치={0}", ePosition.QA));
//                //PUB.logsys.AddI("QC의 QA리모콘 버튼 작업 입니다");
//            }
//        }


//        public void SendToKit(char kitNo, char Value, char enbcall)
//        {
//            List<byte> buffer = new List<byte>
//            {
//                0x02,
//                (byte)kitNo,
//                (byte)Value,
//                (byte)enbcall,
//                0x03
//            };
//            WriteData(buffer.ToArray());
//            //RaiseMessage(MessageType.Normal, $"지그비전송 {kitNo}:{Value}:{enbcall}");
//        }

//        public string GetStatusString()
//        {
//            return DateTime.Now.ToString();
//        }

//        public void SendStatus(String StatusString)
//        {

//            ////IO

//            char kitno = '0';
//            char kitval = '1';
//            if (PUB.Result.TargetPos == ePosition.F1) kitno = '1';
//            else if (PUB.Result.TargetPos == ePosition.F2) kitno = '2';
//            else if (PUB.Result.TargetPos == ePosition.F3) kitno = '3';
//            else if (PUB.Result.TargetPos == ePosition.F4) kitno = '4';
//            else if (PUB.Result.TargetPos == ePosition.QC) kitno = '9';
//            else
//            {
//                //충전기 충전하는 것으로한다
//                if (VAR.BOOL[eVarBool.FLAG_CHARGEONA] == false && VAR.BOOL[eVarBool.FLAG_CHARGEONM] == false)
//                    kitval = '0';
//            }

//            //콜가능여부도 전송한다
//            var enbcall = PUB.IsCanCALL() ? '1' : '0';
//            SendToKit(kitno, kitval, enbcall);


//        }
//    }
//}
