import board
import neopixel
import time
import pwmio
import digitalio
from adafruit_motor import servo
from audiopwmio import PWMAudioOut as AudioOut
from audiocore import WaveFile

from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.color_packet import ColorPacket
from adafruit_bluefruit_connect.button_packet import ButtonPacket


# setup bluetooth


ble = BLERadio()
uart_server = UARTService()
advertisement = ProvideServicesAdvertisement(uart_server)
# Give your CPB a unique name between the quotes below
advertisement.complete_name = "Goal"
ble_radio = BLERadio()
ble_radio.name = advertisement.complete_name # This should make it show in the Bluefruit Connect app. It often takes time to show.
print(f"ble.name is {ble_radio.name}")

receiver_name = "chris-k"
uart_connection = None

def send_packet(uart_connection_name, packet): #sends the stuff to the receiver
    """Returns False if no longer connected."""
    try:
        uart_connection_name[UARTService].write(packet.to_bytes())
    except:  # pylint: disable=bare-except
        try:
            uart_connection[UARTService].write(packet)
        except:  # pylint: disable=bare-except
            try:
                uart_connection_name.disconnect()
            except:  # pylint: disable=bare-except
                pass
            print("No longer connected")
            return False
    return True #If it does send the packet

pwm = pwmio.PWMOut(board.A2, frequency=50)
my_servo = servo.ContinuousServo(pwm)

audio = AudioOut(board.AUDIO)

path = "sounds/"

def play_sound(filename):
    with open(path + filename, "rb") as wave_file:
        wave = WaveFile(wave_file)
        audio.play(wave)
        while audio.playing:
            my_servo.throttle = 0.2


def goalAction():
    print("Got in func")
    connected = False
    #if not uart_connection or not uart_connection.connected:  # If not connected...
    while not connected:
        print("Scanning...")
        for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5):
            print("Test 1")# Scan...
            if UARTService in adv.services:
                print("Test 2") # If UARTService found...
                if adv.complete_name == receiver_name:
                    print("Test 3")
                    uart_connection = ble.connect(adv)  # Create a UART connection...
                    print(f"I've found and connected to {receiver_name}!")
                    connected = True
                    break # MUST include this here or code will never continue after connection.
            # Stop scanning whether or not we are connected.
        ble.stop_scan()
    if uart_connection and uart_connection.connected:
        ble.stop_advertising()
        send_packet(uart_connection, ColorPacket((255, 0, 0)))
        time.sleep(1.5)
        play_sound("devilsGoalHorn.wav")
        my_servo.throttle = 0.0
        send_packet(uart_connection, ColorPacket((0, 0, 0)))
        uart_connection = None


while True:
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass

    while ble.connected:
        # if ble.in_waiting:
        try:
            packet = Packet.from_stream(uart_server)
        except ValueError:
            continue # or pass. This will start the nex
        if isinstance(packet, ButtonPacket): # A button was pressed from the app Control Pad
            if packet.pressed:
                if packet.button == ButtonPacket.BUTTON_1: # app button 1 pressed
                    goalAction()
                elif packet.button == ButtonPacket.BUTTON_2: # app button 2 pressed
                    goalAction()
                elif packet.button == ButtonPacket.BUTTON_3: # app button 3 pressed
                    goalAction()
                elif packet.button == ButtonPacket.BUTTON_4: # app button 4 pressed
                    goalAction()
                elif packet.button == ButtonPacket.UP or packet.button == ButtonPacket.DOWN:
                    goalAction()
                elif packet.button == ButtonPacket.RIGHT: # right button will speed up animations
                    goalAction()
                elif packet.button == ButtonPacket.LEFT: # left button will slow down animations
                    goalAction()
