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

namespace NIDAQmx
{
    public class Task: DAQmxBase
    {

        internal Task(DAQmxSession session):base(session)
        {

        }
        public bool TaskIsCreated => _Session.TaskHandle != IntPtr.Zero;
        public void LoadTask(string taskname)
        {
            _Session.LoadTask(taskname);
        }
        public void CreateTask(string taskname)
        {
            _Session.CreateTask(taskname);
        }
        public void StartTask()
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxStartTask>()(_Session.TaskHandle));
        }
        public void StopTask()
        {
            _Session.StopTask();
        }
        public void ClearTask()
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxClearTask>()(_Session.TaskHandle));
        }
        public void AddGlobalChansToTask(string channelnames)
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxAddGlobalChansToTask>()(_Session.TaskHandle, channelnames));
        }
        public void WaitUntilTaskDone(Double timeToWait)
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxWaitUntilTaskDone>()(_Session.TaskHandle, timeToWait));
        }
        public void WaitForValidTimestamp(int timestampEvent,Double timeout,ref CVIAbsoluteTime timestamp)
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxWaitForValidTimestamp>()(_Session.TaskHandle, timestampEvent, timeout, ref timestamp));
        }
        public Boolean IsTaskDone()
        {
            UInt32 result = 0;
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxIsTaskDone>()(_Session.TaskHandle, ref result));
            return Convert.ToBoolean(result);
        }
        public void TaskControl(TaskControl action)
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxTaskControl>()(_Session.TaskHandle, action));
        }
        public String GetNthTaskChannel(UInt32 index,Int32 buffersize)
        {
            StringBuilder stringBuilder = new StringBuilder(buffersize);
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxGetNthTaskChannel>()(_Session.TaskHandle, index, stringBuilder, buffersize));
            return stringBuilder.ToString();
        }
        public string GetNthTaskDevice(UInt32 index,Int32 buffersize)
        {
            StringBuilder stringBuilder = new StringBuilder(buffersize);
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxGetNthTaskDevice>()(_Session.TaskHandle, index, stringBuilder, buffersize));
            return stringBuilder.ToString();
        }
        public string Name => _Session.GetValue<Internal.Task.DAQmxGetTaskName>();
        public string[] Channels=>_Session.GetStrings<Internal.Task.DAQmxGetTaskChannels>(4096);
        public string[] Devices=>_Session.GetStrings<Internal.Task.DAQmxGetTaskDevices>(4096);
        public uint NumChans=>_Session.GetValue<Internal.Task.DAQmxGetTaskNumChans,uint>();
        public uint NumDevices => _Session.GetValue<Internal.Task.DAQmxGetTaskNumDevices,uint>();

        public unsafe void RegisterEveryNSamplesEvent<T>(EveryNsamplesEventType everyNsamplesEventType,uint nSamples,DAQmxEveryNSamplesEventCallbackPtr callbak,ref T callbakdata,UInt32 options=1)where T:unmanaged
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxRegisterEveryNSamplesEvent>()(_Session.TaskHandle, everyNsamplesEventType, nSamples, options, callbak, Unsafe.AsPointer(ref callbakdata)));
        }
        public unsafe void RegisterDoneEvent<T>(DAQmxDoneEventCallbackPtr callback,ref T callbackdata,UInt32 options=1)where T :unmanaged
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxRegisterDoneEvent>()(_Session.TaskHandle, options, callback, Unsafe.AsPointer(ref callbackdata)));
        }
        public unsafe void RegisterSignalEvent<T>(Int32 signalID,DAQmxSignalEventCallbackPtr callback,ref T callbackdata,UInt32 options=1)where T:unmanaged
        {
            _Session.CheckResult(_Session.GetDelegate<Internal.Task.DAQmxRegisterSignalEvent>()(_Session.TaskHandle, signalID, options, callback, Unsafe.AsPointer(ref callbackdata)));
        }
    }
}
