#!/usr/bin/env python3
'''
Meant to run on your PC.
Receives data generated by rmServerWacomInput.py,
moves the mouse and presses accordingly.

Acts like a touchpad.
'''


import socket
import struct
from pynput.mouse import Button, Controller

mouse = Controller()

# ----------
# Config:

ONLY_DEBUG = False  # Only show data. Don't move mouse

CLICK_PRESSURE = 1000
RELEASE_PRESSURE = 100

MAX_DIST = 20  # Max is 50
SPEED = 1.0
INVERT_X = True  # Can be used to change orientation
INVERT_Y = True
# ----------


WACOM_WIDTH = 15725  # Values just checked by drawing to the edges
WACOM_HEIGHT = 20967 # ↑


# Source: https://github.com/canselcik/libremarkable/blob/master/src/input/wacom.rs
EV_SYNC = 0
EV_KEY = 1
EV_ABS = 3
WACOM_EVCODE_PRESSURE = 24
WACOM_EVCODE_DISTANCE = 25
WACOM_EVCODE_XTILT = 26
WACOM_EVCODE_YTILT = 27
WACOM_EVCODE_XPOS = 0
WACOM_EVCODE_YPOS = 1

lastXPos = None
lastYPos = None
lastXTilt = -1
lastYTilt = -1
lastDistance = -1
lastPressure = -1

mouseButtonPressed = False

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('10.11.99.1', 33333))

while True:
	evDevType, evDevCode, evDevValue = struct.unpack('HHi', client.recv(8))
	if evDevType == EV_ABS:
		if evDevCode == WACOM_EVCODE_XPOS:
			if lastDistance < MAX_DIST and lastXPos is not None:
				xDist = (evDevValue - lastXPos) * (-SPEED if INVERT_X else SPEED)
				mouse.move(xDist, 0)
			lastXPos = evDevValue
		elif evDevCode == WACOM_EVCODE_YPOS:
			if lastDistance < MAX_DIST and lastYPos is not None:
				yDist = (evDevValue - lastYPos) * (-SPEED if INVERT_Y else SPEED)
				mouse.move(0, yDist)
			lastYPos = evDevValue
		elif evDevCode == WACOM_EVCODE_XTILT:
			lastXTilt = evDevValue
		elif evDevCode == WACOM_EVCODE_YTILT:
			lastYTilt = evDevValue
		elif evDevCode == WACOM_EVCODE_DISTANCE:
			lastDistance = evDevValue
		elif evDevCode == WACOM_EVCODE_PRESSURE:
			if not ONLY_DEBUG:
				if not mouseButtonPressed and evDevValue > CLICK_PRESSURE:
					mouse.press(Button.left)
					mouseButtonPressed = True
				elif mouseButtonPressed and evDevValue <= RELEASE_PRESSURE:
					mouse.release(Button.left)
					mouseButtonPressed = False

			lastPressure = evDevValue
