Code viewer for World: VerseCraft
$(document).ready(function() {
  $('body').css("background-image", "url('/uploads/leonard/bg4.jpg')");
  $('body').css("background-repeat", "no-repeat");
  $('body').css("background-size", "cover");
  $('body').css("background-attachment", "fixed"); 
  $('body').css("color", "#ffffff");
  $.getScript("/uploads/leonard/wavesurfer.js", function() {
  });
});


// MH edit
// moved API keys up here
const API_KEY =  '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';
const apiKey = API_KEY;


var wavesurfer;
// Create your own media element
const audio = new Audio()
audio.controls = true

 // Create a script element
  var wavesurferScript = document.createElement('script');

  //a callback function to be executed when the script is loaded
  wavesurferScript.onload = function () {
    // Wavesurfer.js is now loaded

    var playbtn = document.getElementById('playbtn');

      wavesurfer = WaveSurfer.create({
      container: '#waveform',
      waveColor: '#45A29E',
      progressColor: '#66FCF1',
      media: audio,
      barWidth: 4,
      barGap: 5,
      responsive: true,
      height: 90,
      barRadius: 4,
    });

    playbtn.onclick = function () {
      wavesurfer.playPause();
      if (playbtn.src.includes("/uploads/leonard/play.png")) {
        playbtn.src = "/uploads/leonard/pause.png";
      } else {
        playbtn.src = "/uploads/leonard/play.png";
      }
    };

    wavesurfer.on('finish', function () {
      playbtn.src = "/uploads/leonard/play.png";
      wavesurfer.stop();
    });

    wavesurfer.on('click', () => {
      wavesurfer.play();
    });
  };


  wavesurferScript.src = 'https://unpkg.com/wavesurfer.js@7';

  // Append the script element to the head of the document
  document.head.appendChild(wavesurferScript);

 document.write(`    

    <!-- Sections -->
    <section id="welcome" class="section">
        <div class="container">
            <h2 style=" text-align: center; color: white; font-size: 100px">VERSECRAFT</h2>
            <p>Unlock the magic of poetry with our innovative poem generator. My platform crafts lyrical masterpieces at the click of a button. Join me on a journey through rhythmic lines and captivating stanzas, where creativity knows no bounds. Discover your poetic prowess with VerseCraft. today!</p>
            <a href="#top_part" onclick="scrollToSection('top_part', this)"> <button class="btn_one">Let's Go!!</button></a>
            <br>
        </div>
        
    </section>
    
    
    <section class="main">

   <div id="loading" class="loading" style="display: none;">Loading&#8230;</div>

    <table id="top_part"
        style="width: 100%; height: 100vh; table-layout: fixed; padding-left: 140px; padding-right: 140px;">
        <tr>
            <td id="poemImage" style="width: 50%; text-align: center; vertical-align: middle;">
                <div id="image-container" style="width: 50%; text-align: center; vertical-align: middle;">
                    <div id="image-placeholder"
                        style="width: 600px; height: 600px; background-color: ##1F2833; color: white; display: flex; justify-content: center; align-items: center; border-radius: 50%;">
                        Poem Cover Image
                    </div>
                    <img id="generatedImage" alt="Generated Image"
                        style="display: none; width: 600px; height: 600px; justify-content: center; align-items: center; border-radius: 50%;">
                </div>
            </td>
            <td id="poem" style="text-align: center; vertical-align: middle;">
                <div id="text-area-container">
                    <textarea id="response-textarea" placeholder="Poem" readonly></textarea>
                </div>

                <div class="audiowave">
                    <img src="/uploads/leonard/play.png" alt="play" id="playbtn">
                    <div id="waveform"></div>
                </div>
            </td>
        </tr>
        <tr>
            <td colspan="2" style="text-align: center; vertical-align: middle;">
                <input type="text" id="prompt-input" placeholder="Enter the topic you want the poem on eg: Nature or Future or ocean, etc.">
               <select name="options" id="options">
                    <option id="opts" value="William Shakespeare" selected>William Shakespeare</option>
                    <option id="opts" value="Pablo Neruda">Pablo Neruda</option>
                    <option id="opts" value="Rumi">Rumi</option>
                    <option id="opts" value="Rabindranath Tagore">Rabindranath Tagore</option>
                    <option id="opts" value="Robert Frost">Robert Frost</option>
                    <option id="opts" value="Sylvia Plath">Sylvia Plath</option>
                </select>

                <button id="generate-btn" onclick="handleUserInput()">Generate</button>
            </td>
        </tr>
    </table>
    
    </section>

    
    `);

const styleElement = document.createElement("style");

// Set the CSS code as the content of the style element
styleElement.textContent = `

body {
    font-family: 'Poppins', sans-serif;
    padding: 0;
    margin: 0;
    max-width: 100vw;
    overflow-x: hidden;
    background-color: #0c0c18;
    scroll-behavior: smooth;
}


body::-webkit-scrollbar {
  width: 12px; 
}

/* Handle on hover */
body::-webkit-scrollbar-thumb:hover {
  background: #555; 
}


body::-webkit-scrollbar-thumb {
  background: #888; 
  border-radius: 10px;
}


body::-webkit-scrollbar-track {
  background: #f1f1f1; 
}


body::-webkit-scrollbar-thumb:active {
  background: #555; 
}


.section{
   
    height:100vh;
}

.container {
    max-width: 1040px;
    margin: 0 auto;
    padding: 20px;
    text-align: center;
}

p{
     font-size: 25px;
}

.btn_one {
    font-size: 18px;
    font-family: 'Poppins', sans-serif;
    color: white;
    background: rgba(255, 255, 255, 0.0); 
    border: 3px solid #45A29E;
    padding: 8px 40px;
    width: 200px; 
    border-radius: 80px;
    font-weight: bold;
    backdrop-filter: blur(10px);
    margin: 2vh auto; 
    transition: 0.4s ease-in-out;
}


.btn_one:hover {
    box-shadow: 0px 10px 30px #66FCF1;
    cursor: pointer;
    color: #66FCF1;
    background: rgba(255, 255, 255, 0.5);
}


.loader-line {
    width: auto;
    height: 3px;
    position: relative;
    overflow: hidden;
    background-color: #202020;
    border-radius: 20px;
}

.loader-line:before {
    content: "";
    position: absolute;
    left: -50%;
    height: 3px;
    width: 40%;
    background-color: #4CAF50;
    animation: lineAnim 1s linear infinite;
    border-radius: 20px;
}

@keyframes lineAnim {
    0% {
        left: -40%;
    }

    50% {
        left: 20%;
        width: 80%;
    }

    100% {
        left: 100%;
        width: 100%;
    }
}

.section {
    padding: 40px 0;
}

.container section {
    margin-left: 0;
}

hr {
    height: 1px;
    background-color: #303030;
    border: none;
    margin-left: 140px;
    margin-right: 140px;
}


#image-container {
    margin-top: 20px;
}

#image-placeholder {
    width: 100%;
    height: 600px;
    background-color: rgba(255, 255, 255, 0.01);
    display: flex;
    justify-content: center;
    align-items: center;
    backdrop-filter: blur(10px);
    border: 0.5px solid #767676; 
    box-sizing: border-box;
     transition: background-color 0.3s ease; 
   
}

#image-placeholder:hover {
    background-color: rgba(255, 255, 255, 0.1); 
    
}


#prompt-input:hover {
    background-color: rgba(255, 255, 255, 0.1);
   
}



#image {
    display: none;
}

#generatedImage {
    display: none;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#prompt-input {
    margin-top: 40px;
    padding: 5px;
    width: 52%;
    padding-top: 10px;
    padding-bottom: 10px;
    border: 2px solid #767676;
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 0.05);
    color: #ffffff;
    backdrop-filter: blur(10px);
}

#prompt-input::placeholder {
    color: white; 
}
#prompt-input:hover {
    background-color: rgba(255, 255, 255, 0.1); 
    
}



#options {
    margin-top: 40px;
    padding: 5px;
    width: 13%;
    padding-top: 10px;
    padding-bottom: 10px;
    border: 2px solid #767676;
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 0.05);
    color: #ffffff;
    backdrop-filter: blur(10px);
}
#options:hover {
    background-color: rgba(255, 255, 255, 0.1); 
    
}



#opts{
   background-color: rgba(0, 0, 0, 1);
    color: #ffffff;
    backdrop-filter: blur(10px);
}

#generate-btn {
    margin-top: 40px;
    padding: 10px;
    width: 28%;
    border: none;
    cursor: pointer;
    background: linear-gradient(45deg, #ae12a4, #f3784b); 
    color: white;
    font-size: 16px;
    border-radius: 5px;
}

.audiowave{
    display: flex;
    align-items: center;
    margin-top:20px;
}

.audiowave img{
    width: 70px;
    margin-right: 30px;
    cursor: pointer;
}

.audiowave div{
    flex: 1;
}


#text-area-container {
    width: 100%;
    height: 500px;
    margin-top: 20px;
    transition: background-color 0.3s ease; 
}

#text-area-container:hover {
    background-color: rgba(255, 255, 255, 0.1); 
}


#response-textarea {
    width: 100%;
    height: 100%;
    box-sizing: border-box; 
    resize: none;
    padding: 10px; 
    border-radius: 5px;
    background-color: rgba(255, 255, 255, 0.0); 
    color: #ffffff; 
    font-size: 19px;
    backdrop-filter: blur(10px);
    text-align: center;
    
    
    scrollbar-width: thin; 
    scrollbar-color: #66FCF1 #0c0c18; 

    &::-webkit-scrollbar {
        width: 12px;
    }

    &::-webkit-scrollbar-thumb {
        background-color: #66FCF1; 
        border-radius: 10px; 
    }

    &::-webkit-scrollbar-track {
        background-color: #0c0c18; 
        border-radius: 10px; 
    }
}



.loading {
  position: fixed;
  z-index: 999;
  height: 2em;
  width: 2em;
  overflow: visible;
  margin: auto;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
}


.loading:before {
  content: '';
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(0,0,0, 0.2);
   backdrop-filter: blur(10px);
}

.loading:not(:required) {
  /* hide "loading..." text */
  font: 0/0 a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}

.loading:not(:required):after {
  content: '';
  display: block;
  font-size: 10px;
  width: 1em;
  height: 1em;
  margin-top: -0.5em;
  -webkit-animation: spinner 1500ms infinite linear;
  -moz-animation: spinner 1500ms infinite linear;
  -ms-animation: spinner 1500ms infinite linear;
  -o-animation: spinner 1500ms infinite linear;
  animation: spinner 1500ms infinite linear;
  border-radius: 0.5em;
  -webkit-box-shadow: #66FCF1 1.5em 0 0 0, #66FCF1 1.1em 1.1em 0 0, #66FCF1 0 1.5em 0 0, #66FCF1 -1.1em 1.1em 0 0, #66FCF1 -1.5em 0 0 0,#66FCF1 -1.1em -1.1em 0 0, #66FCF1 0 -1.5em 0 0, #66FCF1 1.1em -1.1em 0 0;
 
}

/* Animation */

@-webkit-keyframes spinner {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@-moz-keyframes spinner {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@-o-keyframes spinner {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes spinner {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    -moz-transform: rotate(360deg);
    -ms-transform: rotate(360deg);
    -o-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}


@media only screen and (max-width: 1366px) {
    body {
        margin-left: 10px;
        margin-right: 10px;
    }

  #image-placeholder,
    #generatedImage {
        height: 80px;
    }
    .container {
        padding: 5px;
    }

    p {
        font-size: 14px;
    }

    .btn_one {
        font-size: 12px;
        padding: 6px 12px;
        width: 20%;
    }

    .loader-line {
        height: 1.5px;
    }

    .loader-line:before {
        height: 1.5px;
    }

    #prompt-input,
    #options {
        width: 90%;
    }

    #generate-btn {
        width: 90%;
    }

    .audiowave img {
        width: 20px;
        margin-right: 5px;
    }

    #text-area-container {
        height: 50%;
        width: 50%;
    }

    #response-textarea {
        font-size: 12px;
    }

    .loading {
        height: 1em;
        width: 1em;
    }

    .loading:before {
        font-size: 6px;
    }

    .loading:not(:required):after {
        width: 0.8em;
        height: 0.8em;
        margin-top: -0.4em;
    }
}

`;






    document.head.appendChild(styleElement);

 //Show the loading icon
 const loadingIcon = document.getElementById('loading');
       

    
// Function to get the response from ChatGPT
async function getChatResponse(userInput) {
//  const API_KEY =  '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';
  const apiUrl = 'https://api.openai.com/v1/chat/completions';

  try {
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}`,
      },
      body: JSON.stringify({
        model: 'gpt-3.5-turbo',
        messages: [
          { "role": "system", "content": "You are a 2 paragrph poem generator" },
          { "role": "user", "content": userInput },
        ],
      }),
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`HTTP error! Status: ${response.status}. Details: ${errorText}`);
    }

    return await response.json();
  } catch (error) {
    console.error('Error:', error.message);
    throw error;
  }
}


async function handleUserInput() {
  try {
      
       
       loadingIcon.style.display = 'block';
    // Get user input from the prompt
    const userInput = document.getElementById('prompt-input').value;
    
    // Check if trimmed user input is empty
    if (!userInput) {
      // Display an error message
      loadingIcon.style.display = 'none';
      console.log("please enter the type of poem you want.")
      return;
    }

    // Get the selected poet from the dropdown
    const selectedPoet = document.getElementById('options').value || 'William Shakespeare';

    // Combine the user input, selected poet, and "in 5 paragraphs" as the prompt
    const firstUserInput = `${userInput}: "poem in the style of": ${selectedPoet}`;

    // First iteration: Get response from ChatGPT for generating a poem
    const firstChatGptResponse = await getChatResponse(firstUserInput);

    // Extract the content of the assistant's response from the first choice
    const firstChatGptAssistantResponse = firstChatGptResponse.choices[0].message.content;

    // Set the assistant's response in the text area
    const responseTextarea = document.getElementById('response-textarea');
    responseTextarea.value = firstChatGptAssistantResponse;

    // Optionally, you can log the entire firstChatGptResponse to the console for debugging
    console.log('First ChatGPT Response:', firstChatGptResponse);

    // Second iteration: Get response from ChatGPT for generating a prompt for DALL-E 3
    const secondUserInput = `Generate a prompt based on this poem. it should be creative and intresting and also avoide the words like "write" "text" "story" "poem" "language" or anything similar : ${firstChatGptAssistantResponse}`;
    const secondChatGptResponse = await getChatResponse(secondUserInput);

    // Optionally, you can log the entire secondChatGptResponse to the console for debugging
    console.log('Second ChatGPT Response:', secondChatGptResponse);


const secondChatGptAssistantResponse = secondChatGptResponse.choices[0].message.content;

 console.log('prompt to Dall e 3', secondChatGptAssistantResponse);



    await dalle(secondChatGptAssistantResponse);
    
    await speechModel(firstChatGptAssistantResponse);

  } catch (error) {
    loadingIcon.style.display = 'none';
    console.error('Error:', error.message);
  }
}



// Function to generate image using DALL-E 3
async function dalle(promptForDalle) {
//  const API_KEY =  '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';
  const url = 'https://api.openai.com/v1/images/generations';

  try {
    
    const placeholderElement = document.getElementById('image-placeholder');
    const generatedImageElement = document.getElementById('generatedImage');

   
    placeholderElement.style.display = 'flex';
    generatedImageElement.style.display = 'none';

    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${API_KEY}`
      },
      body: JSON.stringify({
        prompt: promptForDalle, 
        model: 'dall-e-3',
        n: 1,
        size: '1024x1024',
      })
    });

    if (!response.ok) {
      loadingIcon.style.display = 'none';
      throw new Error(`HTTP error! Status: ${response.status}`);
    }

    const responseData = await response.json();
    const imageURL = responseData.data[0].url;

    // Hide placeholder and show generated image
    placeholderElement.style.display = 'none';
    generatedImageElement.src = imageURL;
    generatedImageElement.style.display = 'block';

  } catch (error) {
       loadingIcon.style.display = 'none';
    console.error('Error:', error.message);
  }
}


async function speechModel(resfromgpt) {
  const apiUrl = "https://api.openai.com/v1/audio/speech";
//  const apiKey = "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"; // Replace with your actual API key

  const inputText = resfromgpt;
  const voice = "alloy";

  try {
    const response = await fetch(apiUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: "tts-1",
        voice,
        input: inputText,
      }),
    });

    if (!response.ok) {
         loadingIcon.style.display = 'none';
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
 const arrayBuffer = await response.arrayBuffer();
    const blob = new Blob([arrayBuffer], { type: "audio/mpeg" });

    // Create a URL for the Blob
    const audioURL = URL.createObjectURL(blob);

    // Log or use the audioURL as needed
    console.log("Audio URL:", audioURL);
    
    audio.src= audioURL;
    
    
    wavesurfer.load(audioURL)
    
 
  loadingIcon.style.display = 'none';
    
    
  } catch (error) {
       loadingIcon.style.display = 'none';
    console.error("Error:", error.message);
  }
}

// Smooth Scrolling
function scrollToSection(sectionId, clickedLink) {
    const links = document.querySelectorAll('.navbar a');
    links.forEach(link => link.classList.remove('selected'));
    clickedLink.classList.add('selected');

    const targetSection = document.getElementById(sectionId);
    const offsetTop = targetSection.offsetTop;
    scrollToSmoothly(offsetTop, 1000);
}

function scrollToSmoothly(targetPosition, duration) {
    const startPosition = window.pageYOffset || document.documentElement.scrollTop;
    const distance = targetPosition - startPosition;
    const startTime = performance.now();

    function animateScroll(currentTime) {
        const elapsedTime = currentTime - startTime;
        const scrollProgress = Math.min(elapsedTime / duration, 1);
        const easing = easeInOutQuad(scrollProgress);
        window.scrollTo(0, startPosition + distance * easing);

        if (elapsedTime < duration) {
            requestAnimationFrame(animateScroll);
        }
    }

    function easeInOutQuad(t) {
        return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
    }

    requestAnimationFrame(animateScroll);
}