using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using AR;
using arDev;
using COMM;
namespace vmsnet
{
    public partial class FMain
    {
        void SM_Loop(object sender, StateMachine.RunningEventArgs e)
        {
            //main loop
            var step = (ESMStep)e.Step;
            var obj = this.GetType();

            var stepName = step.ToString();
          

            var methodName = $"_STEP_{stepName}";
            var methodNameStart = $"_STEP_{stepName}_START";
            var runMethodName = $"_{stepName}";

            var method = obj.GetMethod(methodName);
            var methodS = obj.GetMethod(methodNameStart);

            switch (step)
            {
                case ESMStep.NOTSET:
                    PUB.log.Add("S/M Initialize Start");
                    PUB.sm.SetNewStep(ESMStep.INIT);
                    break;

                case ESMStep.WAITSTART:
                    if (e.isFirst) PUB.log.Add("EVENT WAITSTART");
                    break;

                case ESMStep.PAUSE:
                case ESMStep.EMERGENCY:
                case ESMStep.ERROR:
                    if (e.isFirst)
                    {
                        _SM_MAIN_ERROR(e.isFirst, (ESMStep)e.Step, e.StepTime);
                    }
                    break;

                default:

                    if (e.isFirst)
                    {
                        //시작명령은 반드시 구현할 필요가 없다
                        if (methodS != null) methodS.Invoke(this, new object[] { step });
                        else
                        {
                          //  hmi1.ClearMessage();
                            PUB.log.Add($"Undefined step start :{step}");
                        }

                        if (step == ESMStep.HOME_QUICK || step == ESMStep.HOME_FULL || PUB.sm.getOldStep == ESMStep.IDLE || PUB.sm.getOldStep == ESMStep.FINISH)
                        {
                            PUB.sm.seq.ClearData(step);
                            PUB.sm.seq.Clear(step);
                        }

                        PUB.sm.seq.ClearTime();
                        PUB.sm.RaiseStepStarted();
                        return;
                    }

                    //if (PUB.popup.needClose) System.Threading.Thread.Sleep(10);
                    //else
                    {
                        //스텝번호값 보정 220313
                        if (PUB.sm.seq.Get(step) < 1) PUB.sm.seq.Update(step, 1);

                        if (method == null)
                        {
                            var runMethod = obj.GetMethod(runMethodName);
                            if (runMethod == null)
                            {
                                PUB.log.AddE($"unknown command : {methodName}/{runMethodName}");
                               // PUB.Result.SetResultMessage(eResult.DEVELOP, eECode.NOFUNCTION, eNextStep.ERROR, methodName, runMethodName);
                            }
                            else
                            {
                                var stepName2 = step.ToString();
                        
                                //실행코드는 있으니 처리한다.
                                //if (PUB.popup.needClose) System.Threading.Thread.Sleep(10); //팝업이 닫힐때까지 기다린다.
                                //else
                                {
                                    //실행가능여부를 확인 합니다
                                    //if (CheckSystemRunCondition(false) == true)
                                    {
                                        //동작상태가 아니라면 처리하지 않는다.
                                        if (PUB.sm.Step == step && PUB.sm.getNewStep == step)
                                        {
                                            var param = new object[] { step };
                                            var rlt = (bool)runMethod.Invoke(this, param);
                                            if (rlt == true)
                                            {
                                                PUB.log.AddI("change to idle by userstep(auto)");
                                                PUB.sm.SetNewStep(ESMStep.IDLE, true);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            var param = new object[] { step, e.StepTime, PUB.sm.seq.GetTime(step) };
                            var rlt = (StepResult)method.Invoke(this, param);
                            if (rlt == StepResult.Complete) PUB.sm.RaiseStepCompleted();
                            else
                            {
                                //사용자 스텝이 설정되어있다면 자동으로 멈춘다  220223
                                if (rlt == StepResult.Error)
                                {
                                    if (PUB.sm.getNewStep != ESMStep.ERROR)
                                        PUB.sm.SetNewStep(ESMStep.ERROR);
                                }

                                if (VAR.BOOL[EVarBool.USERSTEP] == true)
                                {
                                    if (PUB.sm.Step >= ESMStep.RUN && PUB.sm.getNewStep >= ESMStep.RUN &&
                                        PUB.sm.Step < ESMStep.FINISH && PUB.sm.getNewStep < ESMStep.FINISH)
                                    {
                                        ////유저스텝에 걸려있지 않다면 자동으로 멈춘다
                                        //if (PUB.LockUserStep.WaitOne(3)==false)
                                        //{
                                        //    //Pub.Result.SetResultMessage(eResult.OPERATION, eECode.USER_STOP)
                                        //    PUB.Result.ResultMessage = "USERSTEP - AUTO STOP";
                                        //    PUB.sm.SetNewStep(ESMStep.PAUSE);

                                        //    //한번멈추면 다시 실행되게한다.
                                        //    UserStepRun();
                                        //}
                                    }
                                }
                            }
                        }
                    }
                    break;
            }
        }


    }
}
