using System;
using NinjaTrader.OFA;

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    public partial class Indicator : IndicatorBase
    {
        protected OFAVolumeCluster[] CacheOFAVolumeCluster = null;
        private static readonly object syncOFAVolumeCluster = new object();

        protected OFAMomentum[] CacheOFAMomentum = null;
        private static readonly object syncOFAMomentum = new object();

        protected OFAExhaustion[] CacheOFAExhaustion = null;
        private static readonly object syncOFAExhaustion = new object();

        protected OFADataClassification[] CacheOFADataClassification = null;
        private static readonly object syncOFADataClassification = new object();

        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        public OFAVolumeCluster OFAVolumeCluster(int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            return OFAVolumeCluster(Input, initiatingValue, responsiveValue, clusterConcentration);
        }

        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        public OFAVolumeCluster OFAVolumeCluster(Data.IDataSeries input, int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            if (CacheOFAVolumeCluster != null)
                for (int idx = 0; idx < CacheOFAVolumeCluster.Length; idx++)
                    if (CacheOFAVolumeCluster[idx].InitiatingValue == initiatingValue && CacheOFAVolumeCluster[idx].ResponsiveValue == responsiveValue && CacheOFAVolumeCluster[idx].ClusterConcentration == (OFALevelValue)clusterConcentration && CacheOFAVolumeCluster[idx].EqualsInput(input))
                        return CacheOFAVolumeCluster[idx];

            lock (syncOFAVolumeCluster)
            {
                if (CacheOFAVolumeCluster != null)
                    for (int idx = 0; idx < CacheOFAVolumeCluster.Length; idx++)
                        if (CacheOFAVolumeCluster[idx].InitiatingValue == initiatingValue && CacheOFAVolumeCluster[idx].ResponsiveValue == responsiveValue && CacheOFAVolumeCluster[idx].ClusterConcentration == (OFALevelValue)clusterConcentration && CacheOFAVolumeCluster[idx].EqualsInput(input))
                            return CacheOFAVolumeCluster[idx];

                OFAVolumeCluster indicator = new OFAVolumeCluster();
                indicator.BarsRequired = BarsRequired;
                indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
                indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
                indicator.Input = input;
                indicator.UIIndicator = false; //Don't change this flag
                indicator.InitiatingValue = initiatingValue;
                indicator.ResponsiveValue = responsiveValue;
                indicator.ClusterConcentration = (OFALevelValue)clusterConcentration;
                Indicators.Add(indicator);
                indicator.SetUp();

                OFAVolumeCluster[] tmp = new OFAVolumeCluster[CacheOFAVolumeCluster == null ? 1 : CacheOFAVolumeCluster.Length + 1];
                if (CacheOFAVolumeCluster != null)
                    CacheOFAVolumeCluster.CopyTo(tmp, 0);
                tmp[tmp.Length - 1] = indicator;
                CacheOFAVolumeCluster = tmp;
                return indicator;
            }
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        public OFAMomentum OFAMomentum(OFAMomentumPattern momentumPattern)
        {
            return OFAMomentum(Input, momentumPattern);
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        public OFAMomentum OFAMomentum(Data.IDataSeries input, OFAMomentumPattern momentumPattern)
        {
            if (CacheOFAMomentum != null)
                for (int idx = 0; idx < CacheOFAMomentum.Length; idx++)
                    if (CacheOFAMomentum[idx].MomentumPattern == momentumPattern && CacheOFAMomentum[idx].EqualsInput(input))
                        return CacheOFAMomentum[idx];

            lock (syncOFAMomentum)
            {
                if (CacheOFAMomentum != null)
                    for (int idx = 0; idx < CacheOFAMomentum.Length; idx++)
                        if (CacheOFAMomentum[idx].MomentumPattern == momentumPattern && CacheOFAMomentum[idx].EqualsInput(input))
                            return CacheOFAMomentum[idx];

                OFAMomentum indicator = new OFAMomentum();
                indicator.BarsRequired = BarsRequired;
                indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
                indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
                indicator.Input = input;
                indicator.UIIndicator = false; //Don't change this flag
                Indicators.Add(indicator);
                indicator.SetUp();
                indicator.MomentumPattern = momentumPattern;

                OFAMomentum[] tmp = new OFAMomentum[CacheOFAMomentum == null ? 1 : CacheOFAMomentum.Length + 1];
                if (CacheOFAMomentum != null)
                    CacheOFAMomentum.CopyTo(tmp, 0);
                tmp[tmp.Length - 1] = indicator;
                CacheOFAMomentum = tmp;
                return indicator;
            }
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        public OFAExhaustion OFAExhaustion(OFAExhaustionPattern exhaustionPattern)
        {
            return OFAExhaustion(Input, exhaustionPattern);
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        public OFAExhaustion OFAExhaustion(Data.IDataSeries input, OFAExhaustionPattern exhaustionPattern)
        {
            if (CacheOFAExhaustion != null)
                for (int idx = 0; idx < CacheOFAExhaustion.Length; idx++)
                    if (CacheOFAExhaustion[idx].ExhaustionPattern == exhaustionPattern && CacheOFAExhaustion[idx].EqualsInput(input))
                        return CacheOFAExhaustion[idx];

            lock (syncOFAExhaustion)
            {
                if (CacheOFAExhaustion != null)
                    for (int idx = 0; idx < CacheOFAExhaustion.Length; idx++)
                        if (CacheOFAExhaustion[idx].ExhaustionPattern == exhaustionPattern && CacheOFAExhaustion[idx].EqualsInput(input))
                            return CacheOFAExhaustion[idx];

                OFAExhaustion indicator = new OFAExhaustion();
                indicator.BarsRequired = BarsRequired;
                indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
                indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
                indicator.Input = input;
                indicator.UIIndicator = false; //Don't change this flag
                Indicators.Add(indicator);
                indicator.SetUp();
                indicator.ExhaustionPattern = exhaustionPattern;

                OFAExhaustion[] tmp = new OFAExhaustion[CacheOFAExhaustion == null ? 1 : CacheOFAExhaustion.Length + 1];
                if (CacheOFAExhaustion != null)
                    CacheOFAExhaustion.CopyTo(tmp, 0);
                tmp[tmp.Length - 1] = indicator;
                CacheOFAExhaustion = tmp;
                return indicator;
            }
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        public OFADataClassification OFADataClassification(OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            return OFADataClassification(Input, strongBidAskLevel, weakBidAskLevel);
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        public OFADataClassification OFADataClassification(Data.IDataSeries input, OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            if (CacheOFADataClassification != null)
                for (int idx = 0; idx < CacheOFADataClassification.Length; idx++)
                    if (CacheOFADataClassification[idx].StrongBidAskLevel == strongBidAskLevel && CacheOFADataClassification[idx].WeakBidAskLevel == weakBidAskLevel && CacheOFADataClassification[idx].EqualsInput(input))
                        return CacheOFADataClassification[idx];

            lock (syncOFADataClassification)
            {
                if (CacheOFADataClassification != null)
                    for (int idx = 0; idx < CacheOFADataClassification.Length; idx++)
                        if (CacheOFADataClassification[idx].StrongBidAskLevel == strongBidAskLevel && CacheOFADataClassification[idx].WeakBidAskLevel == weakBidAskLevel && CacheOFADataClassification[idx].EqualsInput(input))
                            return CacheOFADataClassification[idx];

                OFADataClassification indicator = new OFADataClassification();
                indicator.BarsRequired = BarsRequired;
                indicator.CalculateOnBarClose = CalculateOnBarClose;
#if NT7
                indicator.ForceMaximumBarsLookBack256 = ForceMaximumBarsLookBack256;
                indicator.MaximumBarsLookBack = MaximumBarsLookBack;
#endif
                indicator.Input = input;
                //indicator.UIIndicator = false; //Don't change this flag
                Indicators.Add(indicator);
                indicator.SetUp();
                indicator.WeakBidAskLevel = weakBidAskLevel;
                indicator.StrongBidAskLevel = strongBidAskLevel;

                OFADataClassification[] tmp = new OFADataClassification[CacheOFADataClassification == null ? 1 : CacheOFADataClassification.Length + 1];
                if (CacheOFADataClassification != null)
                    CacheOFADataClassification.CopyTo(tmp, 0);
                tmp[tmp.Length - 1] = indicator;
                CacheOFADataClassification = tmp;
                return indicator;
            }
        }
 
    }
}

// This namespace holds all market analyzer column definitions and is required. Do not change it.
namespace NinjaTrader.MarketAnalyzer
{
    public partial class Column : ColumnBase
    {
        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAVolumeCluster OFAVolumeCluster(int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            return _indicator.OFAVolumeCluster(Input, initiatingValue, responsiveValue, clusterConcentration);
        }

        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAVolumeCluster OFAVolumeCluster(Data.IDataSeries input, int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            return _indicator.OFAVolumeCluster(input, initiatingValue, responsiveValue, clusterConcentration);
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAMomentum OFAMomentum(OFAMomentumPattern momentumPattern)
        {
            return _indicator.OFAMomentum(Input, momentumPattern);
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAMomentum OFAMomentum(Data.IDataSeries input, OFAMomentumPattern momentumPattern)
        {
            return _indicator.OFAMomentum(input, momentumPattern);
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAExhaustion OFAExhaustion(OFAExhaustionPattern exhaustionPattern)
        {
            return _indicator.OFAExhaustion(Input, exhaustionPattern);
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAExhaustion OFAExhaustion(Data.IDataSeries input, OFAExhaustionPattern exhaustionPattern)
        {
            return _indicator.OFAExhaustion(input, exhaustionPattern);
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFADataClassification OFADataClassification(OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            return _indicator.OFADataClassification(Input, strongBidAskLevel, weakBidAskLevel);
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFADataClassification OFADataClassification(Data.IDataSeries input, OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            return _indicator.OFADataClassification(input, strongBidAskLevel, weakBidAskLevel);
        }

    }
}

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
    public partial class Strategy : StrategyBase
    {
        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAVolumeCluster OFAVolumeCluster(int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            return _indicator.OFAVolumeCluster(Input, initiatingValue, responsiveValue, clusterConcentration);
        }

        /// <summary>
        /// OFA™ Volume Cluster Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAVolumeCluster OFAVolumeCluster(Data.IDataSeries input, int initiatingValue, int responsiveValue, int clusterConcentration)
        {
            if (InInitialize && input == null)
                throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

            return _indicator.OFAVolumeCluster(input, initiatingValue, responsiveValue, clusterConcentration);
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAMomentum OFAMomentum(OFAMomentumPattern momentumPattern)
        {
            return _indicator.OFAMomentum(Input, momentumPattern);
        }

        /// <summary>
        /// OFA™ Momentum Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAMomentum OFAMomentum(Data.IDataSeries input, OFAMomentumPattern momentumPattern)
        {
            if (InInitialize && input == null)
                throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

            return _indicator.OFAMomentum(input, momentumPattern);
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFAExhaustion OFAExhaustion(OFAExhaustionPattern exhaustionPattern)
        {
            return _indicator.OFAExhaustion(Input, exhaustionPattern);
        }

        /// <summary>
        /// OFA™ Exhaustion Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFAExhaustion OFAExhaustion(Data.IDataSeries input, OFAExhaustionPattern exhaustionPattern)
        {
            if (InInitialize && input == null)
                throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

            return _indicator.OFAExhaustion(input, exhaustionPattern);
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.OFADataClassification OFADataClassification(OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            return _indicator.OFADataClassification(Input, strongBidAskLevel, weakBidAskLevel);
        }

        /// <summary>
        /// OFA™ DataClassification Indicator
        /// </summary>
        /// <returns></returns>
        public Indicator.OFADataClassification OFADataClassification(Data.IDataSeries input, OFALevelValue strongBidAskLevel, OFALevelValue weakBidAskLevel)
        {
            if (InInitialize && input == null)
                throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

            return _indicator.OFADataClassification(input, strongBidAskLevel, weakBidAskLevel);
        }

    }

}

