using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Utilities;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Loader;
using CyberX8_RT.Devices.TransPorter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CyberX8_RT.Devices.PUF
{
    public class PufRotationAxisInterLock : IAxisInterLock
    {
        #region 常量
        private const string IS_DOOR_OPENED = "IsDoorOpened";
        #endregion

        #region 内部变量
        private JetAxisBase _loaderTransporterGantryAxis;
        private JetAxisBase _axis;
        #endregion

        #region 属性
        /// <summary>
        /// 模块名称
        /// </summary>
        public string Module { get { return _axis.Module; } }
        /// <summary>
        /// 子模块名称
        /// </summary>
        public string Name { get { return _axis.Name; } }
        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Module"></param>
        /// <param name="name"></param>
        public PufRotationAxisInterLock(JetAxisBase axis)
        {
            _axis = axis;
        }
        /// <summary>
        /// 加载LoaderTransporter Gantry轴
        /// </summary>
        private void GetLoaderTransporterGantryAxis()
        {
            if(_loaderTransporterGantryAxis==null)
            {
                _loaderTransporterGantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry");
            }
        }
        /// <summary>
        /// GotoPosition检验条件
        /// </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool CheckGotoPosition(string station)
        {
            if (!_axis.IsHomed)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_NOT_HOME, $"{Module}.{Name}", "axis is not homed, Cannot execute GotoSavedPosition");
                return false;
            }
            if (!AxisManager.Instance.CheckModuleAxisSwitchOn(Module, Name))
            {
                return false;
            }
            JetAxisBase flipAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Flip");
            if (flipAxis.Status==CyberX8_Core.RState.Running)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_OTHERAXIS_RUNNING, $"{Module}.{Name}", "flip status is running, Cannot execute GotoSavedPosition");
                return false;
            }
            double flipPosition = flipAxis.MotionData.MotorPosition;
            if (flipAxis.CheckPositionIsEmpty(flipPosition))
            {
                LOG.WriteLog(eEvent.ERROR_PUF_OTHER_AXIS_EMPTY, $"{Module}.{Name}", "flip station is empty, Cannot execute GotoSavedPosition");
                return false;
            }
            bool loaderInstalled = ModuleHelper.IsInstalled(ModuleName.Loader1);
            JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");

            double loaderRotationPosition = loaderInstalled?loaderRotationAxis.MotionData.MotorPosition:0;
            bool loaderTransporterInstalled = ModuleHelper.IsInstalled(ModuleName.Transporter2);
            if(loaderTransporterInstalled)
            {
                GetLoaderTransporterGantryAxis();
            }
            if(station.EndsWith("HOME")||station.EndsWith("Flip")||station.EndsWith("ROBOT"))
            {
                return true;
            }
            if (!loaderInstalled)
            {
                return true;
            }
            if (loaderRotationAxis == null || loaderRotationAxis.CheckPositionIsEmpty(loaderRotationPosition))
            {
                LOG.WriteLog(eEvent.ERROR_PUF_OTHER_AXIS_EMPTY, $"{Module}.{Name}", $"loader rotation axis {loaderRotationPosition} is empty, Cannot execute GotoSavedPosition");
                return false;
            }
            bool isInLOADA = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADA");
            bool isInLOADB = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADB");
            if (!isInLOADA&&!isInLOADB)//loader1 rotation轴不在LOADA或LOADB
            {                
                LOG.WriteLog(eEvent.ERROR_PUF_OTHER_AXIS_STATION, $"{Module}.{Name}", $"load rotation {loaderRotationPosition} is not in LOADA and LOADB");
                return false;
            }
            string side = isInLOADA ? "A" : "B";
            JetAxisBase shuttleAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");
            double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
            if(!shuttleAxis.CheckPositionInStationIgnoreWaferSize(shuttlePosition, "OUT"))
            {
                LOG.WriteLog(eEvent.ERROR_PUF_OTHER_AXIS_STATION, $"{Module}.{Name}", $"load shuttle{side} {shuttlePosition} is not in OUT");
                return false;
            }

            JetAxisBase tiltAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Tilt{side}");
            double tiltPosition = tiltAxis.MotionData.MotorPosition;
            if (!tiltAxis.CheckPositionInStationIgnoreWaferSize(shuttlePosition, "HORI"))
            {
                LOG.WriteLog(eEvent.ERROR_PUF_OTHER_AXIS_STATION, $"{Module}.{Name}", $"load tilt{side} {tiltPosition} is not in HORI");
                return false;
            }

            PufVacuum _pufVacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");
            if (_pufVacuum.Chuck)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_CHUCK_ON, $"{Module}.{Name}", "Chuck is on");
                return false;
            }

            if (_pufVacuum.SideAChuckOut)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_SIDEA_CHUCK_OUT_ON, $"{Module}.{Name}", "SideA Chuck out is on");
                return false;
            }
            if (_pufVacuum.SideBChuckOut)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_SIDEA_CHUCK_OUT_ON, $"{Module}.{Name}", "SideB Chuck out is on");
                return false;
            }
            if (!_pufVacuum.SideAChuckIn)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_SIDEA_CHUCK_IN_OFF, $"{Module}.{Name}", "SideA Chuck in is off");
                return false;
            }
            if (!_pufVacuum.SideBChuckIn)
            {
                LOG.WriteLog(eEvent.ERROR_PUF_SIDEA_CHUCK_IN_OFF, $"{Module}.{Name}", "SideB Chuck in is off");
                return false;
            }
            return true;
        }
    }
}