import time  # import the time library

import pigpio  # import the GPIO library


class Buzzer(object):
    def __init__(self):
        # GPIO.setmode(GPIO.BCM)
        self.pi = pigpio.pi()
        self.buzzer_pin = 18  # set to GPIO pin 5
        # GPIO.setup(self.buzzer_pin, GPIO.IN)
        # GPIO.setup(self.buzzer_pin, GPIO.OUT)
        self.pi.set_mode(self.buzzer_pin, pigpio.INPUT)

        self.pi.set_mode(self.buzzer_pin, pigpio.OUTPUT)
        print("buzzer ready")

    def __del__(self):
        class_name = self.__class__.__name__
        print(class_name, "finished")

    def buzz(self, pitch, duration):  # create the function “buzz” and feed it the pitch and duration)

        if pitch == 0:
            time.sleep(duration)
            return
        period = 1.0 / pitch  # in physics, the period (sec/cyc) is the inverse of the frequency (cyc/sec)
        delay = period / 2  # calculate the time for half of the wave
        cycles = int(duration * pitch)  # the number of waves to produce is the duration times the frequency

        for i in range(cycles):  # start a loop from 0 to the variable “cycles” calculated above
            self.pi.write(self.buzzer_pin, 1)  # set pin 18 to high
            time.sleep(delay)  # wait with pin 18 high
            self.pi.write(self.buzzer_pin, 0)  # set pin 18 to low
            time.sleep(delay)  # wait with pin 18 low

    def play(self, tune):
        # GPIO.setmode(GPIO.BCM)
        self.pi.set_mode(self.buzzer_pin, pigpio.OUTPUT)
        x = 0

        print("Playing tune ", tune)
        if tune == 1:
            pitches = [262, 294, 330, 349, 392, 440, 494, 523, 587, 659, 698, 784, 880, 988, 1047]
            duration = 0.1
            for p in pitches:
                self.buzz(p, duration)  # feed the pitch and duration to the function, “buzz”
                time.sleep(duration * 0.5)
            for p in reversed(pitches):
                self.buzz(p, duration)
                time.sleep(duration * 0.5)

        elif tune == 2:
            pitches = [262, 330, 392, 523, 1047]
            duration = [0.2, 0.2, 0.2, 0.2, 0.2, 0, 5]
            for p in pitches:
                self.buzz(p, duration[x])  # feed the pitch and duration to the function, “buzz”
                time.sleep(duration[x] * 0.5)
                x += 1
        elif tune == 3:
            pitches = [392, 294, 0, 392, 294, 0, 392, 0, 392, 392, 392, 0, 1047, 262]
            duration = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.8, 0.4]
            for p in pitches:
                self.buzz(p, duration[x])  # feed the pitch and duration to the func$
                time.sleep(duration[x] * 0.5)
                x += 1

        elif tune == 4:
            pitches = [1047, 988, 659]
            duration = [0.1, 0.1, 0.2]
            for p in pitches:
                self.buzz(p, duration[x])  # feed the pitch and duration to the func$
                time.sleep(duration[x] * 0.5)
                x += 1

        elif tune == 5:
            pitches = [1047, 988, 523]
            duration = [0.1, 0.1, 0.2]
            for p in pitches:
                self.buzz(p, duration[x])  # feed the pitch and duration to the func$
                time.sleep(duration[x] * 0.5)
                x += 1

        self.pi.set_mode(self.buzzer_pin, pigpio.INPUT)


if __name__ == "__main__":
    a = input("Enter Tune number 1-5:")
    buzzer = Buzzer()
    buzzer.play(int(a))
