# Autor Przemysław Kędziorski korsarzz-project.pl
# UWAGA! Znajdź w kodzie i ustaw parametry "KONFIGURACJA ZEGARA" i "POZOSTAŁA KONFIGURACJA"

import time
import board
import busio
import digitalio
import displayio
import terminalio
import i2cdisplaybus
from adafruit_display_text import label
import adafruit_displayio_sh1106
import adafruit_bmp280
import adafruit_ds3231
import random
import neopixel
import microcontroller

# ==========================================
#          KONFIGURACJA ZEGARA (RTC)
# ==========================================
USTAW_CZAS = False  
NOWA_GODZINA = (2026, 2, 17, 12, 00, 0, 0, 0, -1) 

# ==========================================
#          POZOSTAŁA KONFIGURACJA
# ==========================================
TEKST_POWITANIA = "Czesc A \n(PODPIS)"
GLOSNOSC_STARTOWA = 9  
ILOSC_PIOSENEK = 177    

# --- KOLORY ---
# Stały, intensywny kolor (Czerwony + Trochę Zielonego = Pomarańcz)
KOLOR_LAMPKI = (255, 80, 0)  
KOLOR_CIEMNOSC = (0, 0, 0)

# KOMPLEMENTY (Bez polskich znakow, bo terminalio ich nie obsluguje)
KOMPLEMENTY = [
    "MILEGO\nDNIA A",
    "USMIECHNIJ\nSIE :)",
    "JESTES\nWAZNA",
    "SLODKA JAK\nCYTRUSY",
    "NAJMADRZEJSZA\nGLOWA NA SWIECIE",
    "WYGLADASZ\nSWIETNIE",
    "CENIE TWOJA\nSZCZEROSC",
    "JESTES\nWYJATKOWA",
    "DOBRZE ZE\nJESTES",
    "PIEKNIE\nWYGLADASZ",
    "ZROB SOBIE\nPRZERWE OD NAUKI",
    "JESTES\nINSPIRACJA",
    "DZIS BEDZIE\nDOBRY DZIEN",
    "LUBIE TWOJA\nENERGIE",
    "DASZ RADE\nZE WSZYSTKIM",
    "CHCIALBYM CIE\n ZOBACZYC :)",
    "JESTES\nBARDZO DZIELNA",
    "MASZ PIEKNE\nOCZY",
    "PROMIENIEJESZ\nDZISIAJ",
    "PASUJE CI\nTEN KOLOR",
    "MYSLE\nO TOBIE",
    "JESTES\nPRAWDZIWA",
    "LEK NA\nCALE ZLO",
    "NAJLEPSZA\nNA SWIECIE",
    "PODZIWIAM\nCIE",
    "TWOJA WIEDZA\nIMPONUJE",
    "PRZESYLAM\nUSMIECH",
    "GLOWA DO\nGORY",
    "JESTES\nCUDOWNA",
    "SUPER\nDZIEWCZYNA",
    "FAJNIE ZE\nJESTES",
    "ZARAZASZ\nUSMIECHEM",
    "JESTES\nBEZCENNA",
    "LUBIE\nCIE SLUCHAC",
    "MASZ PIEKNA\nDUSZE",
    "ODPOCZNIJ\nCHWILE",
    "PRZESYLAM\nENERGIE",
    "JESTES\nNIESAMOWITA",
    "UWIELBIAM\nCIE",
    "100 PROCENT\nWDZIEKU",
    "LUBIE TWOJE\nWLOSY",
    "JESTES\nNAJLEPSZA",
    "POWODZENIA\nW NAUCE",
    "BADZ ZAWSZE\nSOBA",
    "CZEKAM NA\nSPOTKANIE",
    "CZESTO O\nTOBIE MYSLE",
    "A - I DZIEN\nJEST LEPSZY"
]

# ==========================================
#             INICJALIZACJA SPRZĘTU
# ==========================================
displayio.release_displays()
i2c = busio.I2C(board.GP1, board.GP0)

# 1. AUDIO (GP8/GP9 + GP10 Busy)
uart_audio = busio.UART(board.GP8, board.GP9, baudrate=9600)
pin_busy = digitalio.DigitalInOut(board.GP10)
pin_busy.direction = digitalio.Direction.INPUT

# 2. RADIO (GP12/GP13)
uart_radio = busio.UART(board.GP12, board.GP13, baudrate=9600)

# 3. LED (GP15)
pixels = neopixel.NeoPixel(board.GP15, 8, brightness=0.3, auto_write=True)
pixels.fill(KOLOR_CIEMNOSC)

# 4. EKRAN OLED
display_bus = i2cdisplaybus.I2CDisplayBus(i2c, device_address=0x3C)
display = adafruit_displayio_sh1106.SH1106(display_bus, width=128, height=64)

# 5. CZUJNIKI (BMP280 + RTC DS3231)
try: bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, address=0x76)
except: bmp280 = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, address=0x77)

rtc = adafruit_ds3231.DS3231(i2c)
if USTAW_CZAS:
    rtc.datetime = time.struct_time(NOWA_GODZINA)

# 6. PRZYCISK GŁÓWNY (GP14 + GND)
dotyk = digitalio.DigitalInOut(board.GP14)
dotyk.direction = digitalio.Direction.INPUT
dotyk.pull = digitalio.Pull.UP 

glosnosc_aktualna = GLOSNOSC_STARTOWA

# ==========================================
#       FUNKCJE PAMIĘCI I AUDIO
# ==========================================
def wyslij_audio(komenda, parametr=0):
    bytes_to_send = bytearray([0x7E, 0xFF, 0x06, komenda, 0x00, (parametr >> 8) & 0xFF, parametr & 0xFF, 0xEF])
    suma = 0 - (0xFF + 0x06 + komenda + 0x00 + ((parametr >> 8) & 0xFF) + (parametr & 0xFF))
    bytes_to_send[7] = (suma >> 8) & 0xFF 
    bytes_to_send.append(suma & 0xFF); bytes_to_send.append(0xEF)
    uart_audio.write(bytes_to_send); time.sleep(0.1)

CMD_PLAY_NUM = 0x03; CMD_SET_VOL = 0x06; CMD_STOP = 0x16
time.sleep(1); wyslij_audio(CMD_SET_VOL, GLOSNOSC_STARTOWA)

def wczytaj_licznik():
    high = microcontroller.nvm[0]; low = microcontroller.nvm[1]
    val = high * 256 + low
    if val > 60000: return 0 
    return val

def zapisz_licznik(val):
    microcontroller.nvm[0] = val // 256; microcontroller.nvm[1] = val % 256

globalny_licznik_klikniec = wczytaj_licznik()

# ==========================================
#            EKRAN STARTOWY
# ==========================================
grupa_powitalna = displayio.Group()
lbl_witaj = label.Label(terminalio.FONT, text=TEKST_POWITANIA, color=0xFFFFFF, scale=1)
lbl_witaj.anchor_point = (0.5, 0.5); lbl_witaj.anchored_position = (64, 32)
grupa_powitalna.append(lbl_witaj); display.root_group = grupa_powitalna
pixels.fill(KOLOR_LAMPKI); time.sleep(2); pixels.fill(KOLOR_CIEMNOSC)

# ==========================================
#            UKŁAD GŁÓWNY
# ==========================================
splash = displayio.Group(); display.root_group = splash
linia = displayio.Bitmap(128, 1, 1); tile_linia = displayio.TileGrid(linia, pixel_shader=displayio.Palette(1), x=0, y=12); splash.append(tile_linia)
lbl_data = label.Label(terminalio.FONT, text="--.--", color=0xFFFFFF, x=2, y=5); splash.append(lbl_data)
lbl_pogoda = label.Label(terminalio.FONT, text="...", color=0xFFFFFF); lbl_pogoda.anchor_point = (1.0, 0.0); lbl_pogoda.anchored_position = (126, 2); splash.append(lbl_pogoda)
lbl_srodek = label.Label(terminalio.FONT, text="00:00", color=0xFFFFFF, scale=2); lbl_srodek.anchor_point = (0.5, 0.5); lbl_srodek.anchored_position = (64, 40); splash.append(lbl_srodek)
lbl_ikona = label.Label(terminalio.FONT, text=" ", color=0xFFFFFF, scale=3); lbl_ikona.anchor_point = (0.5, 0.5); lbl_ikona.anchored_position = (64, 15); splash.append(lbl_ikona)

# ==========================================
#              PĘTLA GŁÓWNA
# ==========================================
tryb_lampka = False       
czas_zmiany_pogody = 0; tryb_pogody = 0
czas_animacji = 0; stan_mrugania_ikony = False; czas_startu_piosenki = 0 
czas_ostatniego_pingu = 0 

while True:
    teraz = time.monotonic()
    
    # ----------------------------------------------------
    # A. OBSŁUGA PRZYCISKU (GP14 -> GND)
    # ----------------------------------------------------
    if dotyk.value == False:
        tryb_lampka = not tryb_lampka
        
        if tryb_lampka:
            # === START ===
            pixels.fill(KOLOR_LAMPKI) # Włączamy światło (STAŁE)
            lbl_data.text = ""; lbl_pogoda.text = ""; tile_linia.x = 200 
            
            lbl_srodek.scale = 1
            lbl_srodek.text = random.choice(KOMPLEMENTY)
            lbl_srodek.anchored_position = (64, 45) 
            lbl_ikona.text = "<3" 
            
            # Start Audio
            wyslij_audio(CMD_SET_VOL, GLOSNOSC_STARTOWA)
            time.sleep(0.1)
            wyslij_audio(CMD_PLAY_NUM, random.randint(1, ILOSC_PIOSENEK))
            czas_startu_piosenki = teraz
            
            # Start Radio
            globalny_licznik_klikniec += 1
            zapisz_licznik(globalny_licznik_klikniec)
            t = rtc.datetime
            msg = "LOVE {:02}:{:02} {}".format(t.tm_hour, t.tm_min, globalny_licznik_klikniec)
            uart_radio.write(bytes(msg, "utf-8"))
            
        else:
            # === STOP ===
            pixels.fill(KOLOR_CIEMNOSC)
            tile_linia.x = 0; lbl_srodek.anchored_position = (64, 40)
            lbl_ikona.text = " "
            wyslij_audio(CMD_STOP)

        # Blokada przycisku
        while dotyk.value == False:
            time.sleep(0.01)
        time.sleep(0.1)

    # ----------------------------------------------------
    # B. EFEKTY I ZEGAR
    # ----------------------------------------------------
    if tryb_lampka:
        # 1. PLAYLISTA (Nieskończona muzyka)
        if pin_busy.value == True and (teraz - czas_startu_piosenki > 2.0):
            wyslij_audio(CMD_PLAY_NUM, random.randint(1, ILOSC_PIOSENEK))
            lbl_srodek.text = random.choice(KOMPLEMENTY)
            czas_startu_piosenki = teraz

        # 2. PING RADIOWY (Co 3 sekundy)
        if teraz - czas_ostatniego_pingu > 3.0:
            uart_radio.write(b"PLAYING")
            czas_ostatniego_pingu = teraz
        
        # 3. MRUGANIE SERDUSZKA (LEDY SĄ STAŁE, TYLKO IKONA MRUGA)
        if teraz - czas_animacji > 0.6: # Zmiana co 0.6 sekundy
            stan_mrugania_ikony = not stan_mrugania_ikony
            if stan_mrugania_ikony:
                lbl_ikona.text = "<3"  # Serce jest
            else:
                lbl_ikona.text = "  "  # Serca nie ma (mignięcie)
            czas_animacji = teraz
            
    else:
        # Tryb zegara (czuwanie)
        if teraz - czas_ostatniego_pingu > 30.0:
            msg = "PING {}".format(globalny_licznik_klikniec)
            uart_radio.write(bytes(msg, "utf-8"))
            czas_ostatniego_pingu = teraz

        if lbl_ikona.text != " ": lbl_ikona.text = " "
        t = rtc.datetime
        
        lbl_data.text = "{:02}.{:02}".format(t.tm_mday, t.tm_mon)
        godzina_tekst = "{:02}:{:02}".format(t.tm_hour, t.tm_min)
        if t.tm_sec % 2 == 0: lbl_srodek.text = godzina_tekst
        else: lbl_srodek.text = godzina_tekst.replace(":", " ")
        lbl_srodek.scale = 2
        
        if teraz - czas_zmiany_pogody > 3.0:
            try:
                if tryb_pogody == 0: tekst = "{:.1f} C".format(bmp280.temperature)
                elif tryb_pogody == 1: tekst = "{:.0f} hPa".format(bmp280.pressure)
                elif tryb_pogody == 2: tekst = "{:.0f}m".format(bmp280.altitude)
                lbl_pogoda.text = tekst; tryb_pogody = (tryb_pogody + 1) % 3
            except: lbl_pogoda.text = ""
            czas_zmiany_pogody = teraz

    time.sleep(0.1)