using NIDAQmx.DAQmxEnum;
using NIDAQmxConst;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace NIDAQmx
{
    public class CO : BaseDevice
    {
        internal CO(DAQmxSession session, string deviceName) : base(session, deviceName)
        {
            PhysicalChans = GetPhysicalChans();
            COSupportedOutputTypes[] types = new COSupportedOutputTypes[Enum.GetValues<COSupportedOutputTypes>().Length];
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOSupportedOutputTypes>()(DeviceName, ref types[0], (uint)types.Length));
            SupportedOutputTypes = types.Where(x => x != 0).ToArray();
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOSampClkSupported>()(DeviceName, ref sampClkSupported));
            int val = 0;
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOTrigUsage>()(DeviceName, ref val));
            List<TriggerUsageTypeBits> bits = new List<TriggerUsageTypeBits>();
            Enum.GetValues<TriggerUsageTypeBits>().ToList().ForEach(x =>
            {
                if ((val & (int)x) == (int)x) bits.Add(x);
            });
            TrigUsage = bits.ToArray();
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOMaxSize>()(DeviceName, ref maxsize));
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOMaxTimebase>()(DeviceName, ref maxtimebase));
            SampleModes[] modes = new SampleModes[Enum.GetValues<SampleModes>().Length];
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOSampModes>()(DeviceName, ref modes[0], (uint)modes.Length));
            SampleModes = modes.Where(x => x != 0).ToArray();
        }
        private string[] GetPhysicalChans()
        {
            byte[] buf = new byte[1024];
            _Session.CheckResult(_Session.GetDelegate<Internal.CO.DAQmxGetDevCOPhysicalChans>()(DeviceName, ref buf[0], (uint)buf.Length));
            return  System.Text.Encoding.UTF8.GetString(buf).Trim('\0').Split(',').Select(x=>x.Trim('\0')).Where(x=>!string.IsNullOrEmpty(x)).ToArray();
        }
        public SampleModes[] SampleModes { get; }
        public string[] PhysicalChans { get; }
        public COSupportedOutputTypes[] SupportedOutputTypes { get; }
        private bool sampClkSupported = false;
        public bool SampClkSupported => sampClkSupported;
        public TriggerUsageTypeBits[] TrigUsage { get; }
        private uint maxsize = 0;
        private double maxtimebase = 0;
        public uint MaxSize => maxsize;
        public double MaxTimebase =>maxtimebase;
    }
}
