// Lets see if CW is selected
const ModeSelected = document.getElementById('mode');

$('#winkey_buttons').hide();

if (location.protocol !== 'https:') {
    // Do something if the page is being served over HTTP
    $('#winkey').hide(); // Hide the CW buttons
}

function toggleWinkeyVisibility() {
    const winkeyElement = document.getElementById('winkey');
    if (ModeSelected && winkeyElement) {
        if (ModeSelected.value === 'CW') {
            $('#winkey').show();
        } else {
            $('#winkey').hide();
        }
    }
}

// Check initial mode
toggleWinkeyVisibility();

// Listen for mode changes
if (ModeSelected) {
    ModeSelected.addEventListener('change', toggleWinkeyVisibility);
}



let function1Name, function1Macro, function2Name, function2Macro, function3Name, function3Macro, function4Name, function4Macro, function5Name, function5Macro;

getMacros();

document.addEventListener('keydown', function(event) {

    if (event.key === 'F1') {
        event.preventDefault();
        morsekey_func1();
    }

    if (event.key === 'F2') {
        event.preventDefault();
        morsekey_func2();
    }

    if (event.key === 'F3') {
        event.preventDefault();
        morsekey_func3();
    }

    if (event.key === 'F4') {
        event.preventDefault();
        morsekey_func4();
    }

    if (event.key === 'F5') {
        event.preventDefault();
        morsekey_func5();
    }
  });

let sendText = document.getElementById("sendText");
let sendButton = document.getElementById("sendButton");
let receiveText = document.getElementById("receiveText");
let connectButton = document.getElementById("connectButton");
let statusBar = document.getElementById("statusBar");

//Couple the elements to the Events
if (connectButton) {
    connectButton.addEventListener("click", clickConnect)
}
if (sendButton) {
    sendButton.addEventListener("click", clickSend)
}
if (sendText) {
    sendText.addEventListener("keydown", function(event) {
        if (event.key === "Enter") {
            event.preventDefault();
            clickSend();
        }
    });
}
// statusButton.addEventListener("click", clickStatus)

//When the connectButton is pressed
async function clickConnect() {
    if (port) {
        //if already connected, disconnect
        disconnect();
        $('#winkey_buttons').hide();
    } else {
        //otherwise connect
        await connect();
        $('#winkey_buttons').show();
    }
}

//Define outputstream, inputstream and port so they can be used throughout the sketch
var outputStream, inputStream, port;

// Auto-reconnect functionality
async function autoReconnect() {
    try {
        // Get previously connected ports
        const ports = await navigator.serial.getPorts();
        if (ports.length > 0) {
            // Try to reconnect to the first available port
            port = ports[0];
            await port.open({ baudRate: 1200 });
            await port.setSignals({ dataTerminalReady: true });

            statusBar.innerText = "Auto-reconnected";
            connectButton.innerText = "Disconnect";

            let decoder = new TextDecoderStream();
            inputDone = port.readable.pipeTo(decoder.writable);
            inputStream = decoder.readable;

            const encoder = new TextEncoderStream();
            outputDone = encoder.readable.pipeTo(port.writable);
            outputStream = encoder.writable;
            
            writeToByte("0x00, 0x02");
            writeToByte("0x02, 0x00");

            $('#winkey_buttons').show();

            reader = inputStream.getReader();
            readLoop();
        }
    } catch (e) {
        console.log("Auto-reconnect failed:", e);
        // If auto-reconnect fails, just continue with normal flow
    }
}

// Call auto-reconnect when page loads
window.addEventListener('load', autoReconnect);
navigator.serial.addEventListener('connect', e => {
    statusBar.innerText = `Connected to ${e.port}`;
    connectButton.innerText = "Disconnect"
});
  
navigator.serial.addEventListener('disconnect', e => {
    statusBar.innerText = `Disconnected`;
    connectButton.innerText = "Connect"
});

let debug              = 0;
let speed              = 24;
let minSpeed           = 20;
let maxSpeed           = 40;

//Connect to the serial
async function connect() {

    //Optional filter to only see relevant boards
    const filter = {
        usbVendorId: 0x2341 // Arduino SA
    };

    //Try to connect to the Serial port
    try {
        port = await navigator.serial.requestPort(/*{ filters: [filter] }*/);
        // Continue connecting to |port|.

        // - Wait for the port to open.
        await port.open({ baudRate: 1200 });
        await port.setSignals({ dataTerminalReady: true });

        statusBar.innerText = "Connected";
        connectButton.innerText = "Disconnect"

        let decoder = new TextDecoderStream();
        inputDone = port.readable.pipeTo(decoder.writable);
        inputStream = decoder.readable;

        const encoder = new TextEncoderStream();
        outputDone = encoder.readable.pipeTo(port.writable);
        outputStream = encoder.writable;
        
        writeToByte("0x00, 0x02");
        writeToByte("0x02, 0x00");

        $('#winkey_buttons').show();

        reader = inputStream.getReader();
        readLoop();
    } catch (e) {
        //If the pipeTo error appears; clarify the problem by giving suggestions.
        if (e == "TypeError: Cannot read property 'pipeTo' of undefined") {
            e += "\n Use Google Chrome and enable-experimental-web-platform-features"
        }
        connectButton.innerText = "Connect"
        statusBar.innerText = e;
    }
}

//Write to the Serial port
async function writeToStream(line) {
    var enc = new TextEncoder(); // always utf-8
    
    const writer = outputStream.getWriter();
    writer.write(line);
    writer.releaseLock();
}

async function writeToByte(line) {
    const writer = outputStream.getWriter();
    const data = new Uint8Array([line]);
    writer.write(data);
    writer.releaseLock();
}

//Disconnect from the Serial port
async function disconnect() {

    if (reader) {
        await reader.cancel();
        await inputDone.catch(() => { });
        reader = null;
        inputDone = null;
    }
    if (outputStream) {
        await outputStream.getWriter().close();
        await outputDone;
        outputStream = null;
        outputDone = null;
    }
    statusBar.innerText = "Disconnected";
    connectButton.innerText = "Connect"
    //Close the port.
    if (port) {
        await port.close();
        port = null;
    }
}

//When the send button is pressed
function clickSend() {
    const textToSend = sendText.value;
    writeToStream(textToSend);
    writeToStream("\r");
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";

}

function morsekey_func1() {
    const textToSend = UpdateMacros(function1Macro);
    console.log("F1: " + textToSend);
    writeToStream(textToSend);
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";
}

function morsekey_func2() {
    const textToSend = UpdateMacros(function2Macro);
    console.log("F2: " + textToSend);
    writeToStream(textToSend);
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";
}

function morsekey_func3() {
    const textToSend = UpdateMacros(function3Macro);
    console.log("F3: " + textToSend);
    writeToStream(textToSend);
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";
}

function morsekey_func4() {
    const textToSend = UpdateMacros(function4Macro);
    console.log("F4: " + textToSend);
    writeToStream(textToSend);
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";
}

function morsekey_func5() {
    const textToSend = UpdateMacros(function5Macro);
    console.log("F5: " + textToSend);
    writeToStream(textToSend);
    if (window.cloudlogCwSidetone) {
        window.cloudlogCwSidetone.playText(textToSend, speed);
    }
    //and clear the input field, so it's clear it has been sent
    sendText.value = "";
}



//Read the incoming data
async function readLoop() {
    while (true) {
        const { value, done } = await reader.read();
        if (done === true){
            break;
        }

        console.log(value);
        //When recieved something add it to the big textarea
        receiveText.value += value;
        //Scroll to the bottom of the text field
        receiveText.scrollTop = receiveText.scrollHeight;
    }
}

function closeModal() {
	var container = document.getElementById("modals-here")
	var backdrop = document.getElementById("modal-backdrop")
	var modal = document.getElementById("modal")

	modal.classList.remove("show")
	backdrop.classList.remove("show")

    getMacros();

	setTimeout(function() {
		container.removeChild(backdrop)
		container.removeChild(modal)
	}, 200)
}

function UpdateMacros(macrotext) { 

    // Get the values from the form set to uppercase
    let CALL = document.getElementById("callsign").value.toUpperCase();
    let RSTS = document.getElementById("rst_sent").value;

    let newString;
    newString = macrotext.replace(/\[MYCALL\]/g, my_call);
    newString = newString.replace(/\[CALL\]/g, CALL);
    newString = newString.replace(/\[RSTS\]/g, RSTS);
    console.log(newString);
    return newString;
}

// Call url and store the returned json data as variables
function getMacros() {
    fetch(base_url + 'index.php/qso/cwmacros_json')
    .then(response => {
        if (!response.ok) {
            throw new Error('HTTP ' + response.status + ': ' + response.statusText);
        }
        return response.json();
    })
    .then(data => {
        // Handle case where no macros are saved yet
        if (data.status === 'not found') {
            // Set default values
            function1Name = 'CQ';
            function1Macro = 'CQ CQ CQ DE [MYCALL] [MYCALL] K';
            function2Name = 'REPT';
            function2Macro = '[CALL] DE [MYCALL] [RSTS] [RSTS] K';
            function3Name = 'TU';
            function3Macro = '[CALL] TU 73 DE [MYCALL] K';
            function4Name = 'QRZ';
            function4Macro = 'QRZ DE [MYCALL] K';
            function5Name = 'TEST';
            function5Macro = 'TEST DE [MYCALL] K';
        } else {
            // Use saved values or defaults if empty
            function1Name = data.function1_name || 'F1';
            function1Macro = data.function1_macro || '';
            function2Name = data.function2_name || 'F2';
            function2Macro = data.function2_macro || '';
            function3Name = data.function3_name || 'F3';
            function3Macro = data.function3_macro || '';
            function4Name = data.function4_name || 'F4';
            function4Macro = data.function4_macro || '';
            function5Name = data.function5_name || 'F5';
            function5Macro = data.function5_macro || '';
        }

        // Update button labels
        const morsekey_func1_Button = document.getElementById('morsekey_func1');
        if (morsekey_func1_Button) {
            morsekey_func1_Button.textContent = 'F1 (' + function1Name + ')';
        }

        const morsekey_func2_Button = document.getElementById('morsekey_func2');
        if (morsekey_func2_Button) {
            morsekey_func2_Button.textContent = 'F2 (' + function2Name + ')';
        }

        const morsekey_func3_Button = document.getElementById('morsekey_func3');
        if (morsekey_func3_Button) {
            morsekey_func3_Button.textContent = 'F3 (' + function3Name + ')';
        }
        
        const morsekey_func4_Button = document.getElementById('morsekey_func4');
        if (morsekey_func4_Button) {
            morsekey_func4_Button.textContent = 'F4 (' + function4Name + ')';
        }

        const morsekey_func5_Button = document.getElementById('morsekey_func5');
        if (morsekey_func5_Button) {
            morsekey_func5_Button.textContent = 'F5 (' + function5Name + ')';
        }
    })
    .catch(error => {
        console.error('Error loading CW macros:', error);
    });
}
