try:
    from tkinter import mainloop
    from time import time, sleep
    from threading import Thread
except:
    from Tkinter import mainloop
from src.compiled_gui import *

# PROJECT_DIR
PROJECT_DIR = '/usr/local/bin'


class BoardType:
    Rpi4 = 0
    Rpi3 = 1
    PcDuino = 2
    Debug = 3
# BOARD_TYPE
boardType = BoardType.Rpi4

# INIT_USER_LOGIC

# GPIOS
GPIO_MODE_PATH = "/sys/class/gpio/gpio{}/direction"
GPIO_PIN_PATH = "/sys/class/gpio/gpio{}/value"
ADC_PATH = os.path.normpath('/proc')
ADC_FILENAME = 'adc'
PWM_PATH = os.path.normpath('/dev/pwmtimer')
PWM_STOP_TIME_ADDRESS = 0x102
PWM_START_TIME_ADDRESS = 0x101
PWM_FREQ_ADDRESS = 0x107
PWMTMR_FUNC_ADDRESS = 0x103
PWMTMR_TONE_ADDRESS = 0x104
PWM_CONFIG_ADDRESS = 0x105
HWPWM_DUTY_ADDRESS = 0x106
MAX_PWMTIMER_FREQ = 2000
MIN_PWMTIMER_FREQ = 126
GPIO_FILNAME = 'gpio'

# isPcduino = False
# isRaspberryPi = False

if boardType == BoardType.Rpi4 or boardType == BoardType.Rpi3:
    import RPi.GPIO as RPI_GPIO
    RPI_GPIO.setmode(RPI_GPIO.BCM)


class GPIO:
    HIGH = 1
    LOW = 0
    INPUT = "in"
    OUTPUT = "out"
    INPUT_PULLUP = "8"
    A0 = 0
    A1 = 1
    A2 = 2
    A3 = 3
    A4 = 4
    A5 = 5

    def __init__(self):
        pass
        # self.pinModeList = [os.path.join(
        #     GPIO_MODE_PATH, 'gpio'+str(idx)) for idx in range(24)]
        # self.pinDataList = [os.path.join(
        #     GPIO_PIN_PATH, 'gpio'+str(idx)) for idx in range(24)]
        # self.adcFiles = [os.path.join(
        #     ADC_PATH, ADC_FILENAME+str(idx)) for idx in range(6)]

    def exportPin(self, pinNumber):
        export_path = "/sys/class/gpio/export"
        with open(export_path, 'r+') as file:
            file.write(pinNumber)

    def pinMode(self, pinNumber, mode):
        print("Initialized pin ", pinNumber)

        if boardType == BoardType.PcDuino:
            pin_path = GPIO_MODE_PATH.format(pinNumber)
            try:
                self.exportPin(pinNumber)
            except:
                print("Pin already exported")
            with open(pin_path, 'r+') as file:
                file.write(mode)
        elif boardType == BoardType.Rpi4:
            RPI_GPIO.setup(int(pinNumber), RPI_GPIO.OUT if mode ==
                           GPIO.OUTPUT else RPI_GPIO.IN)
        else:
            print("Initializing pin: ", pinNumber, " mode: ", mode)

    def digitalWrite(self, pinNumber, state):
        print("Output power", state)
        if boardType == BoardType.PcDuino:
            pin_path = GPIO_PIN_PATH.format(pinNumber)
            with open(pin_path, 'r+') as file:
                file.write(state)
        elif boardType == BoardType.Rpi4:
            RPI_GPIO.output(int(pinNumber), RPI_GPIO.HIGH if state ==
                            GPIO.HIGH else RPI_GPIO.LOW)
        else:
            print("Writing pin: ", pinNumber, " state: ", state)

    def digitalRead(self, pinNumber):
        if boardType == BoardType.PcDuino:
            pin_path = GPIO_PIN_PATH.format(pinNumber)
            with open(pin_path, 'r') as file:
                state = file.read().replace("\n", "").replace(" ", "").replace("\t", "")
            return state
        elif boardType == BoardType.Rpi4:
            return RPI_GPIO.input(pinNumber)
            # pin_path = GPIO_PIN_PATH.format(pinNumber)
            # with open(pin_path, 'r') as file:
            #     state = file.read().replace("\n", "").replace(" ", "").replace("\t", "")
            # return 0 if state == GPIO.LOW else 1
        else:
            print("Reading pin: ", pinNumber)

    def setPinFrequency(self, pinNumber, frequency):
        pwm_stop_struct = struct.pack('i', pinNumber)
        pwm_freq_struct = struct.pack('iiiI', pinNumber, 0, 0, frequency)
        if boardType == BoardType.PcDuino:
            with open(PWM_PATH, 'r+') as file:
                if pinNumber in [3, 9, 10, 11]:
                    ioctl(file, PWM_STOP_TIME_ADDRESS, pwm_stop_struct)
                ioctl(file, PWM_FREQ_ADDRESS, pwm_freq_struct)
        else:
            print("Setting frequency pin: ", pinNumber, " to: ", frequency)

    def analogWrite(self, pinNumber, value):
        pwm_config = struct.pack('ii', pinNumber, value)
        pwm_start_struct = struct.pack('i', 0)
        if boardType == BoardType.PcDuino:
            with open(PWM_PATH, 'r+') as file:
                if pinNumber in [3, 9, 10, 11]:
                    ioctl(file, PWM_CONFIG_ADDRESS, pwm_config)
                    ioctl(file, PWM_START_TIME_ADDRESS, pwm_start_struct)
                elif pinNumber in [5, 6]:
                    print("HW PWM {}".format(pinNumber))
                    ioctl(file, HWPWM_DUTY_ADDRESS, pwm_config)
        else:
            print("Writing analog pin: ", pinNumber, " value: ", value)

    def analogRead(self, pinNumber):
        if boardType == BoardType.PcDuino:
            with open(self.adcFiles[pinNumber], 'r') as file:
                value = file.read()
            realVal = int(value.split(":")[1])
            return realVal
        else:
            print("Reading analog pin: ", pinNumber)

gpio = GPIO()
gpio.pinMode( 9, GPIO.OUTPUT)
gpio.pinMode( 4, GPIO.OUTPUT)
gpio.pinMode( 27, GPIO.OUTPUT)
gpio.pinMode( 2, GPIO.OUTPUT)
gpio.pinMode( 3, GPIO.INPUT)

# INIT_DEFAULT_LOGIC
class Screen1:
	def __init__(self):
		self.load_components()
	def load_components(self):
		Button2.set_property(property_name=null,value=null)
		def Button2_click(event):
			pass
		gpio.digitalRead(pinNumber=null)
		def Button2_click(event):
			pass
		Button2.
		#Screen1
		self.Screen1 = Screen(378,'Screen 1',600,450,'#f8f8f8')
		#Screen1TextBox10
		self.TextBox10 = CompiledTextBox(self.Screen1,10,"rgba(221,75,75,1)",128,107,250,40,'',False)
		self.TextBox10.display_text('TextBox',(0, 40/2),'Arial',15,'#000000',False,False,tk.W,'MiddleLeft')
		mainloop()