using MECF.Framework.Common.DataCenter;
using MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel.Params;
using System;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.MECF.Framework.Common.Utilities;

namespace MECF.Framework.UI.Client.RecipeEditorLib.RecipeModel
{
    /// <summary>
    /// 配方步骤气体流量计算器基类。
    /// <br/>
    /// 同时，该类也作为默认计算器使用；如果构造<see cref="RecipeData"/>时没有指定
    /// 计算器对象实例，则默认使用此计算器。
    /// </summary>
    public class RecipeGasFlowCalculatorBase : IRecipeGasFlowCalculator
    {

        #region Properties

        /// <summary>
        /// Mfc11.Ramp, 流量控制
        /// </summary>
        public virtual string NameTcsBubbleLowFlow => "Mfc11.Ramp";

        /// <summary>
        /// Mfc10.Ramp, 流量控制
        /// </summary>
        public virtual string NameTcsBubbleHighFlow => "Mfc10.Ramp";

        /// <summary>
        /// Mfc12.Ramp, 流量控制
        /// </summary>
        public virtual string NameTcsPushFlow => "Mfc12.Ramp";

        /// <summary>
        /// TCS.SetValve, 控制阀门模式
        /// </summary>
        public virtual string NameTcsFlowMode => "TCS.SetValve";

        /// <summary>
        /// Mfc7.Ramp, 流量控制
        /// </summary>
        public virtual string NameTmaBubbleFlow => "Mfc7.Ramp";

        /// <summary>
        /// Mfc8.Ramp, 流量控制
        /// </summary>
        public virtual string NameTmaPushFlow => "Mfc8.Ramp";

        /// <summary>
        /// TMA.SetValve, 控制阀门模式
        /// </summary>
        public virtual string NameTmaFlowMode => "TMA.SetValve";

        /// <summary>
        /// SiSourSplitRatio, 源分流比
        /// </summary>
        public virtual string NameSiSourceSplitRatio => "SiSourSplitRatio";

        /// <summary>
        /// SiSourTotalFlow, 源总流量
        /// </summary>
        public virtual string NameSiSourceTotalFlow => "SiSourTotalFlow";

        /// <summary>
        /// Mfc23.Ramp, 流量控制
        /// </summary>
        public virtual string NameSiSourceInnerFlow => "Mfc23.Ramp";

        /// <summary>
        /// Mfc22.Ramp, 流量控制
        /// </summary>
        public virtual string NameSiSourceMiddleFlow => "Mfc22.Ramp";

        /// <summary>
        /// Mfc9.Ramp, 流量控制
        /// </summary>
        public virtual string NameSiSourceOuterFlow => "Mfc9.Ramp";

        /// <summary>
        /// Mfc16.Ramp, 流量控制
        /// </summary>
        public virtual string NameCxHxFlow => "Mfc16.Ramp";

        /// <summary>
        /// C2H4.SetValve, 控制阀门模式
        /// </summary>
        public virtual string NameCxHxFlowMode => "C2H4.SetValve";

        /// <summary>
        /// CSourSplitRatio, 源分流比
        /// </summary>
        public virtual string NameCSourceSplitRatio => "CSourSplitRatio";

        /// <summary>
        /// CSourTotalFlow, 源总流量
        /// </summary>
        public virtual string NameCSourceTotalFlow => "CSourTotalFlow";

        /// <summary>
        /// Mfc15.Ramp, 流量控制
        /// </summary>
        public virtual string NameCSourcePushFlow => "Mfc15.Ramp";

        /// <summary>
        /// Mfc26.Ramp, 流量控制
        /// </summary>
        public virtual string NameCSourceInnerFlow => "Mfc26.Ramp";

        /// <summary>
        /// Mfc25.Ramp, 流量控制
        /// </summary>
        public virtual string NameCSourceMiddleFlow => "Mfc25.Ramp";

        /// <summary>
        /// Mfc15.Ramp, 流量控制
        /// </summary>
        public virtual string NameCSourceOuterFlow => "Mfc15.Ramp";

        /// <summary>
        /// DopeTotalFlow, 涂料总流量
        /// </summary>
        public virtual string NameDopeTotalFlow => "DopeTotalFlow";

        /// <summary>
        /// DopeSplitRatio, 涂料分流比
        /// </summary>
        public virtual string NameDopeSplitRatio => "DopeSplitRatio";

        /// <summary>
        /// Mfc20.Ramp, 流量控制
        /// </summary>
        public virtual string NameDopeInnerFlow => "Mfc20.Ramp";

        /// <summary>
        /// Mfc19.Ramp, 流量控制
        /// </summary>
        public virtual string NameDopeMiddleFlow => "Mfc19.Ramp";

        /// <summary>
        /// Mfc2.Ramp, 流量控制
        /// </summary>
        public virtual string NameDopeOuterFlow => "Mfc2.Ramp";

        /// <summary>
        /// N2ActualFlow, 氮气实际流量
        /// </summary>
        public virtual string NameN2ActualFlow => "N2ActualFlow";

        /// <summary>
        /// Mfc4.Ramp, 流量控制
        /// </summary>
        public virtual string NameN2LowFlow => "Mfc4.Ramp";

        /// <summary>
        /// Mfc3.Ramp, 稀释流量控制
        /// </summary>
        public virtual string NameDilutionFlowForN2 => "Mfc3.Ramp";

        /// <summary>
        /// Mfc6.Ramp, 稀释后的氮气流量控制
        /// </summary>
        public virtual string NameDilutedN2Flow => "Mfc6.Ramp";

        /// <summary>
        /// SHTotalFlow, 总流量
        /// </summary>
        public virtual string NameShTotalFlow => "SHTotalFlow";

        /// <summary>
        /// SHTotalFlowSplitRatio, 总流量分流比
        /// </summary>
        public virtual string NameShTotalFlowSplitRatio => "SHTotalFlowSplitRatio";

        /// <summary>
        /// SHSuppTotalFlow, 支持流量
        /// </summary>
        public virtual string NameShPushTotalFlow => "SHSuppTotalFlow";

        /// <summary>
        /// SHInnerFlow, 内部流量
        /// </summary>
        public virtual string NameShInnerFlow => "SHInnerFlow";

        /// <summary>
        /// SHMidFlow, 中间流量
        /// </summary>
        public virtual string NameShMiddleFlow => "SHMidFlow";

        /// <summary>
        /// SHOutterFlow, 外部流量
        /// </summary>
        public virtual string NameShOuterFlow => "SHOutterFlow";

        /// <summary>
        /// Mfc29.Ramp, 内部推送流量控制
        /// </summary>
        public virtual string NameInnerPushFlow => "Mfc29.Ramp";

        /// <summary>
        /// Mfc30.Ramp, 流量控制
        /// </summary>
        public virtual string Mfc30Flow => "Mfc30.Ramp";

        public virtual string V47Value => "V47Value.SetValve";

        /// <summary>
        /// Mfc31.Ramp, 中间推送流量控制
        /// </summary>
        public virtual string NameMiddlePushFlow => "Mfc31.Ramp";

        /// <summary>
        /// Mfc28.Ramp, 外部推送流量控制
        /// </summary>
        public virtual string NameOuterPushFlow => "Mfc28.Ramp";

        /// <summary>
        /// Mfc40.Ramp, 输送气体流量控制
        /// </summary>
        public virtual string NameCarryGasFlow => "Mfc40.Ramp";

        /// <summary>
        /// Mfc14.Ramp, SiH4流量控制
        /// </summary>
        public virtual string NameSiH4Flow => "Mfc14.Ramp";

        /// <summary>
        /// SiH4.SetValve, 控制SiH4阀门模式
        /// </summary>
        public virtual string NameSiH4FlowMode => "SiH4.SetValve";

        /// <summary>
        /// Mfc1.Ramp, 排气推送流量控制
        /// </summary>
        public virtual string NameVentPushFlow => "Mfc1.Ramp";

        /// <summary>
        /// TotalVentFlow, 总排气流量
        /// </summary>
        public virtual string NameTotalVentFlow => "TotalVentFlow";

        /// <summary>
        /// Mfc13.Ramp, HCl流量控制
        /// </summary>
        public virtual string NameHclFlow => "Mfc13.Ramp";

        /// <summary>
        /// HCl.SetValve, 控制HCl阀门模式
        /// </summary>
        public virtual string NameHclFlowMode => "HCl.SetValve";

        /// <summary>
        /// Mfc5.Ramp, 高流量氮气控制
        /// </summary>
        public virtual string NameN2HighFlow => "Mfc5.Ramp";

        /// <summary>
        /// N2Dilution.SetValve, 控制氮气稀释阀门模式
        /// </summary>
        public virtual string NameN2FlowMode => "N2Dilution.SetValve";

        /// <summary>
        /// N2HighDoping.SetValve, 控制高流量氮气掺杂阀门模式
        /// </summary>
        public virtual string NameN2HighFlowMode => "N2HighDoping.SetValve";

        #endregion


        /// <summary>
        /// 计算指定工艺步骤的气体流量。
        /// </summary>
        /// <param name="step">工艺步骤对象。</param>
        /// <param name="chamberName">
        /// 当前配方步骤所属反应腔的名称，可用的名称请参考<see cref="ModuleName"/>。
        /// <remarks>
        /// 为什么需要传入反应腔名称？
        /// <br/>
        /// 计算Vent Flow时，需要使用TCS、TMA的气体流量参数；而上述两个流量的计算需要使用
        /// 系统配置中PM.{chamberName}.Efficiency.TCS-Eff或TMA-Eff的配置值。因此计算
        /// 配方气体流量时需要传入反应腔名称以获取这两个配置参数的数值。
        /// </remarks>
        /// </param>
        public void Calculate(RecipeStep step, string chamberName)
        {
            CalSiSourceFlow(step);
            CalCSourceFlow(step);
            CalDopeFlow(step);
            CalShSupplementFlow(step);
            CalVentFlow(step, chamberName);
            CheckM3M4M6(step);
        }


        #region Gas Flow Calculation

        protected virtual void CheckM3M4M6(RecipeStep step)
        {
            var mfc3 = ((DoubleParam)step.FindParamByControlName(NameDilutionFlowForN2)).Value;
            var mfc4 = ((DoubleParam)step.FindParamByControlName(NameN2LowFlow)).Value;
            var mfc6 = ((DoubleParam)step.FindParamByControlName(NameDilutedN2Flow)).Value;

            if (mfc3 + mfc4 > mfc6)
            {
                step.FindParamByControlName(NameDilutionFlowForN2).ResetCalculatorError();
                step.FindParamByControlName(NameN2LowFlow).ResetCalculatorError();
                step.FindParamByControlName(NameDilutedN2Flow).ResetCalculatorError();
            }
            else
            {
                step.FindParamByControlName(NameDilutionFlowForN2).SetCalculatorError();
                step.FindParamByControlName(NameN2LowFlow).SetCalculatorError();
                step.FindParamByControlName(NameDilutedN2Flow).SetCalculatorError();
            }
        }

        protected virtual double GetTcsFlow(RecipeStep step, string chamberName)
        {
            var currentTcsBubbleLowFlow = ((DoubleParam)step.FindParamByControlName(NameTcsBubbleLowFlow)).Value;
            var currentTcsBubbleHighFlow = ((DoubleParam)step.FindParamByControlName(NameTcsBubbleHighFlow)).Value;
            var currentTcsPushFlow = ((DoubleParam)step.FindParamByControlName(NameTcsPushFlow)).Value;
            var currentTcsFlowMode = ((ComboxParam)step.FindParamByControlName(NameTcsFlowMode)).Value;

            var tcsFlow = 0d;

            var tcsEff =
                (double)QueryDataClient.Instance.Service.GetConfig($"PM.{chamberName}.Efficiency.TCS-Eff");
            if (currentTcsFlowMode.Equals(FlowModeParam.FlowModeEnum.Run)
                || currentTcsFlowMode.Equals(FlowModeParam.FlowModeEnum.Vent))
            {
                tcsFlow = (currentTcsBubbleHighFlow + currentTcsBubbleLowFlow) * tcsEff + currentTcsPushFlow;
            }
            else if (currentTcsFlowMode.Equals(FlowModeParam.FlowModeEnum.Purge))
            {
                tcsFlow = currentTcsBubbleHighFlow + currentTcsBubbleLowFlow + currentTcsPushFlow;
            }

            return tcsFlow;
        }

        protected  virtual double GetTmaFlow(RecipeStep step, string chamberName)
        {
            var currentTmaBubbleFlow = ((DoubleParam)step.FindParamByControlName(NameTmaBubbleFlow)).Value;
            var currentTmaPushFlow = ((DoubleParam)step.FindParamByControlName(NameTmaPushFlow)).Value;
            var currentTmaFlowMode = ((ComboxParam)step.FindParamByControlName(NameTmaFlowMode)).Value;

            var tmaFlow = 0d;
            var tmaEff =
                (double)QueryDataClient.Instance.Service.GetConfig($"PM.{chamberName}.Efficiency.TMA-Eff");

            if (currentTmaFlowMode.Equals(FlowModeParam.FlowModeEnum.Run)
                || currentTmaFlowMode.Equals(FlowModeParam.FlowModeEnum.Vent))
                tmaFlow = currentTmaBubbleFlow * tmaEff + currentTmaPushFlow;
            else if (currentTmaFlowMode.Equals(FlowModeParam.FlowModeEnum.Purge))
                tmaFlow = currentTmaBubbleFlow + currentTmaPushFlow;

            return tmaFlow;
        }

        protected virtual void CalSiSourceFlow(RecipeStep step)
        {
            var currentSiSourSplitRatio = new double[3];
            if (step.FindParamByControlName(NameSiSourceSplitRatio) is Sets3RatioParam siSourceRatio)
                currentSiSourSplitRatio = siSourceRatio.Ratio;

            var currentSiSourTotalFlow = ((DoubleParam)step.FindParamByControlName(NameSiSourceTotalFlow)).Value;

            //double currentSiSourPushFlow = currentSiSourTotalFlow - (currentSiH4FlowMode == FlowMode.Run.ToString() ? currentSiH4Flow : 0)
            //    - (currentTCSFlowMode == FlowMode.Run.ToString() ? TCSFlow : 0) - (currentHClFlowMode == FlowMode.Run.ToString() ? currentHClFlow : 0);

            //(currentStep[(int)RecipColNo.SiSourceOuterFlow] as DoubleParam).Value = currentSiSourPushFlow.ToString("F1");

            double currentSiSourInnerFlow = 0;
            double currentSiSourMidFlow = 0;
            double currentSiSourOutFlow = 0;

            if (currentSiSourSplitRatio.Length == 3)
            {
                var rationSum = currentSiSourSplitRatio[0] + currentSiSourSplitRatio[1] + currentSiSourSplitRatio[2];

                currentSiSourInnerFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[0];
                currentSiSourMidFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[1];
                currentSiSourOutFlow = currentSiSourTotalFlow / rationSum * currentSiSourSplitRatio[2];
            }

            ((DoubleParam)step.FindParamByControlName(NameSiSourceInnerFlow)).Value = Math.Round(currentSiSourInnerFlow, 1);
            ((DoubleParam)step.FindParamByControlName(NameSiSourceMiddleFlow)).Value = Math.Round(currentSiSourMidFlow, 1);
            ((DoubleParam)step.FindParamByControlName(NameSiSourceOuterFlow)).Value = Math.Round(currentSiSourOutFlow, 1);
        }

        protected virtual void CalCSourceFlow(RecipeStep currentStep)
        {
            var currentC2H4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameCxHxFlow)).Value;
            var currentCSourSplitRatio = new double[3];
            if (currentStep.FindParamByControlName(NameCSourceSplitRatio) is Sets3RatioParam cSourceRatio)
                currentCSourSplitRatio = cSourceRatio.Ratio;

            var currentCSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceTotalFlow)).Value;

            var currentC2H4FlowMode = (currentStep.FindParamByControlName(NameCxHxFlowMode) as ComboxParam)?.Value;
            var currentCSourPushFlow =
                currentCSourTotalFlow - (currentC2H4FlowMode != null &&
                                         currentC2H4FlowMode.Equals(FlowModeParam.FlowModeEnum.Run)
                    ? currentC2H4Flow
                    : 0d);


            ((DoubleParam)currentStep.FindParamByControlName(NameCSourcePushFlow)).Value = currentCSourPushFlow.Round(1);

            double currentCSourInnerFlow = 0;
            double currentCSourMidFlow = 0;
            double currentCSourOuterFlow = 0;

            if (currentCSourSplitRatio.Length == 3)
            {
                var ratioSum = currentCSourSplitRatio[0] + currentCSourSplitRatio[1] + currentCSourSplitRatio[2];

                currentCSourInnerFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[0];
                currentCSourMidFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[1];
                currentCSourOuterFlow = currentCSourTotalFlow / ratioSum * currentCSourSplitRatio[2];
            }

            ((DoubleParam)currentStep.FindParamByControlName(NameCSourceInnerFlow)).Value = currentCSourInnerFlow.Round(1);
            ((DoubleParam)currentStep.FindParamByControlName(NameCSourceMiddleFlow)).Value = currentCSourMidFlow.Round(1);
            ((DoubleParam)currentStep.FindParamByControlName(NameCSourceOuterFlow)).Value = currentCSourOuterFlow.Round(1);
        }

        protected virtual void CalDopeFlow(RecipeStep currentStep)
        {
            var currentDopeTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeTotalFlow)).Value;
            var currentN2ActualFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2ActualFlow)).Value;
            var currentN2LowFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2LowFlow)).Value;
            var currentDiluFlowForN2 = ((DoubleParam)currentStep.FindParamByControlName(NameDilutionFlowForN2)).Value;


            var currentDilutedN2Flow =
                (currentN2LowFlow + currentDiluFlowForN2) * currentN2ActualFlow / currentN2LowFlow;
            ((DoubleParam)currentStep.FindParamByControlName(NameDilutedN2Flow)).Value = Math.Round(currentDilutedN2Flow, 1);


            var currentDopeSplitRatio = new double[3];
            if (currentStep.FindParamByControlName(NameDopeSplitRatio) is Sets3RatioParam dopRatio)
                currentDopeSplitRatio = dopRatio.Ratio;



            //double currentDopePushFlow = currentDopeTotalFlow
            //    - (currentN2FlowMode == FlowMode.Run.ToString() ? currentDilutedN2Flow : 0)
            //    - (currentN2HighFlowMode == FlowMode.Run.ToString() ? currentN2HighFlow : 0)
            //    - (currentTMAFlowMode == FlowMode.Run.ToString() ? TMAFlow : 0);

            //(currentStep[(int)RecipColNo.DopeOuterFlow] as DoubleParam).Value = currentDopePushFlow.ToString("F1");

            double currentDopeInnerFlow = 0;
            double currentDopeMidFlow = 0;
            double currentDopeOuterFlow = 0;

            if (currentDopeSplitRatio.Length == 3)
            {
                var ratioSum = currentDopeSplitRatio[0] + currentDopeSplitRatio[1] + currentDopeSplitRatio[2];

                currentDopeInnerFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[0];
                currentDopeMidFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[1];
                currentDopeOuterFlow = currentDopeTotalFlow / ratioSum * currentDopeSplitRatio[2];
            }

            ((DoubleParam)currentStep.FindParamByControlName(NameDopeInnerFlow)).Value = Math.Round(currentDopeInnerFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameDopeMiddleFlow)).Value = Math.Round(currentDopeMidFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameDopeOuterFlow)).Value = Math.Round(currentDopeOuterFlow, 1);
        }

        protected virtual void CalShSupplementFlow(RecipeStep currentStep)
        {
            var currentSiSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceTotalFlow)).Value;
            var currentCSourTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceTotalFlow)).Value;
            var currentDopeTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeTotalFlow)).Value;

            var currentShTotalFlow = ((DoubleParam)currentStep.FindParamByControlName(NameShTotalFlow)).Value;
            var currentSurroundingFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCarryGasFlow)).Value;


            var currentSiSourInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceInnerFlow)).Value;
            var currentSiSourMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameSiSourceMiddleFlow)).Value;

            var currentCSourInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceInnerFlow)).Value;
            var currentCSourMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameCSourceMiddleFlow)).Value;

            var currentDopeInnerFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeInnerFlow)).Value;
            var currentDopeMidFlow = ((DoubleParam)currentStep.FindParamByControlName(NameDopeMiddleFlow)).Value;


            var currentShTotalFlowSplitRatio = new double[3];
            if (currentStep.FindParamByControlName(NameShTotalFlowSplitRatio) is Sets3RatioParam shTotalRatio)
                currentShTotalFlowSplitRatio = shTotalRatio.Ratio;


            var currentShSuppTotalFlow = currentShTotalFlow - currentSurroundingFlow - currentSiSourTotalFlow -
                                         currentCSourTotalFlow - currentDopeTotalFlow;
            var sumShTotalFlowSplitRatio = currentShTotalFlowSplitRatio[0] + currentShTotalFlowSplitRatio[1] +
                                           currentShTotalFlowSplitRatio[2];
            var currentShInnerFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio *
                                     currentShTotalFlowSplitRatio[0];
            var currentShMidFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio *
                                   currentShTotalFlowSplitRatio[1];
            var currentShOutterFlow = (currentShTotalFlow - currentSurroundingFlow) / sumShTotalFlowSplitRatio *
                                      currentShTotalFlowSplitRatio[2];
            var currentInnerSuppFlow = currentShInnerFlow - currentSiSourInnerFlow - currentCSourInnerFlow -
                                       currentDopeInnerFlow;
            var currentMidSuppFlow = currentShMidFlow - currentSiSourMidFlow - currentCSourMidFlow - currentDopeMidFlow;
            var currentOutterSuppFlow = currentShSuppTotalFlow - currentInnerSuppFlow - currentMidSuppFlow;

            ((DoubleParam)currentStep.FindParamByControlName(NameShPushTotalFlow)).Value = Math.Round(currentShSuppTotalFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameShInnerFlow)).Value = Math.Round(currentShInnerFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameShMiddleFlow)).Value = Math.Round(currentShMidFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameShOuterFlow)).Value = Math.Round(currentShOutterFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameInnerPushFlow)).Value = Math.Round(currentInnerSuppFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameMiddlePushFlow)).Value = Math.Round(currentMidSuppFlow, 1);
            ((DoubleParam)currentStep.FindParamByControlName(NameOuterPushFlow)).Value = Math.Round(currentOutterSuppFlow, 1);
        }

        protected virtual void CalVentFlow(RecipeStep currentStep, string chamberName)
        {
            var currentSiH4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameSiH4Flow)).Value;
            var currentTotalVentFlow = ((DoubleParam)currentStep.FindParamByControlName(NameTotalVentFlow)).Value;
            var currentHClFlow = ((DoubleParam)currentStep.FindParamByControlName(NameHclFlow)).Value;
            var currentN2HighFlow = ((DoubleParam)currentStep.FindParamByControlName(NameN2HighFlow)).Value;
            var currentC2H4Flow = ((DoubleParam)currentStep.FindParamByControlName(NameCxHxFlow)).Value;
            var currentDilutedN2Flow = ((DoubleParam)currentStep.FindParamByControlName(NameDilutedN2Flow)).Value;

            var currentN2FlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameN2FlowMode)).Value;
            var currentN2HighFlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameN2HighFlowMode)).Value;
            var currentSiH4FlowMode = (currentStep.FindParamByControlName(NameSiH4FlowMode) as ComboxParam)?.Value;
            var currentTcsFlowMode = (currentStep.FindParamByControlName(NameTcsFlowMode) as ComboxParam)?.Value;
            var currentHClFlowMode = (currentStep.FindParamByControlName(NameHclFlowMode) as ComboxParam)?.Value;
            var currentC2H4FlowMode = (currentStep.FindParamByControlName(NameCxHxFlowMode) as ComboxParam)?.Value;
            var currentTmaFlowMode = ((ComboxParam)currentStep.FindParamByControlName(NameTmaFlowMode)).Value;

            var tcsFlow = GetTcsFlow(currentStep, chamberName);
            var tmaFlow = GetTmaFlow(currentStep, chamberName);

            var currentSiSourTotalFlowForPurge =
                (currentSiH4FlowMode != null && currentSiH4FlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                    ? currentSiH4Flow
                    : 0d)
                + (currentTcsFlowMode != null && currentTcsFlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                    ? tcsFlow
                    : 0d) +
                (currentHClFlowMode != null && currentHClFlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                    ? currentHClFlow
                    : 0d);

            var currentCSourTotalFlowForPurge =
                currentC2H4FlowMode != null && currentC2H4FlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                    ? currentC2H4Flow
                    : 0d;


            var n2Flow = (currentN2FlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                             ? currentDilutedN2Flow
                             : 0d) +
                         (currentN2HighFlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                             ? currentN2HighFlow
                             : 0d);

            var currentDopeTotalFlowForPurge = n2Flow +
                                               (currentTmaFlowMode.Equals(FlowModeParam.FlowModeEnum.Run) == false
                                                   ? tmaFlow
                                                   : 0d);

            var currentVentPushFlow = currentTotalVentFlow - currentSiSourTotalFlowForPurge -
                                      currentCSourTotalFlowForPurge - currentDopeTotalFlowForPurge;

            ((DoubleParam)currentStep.FindParamByControlName(NameVentPushFlow)).Value = Math.Round(currentVentPushFlow, 1);
        }

        #endregion
    }
}
