let myCanvas
const arrows = []
let current_points = []
let t_size
let button
let isOnCanvas = false;
let hf_tkn;
let socket;
let live = false;
let timer;
let capture;
let instructions;
let current_instructions;
let messages_list = []
let timerWaiting;
let waiting = false;

//-----------------------------------------------------
//-----------------------------------------------------

function preload(){
    // Socket events handlers
    socket = io();
    // client-side
    socket.on("connect", () => {
        console.log(socket.id);
    });
    
    socket.on("hello", (arg) => {
        let api_data_test = arg[1]
        console.log(api_data_test) 
    });  

    socket.on("api_error", (arg) => {
        let message = arg
        console.log(message) 
    }); 
    // ————————
}

function call_api(socket, instructions){
    console.log("Calling API ... ")
    waiting = true;
    show_loading()
    cnv_data = myCanvas.elt.toDataURL('image/png');
    let data = [
        cnv_data,
        instructions
    ]
    socket.emit("ask_api", data);
}

function setup() {
    pixelDensity(1)
    myCanvas = createCanvas(576, 320);
    background(220)
    myCanvas.id('myCanvas')
    myCanvas.parent("canvas-container")

    socket.on("api_response", (response) => {
        waiting = false;
        clearTimeout(timerWaiting)
        
        
        vision_text = response[0]
        console.log(vision_text)
        messages_list.push(vision_text)
 
        if(live === true){
            loadingDiv = document.getElementById("loading-div")
            loadingDiv.innerHTML = "_"
            display_messages()
            console.log("Sending new requestion in 3 seconds")
            
            timer = setTimeout(() => {
                console.log(current_instructions)
                call_api(socket, current_instructions)
            }, 3000)
        }
    });
    
    // Watch if cursor is above canvas or not
    let getCanvas = document.getElementById('myCanvas');

    getCanvas.addEventListener("pointerdown", (e) => {
        //console.log("pointerDown");
        getCanvas.setPointerCapture(e.pointerId);
        isOnCanvas = true;
    }, false);

    getCanvas.addEventListener("pointerup", (e) => {
        //console.log("pointerUp");

        if (isOnCanvas) {
        getCanvas.releasePointerCapture(e.pointerId);
        isOnCanvas = false;
        }
    }, false);
    //—————————
  
    // Buttons 
    start_capture_button=createButton("turn on cam")
    start_capture_button.mousePressed(() => {
        capture = createCapture(VIDEO);
        capture.hide();
    })
    
    start_button = createButton('start live vision');
    start_button.mousePressed(() => {
        live = true;
        current_instructions = input_instructions.value()
        console.log("Live in ON")
        console.log(current_instructions)
        call_api(socket, current_instructions)
    })
    
    stop_button = createButton('stop all');
    stop_button.mousePressed(() => {
        live = false;
        waiting = false;
        // Abort the timer
        clearTimeout(timer);
        clearTimeout(timerWaiting)
        loadingDiv.innerHTML = "_"
        if(capture){
            capture.remove();
            capture = undefined
        }
        console.log("live is OFF")
        //redraw()
    })
    
    input_instructions = createInput("What is happening ? ")

    change_instructions = createButton("change instructions")
    change_instructions.mousePressed(() => {
        current_instructions = input_instructions.value()
    })

    start_capture_button.parent("buttons-container")
    start_button.parent("buttons-container")
    stop_button.parent("buttons-container")
    input_instructions.parent("instructions-container")
    change_instructions.parent("instructions-container")

    loadingDiv = document.getElementById("loading-div")

}

function draw() {
  background(220);
  textAlign(CENTER);
  text('turn on your webcam', width/2, height/2);
  if(capture != undefined){
    image(capture, 0, 0)
  }
}

function display_messages(){
    visionDiv = document.getElementById("vision-text-container")
    visionDiv.innerHTML = ""
    //for(i=0; i < messages_list.length - 1; i++){
    //    newNode = document.createElement('div');
    //    newNode.classList.add('text-msg')
    //    newNode.innerHTML = messages_list[i]; 
    //    visionDiv.appendChild(newNode);  
    //}
    newNode_last = document.createElement('div'); 
    newNode_last.classList.add('text-msg')
    visionDiv.appendChild(newNode_last);
    const text_msg = messages_list[messages_list.length - 1]
    const words = text_msg.split(" "); // splits the text into an array of words

    // Function that returns a promise which resolves after a specified number of milliseconds
    function wait(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }

    async function streamText(words) {
        for (let word of words) {
            //console.log(word);
            newNode_last.innerHTML += " " + word;
            //visionDiv.scrollTop = visionDiv.scrollHeight;
            await wait(30); // Wait for 1 second before logging next word
        }
    }

    streamText(words);
    
}

function clean(){
    if(waiting == true){
        loadingDiv.innerHTML = ""
        timerWaiting = setTimeout(show_loading, 500)
    } else {
        loadingDiv.innerHTML = "_"
    }
    
}

function show_loading(){
    
    if(waiting == true){
        loadingDiv.innerHTML = ""
        loading_text = ". . ."
    } else {
        loading_text = "_"
    }
    
    const dots = loading_text.split(" "); // splits the text into an array of words

    // Function that returns a promise which resolves after a specified number of milliseconds
    function wait(ms) {
        if(waiting == true){
            
            return new Promise((resolve) => resolveTimer = setTimeout(resolve, ms));
        } else {
            clearTimeout(resolveTimer)
            loadingDiv.innerHTML = "_"
        }
        
    }

    async function streamDots(words) {
        
        if(waiting == true){
            
            for (let word of words) {
                //console.log(word);
                loadingDiv.innerHTML += " " + word;
                //visionDiv.scrollTop = visionDiv.scrollHeight;
                await wait(500); // Wait for 1 second before logging next word
            }
        
            
            //console.log("ENLEVE")
            
            //timerWaiting = setTimeout(show_loading, 500)
            clean()
        } else {
            clearTimeout(timerWaiting)
            //loadingDiv.innerHTML = "_"
        }
    }

    streamDots(dots);
    
    
}