using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Collections;
using COMM;
using System.Security.Cryptography.X509Certificates;
using AR;

namespace arDev
{
    public partial class Narumi : arRS232
    {

        public bool AGVMoveSet(BunkiData opt)
        {
            return AddCommand(eAgvCmd.MoveSet, opt.ToString());
        }

        public bool AGVMoveManual(ManulOpt opt, Speed spd, Sensor ss)
        {
            var param = opt.ToString() + spd.ToString()[0] + ((int)ss).ToString();
            return AddCommand(eAgvCmd.ManualMove, param);
        }
        public bool AGVMoveRun(eRunOpt opt = eRunOpt.NotSet)
        {
            System.Text.StringBuilder sb = new StringBuilder();
            if (opt == eRunOpt.Backward) sb.Append("B");
            else if (opt == eRunOpt.Forward) sb.Append("F");
            else sb.Append("0");
            sb.Append("000");
            return AddCommand(eAgvCmd.MoveStart, sb.ToString());
        }

        public bool AGVSetSpeed(eSetSpeed item, int speed)
        {
            string cmd = "SS";
            if (item == eSetSpeed.Rotation) cmd = "SRS";
            else cmd += item.ToString()[0];
            cmd += speed.ToString("0000");
            return AddCommand(cmd);
        }
        public bool AGVMoveStop(string Reason, eStopOpt opt = eStopOpt.Stop)
        {
            System.Text.StringBuilder sb = new StringBuilder();
            if (opt == eStopOpt.MarkStop) sb.Append("MS");
            else if (opt == eStopOpt.MarkRotateLeft) sb.Append("TL");
            else if (opt == eStopOpt.MarkRotateRight) sb.Append("TR");
            else if (opt == eStopOpt.MarkChangeDirection) sb.Append("BS");
            else sb.Append("0S");
            sb.Append("00");
            sb.Append("0000");   //재기동시간
            //if (opt == eStopOpt.MarkStop)
            //    VAR.BOOL[eVarBool.NEXTSTOP_MARK] = true;

            //동작중이면 이 멈춤 명령을 기록으로 남긴다 230116
            if (this.system1.agv_run)
                RaiseMessage(MessageType.Normal, $"stop command from {Reason}");
            return AddCommand(eAgvCmd.MoveStop, sb.ToString());
        }
        public bool AGVCommand(string cmd, string data)
        {
            return AddCommand(cmd + data);
        }

        public bool LiftControl(LiftCommand cmd)
        {
            return AddCommand(eAgvCmd.LiftControl, cmd.ToString());
        }
        public bool AGVCharge(int chargetID, bool on, int waittime = 3)
        {
            if (on)
                return AddCommand(eAgvCmd.ChargeOn, chargetID.ToString("0000"));
            else
                return AddCommand(eAgvCmd.ChargeOf, chargetID.ToString("0000"));
        }
        public bool SetBackturnTime(int time)
        {
            return AddCommand(eAgvCmd.BackTrunResumeTime, time.ToString("0000"));
        }
        public bool SetGateOutOffTime(int time)
        {
            return AddCommand(eAgvCmd.GateoutTime, time.ToString("0000"));
        }

        public bool TurnGDSCenterScope(UInt16 time)
        {
            if (time > 2000) time = 2000;
            return AddCommand(eAgvCmd.TurnGDSCenterScope, time.ToString("0000"));
        }
        public bool AGVMoveLeft180Turn()
        {
            return AddCommand(eAgvCmd.TurnLeft);
        }
        public bool AGVMoveRight180Turn()
        {
            return AddCommand(eAgvCmd.TurnRight);
        }
        public bool AGVMoveBack180Turn(bool leftTurn)
        {
            var dir = leftTurn ? "L" : "R";
            return AddCommand(eAgvCmd.BackAndTurn, dir);
        }



        public bool AGVErrorReset()
        {
            return AddCommand(eAgvCmd.ErrorReset, "FFFF");
        }
        public bool AGVTowerLamp(bool on)
        {
            return AddCommand(eAgvCmd.TowerLamp, (on ? "I" : "O"));
        }
        public bool AGVSetAddress(int value)
        {
            return AddCommand($"SAD{value:0000}");
        }
        public bool AGVSetPanID(string value)
        {
            value = value.PadLeft(4, '0');
            return AddCommand($"SPN{value}");
        }
        public bool AGVSetChannel(string value)
        {
            value = value.PadLeft(4, '0');
            return AddCommand($"SCH{value}");
        }
        //public bool AGVGateOutTimer(int value)
        //{
        //    return AddCommand($"SGT{value:0000}");
        //}
        /// <summary>
        /// 정지감속주기 및 상수
        /// </summary>
        /// <returns></returns>
        public bool AGVSetStopAcc(int interval, int value)
        {
            var cmds = new string[] {
                $"SSK{interval:0000}",
                $"SCK{value:0000}"
            };
            return AddCommand(cmds);
        }

        public bool AGVSetTagReinputTime(int value)
        {
            return AddCommand($"STT{value:0000}");
        }
        public bool AGVSetPID(eSetPIDSpeed speed, int P, int I, int D)
        {
            var cmd = "S";
            var cmd2 = "";
            if (speed == eSetPIDSpeed.High) cmd2 = "K";
            else if (speed == eSetPIDSpeed.Middle) cmd2 = "M";
            else if (speed == eSetPIDSpeed.Low) cmd2 = "L";
            else if (speed == eSetPIDSpeed.Stop) cmd2 = "S";

            var cmds = new string[] {
                $"{cmd}P{cmd2}{P:0000}",
                $"{cmd}I{cmd2}{I:0000}",
                $"{cmd}D{cmd2}{D:0000}",
            };
            return AddCommand(cmds);
        }


        protected bool AddCommand(params string[] cmds)
        {
            bool ret = true;
            ACKData = string.Empty;     //회신값 제거
            foreach (var cmdline in cmds)
            {
                var fullcmd = MakeCheckSum(cmdline);
                //commandQueue.Enqueue(fullcmd);
                if (WriteData(fullcmd) == false) ret = false;
                System.Threading.Thread.Sleep(1);
            }
            return ret;
        }


        protected bool AddCommand(eAgvCmd command, BunkiData param)
        {
            return AddCommand(command, param.ToString());
        }

        /// <summary>
        /// CBR커맨드를 사용하여 옵션값을 전송 합니다
        /// 11.분기명령 = CBR
        /// </summary>
        /// <param name="param"></param>
        /// <param name="Repeat"></param>
        protected bool AddCommand(BunkiData param)
        {
            return AddCommand(eAgvCmd.MoveSet, param.ToString());
        }

        protected bool AddCommand(eAgvCmd command, string param = "")
        {
            string cmdString;
            bool retval = false;
            switch (command)
            {
                case eAgvCmd.ErrorReset:
                    cmdString = $"SFR{param}";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.TowerLamp:
                    cmdString = $"CBZ" + $"0299{param}0000";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.MoveStop:
                    cmdString = $"CST{param}";
                    system1.agv_run_manual = false;
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.MoveStart:
                    cmdString = $"CRN{param}";
                    retval = AddCommand(cmdString);
                    break;

                case eAgvCmd.ChargeOf:
                    cmdString = $"CBT{param}O0003"; ///0003=충전대기시간
                    retval = AddCommand(cmdString);
                    RaiseMessage(arRS232.MessageType.Normal, "충전취소전송");
                    break;
                case eAgvCmd.ChargeOn:
                    cmdString = $"CBT{param}I0003"; ///0003=충전대기시간
                    retval = AddCommand(cmdString);
                    RaiseMessage(arRS232.MessageType.Normal, "충전명령전송");
                    break;

                case eAgvCmd.TurnLeft:
                    cmdString = $"CTL0000";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.TurnRight:
                    cmdString = $"CTR0000";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.BackAndTurn:
                    if (param.isEmpty()) param = "L";
                    cmdString = $"CTB000{param}";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.CallCancle:
                    cmdString = $"CCL0{param}010000";
                    retval = AddCommand(cmdString);
                    break;


                case eAgvCmd.MoveSet:
                    cmdString = $"CBR{param}";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.ManualMove:
                    system1.agv_run_manual = true;
                    cmdString = $"CRT{param}";
                    retval = AddCommand(cmdString);
                    break;

                case eAgvCmd.LiftControl:
                    cmdString = "CLF" + param.PadRight(6, '0');
                    retval = AddCommand(cmdString);
                    break;

                case eAgvCmd.CPUReset:
                    cmdString = "CRS0000";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.TurnGDSCenterScope:
                    if (param.isEmpty()) param = "1000";
                    cmdString = "SGS{param}";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.BackTrunResumeTime:
                    cmdString = $"SST{param}";
                    retval = AddCommand(cmdString);
                    break;
                case eAgvCmd.GateoutTime:
                    cmdString = $"SGT{param}";
                    retval = AddCommand(cmdString);
                    break;
            }
            return retval;
        }

    }


}
