Code viewer for World: DALL-E Speech Gallery
//Set the background color, border, and margin for the body
$(document).ready(function() {
    $('body').css("background-color", "black");
    $('body').css("border", "2px solid black");
    $('body').css("margin", "4% 21%");
});




// MH edit
// moved to top

// Replace with your DALL-E 2 API key
const apiAccessKey = "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";
const apiEndpoint = "https://api.openai.com/v1/images/generations";
 
const azureapiKey =   "2218d40917c7410b9f356e9483497d07";
const azureEndpoint = `https://eastus.api.cognitive.microsoft.com/vision/v3.1/describe?maxCandidates=1`;



 
//Dynamically write HTML content
document.write(`
<div style="text-align: center; color: white;">
  <h2 style="margin-top: 20px;">DALL·E Speech Gallery</h2>
  <div style="display: flex; align-items: center; justify-content: center;">
        <div style="margin: 15px;">
            <input style="border-radius: 20px; width: 500px; border-color:#0066b2; padding: 10px;" id="userInput" placeholder="Tell me about the picture!">
            <button title="Speech to Text" onclick="startSpeechRecognition();" style="cursor: pointer; border: none; background-color: transparent; font-size: large; position: absolute; left: 56%; top: 152px;" id="speechRecognitionButton">🎙️</button>
            <button title="Clear Input" onclick="clearInput();" id="clearButton" style="position: absolute; right: 40%; top: 165px; transform: translateY(-50%); cursor: pointer; border: none; background: none; font-size: 17px; color: #999;">X</button>
        </div>
        <div>
            <button title="Generate Image" onclick="getInputText();" style="color: black; cursor: pointer; background-color: white; border: none; border-radius: 20px; padding: 10px; font-weight: bold; font-size: medium;" id="generateButton">Generate Image  &#11118;</button>
        </div>
  </div>
  <div id="loadingText" style="display: none; font-weight: bold; padding: 10px;">Generating image...</div>
  <img id="generatedImage" style="position: fixed; top: 54%; left: 50%; transform: translate(-50%, -50%); width: 300px;">
</div>
`);

//Initialise variables
let generatedImage;
let generatedImageUrl;
let descriptionContainer; // Declare a variable to store the description container
let generatedImages = [];
let generatedImageDescriptions = [];
let currentIndex = -1; // Initialize the index to -1
let recognition;
 
// Create a container for the image
const imageContainer = document.createElement("div");
    imageContainer.style.textAlign = "center";
    document.body.appendChild(imageContainer);
  
// Function to update the displayed image and description
function updateDisplayedImage() {
  if (currentIndex >= 0 && currentIndex < generatedImages.length) {
    const imageUrl = generatedImages[currentIndex];
    const description = generatedImageDescriptions[currentIndex];

    // Create an img element for the image
    const imageElement = document.createElement("img");
    imageElement.src = imageUrl;
    imageElement.style.width = "300px";

    // Create a div for the description
    const descriptionDiv = document.createElement("div");
    if(description){
            descriptionDiv.textContent = "Caption: " + description.toUpperCase();
    }

    descriptionDiv.style.fontWeight = "bold";
    descriptionDiv.style.top = "83%";
    descriptionDiv.style.position = "fixed";
    descriptionDiv.style.left = "45%";
    descriptionDiv.style.width = "490px";
    descriptionDiv.style.color = "white";
    descriptionDiv.style.transform = "translate(-170px, -50px)";
    document.getElementById('loadingText').style.display = 'none';

    // Clear the image container before appending the new image and description
    imageContainer.innerHTML = "";
    imageContainer.appendChild(imageElement);
    imageContainer.appendChild(descriptionDiv);
  }
}

//Event listener for the Enter Key in the input field
document.getElementById('userInput').onkeydown   = function(event) 	{ 
    if (event.keyCode == 13){
        const userProvidedDescription = jQuery("input#userInput").val();
        generateImageFromDescription(userProvidedDescription);
    }  
};

//Function to clear the input field
function clearInput() {
    const userInputField = document.getElementById('userInput');
    userInputField.value = '';
}

//Function to get user input and generate image
function getInputText() {
    const userProvidedDescription = jQuery("input#userInput").val();
    generateImageFromDescription(userProvidedDescription);
}

//Function to generate an image based on user input description
async function generateImageFromDescription(userProvidedDescription) {
    // Show loading text
    document.getElementById('loadingText').style.display = 'block';
  
    // Remove the current generated image
    if (generatedImage) {
        document.body.removeChild(generatedImage);
    }
  
  
  try {
    const apiResponse = await fetch(apiEndpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiAccessKey}`,
        },
            body: JSON.stringify({
            prompt: userProvidedDescription,
            n: 1,
            }),
        });

        if (!apiResponse.ok) {
        throw new Error(`HTTP error! Status: ${apiResponse.status}`);
        }

        const responseData = await apiResponse.json();
        generatedImageUrl = responseData.data[0].url;
        generatedImages.push(generatedImageUrl);
        currentIndex = generatedImages.length - 1; // Update the current index
        updateDisplayedImage();
        console.log('generated Image URL', generatedImageUrl);

        // Display the generated image
        const generatedImage = document.getElementById('generatedImage');

        // Hide loading text once image is rendered
        document.getElementById('loadingText').style.display = 'none';
        toggleArrowVisibility(true);
        } catch (error) {
            console.error("Error:", error.message);
        }
        if(generatedImageUrl) {

        try {
            const response = await fetch(azureEndpoint, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "Ocp-Apim-Subscription-Key": azureapiKey,
            },
            body: JSON.stringify({ url: generatedImageUrl }), // Use the generated image URL
            });

        if (response.ok) {
            const data = await response.json();
            const description = data.description.captions[0].text;
            if(description) {
                // Remove the previous description container, if exists
                if (descriptionContainer) {
                    document.body.removeChild(descriptionContainer);
                }
                generatedImageDescriptions.push(description);
                currentIndex = generatedImages.length - 1; // Update the current index
                updateDisplayedImage();
                // Create a button for reading the description out loud
                const readButton = document.createElement("button");
                readButton.textContent = "Play Caption 🎧";
                readButton.style.position = "fixed";
                readButton.style.top = "87%";
                readButton.style.left = "50%";
                readButton.style.borderRadius = "20px";
                readButton.style.border = "1px solid black";
                readButton.style.padding = "7px";
                readButton.style.color = "black";
                readButton.style.backgroundColor = "white";
                readButton.style.fontWeight = "bold";
                readButton.style.transform = "translate(-50%, -50%)";
                readButton.style.cursor = "pointer";
                document.body.appendChild(readButton);
      
                // Add click event listener to the read button
                readButton.addEventListener("click", function () {
                    
                // Use the Web Speech API to read the description
                        const speechSynthesis = window.speechSynthesis;
                        const speechText = new SpeechSynthesisUtterance(generatedImageDescriptions[currentIndex]);
                        speechSynthesis.speak(speechText);
                    });
      
                }
                    console.log("Generated Image Description:", description);
            } else {
                console.error("Error:", response.status, response.statusText);
            }
    } catch (error) {
        console.error("Error:", error.message);
  }
  }
}
  // Function to navigate to the previous image
function showPreviousImage() {
    if (currentIndex > 0) {
        currentIndex--;
        updateDisplayedImage();
    }
}

  // Function to navigate to the next image
function showNextImage() {
    if (currentIndex < generatedImages.length - 1) {
        currentIndex++;
        updateDisplayedImage();
    }
}
  
  // Create left arrow
const leftArrow = document.createElement("div");
leftArrow.innerHTML = "&#129152;"; // Unicode character for left arrow
leftArrow.style.position = "fixed";
leftArrow.style.top = "44%";
leftArrow.style.left = "29%";
leftArrow.style.fontSize = "32px";
leftArrow.style.cursor = "pointer";
leftArrow.style.display = "none"; // Initially hidden
leftArrow.style.color = "white";
leftArrow.title = "Previous";
document.body.appendChild(leftArrow);

// Create right arrow
const rightArrow = document.createElement("div");
rightArrow.innerHTML = "&#129154;"; // Unicode character for right arrow
rightArrow.style.position = "fixed";
rightArrow.style.top = "44%";
rightArrow.style.left = "69%";
rightArrow.style.fontSize = "32px";
rightArrow.style.cursor = "pointer";
rightArrow.style.display = "none"; // Initially hidden
rightArrow.style.color = "white";
rightArrow.title = "Next";
document.body.appendChild(rightArrow);

// Add click event listeners to the arrows
leftArrow.addEventListener("click", showPreviousImage);
rightArrow.addEventListener("click", showNextImage);

// Function to toggle arrow visibility
function toggleArrowVisibility(visible) {
  leftArrow.style.display = visible ? "block" : "none";
  rightArrow.style.display = visible ? "block" : "none";
}

//Function to convert speech to text
function startSpeechRecognition() {
    // Initialize SpeechRecognition
    recognition = new webkitSpeechRecognition() || new SpeechRecognition();
    recognition.lang = 'en-US';

    // Define event handlers
    recognition.onresult = function(event) {
        const transcript = event.results[0][0].transcript;
        document.getElementById('userInput').value = transcript;
    };

    recognition.onend = function() {
        // Recognition ended
    };

    // Start recognition
    recognition.start();
}