from ctypes import *
from ctypes.wintypes import *
import ctypes
import time

import os

# Load the DLL that sits next to this script.
_HERE = os.path.dirname(os.path.abspath(__file__))

hllDll = CDLL(os.path.join(_HERE, "DSRemoteConnect64.dll"))

dsconInstance = HANDLE()
err_code = hllDll.dsconCreateInstance(pointer(dsconInstance), 0)
err_code = hllDll.dsconConnect(dsconInstance, c_char_p(b""))  # empty = local DCOM

# Point this at your own setup, or leave it out to use the setup DewesoftX
# already has open.
#err_code = hllDll.dsconLoadSetup(dsconInstance, c_char_p(os.path.join(_HERE, 'DSConnTest1.dxs').encode()))

numChannels = c_size_t()
err_code = hllDll.dsconGetChannelCount(dsconInstance, byref(numChannels))
err_code = hllDll.dsconSetAppWindowVisible(dsconInstance, True)


# One way of enumerating Channels
hllDll.dsconInitChannelIdEnum(dsconInstance)
localValue = c_size_t(0)
hllDll.dsconGetNextChannelIdSize(dsconInstance, byref(localValue)) #size of string for preallocation
name = (c_char * (localValue.value))()
id_str   = ctypes.cast(name, c_char_p)
while(hllDll.dsconGetNextChannelId(dsconInstance, id_str) == 0):
	print(id_str.value)
	localValue = c_size_t(0)
	hllDll.dsconGetNextChannelIdSize(dsconInstance, byref(localValue)) #size of string for preallocation
	name = (c_char * (localValue.value))()
	id_str   = ctypes.cast(name, c_char_p)

# Second way of enumerating Channels
labelsPtr = pointer((POINTER(ctypes.c_char_p) * numChannels.value)()) 
localValue = c_size_t(numChannels.value)
hllDll.dsconEnumerateChannels(dsconInstance, labelsPtr, byref(localValue))

name = (c_char * 50)()
ch_name   = ctypes.cast(name, c_char_p)
ch_instances = []
for i in range(0, numChannels.value):
	name = (c_char * len(labelsPtr[0][0][i]))()
	ch_index   = ctypes.cast(name, c_char_p)
	ch_index.value = labelsPtr[0][0][i]
	ch_instance = HANDLE()
	hllDll.dsconCreateChannelInstance(dsconInstance, ch_index, pointer(ch_instance))
	ch_instances.append(ch_instance)
	hllDll.dsconChannelGetName(ch_instances[i], ch_name, 50)
	print(ch_name.value)


err_code = hllDll.dsconStartMeasurement(dsconInstance)

countData = c_size_t(0)
data = (POINTER(c_double) * 1)()
time_stamps = (POINTER(c_double) * 1)()

countData2 = c_size_t(5000)
data2 = ctypes.cast((c_double * 5000)(), POINTER(c_double))
time_stamps2 = ctypes.cast((c_double * 5000)(), POINTER(c_double))

for _ in range(20):
	countData2 = c_size_t(5000)
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[0], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[1], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[2], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[3], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[4], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[5], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[6], data2, time_stamps2, byref(countData2))
	err_code = hllDll.dsconChannelReadScalarData_2(ch_instances[7], data2, time_stamps2, byref(countData2))


err_code = hllDll.dsconStopMeasurement(dsconInstance)

err_code = hllDll.dsconDisconnect(dsconInstance)

for i in range(0, numChannels.value):
	hllDll.dsconFreeChannelInstance(ch_instances[i])

err_code  = hllDll.dsconFreeEnumerateChannels(dsconInstance, labelsPtr)

err_code = hllDll.dsconDestroyInstance(dsconInstance)
print("Finished")