Code viewer for World: AI Recipe Generator
// USECASE on AI RECIPE GENERATOR

// ===================================================================================================================
// ==== Assignment 2 | Part 2  ========================================================================================
/*
        STUDENT NAME:       POOJA NAMDEV SALGAR
        STUDENT NUMBER:     23267148
        STUDENT EMAIL:      pooja.salgar2@dcu.mail.ie
        MODULE NAME:        Foundations of AI (online)
        MODULE CODE:        CA686I
    

*/
// ===================================================================================================================



//===============================================================================================================================================================
// MH edit
// moved to top
// Replace these with your actual OpenAI and Image Generation API URLs and keys

//  const openaiURL = "https://api.openai.com/v1/engines/text-davinci-003/completions";  // removed - 404 error 

    const openaiURL = "https://api.openai.com/v1/chat/completions";       // replacement, can use model 'davinci-002' for compatibility 

const imageGenerationApiURL = "https://api.openai.com/v1/images/generations";

const apiKey =    "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";




// ======================body=======================================================================================================
$('body').css({
     "display": "flex",
    "margin": "0",
    "padding": "0",
    "text-align": "center",
    // Enable vertical scrolling if content overflows
    "overflow-y": "auto", 
    "background-image": "url('https://ancientbrain.com/uploads/pooja20/DALLE2023-12-0201.37.37-Createadark-themedimageforarecipewebsitebackgroundemphasizingmorefoodattheedgeoftheleftside.Theimageshouldfeatureanabundance.png')", // Set your background image // https://labs.openai.com/
    "background-size": "cover", // Cover the entire viewport
    "background-repeat": "no-repeat", // Prevent the image from repeating
    "background-attachment": "fixed", // Keep the background fixed during scroll
    "background-position": "center", // Center the background image
  
    "align-items": "center",
    "justify-content": "center",
    
});


//=================================================================================================================================================================
//Dynamically write HTML content into the document

document.write(`

 
      <nav id="navbar">
        <ul>
            <li><a href="#contact">Contact</a></li>
            <li><a href="#feedback">Feedback</a></li> <!-- Adding Feedback link -->
            <li><a href="#home">Home</a></li>
        </ul>
    </nav>
<div id="contactModal" class="modal" style="display: none;">
        <div class="modal-content">
            <span class="close" onclick="document.getElementById('contactModal').style.display='none'">&times;</span>
            <h3>Contact Us</h3>
            <p>Email: contact@example.com</p>
            <p>Phone: 123-456-7890</p>
            <!-- More contact details here -->
        </div>
    </div>



<div id="enterkey" >

<div class="container">
    <h2>AI Recipe Generator</h2>
    <textarea id="ingredients" placeholder="Enter ingredients, separated by commas (e.g., eggs, flour, sugar) or Dish name"></textarea>
    <button onclick="generateRecipe()">Generate Recipe</button>
</div>
<div class="container" id="response-container">
    <h2 style="text-align:center">Amazing Recipe!!</h2>
    <div id="response"></div>
</div>


<div class="container" id="image-container">
    <h2>Generated Image</h2>
    <img id="recipe-image" src="" alt="Recipe image will appear here" style="max-width:300px; height:300px;" />
</div>


<div class="container" id="feedback-container">
        <h2>Feedback Form</h2>
        <form id="feedback-form">
            <label for="feedback">Your Feedback:</label>
            <textarea id="feedback" placeholder="Please write feedback here"></textarea>
            <button type="submit">Submit Feedback</button>
        </form>
        <div id="feedback-message" style="display:none; color: green; margin-top: 10px;"></div> <!-- Feedback confirmation message -->
    </div>

<audio id="background-music" loop>
    <source src="https://ancientbrain.com/uploads/pooja20/JustinBieber-YummyLyricseMP3.to.mp3" type="audio/mpeg">
    Your browser does not support the audio element.
</audio>

<div class="music-controls">
    <div class="button-container">
        <button id="play-music">&#9658;</button> <!-- Play symbol -->
        <span>Play Music</span>
    </div>
    <div class="button-container">
        <button id="pause-music">&#10074;&#10074;</button> <!-- Pause symbol -->
        <span>Pause Music</span>
    </div>
    <div class="button-container">
        <button id="stop-music">&#9724;</button> <!-- Stop symbol -->
        <span>Stop Music</span>
    </div>
</div>

`);


//======================================================================================================================================================
// Add CSS styles for containers and input elements===============================================================================

const containerStyle = {
   
    "padding": "20px",
    "margin-bottom": "20px",
    "border": "1px solid #ee5f5b",
    "border-radius": "10px", // Rounded corners
   "background-color": "rgba(255, 255, 255, 0.8)", // White with opacity for readability
    "width": "80%", // Adjust the width as needed
    "max-width": "800px", // Set a maximum width
    "box-shadow": "0 4px 8px rgba(0, 0, 0, 0.2)", // Soft shadow for depth
    "color": "#333", // Dark text color for contrast
    "margin": "20px auto", // Center the container
    "text-align": "left" // Align text to the left
};

$(".container").css(containerStyle);

$("h2:contains('AI Recipe Generator')").css({
    "color": "#A52A2A",
    "animation": "pulse 1s infinite ease-in-out"
});

//==========================================================================================================================================
// Adding keyframes for the pulse animation

$("<style>").prop("type", "text/css").html(`
    @keyframes pulse {
      0% { transform: scale(1); }
      50% { transform: scale(1.1); }
      100% { transform: scale(1); }
    }
`).appendTo("head");

//====================================================================================================================================
// jQuery to change color of text to dark blue when user enters text in textarea

$("#ingredients").on('input', function() {
    if ($(this).val() !== "") {
        $(this).css({"color": "darkblue", "font-weight": "bold"}); // Change text color to dark blue and make it bold
    } else {
        $(this).css({"color": "black", "font-weight": "normal"}); // Revert back to black and normal weight when textarea is empty
    }
});



//=====CSS styles for navbar=======================================================================================================

$("#navbar ul").css({
    "list-style-type": "none",
    "margin": "0",
    "padding": "0",
    "overflow": "hidden",
    "background-color": "#27496D",
    "position": "fixed",
    "top": "0",
    "width": "100%",
    "z-index": "1000"
});

$("#navbar ul").css({
    "list-style-type": "none",
    "margin": "0",
    "padding": "0"
});

$("#navbar ul li").css({
    "float": "right" // Right align the navbar items
});

$("#navbar ul li a, .dropbtn").css({
    "display": "block",
    "color": "white",
    "text-align": "right",
    "padding": "0px 4px",
    "font-size": "14px", 
    "text-decoration": "none"
});

$(".dropdown").css({
    "display": "inline-block"
});

$(".dropdown-content").css({
    "display": "none",
    "position": "absolute",
    "background-color": "#f9f9f9",
    "min-width": "160px",
    "box-shadow": "0px 8px 16px 0px rgba(0,0,0,0.2)",
    "z-index": "1"
});

$(".dropdown-content a").css({
    "color": "black",
    "padding": "0px 4px",
    "text-decoration": "none",
    "display": "block",
    "text-align": "left"
});

$(".dropdown-content a:hover").css({
    "background-color": "#f1f1f1"
});

$(".dropdown:hover .dropdown-content").css({
    "display": "block"
});

$(".dropdown:hover .dropbtn").css({
    "background-color": "#3e8e41"
});

$("#navbar ul li a:hover:not(.active), .dropdown:hover .dropbtn").css({
    "background-color": "#555"
});

$("#navbar ul li a.active").css({
    "background-color": "#4CAF50"
});

//=====================================================================================================================================
// CSS styles for modal

$(".modal").css({
    "position": "fixed",
    "z-index": "1",
    "left": "0",
    "top": "0",
    "width": "100%",
    "height": "100%",
    "overflow": "auto",
    "background-color": "rgba(0,0,0,0.4)" // Black with opacity
});

$(".modal-content").css({
    "background-color": "#ADD8E6", // Light blue background color
    "margin": "15% auto",
    "padding": "20px",
    "border": "1px solid #888",
    "width": "80%" // Adjust as needed
});
$(".close").css({
    "color": "#aaa",
    "float": "right",
    "font-size": "28px",
    "cursor": "pointer"
});

//==========================================================================================================================================================
// CSS styles for input elements=====================

const inputStyle = {
    
    "text-align": "center",

    "width":"100%",
    "margin": "20px 20px",
    "padding": "10px",
    "border-radius": "20px",
    "border": "none",
    "box-shadow": "0 4px 8px rgba(0, 0, 0, 0.2), 0 6px 20px rgba(0, 0, 0, 0.19)"
};

$(".container").css(containerStyle);
$("textarea").css(inputStyle);
$("button").css(inputStyle);
$("#enterkey").css({
    "display": "flex",
    "flex-direction": "column", // Stack children vertically
    "align-items": "center", // Center-align children horizontally
    "justify-content": "space-between", // Distribute space between children
    "width": "100%",
    "max-width": "1000px",
    "margin": "0 auto"
});
$("#response-container").css({
  "max-height":"80vh",
  "overflow-y":"scroll",
})

//=============================================================================================================================
// Style the "Generate Recipe" button
$("button").css({
    "width": "50%",
    "padding": "10px",
    "margin-top": "10px",
    "background-color": "#007bff",
    "color": "#fff",
    "border": "none",
    "border-radius": "5px",
    "cursor": "pointer"
});

//================================================================================================================================================================
//=====style for Music buttons===================================================================================================================================
$(".music-controls").css({
    "position": "fixed",
    "top": "0",                 // Positioned at the top of the page
    "left": "-30",                // Positioned at the left side of the page
    "padding": "10px",          // Padding around the controls
    "text-align": "center",
    "z-index": "10"             // Adjusted z-index to prevent overlap
});

$(".music-controls .button-container").css({
    "display": "flex",          // Use flexbox layout
    "align-items": "center",    // Vertically center the items
    "margin-bottom": "5px"      // Margin between each button-container
});

$(".music-controls button").css({
    "border-radius": "50%",     // Circular shape for buttons
    "width": "40px",            // Width of the button
    "height": "40px",           // Height of the button
    "padding": "10px",          // Padding inside the button
    "margin-right": "5px",      // Space between the button and text
    "display": "inline-block"   // Make the button an inline-block element
});

$(".music-controls span").css({
    "font-size": "16px",        // Font size for the text
    "display": "inline-block",  // Make the text an inline-block element
    "position": "relative",     // Position relative to its normal position
    "top": "-5", 
    "font-weight": "bold",
    "color": "#FFFFFF"// Move the text 5 pixels up
    
});

//====================================================================================================================================================

// Add hover effect for the button
$("button").hover(function() {
    $(this).css("background-color", "#0056b3");
}, function() {
    $(this).css("background-color", "#007bff");
});


//================================================================================================================================================================
// Center align text within containers
$(".container").css("text-align", "center");
$(".container:first").css("margin-top", "30px");




//===============================================================================================================================================================
// Function to generate a recipe===========================================================================================================

function generateRecipe() {
    const ingredients = $("#ingredients").val().trim();
    if (!ingredients) {
        displayError("Please enter some ingredients to continue.");
        return;
    }
      
    const recipePrompt = `Given these ingredients: ${ingredients}, can you provide a recipe?`;

    sendRequestToOpenAI(recipePrompt);
}

//================================================================================================================================================================
// Function to play background music==============================================================================================================================

function playBackgroundMusic() {
    var music = document.getElementById("background-music");
    music.play();
}
playBackgroundMusic();


// Add event listeners for music control buttons
$(document).ready(function() {
    $('#play-music').click(function() {
        $('#background-music')[0].play();
    });

    $('#pause-music').click(function() {
        $('#background-music')[0].pause();
    });

    $('#stop-music').click(function() {
        var music = $('#background-music')[0];
        music.pause();
        music.currentTime = 0;
    });
});

//=============================================================================================================================================
//Function to send a request to OpenAI's GPT-3 API
function sendRequestToOpenAI(prompt) {
    $("#response").text("Generating recipe... Please wait.");

    const data = {
        // model: 'davinci-002',  // MH edit   
        prompt: prompt,
        max_tokens: 1024,
        temperature: 0.7
    };
    createImageEdit();

    $.ajax({
        type: "POST",
        url: openaiURL,
        data: JSON.stringify(data),
        headers: {
            "Authorization": `Bearer ${apiKey}`,
            "Content-Type": "application/json"
        },
        success: function(response) {
            const recipeText = response.choices[0].text.trim();
            displayRecipeInSteps(recipeText); // Display the recipe in a step-by-step format
             // Trigger image generation with the recipe text
        },
        error: function(xhr) {
            displayError("Failed to generate recipe. Please try again.");
        }
        
    });
}

//================================================================================================================================================
//display recipe==============================================================================================================================================
function displayRecipeInSteps(recipeText) {
    // Split the recipe text into steps assuming each step is separated by two new lines.
    var steps = recipeText.split("\n\n");

    // Create a list of steps, each in a new line, ensuring empty steps are not added
    var formattedSteps = steps.map(step => `<p>${step.trim()}</p>`).join('');

    // Update the response container with the formatted steps
    $("#response").html(formattedSteps);
}



//===========================================================================================================================================================
//========function of generate image=========================================================================================================================

async function createImageEdit() {
    
    const imagen=document.getElementById('ingredients').value;
    const display_image=document.getElementById('recipe-image');
  try {
    const imageres = await fetch(imageGenerationApiURL,
     // Replace with the actual API endpoint
      {
          method:'post',
          headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
        body:JSON.stringify({
            model:'dall-e-2',
            prompt:imagen,
            n:1,
            size: '1024x1024',
        
            
        })
        
       
      }
      
      
    );
    const getdata=await imageres.json();
    const getimage = getdata.data[0].url;
    display_image.src=getimage;
    
    console.log('Edited Image URL:', imageUrl);
  } catch (error) {
    console.error('Error:', error.message);
  }
}

//=============================================================================================================================================================
$(document).ready(function() {
    // Prevents default form submission and shows feedback message
    $('#feedback-form').on('submit', function(event) {
        event.preventDefault();
        var feedback = $('#feedback').val();
        $('#feedback-message').text('Thank you for your feedback!').show();
        $('#feedback').val('');
    });

    // Change style of text input in the #ingredients textarea
    $("#ingredients").on('input', function() {
        if ($(this).val() !== "") {
            $(this).css({
                "color": "darkblue",
                "font-weight": "bold",
                "font-size": "16px"
            });
        } else {
            $(this).css({
                "color": "black",
                "font-weight": "normal",
                "font-size": "14px"
            });
        }
    });

    // Dropdown animation
    $(".dropdown").hover(function() {
        $(this).find(".dropdown-content").slideDown(200);
    }, function() {
        $(this).find(".dropdown-content").slideUp(200);
    });

    // Contact modal display
    $("#navbar ul li a[href='#contact']").click(function(event) {
        event.preventDefault();
        $("#contactModal").css("display", "block");
    });


    // Change the color of "Amazing Recipe!!" text
    $("#response-container h2:contains('Amazing Recipe!!')").css("color", "darkblue");


    // Change the color and font-weight of the "Generating recipe..." text
    $("#response").css({"color": "black", "font-weight": "bold"});


    // Function to display recipe steps in bold black text
    function displayRecipeInSteps(recipeText) {
        var steps = recipeText.split("\n\n");
        var formattedSteps = steps.map(step => `<p style='color: black; font-weight: bold;'>${step.trim()}</p>`).join('');
        $("#response").html(formattedSteps);
    }

     $("#feedback-container h2:contains('Feedback Form')").css({
        "color": "green", 
        "animation": "animateText 1.5s infinite"
    });
    $("#image-container h2:contains('Generated Image')").css("color", "darkblue"); 

    
 $("#image-container").css({
        "border-radius": "30px" 
    });
    
    
     $("#enterkey .container").css({
        "display": "flex", // Use flexbox
        "flex-direction": "column", // Stack children vertically
        "align-items": "center", // Center-align children horizontally
        "justify-content": "center", // Center-align children vertically
    });

    // Style for the textarea
    $("#ingredients").css({
        "width": "80%", // Adjust the width as needed
        "margin": "10px 0", // Add some margin for spacing
       
    });
    

    // Keyframes for the text animation
    $("<style>").prop("type", "text/css").html(`
        @keyframes animateText {
            0% { transform: scale(1); }
            50% { transform: scale(1.1); }
            100% { transform: scale(1); }
        }
    `).appendTo("head");
    $("#feedback-form label:contains('Your Feedback')").css({
        "color": "darkblue"
    });
});

//=====================================================================================================================================================s
// Function to display error messages

function displayError(message) {
    $("#response-container").html(`<span class="error">${message}</span>`);
}