from typing import cast
import pyglet
import rtmidi
MIDIOUT = rtmidi.MidiOut()
print(MIDIOUT)
available_ports = MIDIOUT.get_ports()
print(available_ports)
if available_ports:
    MIDIOUT.open_port(0)
else:
    MIDIOUT.open_virtual_port("My virtual output")
window = pyglet.window.Window(resizable=True)
tablets = pyglet.input.get_tablets()
canvases = []
if tablets:
    print('Tablets:')
    for i, tablet in enumerate(tablets):
        print('  (%d) %s' % (i + 1, tablet.name))
    print('Press number key to open corresponding tablet device.')
else:
    print('No tablets found.')
PRESSED = False
def clip(value: int, clip: int = 127) -> int:
    if value <= 0:
        value = 0
    if value >= clip:
        value = clip
    return value
def x_to_midi(x: int) -> int:
    full = cast(int, window.width)
    step = full // 127
    return clip(x // step)
def y_to_midi(y: int) -> int:
    full = cast(int, window.height)
    step = full // 127
    without_clip = y // step
    result = clip(without_clip)
    # if y == 1:
    #     print(
    #         f"y_tp_midi(y=1) -> {result}", {
    #             'full': full,
    #             'step': step,
    #             'without_clip': without_clip
    #         }
    #     )
    return result
def pressure_to_midi(pressure: float) -> int:
    full = 1000
    step = full / 127
    return clip(int(pressure * 1000 / step))
# @window.event
# def on_text(text):
#     try:
#         index = int(text) - 1
#     except ValueError:
#         return
#     if not (0 <= index < len(tablets)):
#         return
name = tablets[0].name
try:
    canvas = tablets[0].open(window)
except pyglet.input.DeviceException:
    print('Failed to open tablet %d on window' % index)
print('Opened %s' % name)
@canvas.event
def on_enter(cursor):
    print('%s: on_enter(%r)' % (name, cursor))
@canvas.event
def on_leave(cursor):
    print('%s: on_leave(%r)' % (name, cursor))
    PRESSED = False
@canvas.event
def on_motion(cursor, x, y, pressure, a, b):
    print(
        '%s: on_motion(%r, x=%r, y=%r, pressure=%r, %s, %s)' %
        (name, cursor, x, y, pressure, a, b)
    )
    if x < 0 or y < 0:
        # window.dispatch_event('on_mouse_release', (0, 0, 0, 0))
        return
    pressure_cc = 1
    x_cc = 19
    y_cc = 11
    if not PRESSED:
        return
    MIDIOUT.send_message([0xb0, x_cc, x_to_midi(x)])
    MIDIOUT.send_message([0xb0, y_cc, y_to_midi(y)])
    MIDIOUT.send_message([0xb0, pressure_cc, pressure_to_midi(pressure)])
@window.event
def on_mouse_press(x, y, button, modifiers):
    global PRESSED
    PRESSED = True
    print('on_mouse_press(%r, %r, %r, %r' % (x, y, button, modifiers))
    print(window.width, window.height, '=', x_to_midi(x))
@window.event
def on_mouse_release(x, y, button, modifiers):
    global PRESSED
    PRESSED = False
    print('on_mouse_release(%r, %r, %r, %r' % (x, y, button, modifiers))
pyglet.app.run()