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

class Lautalarm:
    def __init__(self, laut_pin, rot_pin, duration=60, refresh_intvl=1):
        self.triggered = False
        self.activited = False
        self.duration = duration
        self.laut_pin = laut_pin
        self.rot_pin = rot_pin
        self.refresh_intvl = refresh_intvl

    def __del__(self):
        print("Lautalarm deleted.")

    def run(self):
        while True:
            if not self.triggered:
                print("...")
            else:
                #  start laut, start rot, start timer
                if not self.activited:
                    laut = LAUT(pin=self.laut_pin, lautalarm=self)
                    rot = ROT(pin=self.rot_pin, lautalarm=self)
                    laut.start()
                    rot.start()
                    ttimer = Termtimer(timeout=self.duration, lautalarm=self)
                    ttimer.start()
                    self.activited = True
                print("+++")
            time.sleep(self.refresh_intvl)

class IR:
    def __init__(self, pin, lautalarm):
        self.pin = pin
        self.lautalarm = lautalarm
        GPIO.setup(self.pin, GPIO.IN)
        GPIO.add_event_detect(self.pin, GPIO.RISING, callback=self.cb_ir)

    def __del__(self):
        print("IR {} deleted.".format(self.pin))
        GPIO.remove_event_detect(self.pin)

    def cb_ir(self, pin):
        print("cb_ir called")
        self.lautalarm.triggered = True

class PIR:
    def __init__(self, pin, lautalarm):
        self.pin = pin
        self.lautalarm = lautalarm
        GPIO.setup(self.pin, GPIO.IN)
        GPIO.add_event_detect(self.pin, GPIO.RISING, callback=self.cb_pir)

    def __del__(self):
        print("PIR {} deleted.".format(self.pin))
        GPIO.remove_event_detect(self.pin)

    def cb_pir(self, pin):
        print("cb_pir called")
        self.lautalarm.triggered = True

class Termtimer(multiprocessing.Process):
    def __init__(self, timeout, lautalarm):
        super().__init__()
        self.timeout = timeout
        self.lautalarm = lautalarm

    def __del__(self):
        print("Termtimer deleted.")

    def run(self):
        time.sleep(self.timeout)
        self.lautalarm.triggered = False
        self.lautalarm.activited = False

class ROT(multiprocessing.Process):
    def __init__(self, pin, lautalarm, blink_freq=2):
        super().__init__()
        self.pin = pin
        self.blink_freq = blink_freq
        self.blink_intvl = 1 / blink_freq
        GPIO.setup(self.pin, GPIO.OUT)
        self.lautalarm = lautalarm

    def __del__(self):
        print("ROT {} deleted.".format(self.pin))

    def rot_start(self):
        GPIO.output(self.pin, GPIO.HIGH)

    def rot_stop(self):
        GPIO.output(self.pin, GPIO.LOW)

    def run(self):
        while True:
            if not self.lautalarm.activited:
                return
            self.rot_start()
            time.sleep(self.blink_intvl)
            self.rot_stop()

class LAUT(multiprocessing.Process):
    def __init__(self, pin, lautalarm, laut_freq=1, pwm_perc=50, pwm_freq=10000):
        super().__init__()
        self.pin = pin
        self.laut_freq = laut_freq
        self.laut_intvl = 1 / laut_freq
        self.pwm_perc = pwm_perc
        self.pwm_freq = pwm_freq
        GPIO.setup(self.pin, GPIO.OUT)
        self.lautalarm = lautalarm

    def __del__(self):
        print("LAUT {} deleted.".format(self.pin))

    def laut_start(self):
        PWM.start(self.pin, self.pwm_perc, self.pwm_freq)

    def laut_stop(self):
        PWM.stop(self.pin)

    def run(self):
        while True:
            if not self.lautalarm.activited:
                return
            self.laut_start()
            time.sleep(self.laut_intvl)
            self.laut_stop()

if __name__ == "__main__":
    myalarm = Lautalarm(laut_pin="P8_13", rot_pin="P9_27", duration=10)
    ir = IR("P9_12", myalarm)
    pir = PIR("P9_41", myalarm)
    # mag = MAG("P8_7", myalarm)
    myalarm.run()
