import board
import busio
import adafruit_lis3dh
import adafruit_mpr121
import time
import usb_hid
from adafruit_hid.mouse import Mouse
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_debouncer import Button

# Set up I2C for accelerometer and touchpad
i2c = busio.I2C(board.GP5, board.GP4)  # SCL=GP5, SDA=GP4 for Pico W
i2c2 = busio.I2C(board.GP7, board.GP6)

# Initialize the accelerometer
accelerometer = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x18)
accelerometer.range = adafruit_lis3dh.RANGE_8_G  # Set accelerometer range

# Initialize the touchpad
touch_pad = adafruit_mpr121.MPR121(i2c2)
mouse = Mouse(usb_hid.devices)

# Create a pads list and fill it with Buttons using the touch_pads as input
pads = [Button(touch_pad[i], value_when_pressed=True) for i in range(12)]

# Track the actual mouse position
current_x, current_y = 0, 0

kbd = Keyboard(usb_hid.devices)

# Flag for using the accelerometer
use_accelerometer = True
# Track the actual mouse position (set to (0,0) every loop to ensure consistent movement)

while True:
    # Reset current position to (0, 0) to ensure consistent target position movement
    current_x, current_y = 0, 0

    # Disable accelerometer if any pad is pressed
    use_accelerometer = not any(pad.pressed for pad in pads[:7])

    # Read acceleration values only if use_accelerometer is True
    if use_accelerometer:
        x_acc, y_acc, z_acc = accelerometer.acceleration

        # Map the accelerometer values to mouse movement
        x_move = int(pow(abs(x_acc), 1.6))
        y_move = int(pow(abs(y_acc), 1.6))

        # Invert movement direction based on acceleration
        if x_acc > 0:
            x_move = -x_move
        if y_acc < 0:
            y_move = -y_move

        # Move the mouse based on accelerometer
        mouse.move(x_move, y_move)

    pads[0].update()
    if pads[0].pressed:
        mouse.press(Mouse.LEFT_BUTTON)
    if pads[0].released:
        mouse.release(Mouse.LEFT_BUTTON)

    # Check pad presses and move to target positions if any pad is pressed
    for i in range(1, len(pads)):
        pads[i].update()  # Get the current state of each debounced pad

        if pads[1].pressed:
            mouse.click(Mouse.MIDDLE_BUTTON)
        if pads[2].pressed:
            mouse.click(Mouse.RIGHT_BUTTON)
        if pads[4].pressed:
            kbd.press(Keycode.LEFT_ARROW)
        if pads[4].released:
            kbd.release(Keycode.LEFT_ARROW)
        if pads[3].pressed:
            kbd.press(Keycode.RIGHT_ARROW)
        if pads[3].released:
            kbd.release(Keycode.RIGHT_ARROW)
        if pads[5].pressed:
            kbd.press(Keycode.UP_ARROW)
        if pads[5].released:
            kbd.release(Keycode.UP_ARROW)
        if pads[6].pressed:
            kbd.press(Keycode.DOWN_ARROW)
        if pads[6].released:
            kbd.release(Keycode.DOWN_ARROW)

    # Release the mouse button if any of the pads are released
    if any(pad.released for pad in pads[1:7]):
        mouse.release(Mouse.LEFT_BUTTON)

    # Sleep briefly to avoid flooding the output
    time.sleep(0.1)
