import socket
import re
import struct

# Portit ja asetukset
N1MM_PORT = 12062
VM_IP = "127.0.0.1"
VM_PORT = 6980
STREAM_NAME = "Command1"  # Täytyy olla sama kuin Voicemeeterin VBAN-ruudussa

# Luodaan verkkoyhteydet
sock_in = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_in.bind(("127.0.0.1", N1MM_PORT))
sock_out = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

def luo_vban_text_paketti(komento_teksti, stream_name):
    """Rakentaa virallisen VBAN-TEXT/ASCII-paketin otsikoineen."""
    # VBAN Header (28 tavua)
    vban_id = b'VBAN'                                 # 4 tavua
    sample_rate_index = 0x40 | 0x00                   # TEXT sub-protocol (0x40) + ASCII (0x00)
    samples_per_frame = 0                             # 0 TEXT-protokollassa
    channels_minus_one = 0                            # 0 TEXT-protokollassa
    data_format = 0x10                                # UTF8/ASCII teksti
    
    # Muotoillaan striimin nimi 16 tavun mittaiseksi (täytetään nollatavuilla)
    stream_bytes = stream_name.encode('ascii')[:16]
    stream_bytes = stream_bytes.ljust(16, b'\x00')
    
    frame_counter = 0                                 # Yksinkertainen laskuri
    
    # Lyödään otsikko kasaan (struct.pack)
    header = struct.pack('<4sBBBB16sI', 
                         vban_id, 
                         sample_rate_index, 
                         samples_per_frame, 
                         channels_minus_one, 
                         data_format, 
                         stream_bytes, 
                         frame_counter)
    
    # Palautetaan otsikko + itse tekstikomento tavuina
    return header + komento_teksti.encode('ascii')

print("==================================================")
print("       N1MM -> VBAN-ASCII SILTA KÄYNNISSÄ         ")
print("==================================================")

viimeisin_focus = None

while True:
    data, addr = sock_in.recvfrom(4096)
    teksti = data.decode('utf-8', errors='ignore')
    
    # Etsitään N1MM:n radiotieto datasta
    haku1 = re.search(r'<RadioNr>(\d+)</RadioNr>', teksti)
    haku2 = re.search(r'<RadioNum>(\d+)</RadioNum>', teksti)
    loytymys = haku1 or haku2
    
    if loytymys:
        nykyinen_focus = loytymys.group(1)
        
        if nykyinen_focus != viimeisin_focus:
            if nykyinen_focus == "1":
                komento = "Strip[0].Mute = 1;"
            else:
                komento = "Strip[0].Mute = 0;"
                
            # Rakennetaan virallinen VBAN-paketti
            vban_paketti = luo_vban_text_paketti(komento, STREAM_NAME)
            
            # Lähetetään paketti Voicemeeteriin
            sock_out.sendto(vban_paketti, (VM_IP, VM_PORT))
            print(f"[OK] Radio {nykyinen_focus} aktiivinen -> Lähetetty VBAN: {komento}")
            
            viimeisin_focus = nykyinen_focus