var voiceBtn = document.getElementById("voiceBtn");
var voiceDiv = document.getElementById("voiceDiv");
var voiceSpan = document.getElementById("voiceSpan");
var heardSpan = document.getElementById("heardSpan");
var commandSpan = document.getElementById("commandSpan");

const voiceSelect = document.getElementById("selectVoice");

let voices = [];

const synth = window.speechSynthesis;

var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList;
var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent;

function populateVoiceList() {
  voices = synth.getVoices().sort(function (a, b) {
    const aname = a.name.toUpperCase();
    const bname = b.name.toUpperCase();

    if (aname < bname) {
      return -1;
    } else if (aname == bname) {
      return 0;
    } else {
      return +1;
    }
  });

  const selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
  
  for (let i = 0; i < voices.length; i++) {
    const option = document.createElement("option");
    option.textContent = `${voices[i].name} (${voices[i].lang})`;

    if (voices[i].default) {
      option.textContent += " -- DEFAULT";
    }

    option.setAttribute("data-lang", voices[i].lang);
    option.setAttribute("data-name", voices[i].name);
    voiceSelect.appendChild(option);
  }
  voiceSelect.selectedIndex = selectedIndex;
}

voiceBtn.addEventListener("click", startListening);

if ('speechSynthesis' in window) {
    
}else{
    // Speech Synthesis Not Supported
    alert("Sorry, your browser doesn't support text to speech!");
}

function startListening(){
    voiceBtn.disabled = true;
    voiceSpan.innerText = 'Dites "Cristo !" pour commencer a donner votre requete';
    voiceSpan.style.display = "";
    heardSpan.innerText = "";
    heardSpan.style.display = "none";
    commandSpan.innerText = "";
    commandSpan.style.display = "none";
    voiceBtn.innerText = "Ecoute en cours";
    listenForCristo();
}

function listenForCristo(){
    var cristo = [
        'Cristo',
        'cristo',
        'crist',
        'risto'
    ];

    var grammar = '#JSGF V1.0; grammar phrase; public <phrase> = cristaux;';
    var recognition = new SpeechRecognition();
    var speechRecognitionList = new SpeechGrammarList();
    speechRecognitionList.addFromString(grammar, 1);
    recognition.grammars = speechRecognitionList;
    recognition.lang = 'fr-FR';
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;
    speak("Dites cristeaux pour donner votre requete");
    recognition.start();
    console.log('Started first listening');
    recognition.onresult = function(event) {
        console.log('Listened');
        var speechResult = event.results[0][0].transcript.toLowerCase();
        console.log(speechResult);
        heardSpan.innerText = " A entendu = " + speechResult;
        heardSpan.style.display = "";
        voiceSpan.style.display = "none";
        console.log('Confidence: ' + event.results[0][0].confidence);
        if(speechResult.toLowerCase().includes("cristaux")){
            speak("Veuillez me donner votre requete");
            console.log('Heard Cristo ! (or Cristaux)');
            listenForCommand();
        } else {
            speak("Je n'ai pas entendu Cristeaux");
            console.log('Heard nothing');
            enableBtn();
        }
    }

    recognition.onspeechend = function() {
        recognition.stop();
    }
    recognition.onerror = function(event) {
        voiceBtn.disabled = false;
        voiceBtn.textContent = 'Ecouter a nouveau';
        console.log('Error occurred in recognition: ' + event.error);
        voiceSpan.style.display = "none";
        heardSpan.innerText = " Erreur ";
        heardSpan.style.display = "";
    }
    recognition.onaudiostart = function(event) {
        //Fired when the user agent has started to capture audio.
        console.log('SpeechRecognition.onaudiostart');
     } 
    recognition.onaudioend = function(event) {
        //Fired when the user agent has finished capturing audio.
        console.log('SpeechRecognition.onaudioend');
    } 
    recognition.onend = function(event) {
        //Fired when the speech recognition service has disconnected.
        /* console.log('SpeechRecognition.onend'); */
        /* console.log("A entendu = " + event.results); */
        voiceSpan.style.display = "none";
    }
    recognition.onnomatch = function(event) {
        //Fired when the speech recognition service returns a final result with no significant recognition. This may involve some degree of recognition, which doesn't meet or exceed the confidence threshold.
        console.log('SpeechRecognition.onnomatch');
    }
    recognition.onsoundstart = function(event) {
        //Fired when any sound — recognisable speech or not — has been detected.
        console.log('SpeechRecognition.onsoundstart');
    } 
    recognition.onsoundend = function(event) {
        //Fired when any sound — recognisable speech or not — has stopped being detected.
        /* console.log('SpeechRecognition.onsoundend'); */
    }
    recognition.onspeechstart = function (event) {
        //Fired when sound that is recognised by the speech recognition service as speech has been detected.
        console.log('SpeechRecognition.onspeechstart');
    }
    recognition.onstart = function(event) {
        //Fired when the speech recognition service has begun listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
        console.log('SpeechRecognition.onstart');
    }
}

function listenForCommand(){
    var grammar = '#JSGF V1.0; grammar phrase; public <phrase> = descends | descend | remonte | monte | recette | aleatoire | suivante | precedente;';
    var recognition = new SpeechRecognition();
    var speechRecognitionList = new SpeechGrammarList();
    speechRecognitionList.addFromString(grammar, 1);
    recognition.grammars = speechRecognitionList;
    recognition.lang = 'fr-FR';
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;
    recognition.start();
    console.log('Started first listening');
    recognition.onresult = function(event) {
        console.log('Listened');
        var speechResult = event.results[0][0].transcript.toLowerCase();
        console.log(speechResult);
        heardSpan.innerText = " A entendu = " + speechResult;
        heardSpan.style.display = "";
        voiceSpan.style.display = "none";
        console.log('Confidence: ' + event.results[0][0].confidence);
        if(speechResult.toLowerCase().includes("descend")){
            speak("Je vais descendre dans la page");
            pageScrollDown();
        }
        else if(speechResult.toLowerCase().includes("monte")){
            speak("Je vais monter dans la page");
            pageScrollUp();
        }
        else if(speechResult.toLowerCase().includes("recette")){
            if(speechResult.toLowerCase().includes("précédente")){
                speak("Voici la recette precedente");
            }
            else if(speechResult.toLowerCase().includes("suivante")){
                speak("Voici la prochaine recette");
            }
            else if(speechResult.toLowerCase().includes("aléatoire")){
                speak("Voici une recette aleatoire");
                recetteAleatoire();
            }
        }
        else {
            speak("Je n'ai rien entendu ou je n'ai pas reconnu la requete");
        }
        enableBtn();
    }

    recognition.onspeechend = function() {
        recognition.stop();
    }
    recognition.onerror = function(event) {
        enableBtn();
        diagnosticPara.textContent = 'Error occurred in recognition: ' + event.error;
        heardSpan.innerText += " Erreur ";
        heardSpan.style.display = "";
    }
    recognition.onaudiostart = function(event) {
        //Fired when the user agent has started to capture audio.
        console.log('SpeechRecognition.onaudiostart');
     } 
    recognition.onaudioend = function(event) {
        //Fired when the user agent has finished capturing audio.
        console.log('SpeechRecognition.onaudioend');
    } 
    recognition.onend = function(event) {
        //Fired when the speech recognition service has disconnected.
        /* console.log('SpeechRecognition.onend'); */
        /* console.log("A entendu = " + event.results); */
        voiceSpan.style.display = "none";
    }
    recognition.onnomatch = function(event) {
        //Fired when the speech recognition service returns a final result with no significant recognition. This may involve some degree of recognition, which doesn't meet or exceed the confidence threshold.
        console.log('SpeechRecognition.onnomatch');
    }
    recognition.onsoundstart = function(event) {
        //Fired when any sound — recognisable speech or not — has been detected.
        console.log('SpeechRecognition.onsoundstart');
    } 
    recognition.onsoundend = function(event) {
        //Fired when any sound — recognisable speech or not — has stopped being detected.
        /* console.log('SpeechRecognition.onsoundend'); */
    }
    recognition.onspeechstart = function (event) {
        //Fired when sound that is recognised by the speech recognition service as speech has been detected.
        console.log('SpeechRecognition.onspeechstart');
    }
    recognition.onstart = function(event) {
        //Fired when the speech recognition service has begun listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
        console.log('SpeechRecognition.onstart');
    }
}

function listenForStop(){
    var grammar = '#JSGF V1.0; grammar phrase; public <phrase> = stop | arrete;';
    var recognition = new SpeechRecognition();
    var speechRecognitionList = new SpeechGrammarList();
    speechRecognitionList.addFromString(grammar, 1);
    recognition.grammars = speechRecognitionList;
    recognition.lang = 'fr-FR';
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;
    recognition.start();
    console.log('Started first listening');
    recognition.onresult = function(event) {
        console.log('Listened');
        var speechResult = event.results[0][0].transcript.toLowerCase();
        console.log(speechResult);
        heardSpan.innerText += " A entendu = " + speechResult;
        heardSpan.style.display = "";
        voiceSpan.style.display = "none";
        console.log('Confidence: ' + event.results[0][0].confidence);
        if(speechResult.toLowerCase().includes("stop")){
            speak("Je vais arreter de descendre dans la page");
            return true;
        }
        else if(speechResult.toLowerCase().includes("arrete")){
            speak("Je vais arreter de descendre dans la page");
            return true;
        }
        else {
            return false;
        }
    }
}

function speak(text){
    if (synth.speaking) {
        console.error("speechSynthesis.speaking");
        return;
    }

    const utterThis = new SpeechSynthesisUtterance(text);
    utterThis.onend = function (event) {
      console.log("SpeechSynthesisUtterance.onend");
    };
    utterThis.onerror = function (event) {
      console.error("SpeechSynthesisUtterance.onerror");
    };

    for (let i = 0; i < voices.length; i++) {
        if (voices[i].name === voiceSelect.selectedOptions[0].getAttribute("data-name")) {
          utterThis.voice = voices[i];
          break;
        }
    }

    utterThis.pitch = 1;
    utterThis.rate = 1;

    synth.speak(utterThis);
}

function enableBtn(){
    voiceBtn.disabled = false;
    voiceBtn.textContent = 'Ecouter a nouveau';
    voiceSpan.style.display = "none";
}

function pageScrollDown() {
    window.scrollBy(0,1);
    if ((window.innerHeight + Math.round(window.scrollY)) >= document.body.offsetHeight) {
        speak("Bas de page atteind, j'arrete de descendre");
    }
    else{
        scrolldelay = setTimeout(pageScrollDown,5);
    }
}

function pageScrollUp() {
    window.scrollBy(0,-1);
    if (window.scrollY <= 1) {
        speak("Haut de page atteind, j'arrete de monter");
    }
    else{
        scrolldelay = setTimeout(pageScrollUp,5);
    }
}

function getRandomInt(max) {
    return Math.floor(Math.random() * max);
  }

function recetteAleatoire(){
    let recettes = ["cookie-au-chocolat", "soupe-au-potiron", "pain-perdu", "quiche-lorraine"]
    let number = getRandomInt(recettes.length);
    url = window.location;
    window.location.href = url.origin+'/recette/'+recettes[number];

}

function scrollDown(){
    
}

docReady(function() {
    populateVoiceList();
    voiceSelect.value= "Microsoft Paul - French (France) (fr-FR)";
});

navigator.mediaDevices.getUserMedia({ audio: true })
      .then(function(stream) {
        console.log('You let me use your mic!')
      })
      .catch(function(err) {
        console.log('No mic for you!')
      });