using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aitex.Core.RT.SCCore;
namespace CyberX8_RT.Devices.LinMot
{
   
    public class LinMotStartContinueCurveRoutine : RoutineBase, IRoutine
    {
        private enum LinMotStartContinueStep
        {
            WriteCurveIdRam,
            CurveIdDelay,
            WriteAmplitudeRam,
            AmplitudeDelay,
            WriteTimeScaleRam,
            Delay,
            CommandTable,
            CommandTableDelay,
            CommandTableCheckRun,
            ReCommandTable,
            End
        }
        #region 内部变量
        private LinMotAxis _axis;
        private int _speed;
        /// 
        /// Linmot检测运动时间
        /// 
        private int _holdoffMilliseconds = 5000;
        /// 
        /// 是否运动
        /// 
        private bool _isRun = false;
        #endregion
        public LinMotStartContinueCurveRoutine(string module,LinMotAxis axis) : base(module)
        {
            _axis = axis;
        }
        public void Abort()
        {
            Runner.Stop("Manual Abort");
        }
        public RState Monitor()
        {
            //Runner.Run(LinMotStartContinueStep.WriteCurveIdRam, () => { return _axis.WriteRamIntValue(0xC8, 0x14, 1); }, 100)
            //    .Delay(LinMotStartContinueStep.CurveIdDelay, 200)
            Runner.Run(LinMotStartContinueStep.WriteAmplitudeRam, () => { return _axis.WriteRamIntValue(0xCA, 0x14, 50 * 10); }, 100)
                .Delay(LinMotStartContinueStep.AmplitudeDelay, 100)
                .Run(LinMotStartContinueStep.WriteTimeScaleRam, () => { return _axis.WriteRamIntValue(0xCB,0x14,_speed*100); }, 100)
                .Delay(LinMotStartContinueStep.Delay, 100)
                .Run(LinMotStartContinueStep.CommandTable, () => { return _axis.SendCommandTableOperation(1); },_delay_1ms)
                .Delay(LinMotStartContinueStep.CommandTableDelay,500)
                .Run(LinMotStartContinueStep.CommandTableCheckRun, () => { _isRun = _axis.IsMotorOn; return true; },_delay_1ms)
                .RunIf(LinMotStartContinueStep.ReCommandTable,!_isRun, () => { return _axis.SendCommandTableOperation(1); }, 
                    () => _axis.IsMotorOn,_holdoffMilliseconds-_delay_1s)
                .End(LinMotStartContinueStep.End, NullFun);
            return Runner.Status;
        }
        public RState Start(params object[] objs)
        {
            _speed = (int)(objs[0]);
            if (!CheckPreCondition())
            {
                return RState.Failed;
            }
            if (SC.ContainsItem("Linmot.LinmotHoldoffMilliseconds"))
            {
                _holdoffMilliseconds = SC.GetValue("Linmot.LinmotHoldoffMilliseconds");
            }
            _isRun = false;
            return Runner.Start(Module, "Start Curve");
        }
        /// 
        /// 前置条件
        /// 
        /// 
        private bool CheckPreCondition()
        {
            if (!_axis.IsSwitchOn)
            {
                LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not switch on");
                return false;
            }
            if (!_axis.IsHomed)
            {
                LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not homed");
                return false;
            }
            if (!_axis.IsConnectd)
            {
                LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is not connected");
                return false;
            }
            if (_axis.IsError)
            {
                LOG.WriteLog(eEvent.ERR_LINMOT, Module, "axis is in error");
                return false;
            }
            return true;
        }
    }
}