// include "constants.js"
// include "matrix.js"

function animateCamera(cam, t)
{
    return mat4Multiply(mat4.translation(0.02*t,.02*t,0.0), cam);
}

function endStage() {
    img = document.createElement('IMG');
    img.src = IMGDIR+ENDPICNAME;
    img.style.position = 'absolute';
    img.style.top = '50%';
    img.style.left = '50%';
    img.style.transform = 'translate(-50%,-50%)';
    document.body.appendChild(img);
}

function beginRendering(gl, audio)
{
    // Function begins rendering frames and holds scope for
    // required gl parameters

    // Makeshif enumerator
    const POS = 0; const RES = 1; const TIME = 2; const CAM = 3; const BUF = 4;
    const PROG = 5; const BEAT = 6;

    // Initialize scenes and get variables
    var fadein_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_fadein');

    var march1_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_march1');
    var march2_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_march2');
    var march3_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_march3');

    var back1_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_back1');
    var back2_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_back2');
    var back3_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_back3');
    var back4_vars = initializeMarch(gl, 'vertex_canvas', 'fragment_back4');

    var camera = mat4.translation(0.,0.,0.);
    var dftTexture = initializeDftTexture(gl);

    var startTime = Date.now();
    var elapsedBeats = 0; // Number of beats elapsed, used for syncing
    var beat = 0.; // level of beat for visualization

    var flag_ended = false; // flag to inform of ending
    var flag_switchMusic = false; // If music has been changed at the ending

    function drawMarch(time, vars)
    {
        // Put forward correct vertices
        gl.enableVertexAttribArray(vars[POS]);
        gl.bindBuffer(gl.ARRAY_BUFFER, vars[BUF]);
        gl.vertexAttribPointer(vars[POS], 3, gl.FLOAT, false, 0, 0);

        // Use correct program (shaders) for this scene
        gl.useProgram(vars[PROG]);

        gl.uniform2fv(vars[RES], new Float32Array(RESOLUTION));
        gl.uniform1f(vars[TIME], time);
        gl.uniform1f(vars[BEAT], beat);
        gl.uniformMatrix4fv(vars[CAM], false, new Float32Array(camera));
        
        // update audio analyzer                                                
        audio.updateFrequencies();                                              
                                                                                
        // get freq data from audio and write it into a texture                 
        gl.activeTexture(gl.TEXTURE0);                                          
        gl.bindTexture(gl.TEXTURE_2D, dftTexture);                            
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,                                
            audio.analyserNode.frequencyBinCount/4,                             
            1, 0, gl.RGBA, gl.UNSIGNED_BYTE, audio.frequencyTable               
            );                                                                      

        //console.log(audio.frequencyTable);

        gl.drawArrays(gl.TRIANGLES, 0, 6);
    }

    function scene1(time)
    {
        drawMarch(3500, back1_vars);
        drawMarch(3500, march1_vars);
        drawMarch(time, fadein_vars);
    }

    function scene2(time)
    {
        drawMarch(time, back1_vars);
        drawMarch(time, march1_vars);
    }

    function scene3(time)
    {
        drawMarch(time, back2_vars);
        drawMarch(time, march1_vars);
    }

    function scene4(time)
    {
        drawMarch(time, back3_vars);
        drawMarch(time, march1_vars);
    }

    function scene5(time)
    {
        drawMarch(time, back2_vars);
        drawMarch(time, march2_vars);
    }

    function scene6(time)
    {
        drawMarch(time, back1_vars);
        drawMarch(time, march3_vars);
    }

    function scene7(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march3_vars);
    }

    function scene8(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march2_vars);
    }

    function scene9(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march1_vars);
    }

    function scene10(time) {
        //drawMarch(time, back4_vars);
        drawMarch(time, march1_vars);
    }

    function scene11(time) {
        scene9(time);
    }

    function scene12(time) {
        drawMarch(time, back1_vars);
        drawMarch(time, march1_vars);
        drawMarch(time-3000, march1_vars);
    }

    function scene13(time) {
        drawMarch(time, back3_vars);
        drawMarch(time, march2_vars);
        drawMarch(time-3000, march1_vars);
    }

    function sceneFinal1(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march1_vars);
    }

    function sceneFinal2(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march1_vars);
        drawMarch(time, march3_vars);
    }

    function sceneFinal3(time) {
        drawMarch(time, back4_vars);
        drawMarch(time, march1_vars);
        drawMarch(time, march3_vars);
        drawMarch(time, march2_vars);
    }

    function sceneFinal4(time) {
        
        if (!flag_switchMusic) {
            audio.audioSource.src = AUDIODIR+ENDSONGNAME;
            audio.audioSource.loop = false;
            audio.audioSource.load();
            audio.audioSource.play();
            flag_switchMusic = true;
        }

        camera = animateCamera(camera,1.);
        drawMarch(time, march1_vars);
        drawMarch(time, march3_vars);
        drawMarch(time, march2_vars);
    }

    var currentScene = scene1;

    function switchScene(eb)
    {
        if (eb > 6) {
            currentScene = scene2;
        }
        if (eb > 16) {
            currentScene = scene3;
        }
        if (eb > 32) {
            currentScene = scene4;
        }
        if (eb > 48) {
            currentScene = scene5;
        }
        if (eb > 64) {
            currentScene = scene6;
        }
        if (eb > 80) {
            currentScene = scene7;
        }
        if (eb > 96) {
            currentScene = scene8;
        }
        if (eb > 100) {
            currentScene = scene9;
        }
        if (eb > 101) {
            currentScene = scene10;
        }
        if (eb > 102) {
            currentScene = scene11;
        }
        if (eb > 104) {
            currentScene = scene12;
        }
        if (eb > 128) {
            currentScene = scene13;
        }
        if (eb > 144) {
            currentScene = sceneFinal1;
        }
        if (eb > 150) {
            currentScene = sceneFinal2;
        }
        if (eb > 156) {
            currentScene = sceneFinal3;
        }
        if (eb > 160) {
            currentScene = sceneFinal4;
        }
        if (eb > 172) {
            flag_ended = true;
        }
    }

    function drawFrame()
    {
        // Render the current scene
        var time = Date.now()-startTime;
        currentScene(time);

        // Manage beat-sync
        var newElapsedBeats = Math.floor((time/60000)*120);
        if (beat > 0.) {
            beat -= .05;
        }
        if (newElapsedBeats > elapsedBeats) {
            elapsedBeats = newElapsedBeats;
            beat = 1.;
        }

        // Switch scene if needed
        switchScene(elapsedBeats);

        if (!flag_ended) {
            window.requestAnimationFrame(drawFrame);
        } else {
            endStage()
        }
    }
    window.requestAnimationFrame(drawFrame);
}
