using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.Routine;
using Aitex.Core.UI.Control;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.ModuleIO;
using MECF.Framework.Common.CommonData.Metal;
using MECF.Framework.Common.Persistent.Reservoirs;
using MECF.Framework.Common.TwinCat;
using CyberX8_Core;
using CyberX8_RT.Devices.LinMot;
using CyberX8_RT.Devices.Prewet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using MECF.Framework.Common.IOCore;
using Aitex.Core.RT.SCCore;
using CyberX8_RT.Devices.PowerSupplier;
using MECF.Framework.Common.ToolLayout;
using SecsGem.Core.ItemModel;
namespace CyberX8_RT.Devices.Metal
{
    public class StandardHotMetalDevice : MetalCellDevice
    {
        private enum MetalOperation
        {
            None,
            CellPumpOn
        }
        #region 常量 
        private const string PERSISTENT_VALUE = "PersistentValue";
        private const string CELL_PUMP = "CellPump";
        private const string CELL_FLOW = "CellFlow";
        private const string WH_CLAMP = "WaferHolderClamp";
        private const string CIRCULATION = "Circulation";
        
        #endregion
        #region 内部变量
        /// 
        /// 设备数据
        /// 
        private StandardHotMetalDeviceData _metalDeviceData = new StandardHotMetalDeviceData();
        /// 
        /// 变量是否初始化字典
        /// 
        private Dictionary _variableInitializeDic = new Dictionary();
        /// 
        /// Pump Routine
        /// 
        private StandardHotMetalCellPumpRoutine _cellPumpRoutine;
        /// 
        /// 当前操作
        /// 
        private MetalOperation _currentOperation;
        /// 
        /// Flow Valve计时
        /// 
        private Stopwatch _flowValveStopWatch = new Stopwatch();
        /// 
        /// 是否有独立的泵
        /// 
        private bool _isSignalPump;
        #endregion
        #region 属性
        /// 
        /// 设备数据
        /// 
        public StandardHotMetalDeviceData MetalDeviceData { get { return _metalDeviceData; } }
        /// 
        /// Flow Valve稳定状态
        /// 
        public bool FlowValveStable { get { return _metalDeviceData.Circulation && _flowValveStopWatch.ElapsedMilliseconds >= 3000; } }
        /// 
        /// 是否有单独的泵
        /// 
        public bool IsSignalPump { get { return _isSignalPump; } }
        #endregion
        /// 
        /// 构造函数
        /// 
        /// 
        public StandardHotMetalDevice(string moduleName) : base(moduleName)
        {
        }
        /// 
        /// 初始化
        /// 
        /// 
        public override bool Initialize()
        {
            base.Initialize();
            InitializeParameter();
            InitializeRoutine();
            SubscribeValueAction();
            SubscribeData();
            return true;
        }
        /// 
        /// 初始化参数
        /// 
        private void InitializeParameter()
        {
            _persistentValue = MetalPersistentManager.Instance.GetMetalPersistentValue(Module);
            if (_persistentValue == null)
            {
                LOG.WriteLog(eEvent.ERR_RESERVOIR, Module, "Persistent Value Object is not exist");
            }
            MetalItem metalItem = MetalItemManager.Instance.GetMetalItem(Module);
            
            if (metalItem != null && metalItem.DepPump) 
            {
                _isSignalPump = true;
            }
        }
        /// 
        /// 初始化Routine
        /// 
        private void InitializeRoutine()
        {
            _cellPumpRoutine = new StandardHotMetalCellPumpRoutine(Module.ToString());
        }
        /// 
        /// 订阅数据
        /// 
        private void SubscribeData()
        {
            DATA.Subscribe($"{Module}.MetalData", () => _metalDeviceData, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.CellPumpEnable", () => _metalDeviceData.CellPump, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.WaferShuttleClamped", () => _metalDeviceData.WaferHolderClamp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.CellFlow", () => _metalDeviceData.CellFlow, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.Circulation", () => _metalDeviceData.Circulation, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            DATA.Subscribe($"{Module}.IsSingalPump", () => _isSignalPump, SubscriptionAttribute.FLAG.IgnoreSaveDB);
            
        }
        /// 
        /// 订阅变量数值发生变化
        /// 
        private void SubscribeValueAction()
        {
            BeckhoffIoSubscribeUpdateVariable(CELL_PUMP);
            BeckhoffIoSubscribeUpdateVariable(CELL_FLOW);
            BeckhoffIoSubscribeUpdateVariable(WH_CLAMP);
            BeckhoffIoSubscribeUpdateVariable(CIRCULATION);
        }
        /// 
        /// 订阅Operation
        /// 
        protected override void InitializeOperation()
        {
            base.InitializeOperation();
            OP.Subscribe($"{Module}.PumpEnable", OpenPump);
            OP.Subscribe($"{Module}.PumpDisable", ClosePump);
            OP.Subscribe($"{Module}.CellSwitchToBypass", (cmd, args) => { return SwitchToBypass(cmd, args); });
            OP.Subscribe($"{Module}.CellSwitchToFlow", (cmd, args) => { return SwitchToFlow(cmd, args); });
            OP.Subscribe($"{Module}.ClampOn", (cmd, args) => { return WaferHolderClampOn(cmd, args); });
            OP.Subscribe($"{Module}.ClampOff", (cmd, args) => { return WaferHolderClampOff(cmd, args); });
            OP.Subscribe($"{Module}.WaferHolderClampOn", (cmd, args) => { return WaferHolderClampOn(cmd, args); });
            OP.Subscribe($"{Module}.WaferHolderUnclampOn", (cmd, args) => { return WaferHolderClampOff(cmd, args); });
            
        }
        /// 
        /// 订阅IO变量
        /// 
        /// 
        private void BeckhoffIoSubscribeUpdateVariable(string variable)
        {
            _variableInitializeDic[variable] = false;
            IOModuleManager.Instance.SubscribeModuleVariable(Module, variable, UpdateVariableValue);
        }
        /// 
        /// 更新变量数值
        /// 
        /// 
        /// 
        private void UpdateVariableValue(string variable, object value)
        {
            if (!_metalDeviceData.IsDataInitialized)
            {
                _metalDeviceData.IsDataInitialized = true;
            }
            PropertyInfo property = _metalDeviceData.GetType().GetProperty(variable);
            if (property != null)
            {
                property.SetValue(_metalDeviceData, value);
            }
            if (_variableInitializeDic.ContainsKey(variable) && !_variableInitializeDic[variable])
            {
                _variableInitializeDic[variable] = true;
            }
            if (variable == CIRCULATION)
            {
                bool bValue = (bool)value;
                if (bValue)
                {
                    _flowValveStopWatch.Restart();
                }
            }
        }
        public bool OpenPump(string cmd, Object[] args)
        {
            bool result = false;
            result = PumpOnOperation(cmd, args);
            return result;
        }
        public bool ClosePump(string cmd, Object[] args)
        {
            bool result = false;
            result = PumpOffOperation(cmd, args);
            return result;
        }
        #region CellPump
        /// 
        /// Cell Pump On操作
        /// 
        /// 
        /// 
        /// 
        public bool PumpOnOperation(string cmd, object[] param)
        {
            if (_status == RState.Running)
            {
                LOG.WriteLog(eEvent.ERR_METAL, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump On");
                return false;
            }
            _status = _cellPumpRoutine.Start(true);
            _currentOperation = MetalOperation.CellPumpOn;
            return _status == RState.Running;
        }
        /// 
        /// Cell Pump Off操作
        /// 
        /// 
        /// 
        /// 
        public bool PumpOffOperation(string cmd, object[] param)
        {
            bool result = true;
            if (MetalDeviceData.CellPump)
            {
                result = PumpOff();
            }
            return result;
            //return PumpOff();
        }
        /// 
        /// Pump Off
        /// 
        /// 
        public bool PumpOff()
        {
            if (_status == RState.Running && _currentOperation == MetalOperation.CellPumpOn)
            {
                IRoutine routine = GetCurrentRoutine();
                if (routine != null)
                {
                    routine.Abort();
                }
            }
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CELL_PUMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        #region WaferHolderClampOn
        /// 
        /// Wafer Holder Clamp On
        /// 
        /// 
        /// 
        /// 
        public bool WaferHolderClampOn(string cmd, object[] param)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WH_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        #endregion
        #region WaferHolderClampOff
        /// 
        /// Wafer Holder Clamp On
        /// 
        /// 
        /// 
        /// 
        public bool WaferHolderClampOff(string cmd, object[] param)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{WH_CLAMP}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        #endregion
        #region circulation
        /// 
        /// 切换至Bypass
        /// 
        /// 
        public bool SwitchToBypass(string cmd, object[] param)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CIRCULATION}");
            return IOModuleManager.Instance.WriteIoValue(ioName, false);
        }
        /// 
        /// 切换至Flow
        /// 
        /// 
        public bool SwitchToFlow(string cmd, object[] param)
        {
            string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{CIRCULATION}");
            return IOModuleManager.Instance.WriteIoValue(ioName, true);
        }
        #endregion
        /// 
        /// Enter Disabled Operation
        /// 
        /// 
        public void EnterDisabledOperation()
        {
            if (_metalDeviceData.CellPump)
            {
                ClosePump("", null);
            }
        }
        /// 
        /// 定时器
        /// 
        /// 
        public override bool OnTimer(int interval)
        {
            if (_status == RState.Running)
            {
                IRoutine routine = GetCurrentRoutine();
                if (routine != null)
                {
                    RState rsState = routine.Monitor();
                    if (rsState == RState.Failed || rsState == RState.Timeout)
                    {
                        _status = RState.Failed;
                        ClosePump("", null);
                        _currentOperation = MetalOperation.None;
                    }
                    else if (rsState == RState.End)
                    {
                        _status = RState.End;
                        _currentOperation = MetalOperation.None;
                    }
                }
            }
            return true;
        }
        /// 
        /// 当前Routine;
        /// 
        /// 
        private IRoutine GetCurrentRoutine()
        {
            switch (_currentOperation)
            {
                case MetalOperation.CellPumpOn:
                    return _cellPumpRoutine;
                default:
                    return null;
            }
        }
        #region 设备接口
        public override void Monitor()
        {
        }
        public override void Reset()
        {
        }
        public override void Terminate()
        {
        }
        #endregion
    }
}