<html>
<head>
    <title>Continuous Speech Demo</title>
    <style>
        body { 
            font-family: sans-serif; 
            padding: 20px; 
            max-width: 800px;
            margin: 0 auto;
        }
        button { 
            padding: 10px 20px; 
            margin: 10px 5px;
            font-size: 16px;
        }
        #status { 
            margin: 10px 0;
            padding: 10px;
            background: #e8f5e9;
            border-radius: 4px;
        }
        #output {
            white-space: pre-wrap;
            padding: 15px;
            background: #f5f5f5;
            border-radius: 4px;
            margin: 10px 0;
            min-height: 100px;
            max-height: 400px;
            overflow-y: auto;
        }
        .controls {
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <!-- Set up your HTML here -->
    <input id="myinput" value="" />

    <div class="controls">
        <button id="start">Start Listening</button>
        <button id="stop" disabled>Stop Listening</button>
        <button id="clear">Clear Text</button>
    </div>
    <div id="status">Ready</div>
    <div id="output"></div>
    
    <!-- Add the hidden input here -->
    <input type="hidden" id="streamlit-data" value="">
    
    <script>
        if (!('webkitSpeechRecognition' in window)) {
            alert('Speech recognition not supported');
        } else {
            const recognition = new webkitSpeechRecognition();
            const startButton = document.getElementById('start');
            const stopButton = document.getElementById('stop');
            const clearButton = document.getElementById('clear');
            const status = document.getElementById('status');
            const output = document.getElementById('output');
            let fullTranscript = '';
            let lastUpdateTime = Date.now();

            // Configure recognition
            recognition.continuous = true;
            recognition.interimResults = true;

            // Function to start recognition
            const startRecognition = () => {
                try {
                    recognition.start();
                    status.textContent = 'Listening...';
                    startButton.disabled = true;
                    stopButton.disabled = false;
                } catch (e) {
                    console.error(e);
                    status.textContent = 'Error: ' + e.message;
                }
            };

            // Auto-start on load
            window.addEventListener('load', () => {
                setTimeout(startRecognition, 1000);
            });

            startButton.onclick = startRecognition;

            stopButton.onclick = () => {
                recognition.stop();
                status.textContent = 'Stopped';
                startButton.disabled = false;
                stopButton.disabled = true;
            };

            clearButton.onclick = () => {
                fullTranscript = '';
                output.textContent = '';
                window.parent.postMessage({
                    type: 'clear_transcript',
                }, '*');
            };

            recognition.onresult = (event) => {
                let interimTranscript = '';
                let finalTranscript = '';

                for (let i = event.resultIndex; i < event.results.length; i++) {
                    const transcript = event.results[i][0].transcript;
                    if (event.results[i].isFinal) {
                        finalTranscript += transcript + '\\n';
                    } else {
                        interimTranscript += transcript;
                    }
                }

                if (finalTranscript || (Date.now() - lastUpdateTime > 5000)) {
                    if (finalTranscript) {
                        fullTranscript += finalTranscript;
                        
                        // Update the hidden input value
                        document.getElementById('streamlit-data').value = fullTranscript;

                    }
                    lastUpdateTime = Date.now();
                }            

                output.textContent = fullTranscript + (interimTranscript ? '... ' + interimTranscript : '');
                output.scrollTop = output.scrollHeight;

                document.getElementById('streamlit-data').value = fullTranscript;
                sendDataToPython({value: fullTranscript,dataType: "json",});

            };

            recognition.onend = () => {
                if (!stopButton.disabled) {
                    try {
                        recognition.start();
                        console.log('Restarted recognition');
                    } catch (e) {
                        console.error('Failed to restart recognition:', e);
                        status.textContent = 'Error restarting: ' + e.message;
                        startButton.disabled = false;
                        stopButton.disabled = true;
                    }
                }
            };

            recognition.onerror = (event) => {
                console.error('Recognition error:', event.error);
                status.textContent = 'Error: ' + event.error;
                
                if (event.error === 'not-allowed' || event.error === 'service-not-allowed') {
                    startButton.disabled = false;
                    stopButton.disabled = true;
                }
            };
        }


      // ----------------------------------------------------
      // Just copy/paste these functions as-is:

      function sendMessageToStreamlitClient(type, data) {
        var outData = Object.assign({
          isStreamlitMessage: true,
          type: type,
        }, data);
        window.parent.postMessage(outData, "*");
      }

      function init() {
        sendMessageToStreamlitClient("streamlit:componentReady", {apiVersion: 1});
      }

      function setFrameHeight(height) {
        sendMessageToStreamlitClient("streamlit:setFrameHeight", {height: height});
      }

      // The `data` argument can be any JSON-serializable value.
      function sendDataToPython(data) {
        sendMessageToStreamlitClient("streamlit:setComponentValue", data);
      }

      // ----------------------------------------------------
      // Now modify this part of the code to fit your needs:

      var myInput = document.getElementById("myinput");
      var myOutput = document.getElementById("output");

      // data is any JSON-serializable value you sent from Python,
      // and it's already deserialized for you.
      function onDataFromPython(event) {
        if (event.data.type !== "streamlit:render") return;
        myInput.value = event.data.args.my_input_value;  // Access values sent from Python here!
      }

      myInput.addEventListener("change", function() {
        sendDataToPython({
          value: myInput.value,
          dataType: "json",
        });
      })
      
      myOutput.addEventListener("change", function() {
        sendDataToPython({
          value: myOutput.value,
          dataType: "json",
        });
      })

      // Hook things up!
      window.addEventListener("message", onDataFromPython);
      init();

      // Hack to autoset the iframe height.
      window.addEventListener("load", function() {
        window.setTimeout(function() {
          setFrameHeight(document.documentElement.clientHeight)
        }, 0);
      });

      // Optionally, if the automatic height computation fails you, give this component a height manually
      // by commenting out below:
      //setFrameHeight(200);


      


    </script>
  </body>
</html>