# ESP32-2432S028C
import machine
import time
import lvgl as lv
import ili9341
import lcd_bus
import cst820
import i2c
import task_handler

DISP_ROTATION = lv.DISPLAY_ROTATION._90

if not lv.is_initialized():
    print("LVGL {:d}.{:d} init...".format(lv.version_major(), lv.version_minor()))
    lv.init()

spi_bus = machine.SPI.Bus(host=1, mosi=13, miso=12, sck=14)
disp_bus = lcd_bus.SPIBus(spi_bus=spi_bus, freq=40_000_000, dc=2, cs=15)
display = ili9341.ILI9341(data_bus=disp_bus,
                          display_width=240, display_height=320,
                          backlight_pin=27, backlight_on_state=ili9341.STATE_PWM,
                          # reset_pin=_RESET_PIN, reset_state=st7796.STATE_HIGH,
                          # power_pin=_POWER_PIN, power_on_state=st7796.STATE_HIGH,
                          color_space=lv.COLOR_FORMAT.RGB565,
                          color_byte_order=ili9341.BYTE_ORDER_BGR,
                          rgb565_byte_swap=True)
display.set_rotation(DISP_ROTATION)

display.set_power(True)
display.init(type=1)
display.set_backlight(100)

i2c_bus = i2c.I2C.Bus(host=0, scl=32, sda=33, freq=400_000, use_locks=False)
touch_device = i2c.I2C.Device(i2c_bus, dev_id=cst820.I2C_ADDR, reg_bits=cst820.BITS)
indev = cst820.CST820(device=touch_device, reset_pin=25, int_pin=21, startup_rotation=DISP_ROTATION)

# if not indev.is_calibrated:
#     print("Touch calibration...")
#     indev.calibrate()  # set DISP_ROTATION = lv.DISPLAY_ROTATION._0 for proper disp size

@micropython.native
def touch_read(self, indev, data) -> int:
    n, x, y = indev._get_coords()
    print(n, x, y)
    data.point.x = x
    data.point.y = y
    data.state = n
    return n == lv.INDEV_STATE.PRESSED

indev_drv = lv.indev_create()
indev_drv.set_type(lv.INDEV_TYPE.POINTER)
indev_drv.set_read_cb(touch_read)

# th = task_handler.TaskHandler()     # -> TypeError: function takes 3 positional arguments but 2 were given
# lv.tick_set_cb(time.sleep_ms)   # [ms]  # -> SyntaxError: Cannot convert 'function' to pointer!

scr = lv.screen_active()
scr.set_style_bg_color(lv.color_hex(0x000000), 0)

print("Display {}x{} r{} ready".format(display.get_physical_horizontal_resolution(),
                                       display.get_physical_vertical_resolution(),
                                       display._disp_drv.get_rotation()))

# Text label
label = lv.label(scr)
label.set_text("LVGL Test")
label.set_style_text_color(lv.color_hex(0x00FF00), 0)
label.align(lv.ALIGN.CENTER, 0, -50)

def on_touch(evt):
    indev = evt.get_indev()
    if indev:
        point = lv.point_t()
        indev.get_point(point)
        x = point.x
        y = point.y
        print("Touch ", x, y)
        dot = lv.obj(scr)
        dot.set_size(6, 6)
        dot.set_pos(x - 3, y - 3)
        dot.set_style_bg_color(lv.color_hex(0x0000ff), 0)
        dot.set_style_border_width(0, 0)

# Transparent overlay
overlay = lv.obj(scr)
overlay.set_size(lv.pct(100), lv.pct(100))
overlay.set_style_bg_opa(lv.OPA.TRANSP, 0)
overlay.add_event_cb(on_touch, lv.EVENT.PRESSED, None)

#
while True:
    time.sleep_ms(20)
    lv.task_handler()
    # print(indev._get_coords())
