# Copyright © 2026 Remco van 't Veer
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

from machine import Pin

class RotaryEncoder:
    def __init__(self, *,
                 sw_gpio: None,
                 sw_on_handler: None,
                 sw_off_handler: None,
                 clk_gpio: None,
                 dt_gpio: None,
                 cw_handler: None,
                 ccw_handler: None):

        self.sw_pin = Pin(sw_gpio, Pin.IN, Pin.PULL_UP)
        self.sw_on_handler = sw_on_handler
        self.sw_off_handler = sw_off_handler
        self.sw_pin.irq(
            trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self.__sw_handler
        )

        self.clk_pin = Pin(clk_gpio, Pin.IN, Pin.PULL_UP)
        self.dt_pin = Pin(dt_gpio, Pin.IN, Pin.PULL_UP)
        self.cw_handler = cw_handler
        self.ccw_handler = ccw_handler
        self.clk_pin.irq(
            trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self.__clk_handler
        )

    def __sw_handler(self, _pin):
        sw_value = self.sw_pin.value()
        if sw_value == 0 and self.sw_on_handler:
            self.sw_on_handler()
        elif sw_value == 1 and self.sw_off_handler:
            self.sw_off_handler()

    old_clk_value = None

    def __clk_handler(self, _pin):
        clk_value = self.clk_pin.value()
        dt_value  = self.dt_pin.value()

        if clk_value != self.old_clk_value and clk_value == 1:
            if dt_value == 0 and self.cw_handler:
                self.cw_handler()
            elif dt_value == 1 and self.ccw_handler:
                self.ccw_handler()

        self.old_clk_value = clk_value

if __name__ == "__main__":
    def sw_on():
        print("on")
    def sw_off():
        print("off")
    def cw():
        print("cw")
    def ccw():
        print("ccw")

    RotaryEncoder(sw_gpio = 7,
                  sw_on_handler = sw_on,
                  sw_off_handler = sw_off,
                  clk_gpio = 5,
                  dt_gpio = 6,
                  cw_handler = cw,
                  ccw_handler = ccw)
