using NIDAQmx.DAQmxEnum;
using NIDAQmxConst;
using System;
using System.Collections.Generic;
using System.Diagnostics.SymbolStore;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NIDAQmx
{
    public class COChannelConfig : BaseChannelConfig
    {
        internal COChannelConfig(ChannelAttributeSession session) : base(session)
        {
            AttributeSession = session;
            Pulse = new PulseConfig(session);
            GeneralProperties = new GeneralPropertiesConfig(session);
        }
        internal override ChannelAttributeSession AttributeSession { get; }
        public PulseConfig Pulse { get; }
        public GeneralPropertiesConfig GeneralProperties { get; }
        public COOutputType OutputType { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOOutputType,COOutputType>(); }

        public class PulseConfig:BaseChannelConfig
        {
            internal PulseConfig(ChannelAttributeSession session) : base(session)
            {
                AttributeSession = session;
                Time = new TimeConfig(session);
                Freq = new FreqConfig(session);
                Ticks = new TicksConfig(session);
            }
            internal override ChannelAttributeSession AttributeSession { get; }
            public TimeConfig Time { get; }
            public FreqConfig Freq { get; }
            public TicksConfig Ticks { get; }
            public OutputState IdleState { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOOutputState,OutputState>(); }
            public string Term { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseTerm>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseTerm>(value); }


            public class TimeConfig:BaseChannelConfig
            {
                internal TimeConfig(ChannelAttributeSession session) : base(session)
                {
                    AttributeSession = session;
                }
                internal override ChannelAttributeSession AttributeSession { get; }
                public PulseTimeUnits Units { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseTimeUnits,PulseTimeUnits>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseTimeUnits,PulseTimeUnits>(value); }
                public double HighTime { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseHighTime,double>();set=> AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseHighTime,double>(value); }
                public double LowTime { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseLowTime,double>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseLowTime,double>(value); }
                public double InitialDelay { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseTimeInitialDelay,double>();set=> AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseTimeInitialDelay,double>(value); }
            }

            public class FreqConfig:BaseChannelConfig
            {
                internal FreqConfig(ChannelAttributeSession session) : base(session)
                {
                    AttributeSession = session;
                }
                internal override ChannelAttributeSession AttributeSession { get; }
                public double DutyCyc { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseDutyCyc,double>();set=> AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseDutyCyc,double>(value); }
                public PulseFreqUnits Units { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseFreqUnits,PulseFreqUnits>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseFreqUnits,PulseFreqUnits>(value); }
                public double Freq { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseFreq,double>();set=> AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseFreq,double>(value); }
                public double InitialDelay { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseFreqInitialDelay,double>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseFreqInitialDelay,double>(value); }

            }
            public class TicksConfig : BaseChannelConfig
            {
                internal TicksConfig(ChannelAttributeSession session) : base(session)
                {
                    AttributeSession = session;
                }
                internal override ChannelAttributeSession AttributeSession { get; }
                public uint HighTicks { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseHighTicks,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseHighTicks,uint>(value); }
                public uint LowTicks { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseLowTicks,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseLowTicks,uint>(value); }
                public uint InitialDelay { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseTicksInitialDelay,uint>();set=> AttributeSession.SetValue<Internal.CO.DAQmxSetCOPulseTicksInitialDelay,uint>(value); }
            }
        }

        public class GeneralPropertiesConfig : BaseChannelConfig
        {
            internal GeneralPropertiesConfig(ChannelAttributeSession session) : base(session)
            {
                AttributeSession = session;
                CtrTimebase = new CtrTimebaseConfig(session);
                Advanced = new AdvancedConfig(session);
            }
            internal override ChannelAttributeSession AttributeSession { get; }
            public uint Count => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCount,uint>();
            public bool PulseDone => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPulseDone,bool>();
            public bool EnableInitialDelayOnRetrigger { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOEnableInitialDelayOnRetrigger,bool>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOEnableInitialDelayOnRetrigger,bool>(value); }
            public OutputState OutputState => AttributeSession.GetValue<Internal.CO.DAQmxGetCOOutputState,OutputState>();
            public uint AutoIncrCnt { get => AttributeSession.GetValue<Internal.CO.DAQmxSetCOAutoIncrCnt,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxGetCOAutoIncrCnt,uint>(value); }
            public uint CtrTimebaseMasterTimebaseDiv { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseMasterTimebaseDiv,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOCtrTimebaseMasterTimebaseDiv,uint>(value); }

            public CtrTimebaseConfig CtrTimebase { get; }
            public AdvancedConfig Advanced { get; }

            public class CtrTimebaseConfig : BaseChannelConfig
            {
                internal CtrTimebaseConfig(ChannelAttributeSession session) : base(session)
                {
                    AttributeSession = session;
                    DigFltr = new DigFltrConfig(session);
                }
                internal override ChannelAttributeSession AttributeSession { get; }
                public DigFltrConfig DigFltr { get; }
                public string Src { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseSrc>(); set => AttributeSession.SetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseSrc>(value); }
                public double Rate { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseRate,double>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOCtrTimebaseDigFltrTimebaseRate,double>(value); }
                public AnalogActiveEdge ActiveEdge { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseActiveEdge,AnalogActiveEdge>(); set => AttributeSession.SetValue<Internal.CO.DAQmxGetCOCtrTimebaseActiveEdge,AnalogActiveEdge>(value); }
                public class DigFltrConfig : BaseChannelConfig
                {
                    internal DigFltrConfig(ChannelAttributeSession session) : base(session)
                    {
                        AttributeSession = session;
                    }
                    internal override ChannelAttributeSession AttributeSession { get; }
                    public bool Enable { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrEnable,bool>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOCtrTimebaseDigFltrEnable,bool>(value); }
                    public double MinPulseWidth { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrMinPulseWidth,double>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOCtrTimebaseDigFltrMinPulseWidth,double>(value); }
                    public string TicksbaseSrc { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseSrc>(); set => AttributeSession.SetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseSrc>(value); }
                    public double TicksbaseRate { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigFltrTimebaseRate,double>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOCtrTimebaseDigFltrTimebaseRate,double>(value); }
                    public bool DigSyncEnable { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigSyncEnable,bool>(); set => AttributeSession.SetValue<Internal.CO.DAQmxGetCOCtrTimebaseDigSyncEnable,bool>(value); }

                }

            }

            public class AdvancedConfig : BaseChannelConfig
            {
                internal AdvancedConfig(ChannelAttributeSession session) : base(session)
                {
                    AttributeSession = session;
                }
                internal override ChannelAttributeSession AttributeSession { get; }
                public ConstrainedGenMode ConstrainedGenMode { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOConstrainedGenMode,ConstrainedGenMode>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOConstrainedGenMode,ConstrainedGenMode>(value); }
                public DataXferMech DataXferMech { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCODataXferMech,DataXferMech>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCODataXferMech,DataXferMech>(value); }
                public OutDataXferReqCond DataXferReqCond { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCODataXferReqCond,OutDataXferReqCond>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCODataXferReqCond,OutDataXferReqCond>(value); }
                public uint UsbXferReqSize { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOUsbXferReqSize, uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOUsbXferReqSize, uint>(value); }
                public uint UsbXferReqCount { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOUsbXferReqCount,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOUsbXferReqCount,uint>(value); }
                public bool MemMapEnable { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOMemMapEnable,bool>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOMemMapEnable,bool>(value); }
                public uint Prescaler { get => AttributeSession.GetValue<Internal.CO.DAQmxGetCOPrescaler,uint>(); set => AttributeSession.SetValue<Internal.CO.DAQmxSetCOPrescaler,uint>(value); }
                public bool RdyForNewVal => AttributeSession.GetValue<Internal.CO.DAQmxGetCORdyForNewVal,bool>();
            }
        }
    }
}
