using System;
using System.Xml;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Venus_RT.Devices.IODevices;
using Aitex.Core.RT.Device.Unit;
namespace Venus_RT.Devices
{
    /// 
    /// 先送Setpoint, 然后再设置控制模式, 切换设置模式后立即生效
    /// 
    public class IoBacksideHe : BaseDevice, IDevice
    {
        private readonly MfcBase1 _mfc;
        private readonly IoValve _DownValve;
        private readonly IoValve _UpValve;
        private readonly IoValve _Up2Valve;
        private AOAccessor _aoPressure;
        private AOAccessor _aoCtrlMode;
        private eEvent _lastEvent;
        private string _lastLogInfo;
        public int MinFlowThreshold { get; set;}
        public int MaxFlowThreshold { get; set; }
        public bool OutOfRange { get; private set; }
        public IoBacksideHe(string module, XmlElement node, string ioModule = "")
        {
            base.Module = module;
            base.Name = node.GetAttribute("id");
            base.Display = node.GetAttribute("display");
            base.DeviceID = node.GetAttribute("schematicId");
            _DownValve  = ParseDeviceNode(Module, "downvalve", node);
            _UpValve = ParseDeviceNode(Module, "upvalve", node);
            _Up2Valve = ParseDeviceNode(Module, "up2valve", node);
            _mfc = ParseDeviceNode(Module, "mfc", node);
            _aoPressure = ParseAoNode("aoPressureSP", node, ioModule);
            _aoCtrlMode = ParseAoNode("aoControlMode", node, ioModule);
        }
        public bool Initialize()
        {
            OutOfRange = false;
            return true;
        }
        public void Monitor()
        {
            if(MinFlowThreshold > 0 && _mfc.FeedBack <= MinFlowThreshold)
            {
                OutOfRange = true;
                _noRepeatLog(eEvent.WARN_BACKSIDE_HE, $"Backside Helium Flow: {_mfc.FeedBack} exceed min threshold value: {MinFlowThreshold}");
            }
            else if(MaxFlowThreshold > 0 && _mfc.FeedBack >= MaxFlowThreshold)
            {
                OutOfRange = true;
                _noRepeatLog(eEvent.WARN_BACKSIDE_HE, $"Backside Helium Flow: {_mfc.FeedBack} exceed max threshold value: {MaxFlowThreshold}");
            }
            else
            {
                OutOfRange = false;
            }
            _DownValve.Monitor();
            _mfc.Monitor();
        }
        public void Terminate()
        {
        }
        public void Reset()
        {
        }
        public bool SetBacksideHelium(float mTorr)
        {
            
            _SetRealFloat(_aoPressure, mTorr);
            if (mTorr >= 0.01)
            {
                _DownValve.TurnValve(true, out _);
                _UpValve.TurnValve(true, out _);
                _Up2Valve.TurnValve(true, out _);
                //this.FlowSP = setpoint;
            }
            else
            {
                _DownValve.TurnValve(false, out _);
                _UpValve.TurnValve(false, out _);
                _Up2Valve.TurnValve(false, out _);
            }
            SetESCHeControlMode(true);
            return true;
        }
        public bool SetFlowThreshold(int nMin, int nMax)
        {
            MinFlowThreshold = nMin;
            MaxFlowThreshold = nMax;
            return true;
        }
        public void Flow(double setpoint)
        {
            //setpoint = setpoint / 100 * 4000;
            if (setpoint >= 0.01)
            {
                _DownValve.TurnValve(true, out _);
                //this.FlowSP = setpoint;
            }
            else
            {
                _DownValve.TurnValve(false, out _);
            }
            _mfc.Ramp(setpoint, 1000);
            SetESCHeControlMode(false);
        }
        public void SetESCHeControlMode(bool bPressureMode)
        {
            _SetRealFloat(_aoCtrlMode, bPressureMode ? 1 : 0);
        }
        private void _noRepeatLog(eEvent evt, string logInfo)
        {
            if(evt != _lastEvent || logInfo != _lastLogInfo)
            {
                LOG.Write(evt, Module, logInfo);
                _lastEvent = evt;
                _lastLogInfo = logInfo;
            }
        }
    }
}