let loaded = [];
let ctx2;

const canvas = setupCanvas();
const gl = canvas.getContext("webgl2");
document.body.style.overflow = "hidden";
gl.viewport(0, 0, canvas.width, canvas.height);
console.log(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
let program, timeLocation, resolutionLocation, mouseLocation, texcoordLocation, samplerLocation, texture, textures;
let click = false;
let lastMousePos = { x: 0, y: 0 };
let useResize = window.innerWidth === window.innerWidth || window.innerHeight === window.innerHeight;
const buffer = gl.createBuffer();

// loadShaders(ready);
loadTextures();
let audio;
function setupCanvas() {
    const c = document.createElement("canvas");
    c.style.margin = "0 auto";
    c.style.display = "block";
    c.id = "space";
    c.width = 1920;
    c.height = 1080;
    document.body.appendChild(c);
    document.body.style.backgroundColor = "black";
    document.addEventListener("mousemove", mousemove);
    c.addEventListener("mousedown", (e) => { click = true; });
    c.addEventListener("mouseup", (e) => { click = false; });
    
    return c;
}
let playing = false;
function resize() {
    if (!useResize) {
        return;
    }
    let w = window.innerWidth;
    let h = window.innerHeight;
    canvas.width = w;
    canvas.height = h;
    console.log(w, h);
    gl.uniform2f(resolutionLocation, w, h);
    gl.viewport(0, 0, w, h);
}

function mousemove(e) {
    let cRect = canvas.getBoundingClientRect();              // Gets the CSS positions along with width/height
    let canvasX = Math.round(e.clientX - cRect.left);        // Subtract the 'left' of the canvas from the X/Y
    let canvasY = Math.round(e.clientY - cRect.top);
    let c = -1;
    let r = -1;
    if (click) {
        lastMousePos.x = canvasX / canvas.width;
        lastMousePos.y = canvasY / canvas.height;
        c = 1;
    } else {
        c = -1;
    }
    gl.uniform4f(mouseLocation, lastMousePos.x, lastMousePos.y, c, r);
}
let currentScene = 1;
function loadNextScene(){
    let img = loaded.shift();
    console.log(img.src);
    if (img) {
        bindImage(img, texture);
        currentScene++;
    }

}
function bet(s,t,sc){
    return floor(s)===t && currentScene === sc;
}
let load = false;
function render(time) {
    if(!playing){
        audio.play();
        playing = true;
    }
    let secs = time * 0.001;
   
    if (bet(secs, 0,1)) {
        loadNextScene();
    }
    if (bet(secs, 6,2)) {
        loadNextScene();
    }
    if (bet(secs, 9,3)) {
        loadNextScene();
    }
    if (bet(secs, 14,4)) {
        loadNextScene();
    }
    if (bet(secs, 18,5)) {
        loadNextScene();
    }
    if (bet(secs, 22,6)) {
        loadNextScene();
    }
    if (bet(secs, 55,7)) {
        loadNextScene();
    }
    if (bet(secs, 59,8)) {
        loadNextScene();
    }
    if (bet(secs, 91,9)) {
        loadNextScene();
    }
    if (bet(secs, 96,10)) {
        loadNextScene();
    }
    if (bet(secs, 100,11)) {
        loadNextScene();
    }
    gl.uniform1f(timeLocation, secs);
    gl.drawArrays(gl.TRIANGLES, 0, 6);

    requestAnimationFrame(render);
}

function ready() {
    gl.useProgram(program);
    let positionLocation = gl.getAttribLocation(program, "a_position");
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        -1.0, -1.0, 1.0, -1.0, -1.0, 1.0,
        -1.0, 1.0, 1.0, -1.0, 1.0, 1.0]), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.enableVertexAttribArray(positionLocation);
    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
    gl.uniform2fv(resolutionLocation, [canvas.width, canvas.height]);
    audio = new Audio("/journey.mp3");
    requestAnimationFrame(render);

   
}
function loadImage(url, cb) {
    let image = new Image();
    image.onload = cb;
    image.src = url;
    return image;
}

function loadImages(images, cb) {

    let total = images.length;
    let done = () => {
        --total;
        if (total === 0) {
            cb(loaded);
        }
    };
    for (let url of images) {
        loaded.push(loadImage(url, done));
    }
}
function processTextures(textures) {

    const texture = gl.createTexture();
    return texture;
}
function bindImage(image, texture) {
    let texcoordBuffer = gl.createBuffer();

    gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        0.0, 0.0,
        1.0 + image.width, 0.0,
        0.0, 1.0,
        0.0, 1.0,
    ]), gl.STATIC_DRAW);
    gl.enableVertexAttribArray(texcoordLocation);
    gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
    gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
    gl.bindTexture(gl.TEXTURE_2D, texture);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

}
let processedTextures;
function loadTextures() {
    let urls = ["../textures/1.png", 
    "../textures/2.png","../textures/3.png","../textures/4.png","../textures/5.png","../textures/6.png","../textures/7.png","../textures/8.png","../textures/9.png","../textures/10.png","../textures/12.png","../textures/1.png"];
    loadImages(urls, (tex) => {
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
        processedTextures = tex;
        loadShaders(ready);

    });
}
function loadShaders(cb) {
    fetch("shaders/vertex.shader")
        .then((res) => res.text())
        .then((text) => {
            program = gl.createProgram();
            buildShader(text, gl.VERTEX_SHADER, program);
            texture = processTextures(processedTextures);
            return fetch("shaders/fragment.shader");
        })
        .then((res) => res.text())
        .then((text) => {
            buildShader(text, gl.FRAGMENT_SHADER, program);
            gl.linkProgram(program);

            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                console.error("Cannot link program", gl.getProgramInfoLog(program));
            }
            gl.useProgram(program);
            texcoordLocation = gl.getAttribLocation(program, "a_texCoord");
            var matrixLocation = gl.getUniformLocation(program, "u_matrix");
            let canvasDisplayWidth = gl.canvas.clientWidth;
            let canvasDisplayHeight = gl.canvas.clientHeight;
            let imageDisplayWidth = canvasDisplayWidth;
            let imageDisplayHeight = loaded[0].height * imageDisplayWidth / loaded[0].width;

            if (imageDisplayHeight > canvasDisplayHeight) {
                imageDisplayHeight = canvasDisplayHeight;
            }
            imageDisplayWidth = loaded[0].width * imageDisplayHeight / loaded[0].height;
            let canvasPixelsAcrossPerDisplayPixel = gl.canvas.width / canvasDisplayWidth;
            let canvasPixelsDownPerDisplayPixel = gl.canvas.height / canvasDisplayHeight;

            let imageDrawWidth = imageDisplayWidth * canvasPixelsAcrossPerDisplayPixel;
            let imageDrawHeight = imageDisplayHeight * canvasPixelsDownPerDisplayPixel;
            var clipWidth = imageDrawWidth / gl.canvas.width;
            var clipHeight = imageDrawHeight / gl.canvas.height;
            var m = m4.identity();

            m4.scale(m, [clipWidth, clipHeight, 1], m);
            m4.translate(m, [-1, 1, 0], m);
            m4.scale(m, [2, -2, 1], m);
            gl.uniformMatrix4fv(matrixLocation, false, m);
            timeLocation = gl.getUniformLocation(program, "u_time");
            resolutionLocation = gl.getUniformLocation(program, "u_resolution");
            mouseLocation = gl.getUniformLocation(program, "u_mouse");
            samplerLocation = gl.getAttribLocation(program, "u_sampler");

            cb(0);
        })
        .catch((err) => {
            console.log(err);
        });
}

function buildShader(source, type, program) {
    let shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error("Cannot compile shader\nSyntax error!", gl.getShaderInfoLog(shader));
        return;
    }
    gl.attachShader(program, shader);
}


