import time
import LDA_module

FALSE = 0
TRUE = not FALSE
TESTVERSION = "0.3 2024-09-03"

activeDevices = list(range(64))
nActive = 0
STATUS_OK = 0
BAD_PARAMETER = 0x80010000  # out of range input -- frequency outside min/max etc.
BAD_HID_IO = 0x80020000 # an error was returned by the lower level USB drivers
DEVICE_NOT_READY = 0x80030000   # device isn't open, no handle, etc.
ERROR_STATUS_MSK = 0x80000000   # the MSB is set for errors

# The C library we're calling will be expecting us to have a list
# if active devices. In C this is an array of zeroes but in Python we'll
# substitute a list. The C header defines 'MAXDEVICES' which for the 1.02
# library was 64. So we'll make our list that long.
#
# One way of doing this is the following three lines:
#activeDevices = list(range(64))
#for i in range (0, len(activeDevices)):
#    activeDevices[i] = 0
# But here's a more fun way. :)
activeDevices = [0] * 64

# ---------------- Helper programs ----------------
#
# convert from our integer 10Hz representation to a floating point value in GHz
def FreqInGHz(frequency10Hz):
    return frequency10Hz / 1.0e8

# Takes a number and masks off all but the lowest 32 bits
def Low32(n):
    return n & 0xFFFFFFFF

def AnyError(returnedResult):
    # Because of the 32-bit nature of the C code, we have conversion
    # issues getting values back and forth to/from C. Error values have the
    # high order bit set and are defined up above. We'll mask off all except
    # the lower 32 bits.
    #
    # Returns:
    #   TRUE if the result represents any of the known errors or
    #   FALSE if the result is a valid return value
    temp = Low32(returnedResult)
    if temp == BAD_PARAMETER or temp == BAD_HID_IO or temp == DEVICE_NOT_READY:
        return TRUE
    else:
        return FALSE
    
def SomeSpecificError(returnedResult, error):
    # Because of the 32-bit nature of the C code, we have conversion
    # issues getting values back and forth to/from C. Error values have the
    # high order bit set and are defined up above. We'll mask off all except
    # the lower 32 bits.
    #
    # Returns:
    #   TRUE if the result is the error passed as an argument or
    #   FALSE if the result is a valid return value
    temp = Low32(returnedResult)
    if temp == error:
        return TRUE
    else:
        return FALSE

# Because of the same 32/64 bit madness, the C perror() function gets confused with high bits as well.
# To get around this you have to call the extension like "LDA_module.fnLDA_perror(Low32(result))" but that's tedious
# so this helper does that for you.
def DecodeError(error):
    return LDA_module.fnLDA_perror(Low32(error))

# Humans like to see big numbers in groups of 3 with commas
# This only handles integers!!!
def PrettyPrint(n):
    ntemp = str(abs(n))
    retval = ""
    while len(ntemp) > 0:
        retval = "," + ntemp[-3:] + retval
        ntemp = ntemp[0:-3]
    # We're good to go except for a leading comma.
    retval = retval[1:]
    # If it was negative, fix that now
    if n < 0:
        retval = "-"+retval
    return retval

# ---------------- End of helper programs ----------------

LDA_module.fnLDA_Init()
LDA_module.fnLDA_SetTestMode(FALSE);
nDevices = LDA_module.fnLDA_GetNumDevices()
print("LDA test/demonstration program version",TESTVERSION,
      "using library version", LDA_module.fnLDA_LibVersion(),
      "and wrapper version",LDA_module.WrapperVersion())

print("I think there are",nDevices,"devices") 
if 0 == nDevices:
    c = input("No Vaunix LDA devices located. Would you like to run in test mode?")
    if c == 'Y' or c == 'y':
        LDA_module.fnLDA_Init();
        LDA_module.fnLDA_SetTestMode(TRUE);
        nDevices = LDA_module.fnLDA_GetNumDevices()
print("Found",nDevices,"devices")

for i in range(1,1+nDevices):
    print(i)
    cModelName = LDA_module.fnLDA_GetModelName(i)
    print("  Model",i,"is ",cModelName)

nActive = LDA_module.fnLDA_GetDevInfo(activeDevices)
print("We have",nActive,"active devices")

for i in range(0, nActive):
    if i > 0:
        print("")
    print("  Device",activeDevices[i]," is active")
    result = LDA_module.fnLDA_InitDevice(activeDevices[i])
    print("  Opened device",activeDevices[i],". Returned status",
          hex(Low32(result)),"(",DecodeError(result),")")

    print("Before we do any tests, let's let the system know the device...")
    time.sleep(1)

    # --- show the state of the device ---
    cModelName = LDA_module.fnLDA_GetModelName(activeDevices[i])
    result = LDA_module.fnLDA_GetSerialNumber(activeDevices[i])
    print("  Device",activeDevices[i],"(",cModelName,") has serial number",result)
    
    result = LDA_module.fnLDA_GetNumChannels(activeDevices[i])
    print("Max Channels:",result)

    result = LDA_module.fnLDA_GetAttenuation(activeDevices[i])
    print("Current Attenuation:",result)

    result = LDA_module.fnLDA_SetAttenuation(activeDevices[i], 0)
    if AnyError(result):
        print("ERROR Setting Attenuation")
    else:
        print("Success Setting Attenuation")

    result = LDA_module.fnLDA_GetAttenuation(activeDevices[i])
    print("Current Attenuation:",result)

    result = LDA_module.fnLDA_SetAttenuation(activeDevices[i], 20)
    if AnyError(result):
        print("ERROR Setting Attenuation")
    else:
        print("Success Setting Attenuation")

    result = LDA_module.fnLDA_GetAttenuation(activeDevices[i])
    print("Current Attenuation:",result)

#    result = LDA_module.fnLDA_SetAttenuation(activeDevices[i], 40)
#    if AnyError(result):
#        print("ERROR Setting Attenuation")
#    else:
#        print("Success Setting Attenuation")

    result = LDA_module.fnLDA_GetAttenuation(activeDevices[i])
    print("Current Attenuation:",result)
        
    result = LDA_module.fnLDA_SetWorkingFrequency(activeDevices[i],  2000)
    if AnyError(result):
        print(" ERROR: Status=",hex(Low32(result))," (",DecodeError(result),") inLDA_module.fnLDA_SetWorkingFrequency")
    else:
         print("  Set Set Frequency to ", 2000 )
        
    result = LDA_module.fnLDA_GetWorkingFrequency(activeDevices[i])
    print("  Frequency Data =", result)

    result = LDA_module.fnLDA_CloseDevice(activeDevices[i])
    print("  Closed device ",activeDevices[i],". Return Status=",hex(Low32(result))," (",DecodeError(result),")")

print("End of test")


LDA_module.print_hello_world()
