using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;

namespace Project
{
    public partial class FMain
    {

        //System.Threading.ManualResetEvent LockLL = new System.Threading.ManualResetEvent(true);
        //System.Threading.ManualResetEvent LockLR = new System.Threading.ManualResetEvent(true);

        System.Threading.ManualResetEvent LockPK = new System.Threading.ManualResetEvent(true);

        System.Threading.ManualResetEvent LockUserL = new System.Threading.ManualResetEvent(true);
        System.Threading.ManualResetEvent LockUserR = new System.Threading.ManualResetEvent(true);


        async public void _STEP_RUN_START(eSMStep step)
        {

            //새로시작하면 포트 얼라인을 해제 해준다
            PUB.flag.set(eVarBool.FG_RDY_PORT_PL, false, "SM_RUN");
            PUB.flag.set(eVarBool.FG_RDY_PORT_PC, false, "SM_RUN");
            PUB.flag.set(eVarBool.FG_RDY_PORT_PR, false, "SM_RUN");

            //작업완료기준시간 초기화
            if (PUB.flag.get(eVarBool.FG_JOB_END) == true) VAR.TIME.Update(eVarTime.JOB_END);

            //라이브뷰시간 초기화
            VAR.TIME.Update(eVarTime.LIVEVIEW0);
            VAR.TIME.Update(eVarTime.LIVEVIEW1);
            VAR.TIME.Update(eVarTime.LIVEVIEW2);

            //룸조명과, 타워램프 ON 한다 - 210402
            //COMM.SETTING.Data.Disable_RoomLight = false;
            //COMM.SETTING.Data.Disable_TowerLamp = false;

            //얼라인상태 초기화
            hmi1.arVar_Port[1].AlignReset();
            hmi1.Scean = UIControl.HMI.eScean.Nomal;
            //loader1.arVar_Port.ToList().ForEach(t => t.AlignReset());

            //daycount 초기화
            if (SETTING.Counter.DateStr != DateTime.Now.ToString("yyyy-MM-dd"))
            {
                SETTING.Counter.ClearDay();
                SETTING.Counter.DateStr = DateTime.Now.ToString("yyyy-MM-dd");
                SETTING.Counter.Save();
            }


            //키엔스 시작시간을 초기화한다.
            VAR.TIME.Update(eVarTime.KEYENCEWAIT);

            //조명켜기 - 201228
            DIO.SetRoomLight(true); //조명은 켜는 것으로 한다 221107

            //각스텝의 시작변수 초기화한다.
            PUB.sm.seq.ClearTime();//.ClearRunStepSeqTime();

            //대기메세지소거
            PUB.WaitMessage = new string[] { "", "", "", "", "", "", "", "", "", "", "" };

            if (PUB.flag.get(eVarBool.FG_PRC_VISIONL) && PUB.flag.get(eVarBool.FG_END_VISIONL) == false)
            {
                //작업을 재시작하면 카메라 트리거를 다시 보낸다
                WS_Send(eWorkPort.Left, PUB.wsL, PUB.Result.ItemDataL.guid, "TRIG", PUB.Result.ItemDataL.VisionData.PrintQRData);
            }

            if (PUB.flag.get(eVarBool.FG_PRC_VISIONR) && PUB.flag.get(eVarBool.FG_END_VISIONR) == false)
            {
                //Pub.Result.ItemData[2].Clear("[0] RUN FIRST");
                WS_Send(eWorkPort.Right, PUB.wsR, PUB.Result.ItemDataR.guid, "TRIG", PUB.Result.ItemDataR.VisionData.PrintQRData);
            }

            //재시작할때에는 이것이 동작하면 안됨
            if (PUB.sm.getOldStep == eSMStep.IDLE)
            {
                //인쇄용지감지상태 초기화
                PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTL, false, "");
                PUB.flag.set(eVarBool.FG_WAIT_PAPERDETECTR, false, "");


                PUB.flag.set(eVarBool.FG_PRC_VISIONL, false, "");
                PUB.flag.set(eVarBool.FG_PRC_VISIONR, false, "");

                PUB.flag.set(eVarBool.FG_END_VISIONL, false, "");
                PUB.flag.set(eVarBool.FG_END_VISIONR, false, "");

                PUB.flag.set(eVarBool.FG_OK_PRINTL, false, "");
                PUB.flag.set(eVarBool.FG_OK_PRINTR, false, "");
                PUB.flag.set(eVarBool.FG_RUN_PRINTL, false, "");
                PUB.flag.set(eVarBool.FG_RUN_PRINTR, false, "");

                PUB.flag.set(eVarBool.FG_RDY_PX_PICKON, false, "");
                PUB.flag.set(eVarBool.FG_RDY_PX_LPICKOF, false, "");
                PUB.flag.set(eVarBool.FG_RDY_PX_RPICKOF, false, "");
                PUB.flag.set(eVarBool.FG_SET_DATA_PORT0, false, "");
                PUB.flag.set(eVarBool.FG_SET_DATA_PORT2, false, "");
                PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITL, false, "");
                PUB.flag.set(eVarBool.FG_RDY_PX_PICKONWAITR, false, "");

                PUB.flag.set(eVarBool.FG_PORTL_ITEMON, false, "");
                PUB.flag.set(eVarBool.FG_PORTR_ITEMON, false, "");

                //PUB.flag.set(eVarBool.INPUT_LEFT, false, "SM_RUN");

                //step seq 를 모두 소거해준다
                PUB.sm.seq.Clear(eSMStep.RUN_PICK_RETRY);

                //자료를 소거한다.
                //PUB.Result.Clear("RUN_START");
                //PUB.Result.JobStartTime = DateTime.Now; //200728

                //신규실행이므로 작업차수별 수량을 초기화해준다
                SETTING.Counter.ClearP(); //200711

                PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN");

                PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_L);
                PUB.sm.seq.Clear(eSMStep.RUN_ROOT_SEQUENCE_R);

                if (await _SM_RUN_STARTCHKSW(true, new TimeSpan(0)) == false) return;
                if (_SM_RUN_STARTCHKHW(true, new TimeSpan(0)) == false) return;

                //plc의 SID 데이터를 갱신하도록 한다
                PUB.Result.ClearAllSID = true;
                PUB.log.AddI("*** New job has started ***");
                //PUB.flag.set(eVarBool.RDY_VISION1, true, "JOB START"); //최초 시작시에는 1번 비젼이 동작하게 한다

                //새로시작할때에는  이 값을 초기화 해준다.
                PUB.Result.LastSIDFrom = string.Empty;
                PUB.Result.LastSIDTo = string.Empty;
                //Pub.Result.LastSID103_2 = string.Empty;
                PUB.Result.LastSIDCnt = -1;
                PUB.Result.LastVName = string.Empty;


                //릴아디이 221107
                VAR.STR[eVarString.PrePick_ReelIDNew] = string.Empty;
                VAR.STR[eVarString.PrePick_ReelIDOld] = string.Empty;
                VAR.STR[eVarString.PrePick_ReelIDTarget] = string.Empty;
            }
            else
            {
                if (VAR.BOOL[eVarBool.wait_for_keyence])
                {
                    PUB.log.Add($"Deleting existing values because barcode reception was waiting (CONF={PUB.Result.ItemDataC.VisionData.Confirm}, ID:{PUB.Result.ItemDataC.VisionData.RID})");
                    PUB.Result.ItemDataC.VisionData.Clear("RESTART", true);
                }
                PUB.log.AddI("*** Job has been restarted ***");
            }
        }

        public StepResult _STEP_RUN(eSMStep step, TimeSpan stepTime, TimeSpan seqTime)
        {
            if (PUB.popup.needClose)
            {
                System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
                return StepResult.Wait;
            }

            //사용자 스텝처리가 아닌경우에만 동작 중지를 검사 한다
            //중단조건 검사는 0번 축에만 동작하게 한다
            //if (PUB.flag.get(eVarBool.UserStepCheck) == false)
            //{
            //    return false;
            //}

            if (CheckSystemRunCondition() == false)
            {
                return StepResult.Wait;
            }

            //동작상태가 아니라면 처리하지 않는다.
            if (PUB.sm.Step == eSMStep.RUN && PUB.sm.getNewStep == eSMStep.RUN)
            {
                var RStepisFirst = runStepisFirst[0];

                //릴포트 제어
                _SM_RUN_MOT_PORT(0, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT0));
                _SM_RUN_MOT_PORT(1, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT1));
                _SM_RUN_MOT_PORT(2, false, PUB.sm.seq.GetTime(eSMStep.RUN_COM_PT2));

                //컨베어 상시동작 - 230503
                Boolean cvl = PUB.iLockCVL.IsEmpty();
                Boolean cvr = PUB.iLockCVR.IsEmpty();
                DIO.SetOutput(eDOName.LEFT_CONV, cvl);
                DIO.SetOutput(eDOName.RIGHT_CONV, cvr);

                //왼쪽작업
                if (PUB.flag.get(eVarBool.FG_ENABLE_LEFT))
                {
                    _RUN_ROOT_SEQUENCE(eWorkPort.Left, eSMStep.RUN_ROOT_SEQUENCE_L);
                }

                //오른쪽작업
                if (PUB.flag.get(eVarBool.FG_ENABLE_RIGHT))
                {
                    _RUN_ROOT_SEQUENCE(eWorkPort.Right, eSMStep.RUN_ROOT_SEQUENCE_R);
                }

                //작업완료조건확인
                var PLReady = MOT.GetLMPos(eLMLoc.READY);
                var PRReady = MOT.GetRMPos(eRMLoc.READY);

                //최종이벤트시간에서 10초이상 기다려준다 230504
                var tsEventTime = VAR.TIME.RUN((int)eVarTime.JOBEVENT);

                //컨베이어모드
                var CVMode = VAR.BOOL[eVarBool.Use_Conveyor];

                if (tsEventTime.TotalSeconds > 10 &&
                    stepTime.TotalSeconds > 5.0 &&
                    DIO.isSaftyDoorF(false) == true &&
                    PUB.flag.get(eVarBool.FG_PK_ITEMON) == false &&
                    PUB.flag.get(eVarBool.FG_PL_ITEMON) == false &&
                    PUB.flag.get(eVarBool.FG_PR_ITEMON) == false &&

                    //신규로 추가된 컨베이어 센서이다
                    (CVMode == false || DIO.GetIOInput(eDIName.L_CONV1) == false) &&
                   // (CVMode == false || DIO.GetIOInput(eDIName.L_CONV3) == false) &&
                    (CVMode == false || DIO.GetIOInput(eDIName.L_CONV4) == false) &&
                    (CVMode == false || DIO.GetIOInput(eDIName.R_CONV1) == false) &&
                  //  (CVMode == false || DIO.GetIOInput(eDIName.R_CONV3) == false) &&
                    (CVMode == false || DIO.GetIOInput(eDIName.R_CONV4) == false) &&

                    //작업진행중  확인
                    PUB.flag.get(eVarBool.FG_BUSY_LEFT) == false &&
                    PUB.flag.get(eVarBool.FG_BUSY_RIGHT) == false &&

                    //비전처리중  확인
                    //PUB.flag.get(eVarBool.FG_PRC_VISIONL) == false &&
                    //PUB.flag.get(eVarBool.FG_PRC_VISIONR) == false &&

                    //모든 모터는 멈춰있어야  한다
                    PUB.mot.HasMoving == false && //피커는 중앙에 있어야 한다

                    //좌,우측 프린터 Y축이  정위치에  있어야  한다
                    MOT.getPositionMatch(PLReady) &&
                    MOT.getPositionMatch(PRReady) &&

                    isPortDetUp(1) == false &&
                    isPortLimUP(1) &&

                    //드라이런 중에는 완료하지 않는다
                    PUB.Result.DryRun == false)
                {

                    if (PUB.flag.get(eVarBool.FG_JOB_END) == false)
                    {
                        PUB.log.AddAT("Work completion condition execution");
                        VAR.TIME.Update(eVarTime.JOB_END);
                        PUB.flag.set(eVarBool.FG_JOB_END, true, "SM_RUN");
                    }
                    else
                    {
                        //10초가 지나면 최조 완료로 한다
                        var ts = VAR.TIME.RUN((int)eVarTime.JOB_END);
                        if (ts.TotalSeconds >= AR.SETTING.Data.Timeout_JOBEnd)
                        {
                            PUB.Result.JobEndTime = DateTime.Now;
                            PUB.log.AddI($"Switching to job completion state (wait time: {AR.SETTING.Data.Timeout_JOBEnd} seconds)");
                            PUB.sm.SetNewStep(eSMStep.FINISH);
                            PUB.flag.set(eVarBool.FG_JOB_END, false, "SM_RUN:FINISH");
                        }
                    }
                }
                else
                {
                    //이조건일때에는 job_End 가 없어야한다
                    if (PUB.flag.get(eVarBool.FG_JOB_END) == true)
                    {
                        PUB.log.AddI("Work completion condition released");
                        PUB.flag.set(eVarBool.FG_JOB_END, false, "run");

                        //메인메세지를 제거 해준다.
                        PUB.StatusMessage.set(Class.eStatusMesage.Main, string.Empty);
                    }
                }
            }
            return StepResult.Wait;
        }

        public Boolean CheckSystemRunCondition()
        {
            if (PUB.mot.IsInit == false)
            {
                PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
                return false;
            }

            if (PUB.dio.IsInit == false)
            {
                PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.AZJINIT, eNextStep.ERROR);
                return false;
            }

            if (PUB.mot.HasHomeSetOff == true)
            {
                PUB.Result.SetResultMessage(eResult.HARDWARE, eECode.MOT_HSET, eNextStep.ERROR);
                return false;
            }

            if (PUB.Result.vModel == null || PUB.Result.vModel.Title.isEmpty())
            {
                PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELV, eNextStep.ERROR);
                return false;
            }
            if (PUB.Result.mModel == null || PUB.Result.mModel.Title.isEmpty())
            {
                PUB.Result.SetResultMessage(eResult.SETUP, eECode.NOMODELM, eNextStep.ERROR);
                return false;
            }

            if (DIO.isSaftyDoorF() == false || DIO.isSaftyDoorR() == false)
            {
                PUB.Result.SetResultMessage(eResult.OPERATION, eECode.DOORSAFTY, eNextStep.PAUSE);
                return false;
            }
            return true;
        }
    }
}
