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

namespace Project
{
    public partial class fMain
    {
        #region "Common Utility"

        /// <summary>
        /// 지정한 출력핀의 상태를 변경하고 최대 10초간 상태를 모니터링 합니다.
        /// </summary>
        /// <param name="doPin"></param>
        /// <param name="isFirst"></param>
        /// <param name="stepTime"></param>
        /// <param name="checkValue"></param>
        /// <param name="sendIntervalMs"></param>
        /// <param name="timeoutSec"></param>
        /// <returns></returns>
        bool checkDigitalO(int shutIdx, eDOName doPin, Boolean isFirst, TimeSpan stepTime, Boolean checkValue, int sendIntervalMs = 1000, int timeoutSec = 0)
        {

            //eIOCheckResult result = eIOCheckResult.Complete;
            var retval = false;
            if (timeoutSec == 0) timeoutSec = Pub.setting.Timeout_DIOCommand;

            if (isFirst)
            {
                Pub.Result.doCheckTime[shutIdx, (int)doPin] = DateTime.Now.AddDays(-1);
            }



            //지정한 출력핀이 조건에 맞지 않을 경우ㅍ
            var curValue = Util_DO.GetIOOutput(doPin);
            if (curValue != checkValue)
            {
                //Offt신호는 1초에 1번씩 전송하게 한다.
                var ts = DateTime.Now - Pub.Result.doCheckTime[shutIdx, (int)doPin];
                if (ts.TotalMilliseconds >= sendIntervalMs)
                {
                    Pub.dio.SetOutput((int)doPin, checkValue);
                    Pub.Result.doCheckTime[shutIdx, (int)doPin] = DateTime.Now;
                }

                //전체 시간이 10초를 넘어가면 오류로 처리함
                if (stepTime.TotalSeconds >= timeoutSec)
                    Pub.Result.SetResultTimeOutMessage(doPin, checkValue, eNextStep.pause);
            }
            else retval = true;
            return retval;
        }

        bool checkDigitalO(int shutIdx, eDIName doPin, Boolean isFirst, TimeSpan stepTime, Boolean checkValue, int timeoutSec = 0)
        {
            //eIOCheckResult result = eIOCheckResult.Complete;
            var retval = false;
            if (timeoutSec == 0) timeoutSec = (int)Pub.setting.Timeout_DIOCommand;

            //지정한 출력핀이 조건에 맞지 않을 경우ㅍ
            var curValue = Util_DO.GetIOInput(doPin);
            if (curValue != checkValue)
            {
                //전체 시간이 10초를 넘어가면 오류로 처리함
                //var diRunTime = DateTime.Now - Pub.Result.diCheckTime[shutIdx, (int)doPin];
                if (stepTime.TotalSeconds >= timeoutSec)
                {
                    //result = eIOCheckResult.Timeout;
                    Pub.Result.SetResultTimeOutMessage(doPin, checkValue, eNextStep.pause);
                }
            }
            else retval = true;
            return retval;
        }

        Boolean CheckMotionPos(int seqIdx, eAxis Motaxis, TimeSpan stepTime, double pos, double speed, double acc, double dcc, string source, Boolean useInterLocak=true, int timeoutSec = 0)
        {
            var axis = (int)Motaxis;

            //타임아웃 적용 191213
            if (timeoutSec == 0) timeoutSec = Pub.setting.Timeout_MotionCommand;


            //X축을 그립위치까지 이동함
            if (Pub.mot.isINP[axis] && Pub.mot.isMotion[axis] == false)
            {
                var offset = Math.Abs(Pub.mot.dCMDPOS[axis] - pos);
                var offsetReal = Math.Abs(Pub.mot.dCMDPOS[axis] - Pub.mot.dACTPOS[axis]);
                if (offset > 0.01 || offsetReal > 0.1)
                {
    
                    if (Util_Mot.Move(Motaxis, pos, speed, acc, false, true, useInterLocak) == false)
                        Console.WriteLine("move error {0},pos={1} => {2}",Motaxis,pos,Pub.mot.errorMessage);
                        

                    //모션을 옴겨야하는 상황인데 최대시간을 초과했다면 오류로 처리한다
                    if (timeoutSec != -1 && stepTime.TotalSeconds >= timeoutSec)
                    {
                        Pub.Result.SetResultTimeOutMessage(Motaxis, eECode.MOT_CMD, eNextStep.pause, source);
                    }

                    //모션을 이동시켰으니 False 처리한다
                    //return false;
                }
            }

            //축이 이동중이면 처리하지 않는다.
            if (Pub.mot.isINP[axis] == false || Pub.mot.isMotion[axis] == true)
            {
                return false;
            }

            //X축실위치값 확인
            if (Util_Mot.getPositionMatch(axis, pos) == false)
            {
                return false;
            }

            return true;
        }


        /// <summary>
        /// 지정된 시간만큼 대기하며 완료되면 true를 반환합니다.
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        Boolean WaitForSeconds(eWaitType wait, double timems)
        {
            var idx = (byte)wait;
            if (Pub.Result.WaitForVar[idx] == null || Pub.Result.WaitForVar[idx].Year == 1982)
            {
                Pub.Result.WaitForVar[idx] = Pub.Result.WaitForVar[idx] = DateTime.Now;
                //Pub.log.Add(string.Format("Wait for [{0}], Wait Time:{1}ms", wait, timems));
            }
            var ts = DateTime.Now - Pub.Result.WaitForVar[idx];
            if (ts.TotalSeconds >= timems) return true;
            else return false;
        }

        void ResetWaitForSeconds(eWaitType wait)
        {
            var idx = (byte)wait;
            Pub.Result.WaitForVar[idx] = DateTime.Parse("1982-11-23");
        }

        #endregion

    }//cvass
}
