#############################################################
 # 
 # FILE:        CLSerialCom.py
 # DATE:        11/16/2021
 # COMPANY:     BitFlow, Inc.
 # DESCRIPTION: Rudimentary implementation of a Camera Link serial com terminal client using 
 #              mutli-threading to handle user command input and data reception from the camera's
 #              serial device asynchronously.
 #
#############################################################
import platform
import sys
if(platform.system() == 'Windows'):
    import msvcrt
    if (sys.version_info.major >= 3 and sys.version_info.minor >= 8):
        import os
        #Following lines specifying, the location of DLLs, are required for Python Versions 3.8 and greater
        os.add_dll_directory("C:\BitFlow SDK 6.5\Bin64")
        os.add_dll_directory("C:\Program Files\CameraLink\Serial")
import BFModule.CLComm as CLCom
import time
import threading
g_run = False
# thread to handle reading and printing incoming data
def readThread(ThreadName, CL):
    global g_run
    while(g_run):
        if(CL.GetNumBytesAvailable() > 0):
            try:
                inStr = CL.SerialRead(CL.GetNumBytesAvailable(), 1000)
                print(inStr, end="")
            except:
                pass
        else:
            time.sleep(0)
#thread to handle reading and printing incoming data using CL 2.1 API
def readThread_2_1(ThreadName, CL):
    global g_run
    while(g_run):
        try:
           inStr = CL.SerialReadEx(256, 10)
           if(len(inStr) != 0):
               print(inStr, end="")
        except:
            pass
def main():
    global g_run
    CL = CLCom.clsCLAllSerial()
    
    #Initialize serial device using board open dialog
    CL.SerialInit(CLCom.Parity(0), CLCom.StopBits.SB1, CLCom.BaudRates.CLBaudRate115200, 8)
    t1 = threading.Thread(target=readThread, args=('readThread', CL))
    g_run = True
    t1.start()
    print("\nReady")
    print('Type \"Exit\" to quit\n')
    while g_run:
        # Get message from stdio
        for line in sys.stdin:
            # check for exit
            if(line.rstrip('\n').upper() == 'EXIT'):
                g_run = False
                break
            else:
                try:
                    # Add <CR> as required by most cameras and write to serial port
                    CL.SerialWrite(line.rstrip('\n') + '\r')
                except Exception as e:
                    print(e)
        time.sleep(0)
    
    g_run = False
    t1.join()
    # Close port
    CL.SerialClose()
if __name__ == "__main__":
    main()