Code viewer for World: DeepAI text to image
// AI API credit: https://deepai.org/api-docs

document.write(`
<!DOCTYPE html>
<html>
<head>
    <!-- Title -->
    <title>Text-to-Image on 3D Cube using DeepAI API</title>
    
    <!-- jQuery library for AJAX requests -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
   
   
   
<!-- 
MH edit
changed document.write <script> from remote:
https://threejs.org/build/three.js
to local:
https://run.ancientbrain.com/api/threeab30/libs/three.min.js
-->

    <!-- Three.js library for 3D graphics rendering -->
    <script src="/api/threeab30/libs/three.min.js"></script>
    
    
    
    <!-- CSS styles -->
    <style>
        body { margin: 0; }
        canvas { display: block; }
        #ui { position: absolute; top: 10px; left: 10px; z-index: 1000; }
        input, select, button { margin-top: 5px; }
        .description-input {
        width: 300px; 
    </style>
</head>
<body>
    <!-- UI container -->
    <div id="ui">
        <!-- Heading -->
        <h1>Text-to-Image on 3D Cube using DeepAI API</h1>
        
        <!-- API key field, hides input -->
        <input type="password" id="apiKey" placeholder="Please enter your API Key" />
        
        <!-- Container to API missing error to show the user -->
        <div id="userMessage" style="font-family: Arial, sans-serif; color: red; margin-top: 5px;"></div>
    
        <!-- User input description for the image generation -->
        <input type="text" id="textDescription" class="description-input" placeholder="Describe a person or emotion i.e Girl">

        <!-- Dropdown menu for selecting a mood, this influences the style of the generated image showing the power of API -->
        <label for="moodSelector">Choose a mood:</label>
        <select id="moodSelector">
            <option value="happy">Happy</option>
            <option value="sad">Sad</option> 
            <option value="crying">Crying</option> 
            <option value="mysterious">Mysterious</option>
            <option value="futuristic">Futuristic</option>
            <option value="fantasy">Fantasy</option>
            <option value="serene">Serene</option>
            <option value="dramatic">Dramatic</option>
            <option value="retro">Retro</option>
            <option value="surreal">Surreal</option>
            <option value="gothic">Gothic</option>
            <option value="abstract">Abstract</option>
            <option value="romantic">Romantic</option>
            <option value="eerie">Eerie</option>
            <option value="vibrant">Vibrant</option>
            <option value="">None</option>
        </select>
        <button onclick="generateImage()">Generate Image</button>
    </div>
    <div id="sceneContainer"></div>

    <script>
    
        // Three.js scene variables
        let scene, camera, renderer, cube;
        
         // Handles image generation
        function generateImage() {
            var apiKey = document.getElementById('apiKey').value;
            
            // Show error if API key is not entered
            if (!apiKey) {
                document.getElementById('userMessage').innerHTML = 'API key is missing. Please enter your API key to continue.';
                console.log('API key is missing.');
                return;
            }
            document.getElementById('userMessage').innerHTML = ''; // Clear user input message
            
            // Gets inputs from user (both description and mood)
            var description = document.getElementById('textDescription').value;
            var mood = document.getElementById('moodSelector').value;
            var combinedDescription = mood ? description + ', ' + mood : description;
            
            // DeepAI API endpoint
            var url = 'https://api.deepai.org/api/text2img';
            
            // Start time
            var startTime = new Date();
            console.log('Request start time: ' + startTime);
    
            // AJAX POST request to DeepAI API
            $.ajax({
                url: url,
                type: 'POST',
                data: {
                    text: combinedDescription
                },
                headers: {
                    'Api-Key': apiKey
                },
                success: function(data) {
                    var endTime = new Date(); // End time
                    var duration = (endTime - startTime) / 1000; // Time in seconds
                    console.log('Request end time: ' + endTime);
                    console.log('Response time: ' + duration + ' ms');
                    
                    // MH edit
                    console.log(data);
                    console.log(data.output_url);
                    
                    var imageUrl = data.output_url;
                    applyImageToAllFaces(imageUrl);
                },
                error: function(xhr, status, error) {
                    var errorMessage = xhr.status + ': ' + xhr.statusText;
                    console.error('Error - ' + errorMessage);
                }
            });
        }
        
        // Setting up the Three.js scene
        function setupScene() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color('#87CEEB'); // Sky blue background
            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            renderer = new THREE.WebGLRenderer();
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.getElementById('sceneContainer').appendChild(renderer.domElement);
            
            // Set up Cube
            const geometry = new THREE.BoxGeometry(5, 5, 5);
            cube = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0xffffff }));
            scene.add(cube);
            camera.position.z = 10;
            
            // Start animation
            animate();
        }
        
        // Animation loop for the scene
        function animate() {
            requestAnimationFrame(animate);
            cube.rotation.x += 0.005;
            cube.rotation.y += 0.005;
            renderer.render(scene, camera);
        }
        
        // MH debug - added error function 
        // Apply the generated image to all 6 faces of the cube
        function applyImageToAllFaces(imageUrl) 
        {
            console.log ("Applying this URL to cube: " + imageUrl );
            new THREE.TextureLoader().load 
            ( 
                imageUrl, 
                function(tex) 
                {
                const materials = [];
                for (let i = 0; i < 6; i++) 
                    materials.push(new THREE.MeshBasicMaterial({ map: tex }));
                cube.material = materials;
                },
                undefined,
	            function ( err ) { console.log ( err ); }
            );
        }
        
        
        // Initializes the scene
        setupScene(); // Initialize the scene
    </script>
</body>
</html>
`);