import time
import board
import math
import random
import busio
from digitalio import DigitalInOut, Direction, Pull
import displayio
from vectorio import Rectangle, Circle, Polygon
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font
import gc9a01
import usb_hid
from characters import characters
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

kbd = Keyboard(usb_hid.devices)


font = bitmap_font.load_font("fonts/VictorMonoNerdFont-SemiBoldItalic-32.pcf")

displayio.release_displays()

mode_labels = [
    ["Letters", "Words", "Predictive"], 
    ["Lettres", "Mots", "Predictif"]
]
language_labels = ["English", "Francais"]
backlight_labels = ["Backlight", "Retroeclairage"]

tft_clk = board.GP2
tft_mosi= board.GP3
tft_rst = board.GP4
tft_dc  = board.GP1
tft_cs  = board.GP0

tft_bl  = DigitalInOut(board.GP5)
tft_bl.direction = Direction.OUTPUT
tft_bl.value = True

key0 = DigitalInOut(board.GP6)
key0.pull = Pull.UP
key1 = DigitalInOut(board.GP7)
key1.pull = Pull.UP
key2 = DigitalInOut(board.GP8)
key2.pull = Pull.UP
key3 = DigitalInOut(board.GP9)
key3.pull = Pull.UP
key4 = DigitalInOut(board.GP10)
key4.pull = Pull.UP
key5 = DigitalInOut(board.GP11)
key5.pull = Pull.UP
key6 = DigitalInOut(board.GP12)
key6.pull = Pull.UP

spi = busio.SPI(clock=tft_clk, MOSI=tft_mosi)
    
display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_rst)
display = gc9a01.GC9A01(display_bus, width=240, height=240)

main_display = displayio.Group()
display.root_group = main_display

label_position_radius = 90

top_text = label.Label(
    font, 
    text=" "*10, 
    color=0xffffff,
    anchor_point=(0.5, 0.5), 
    anchored_position=(0, 0)
)
top = displayio.Group(scale=1)
top.x, top.y = 120, 50
top.append(top_text)
main_display.append(top)

middle_text = label.Label(
    font, 
    text=" "*8, 
    color=0xffffff,
    anchor_point=(0.5, 0.5), 
    anchored_position=(0, 0)
)
middle = displayio.Group(scale=1)
middle.x, middle.y = 120, 110
middle.append(middle_text)
main_display.append(middle)

bottom_text = label.Label(
    font, 
    text=" "*14, 
    color=0xffffff,
    anchor_point=(0.5, 0.5), 
    anchored_position=(0, 0)
)
bottom = displayio.Group(scale=1)
bottom.x, bottom.y = 120, 170
bottom.append(bottom_text)
main_display.append(bottom)

key0_text = label.Label(
    font,
    text = " ",
    color=0xffffff,
    anchor_point=(0.5, 0.5),
    anchored_position=(0, 0)
)
key0_colour = (219, 97, 71)
key0_palette = displayio.Palette(1)
key0_palette[0] = (0, 0, 0)
key0_display = displayio.Group(scale=1)
key0_angle = - 2. * math.pi / 3. 
key0_display.x = int(120 + label_position_radius * math.sin(key0_angle))
key0_display.y = int(120 - label_position_radius * math.cos(key0_angle))
key0_display.append(key0_text)
main_display.append(Circle(pixel_shader=key0_palette, radius=16, x=key0_display.x, y=key0_display.y))
main_display.append(key0_display)

key1_text = label.Label(
    font,
    text = " ",
    color=0xffffff,
    anchor_point=(0.5, 0.5),
    anchored_position=(0, 0)
)
key1_colour = (100, 150, 40)
key1_palette = displayio.Palette(1)
key1_palette[0] = (0, 0, 0)
key1_display = displayio.Group(scale=1)
key1_angle = - math.pi / 3.
key1_display.x = int(120 + label_position_radius * math.sin(key1_angle))
key1_display.y = int(120 - label_position_radius * math.cos(key1_angle))
key1_display.append(key1_text)
main_display.append(Circle(pixel_shader=key1_palette, radius=16, x=key1_display.x, y=key1_display.y))
main_display.append(key1_display)

key2_text = label.Label(
    font,
    text = " ",
    color=0xffffff,
    anchor_point=(0.5, 0.5),
    anchored_position=(0, 0)
)
key2_colour = (40, 150, 100)
key2_palette = displayio.Palette(1)
key2_palette[0] = (0, 0, 0)
key2_display = displayio.Group(scale=1)
key2_angle = 0
key2_display.x = int(120 + label_position_radius * math.sin(key2_angle))
key2_display.y = int(120 - label_position_radius * math.cos(key2_angle))
key2_display.append(key2_text)
main_display.append(Circle(pixel_shader=key2_palette, radius=16, x=key2_display.x, y=key2_display.y))
main_display.append(key2_display)

key3_text = label.Label(
    font,
    text = " ",
    color=0xffffff,
    anchor_point=(0.5, 0.5),
    anchored_position=(0, 0)
)
key3_colour = (100, 40, 150)
key3_palette = displayio.Palette(1)
key3_palette[0] = (0, 0, 0)
key3_display = displayio.Group(scale=1)
key3_angle = math.pi / 3.
key3_display.x = int(120 + label_position_radius * math.sin(key3_angle))
key3_display.y = int(120 - label_position_radius * math.cos(key3_angle))
key3_display.append(key3_text)
main_display.append(Circle(pixel_shader=key3_palette, radius=16, x=key3_display.x, y=key3_display.y))
main_display.append(key3_display)

key4_text = label.Label(
    font,
    text = " ",
    color=0xffffff,
    anchor_point=(0.5, 0.5),
    anchored_position=(0, 0)
)
key4_colour = (40, 40, 150)
key4_palette = displayio.Palette(1)
key4_palette[0] = (0, 0, 0)
key4_display = displayio.Group(scale=1)
key4_angle = 2. * math.pi / 3.
key4_display.x = int(120 + label_position_radius * math.sin(key4_angle))
key4_display.y = int(120 - label_position_radius * math.cos(key4_angle))
key4_display.append(key4_text)
main_display.append(Circle(pixel_shader=key4_palette, radius=16, x=key4_display.x, y=key4_display.y))
main_display.append(key4_display)

key5_colour = (0, 100, 30)
key5_palette = displayio.Palette(1)
key5_palette[0] = (0, 0, 0)
main_display.append(Circle(pixel_shader=key5_palette, radius=16, x=120-32, y=120))

key6_colour = (15, 100, 200)
key6_palette = displayio.Palette(1)
key6_palette[0] = (0, 0, 0)
main_display.append(Circle(pixel_shader=key6_palette, radius=16, x=120+32, y=120))

def swap_to_settings_display():
    key0_text.text = ""
    key1_text.text = ""
    key2_text.text = ""
    key3_text.text = ""
    key4_text.text = ""
    
def settings_display(mode, language, location):
    print(mode, language, location, mode_labels[language][mode])
    display.refresh()
    top_text.text = mode_labels[language][mode]
    top_text.color = 0x1c4d2d if location == 0 else 0xffffff
    middle_text.text = language_labels[language]
    middle_text.color = 0x1c4d2d if location == 1 else 0xffffff
    bottom_text.text = backlight_labels[language]
    bottom_text.color = 0x1c4d2d if location == 2 else 0xffffff

def swap_to_character_display():
    top_text.text = ""
    middle_text.text = ""
    bottom_text.text = ""

def edit_character(pin, character, key_text, key_palette, colour):
    if pin is 0:
        key_palette[0] = (0, 0, 0)
        if character is None:
            key_text.text = ""
        else:
            key_text.text = character
    else:
        key_text.text = ""
        key_palette[0] = colour
        
def character_display(pin0, pin1, pin2, pin3, pin4, selection):
    display.refresh()
    edit_character(pin0, characters[1][pin1][pin2][pin3][pin4][selection], key0_text, key0_palette, key0_colour)
    edit_character(pin1, characters[pin0][1][pin2][pin3][pin4][selection], key1_text, key1_palette, key1_colour)
    edit_character(pin2, characters[pin0][pin1][1][pin3][pin4][selection], key2_text, key2_palette, key2_colour)
    edit_character(pin3, characters[pin0][pin1][pin2][1][pin4][selection], key3_text, key3_palette, key3_colour)
    edit_character(pin4, characters[pin0][pin1][pin2][pin3][1][selection], key4_text, key4_palette, key4_colour)

def mode_display(selection):
    if selection is 0:
        key5_palette[0] = (0, 0, 0)
        key6_palette[0] = (0, 0, 0)
    elif selection is 1:
        key5_palette[0] = key5_colour
        key6_palette[0] = (0, 0, 0)
    elif selection is 2:
        key5_palette[0] = (0, 0, 0)
        key6_palette[0] = key6_colour
    elif selection is 3:
        key5_palette[0] = key5_colour
        key6_palette[0] = key6_colour

def pressed(key):
    return not key.value

def poll():
    return [pressed(key0), pressed(key1), pressed(key2), pressed(key3), pressed(key4), pressed(key5), pressed(key6)]

def main():
    for selection in range(4):
        mode_display(selection)
        character_display(0, 0, 0, 0, 0, selection)
        time.sleep(1)
        character_display(0, 0, 0, 0, 1, selection)
        time.sleep(1)
        character_display(0, 0, 0, 1, 0, selection)
        time.sleep(1)
        character_display(0, 0, 1, 0, 0, selection)
        time.sleep(1)
        character_display(0, 1, 0, 0, 0, selection)
        time.sleep(1)
        character_display(1, 0, 0, 0, 0, selection)
        time.sleep(1)
        character_display(0, 0, 0, 1, 1, selection)
        time.sleep(1)
        character_display(0, 0, 1, 0, 1, selection)
        time.sleep(1)
        character_display(0, 1, 0, 0, 1, selection)
        time.sleep(1)
        character_display(1, 0, 0, 0, 1, selection)
        time.sleep(1)
        character_display(0, 0, 1, 1, 0, selection)
        time.sleep(1)
        character_display(0, 1, 0, 1, 0, selection)
        time.sleep(1)
        character_display(1, 0, 0, 1, 0, selection)
        time.sleep(1)
        character_display(0, 1, 1, 0, 0, selection)
        time.sleep(1)
        character_display(1, 0, 1, 0, 0, selection)
        time.sleep(1)
        character_display(1, 1, 0, 0, 0, selection)
        time.sleep(1)
        character_display(0, 0, 1, 1, 1, selection)
        time.sleep(1)
        character_display(0, 1, 0, 1, 1, selection)
        time.sleep(1)
        character_display(1, 0, 0, 1, 1, selection)
        time.sleep(1)
        character_display(0, 1, 1, 1, 0, selection)
        time.sleep(1)
        character_display(1, 0, 1, 1, 0, selection)
        time.sleep(1)
        character_display(1, 1, 1, 0, 0, selection)
        time.sleep(1)
        character_display(0, 1, 1, 1, 1, selection)
        time.sleep(1)
        character_display(1, 1, 1, 0, 1, selection)
        time.sleep(1)
        character_display(1, 1, 0, 1, 1, selection)
        time.sleep(1)
        character_display(1, 0, 1, 1, 1, selection)
        time.sleep(1)
        character_display(0, 1, 1, 1, 1, selection)
        time.sleep(1)
        character_display(1, 1, 1, 1, 1, selection)
        time.sleep(1)
    tft_bl.value = False
    while True:
        pass
#        keypresses = poll()
#        if any(keypresses):
#            kbd.send(Keycode.A)
#        time.sleep(1)
    


main()
