using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Project.StateMachine;
using COMM;
using AR;

namespace Project
{
    public partial class fMain
    {
        DateTime tm_gocharge_command = DateTime.Now;
        public Boolean _SM_RUN_GOCHARGE(bool isFirst, TimeSpan stepTime)
        {
            if (runStepisFirst)
            {
                //홈을 찾도록 항상 위치를 지워버리자
                PUB.Result.CurrentPos = ePosition.NONE;
                PUB.Result.CurrentPos = ePosition.NONE;
            }

            //HW 연결오류
            if (PUB.AGV.IsOpen == false)
            {
                PUB.Result.SetResultMessage(eResult.Hardware, eECode.AGVCONN, eNextStep.ERROR);
                return false;
            }
         

            //충전 상태가 OFF되어야 동작하게한다
            if (_SM_RUN_CHGOFF(isFirst, stepTime) == false)
                return false;


            //라이더멈춤이 설정되어있다면 음성으로 알려준다 200409
            if (PUB.AGV.system1.stop_by_front_detect == true)
            {
                var tsSpeak = DateTime.Now - LastSpeakTime;
                if (tsSpeak.TotalSeconds >= PUB.setting.doorSoundTerm)
                {
                    PUB.Speak(Lang.전방에물체가감지되었습니다);
                    LastSpeakTime = DateTime.Now;
                }
                return false;
            }

            //현재 위치가 결정되어있는지 체크한다
            if (_SM_RUN_POSCHK(isFirst, stepTime) == false)
            {
                PUB.Result.result_message = "충전기 검색 전 현재 위치 검색";
                PUB.Result.result_progressmax = 0;
                return false;
            }

            //충전작업진행상태 //220629
            //if (PUB.flag.get(EFlag.FLAG_GO_CHAGER_TEMP) == false)
            //{
            //	PUB.flag.set(EFlag.FLAG_GO_CHAGER_TEMP, true);
            //}

            var idx = 1;
            if (PUB.sm.RunStepSeq == idx++)
            {
                PUB.Speak(Lang.충전을위해홈위치로이동합니다);
                PUB.Result.TargetPos = ePosition.QC;
                VAR.TIME.Update(eVarTime.ChargeSearch);
                PUB.sm.UpdateRunStepSeq();
                PUB.log.Add($"충전:대상위치 QC 시작");
                return false;
            }
            else if (PUB.sm.RunStepSeq == idx++)
            {
                //모션 전후진 제어
                if (UpdateMotionPositionForMark("GOCHARGE #1") == true)
                {
                    PUB.log.Add($"충전:충전기 검색 전 QC위치 확인 완료");
                    PUB.sm.UpdateRunStepSeq();
                }
                else
                {
                    //아직 충진기 위치를 찾지 못했다
                    var ts = VAR.TIME.RUN(eVarTime.ChargeSearch);
                    if (ts.TotalSeconds > PUB.setting.ChargeSearchTime)
                    {
                        PUB.log.Add($"충전:충전검색시간초과({ts.TotalSeconds}/{PUB.setting.ChargeSearchTime})");
                        PUB.Speak(Lang.충전기검색실패);
                        VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
                        PUB.sm.ClearRunStep();
                        PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
                        PUB.sm.SetNewStep(eSMStep.RUN);
                        PUB.counter.CountChargeE += 1;
                        PUB.counter.Save();
                    }
                }
                return false;
            }
            else if (PUB.sm.RunStepSeq == idx++)
            {
                if (PUB.setting.chargerpos == 0) //down search
                {
                    PUB.log.Add($"충전:충전기 검색을 위한 전진시작");
                    PUB.Speak(Lang.충전기를검색합니다);
                    PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
                    {
                        Speed = arDev.Narumi.eMoveSpd.Low,
                        Bunki = arDev.Narumi.eBunki.Strate,
                        Direction = arDev.Narumi.eMoveDir.Forward,
                        PBSSensor = 1,
                    });
                    PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Forward);
                    //PUB.Result.TargetPos = ePosition.CHARGE;
                    VAR.TIME.Update(eVarTime.ChargeSearch);
                }
                else if (PUB.setting.chargerpos == 2) //up search
                {
                    PUB.log.Add($"충전:충전기 검색을 위한 전진시작");
                    PUB.Speak(Lang.충전기를검색합니다);
                    PUB.AGV.AGVMoveSet(new arDev.Narumi.BunkiData
                    {
                        Speed = arDev.Narumi.eMoveSpd.Low,
                        Bunki = arDev.Narumi.eBunki.Strate,
                        Direction = arDev.Narumi.eMoveDir.Backward,
                        PBSSensor = 1,
                    });
                    PUB.AGV.AGVMoveRun(arDev.Narumi.eRunOpt.Backward);
                    //PUB.Result.TargetPos = ePosition.CHARGE;
                    VAR.TIME.Update(eVarTime.ChargeSearch);
                }
                else
                {
                    PUB.log.Add($"충전기위치가 QC위치로 설정되어 있습니다");
                }

                PUB.sm.UpdateRunStepSeq();
                return false;
            }
            else if (PUB.sm.RunStepSeq == idx++)
            {
                if (PUB.setting.chargerpos != 1)
                {
                    if (PUB.AGV.system1.agv_run)
                    {
                        PUB.log.Add($"충전:AGV기동확인으로 마크정지신호설정");
                        PUB.Speak(Lang.다음마크위치에서정지합니다);
                        PUB.AGV.AGVMoveStop("SM_RUN_GOCHARGE", arDev.Narumi.eStopOpt.MarkStop);
                        VAR.TIME.Update(eVarTime.ChargeSearch);
                        PUB.sm.UpdateRunStepSeq();
                    }
                    else
                    {
                        if (VAR.TIME.RUN(eVarTime.ChargeSearch).TotalSeconds > 5)
                        {
                            //5초이상 이곳에서 대기한다면 다시 돌려준다
                            PUB.sm.UpdateRunStepSeq(-1);
                            PUB.log.Add($"충전:AGV기동확인 안됨, 롤백 다시 이동할 수 있게 함");
                        }
                    }
                }
                else
                {
                    VAR.TIME.Update(eVarTime.ChargeSearch);
                    PUB.sm.UpdateRunStepSeq();
                }
         

                return false;
            }
            else if (PUB.sm.RunStepSeq == idx++)
            {
                if (PUB.AGV.system1.agv_stop)
                {
                    PUB.log.Add($"충전:충전기멈춤확인 다음진행");
                    PUB.logagv.Add("충전 위치에 멈췄습니다");
                    PUB.sm.UpdateRunStepSeq();
                }
                else
                {
                    if (VAR.TIME.RUN(eVarTime.ChargeSearch).TotalSeconds > 60)
                    {
                        PUB.log.Add($"충전:멈춤 확인 60초 초과로 전체 취소함");
                        PUB.sm.ClearRunStep();
                        PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
                        PUB.sm.SetNewStep(eSMStep.RUN);
                        PUB.counter.CountChargeE += 1;
                        PUB.counter.Save();
                        VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
                        PUB.AddEEDB("충전실패로 인한 취소");
                    }
                }
                return false;
            }
            //충전기위치까지 왔다
            else if (PUB.sm.RunStepSeq == idx++)
            {
                //센서가 안정화되기 위한 5초간 기다려준다
                if (stepTime.TotalSeconds <= 3) return false;
                PUB.log.Add($"충전:충전기위치정지완료");
                PUB.Result.CurrentPos = ePosition.CHARGE; //현재위치를 충전기로 한다
                PUB.Result.TargetPos = ePosition.CHARGE;
                PUB.Result.CurrentPosCW = "1";
                ctlPos1.SetPosition(ePosition.CHARGE);
                ctlPos1.SetPositionActive(ePosition.CHARGE);
                ctlPos1.Invalidate();
                PUB.sm.UpdateRunStepSeq();
                return false;
            }
            else if (PUB.sm.RunStepSeq == idx++)
            {
                //충전시작 명령을 전송한다
                PUB.log.Add($"충전:충전명령전송");
                PUB.Speak(Lang.충전시작명령을전송합니다);
                PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
                VAR.BOOL[eVarBool.WAIT_CHARGEACK] = true;
                LastCommandTime = DateTime.Now;
                VAR.BYTE[eVarByte.CHARGE_CMDCNT] = 0;
                PUB.sm.UpdateRunStepSeq();
                return false;
            }
            //충전시작명령의 ACK를 체크합니다
            else if (PUB.sm.RunStepSeq == idx++)
            {
                //충전시작 명령을 전송한다
                if (PUB.AGV.ACKData.Equals("CBT"))
                {
                    PUB.log.Add($"충전명령 회신 확인");
                    PUB.sm.UpdateRunStepSeq();
                }
                else
                {
                    var ts = DateTime.Now - LastCommandTime;
                    if (ts.TotalSeconds > 3)
                    {
                        if (VAR.BYTE[eVarByte.CHARGE_CMDCNT] > 5)
                        {
                            PUB.logagv.Add($"충전명령 재전송 5회초과로 전체 취소함");
                            PUB.sm.ClearRunStep();
                            PUB.sm.SetNewRunStep(ERunStep.CHARGEOFF);
                            PUB.sm.SetNewStep(eSMStep.RUN);
                            PUB.counter.CountChargeE += 1;
                            PUB.counter.Save();
                            VAR.BOOL[eVarBool.WAIT_CHARGEACK] = false;
                            PUB.AddEEDB("충전실패로 인한 취소");
                        }
                        else
                        {
                            PUB.logagv.Add($"충전시작명령 재전송");
                            VAR.BYTE.Add(eVarByte.CHARGE_CMDCNT, 1);
                            PUB.AGV.AGVCharge(PUB.setting.ChargerID, true);
                            LastCommandTime = DateTime.Now;
                        }
                    }
                }
                return false;
            }

            return true;
        }
    }
}
