import time
import Adafruit_BBIO.GPIO as GPIO
import Adafruit_BBIO.PWM as PWM



class IR:
    _name = ""
    _pin = ""
    _mode = GPIO.IN
    _rot = None
    _laut = None
    def __init__(self, name, pin, rot, laut):
        self._name = name
        self._pin = pin
        self._rot = rot
        self._laut = laut
        GPIO.setup(self._pin, self._mode)
        GPIO.add_event_detect(self._pin, GPIO.RISING, callback=self.cb_ir)
    
    def __del__(self):
        print("IR {} deleted.".format(self._name))
        GPIO.remove_event_detect(self._pin)

    def cb_ir(self, pin):
        print("cb_ir called")
        for i in range(self._laut._duration * self._rot._blink_freq):
            self._laut.start()
            self._rot.start()
            time.sleep(1/self._rot._blink_freq)
            self._rot.stop()
            self._laut.stop()

class PIR:
    _name = ""
    _pin = ""
    _mode = GPIO.IN
    _rot = None
    _laut = None
    def __init__(self, name, pin, rot, laut):
        self._name = name
        self._pin = pin
        self._rot = rot
        self._laut = laut
        GPIO.setup(self._pin, self._mode)
        GPIO.add_event_detect(self._pin, GPIO.RISING, callback=self.cb_pir)
    
    def __del__(self):
        print("PIR {} deleted.".format(self._name))
        GPIO.remove_event_detect(self._pin)

    def cb_pir(self, pin):
        print("cb_pir called")
        for i in range(self._laut._duration * self._rot._blink_freq):
            self._laut.start()
            self._rot.start()
            time.sleep(1/self._rot._blink_freq)
            self._rot.stop()
            self._laut.stop()
        
class MAG:
    _name = ""
    _pin = ""
    _mode = GPIO.IN
    _window_closed = True
    _rot = None
    _laut = None
    def __init__(self, name, pin, rot, laut):
        self._name = name
        self._pin = pin
        self._rot = rot
        self._laut = laut
        GPIO.setup(self._pin, self._mode)
        GPIO.add_event_detect(self._pin, GPIO.BOTH, callback=self.cb_mag)
    
    def __del__(self):
        print("MAG {} deleted.".format(self._name))
        GPIO.remove_event_detect(self._pin)

    def cb_mag(self, pin):
        if self._window_closed:
            print("Fenster geoeffnet...")
            self._window_closed = False
            for i in range(self._laut._duration * self._rot._blink_freq):
                self._laut.start()
                self._rot.start()
                time.sleep(1/self._rot._blink_freq)
                self._rot.stop()
                self._laut.stop()
        else:
            print("Fenster zu...")
            self._window_closed = True

class ROT:
    _name = ""
    _pin = ""
    _mode = GPIO.OUT
    _blink_freq = 2
    def __init__(self, name, pin, blink_freq=2):
        self._name = name
        self._pin = pin
        self._blink_freq = blink_freq
        GPIO.setup(self._pin, self._mode)
    
    def __del__(self):
        print("ROT {} deleted.".format(self._name))

    def start(self):
        GPIO.output(self._pin, GPIO.HIGH)
    
    def stop(self):
        GPIO.output(self._pin, GPIO.LOW)

class LAUT:
    _name = ""
    _pin = ""
    _mode = GPIO.OUT
    _duration = 60 # in second
    _pwm_perc = 50 # in percentage
    _pwm_freq = 10000 # in hz
    def __init__(self, name, pin, duration=60, pwm_perc=50, pwm_freq=10000):
        self._name = name
        self._pin = pin
        self._duration = duration
        self._pwm_perc = pwm_perc
        self._pwn_freq = pwm_freq
        GPIO.setup(self._pin, self._mode)
    
    def __del__(self):
        print("PWM {} deleted.".format(self._name))

    def start(self):
        PWM.start(self._pin, self._pwm_perc, self._pwm_freq)
    
    def stop(self):
        PWM.stop(self._pin)

if __name__ == "__main__":
    try:
        print("Program start. Initializing with alarm config...")
        rot = ROT("outPinROT", "P9_27")
        laut = LAUT("myPWMLAUT", "P8_13", duration=4)
        ir = IR("inPinIR", "P9_12", rot, laut)
        pir = PIR("inPinPIR", "P9_41", rot, laut)
        mag = MAG("inPinMAG", "P8_7", rot, laut)

        print("Initialization succeeded. Start in 2 seconds.")
        time.sleep(2)
        while True:
            print("...")
            time.sleep(2)
    except Exception as e:
        print("Exception captured. Clean up and quit...")
        GPIO.cleanup()
        PWM.cleanup()
        print(e)
