# Filename: KinisiController.py
# Description: Kinisi controller class. This class implements serial communication with the Kinisi controller.
# and adds some additional functionality to autogenerated api.

import serial
from .KinisiCommands import *

class MotorIndex:
    Motor0 = 0
    Motor1 = 1
    Motor2 = 2
    Motor3 = 3

class EncoderIndex:
    Encoder0 = 0
    Encoder1 = 1
    Encoder2 = 2
    Encoder3 = 3

class GPIOIndex:
    GPIO0 = 0
    GPIO1 = 1
    GPIO2 = 2
    GPIO3 = 3
    GPIO4 = 4
    GPIO5 = 5
    GPIO6 = 6
    GPIO7 = 7
    GPIO8 = 8
    GPIO9 = 9

class GPIOMode:
    INPUT = 0
    INPUT_PULLUP = 1
    INPUT_NOPULL = 2
    OUTPUT = 3

class State:
    LOW = 0
    HIGH = 1

class KinisiController(KinisiCommands):
    # Constructor
    def __init__(self):
        super().__init__()
        self.serial = None

    # This method is used to connect to the motor controller.
    # Parameters:
    #   port: The port to connect to. Example: /dev/ttyUSB0
    @thread_safe_method
    def connect(self, port):
        try:
            self.serial =  serial.Serial(port, 115200, timeout = 1)
            return True
        except serial.SerialException:
            return False
        except:
            return False

    # This method is used to write data to the serial port.
    # Parameters:
    #   msg: The message to be sent.
    def _write(self, msg: bytearray):
        self.serial.write(msg)

    # This method is used to read data from the serial port.
    # Parameters:
    #   length: The number of bytes to be read.
    def _read(self, length: int) -> bytearray:
        return self.serial.read(length)

    # This method is used disconnect from the motor controller.
    @thread_safe_method
    def disconnect(self):
        if self.serial:
            self.serial.close()
            self.serial = None

    # Destructor
    def __del__(self):
        if self.serial:
            self.serial.close()