//--------------------Game--------------------
// Game variables
const width = 1260;
const height = 620;
let requesteddata = [];	
// Menu variables
let letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
let currentIndex = [0, 0, 0];
let nameHS = '';
let pressed = false;

// Player variables
const playerSize = 10;
let radius = playerSize / 2;
let playerPosX = 500
let playerPosY = 300;
let playerSpeed = 4;
let booleanArray = window.booleanArray;
let lives = 1;
let isDead = false;
let bossPosX = width / 2;
let bossPosY = 100;
let shotSpeed = 16;
let shotSpeedAdj;
let projectile;
let projSize = 5;
let shot = false;
let hit = false;
let shotPosX;
let shotPosY;

let initialPlayerPosX = playerPosX;
let initialPlayerPosY = playerPosY;
let bullets = [];
let direction;
let framerate = 60;
let hasMoved = false;
let time = 0;
let shotPoint = 0;
let angle = 0;

let patern;
let paternArray = [];
let suroundX = 300;
let suroundY = 300;
let x2;
let y2;
let x3;
let y3;
let x4;
let y4;
let x5;
let y5;
let homescreenOn = true;
let chosen = false;
let finalPhase = false;
let nextWave = [];
let iIndex = 0;
let buttonSelectDead = 0;
let buttonSelectHome = 0;
let buttonSelectPause = 0;
let entered = false;
let submitted = false;

let bulletAmount = 5;

let phases = [false, false, false, false, false];

//let myBullet = new bullet();
// the function setup() is called once when the page is loaded
function setup() {
    // create a canvas element and append it to the body
    getData()
    createCanvas(width, height);
    frameRate(framerate);
    angleMode(DEGREES);
    // disable the outline of shapes
    Movementloop()
    noStroke();
    // bg = loadImage('background.webp');
}

function score() {
    time += 3 / framerate;
}

function reset() {
    lives = 1;
    time = 0;
    bounceX = bossPosX;
    bounceY = bossPosY;
    initialPlayerPosX = playerPosX;
    initialPlayerPosY = playerPosY;
    hasMoved = false;
    bullets = [];
    shot = false;
    chosen = false;
    finalPhase = false;
    isDead = false;
    entered = false;
    buttonSelectDead = 0;
    submitted = false;
    getData()
}

function gameOver() {
    if (lives == 0) {
        //game over screen
        iIndex = constrain(iIndex, 0, 2);
        buttonSelectDead = constrain(buttonSelectDead, 0, 2);
        isDead = true;
        push();
        fill(255, 0, 0);
        textSize(40);
        textAlign(CENTER);
        text("Game Over", width / 2, height / 2 - 80);

        fill(255, 255, 255)
        textSize(18);
        textAlign(CENTER);
        text("Score: " + int(time), width / 2, height / 2 - 55);

        textSize(32);
        text(letters[currentIndex[0]], width / 2 - 30, height / 2);
        text(letters[currentIndex[1]], width / 2, height / 2);
        text(letters[currentIndex[2]], width / 2 + 30, height / 2);

        text("Restart", width / 2, height / 2 + 45);

        text("Main Menu", width / 2, height / 2 + 90);
        pop();
    }
}

function movementCheck() {
    //check if the player has moved
    if (playerPosX != initialPlayerPosX || playerPosY != initialPlayerPosY) {
        hasMoved = true;
    }
}

async function keyPressed() {
    if (!isDead) {
        if (keyIsDown(LEFT_ARROW) && playerPosX > 0 + radius) {
            playerPosX -= playerSpeed;
        }
        if (keyIsDown(RIGHT_ARROW) && playerPosX < width - radius) {
            playerPosX += playerSpeed;
        }
        if (keyIsDown(UP_ARROW) && playerPosY > 0 + radius) {
            playerPosY -= playerSpeed;
        }
        if (keyIsDown(DOWN_ARROW) && playerPosY < height - radius) {
            playerPosY += playerSpeed;
        }
    }
    if (isDead && keyReleasedFlag && !entered) {
        if ((!(iIndex > 2)) || (!(iIndex < 0))) {
            if (keyCode == LEFT_ARROW) {
                iIndex -= 1;
                keyReleasedFlag = false;
            }
            if (keyCode == RIGHT_ARROW) {
                iIndex += 1;
                keyReleasedFlag = false;
            }
        }
        if (keyCode == UP_ARROW) {
            currentIndex[iIndex] = (currentIndex[iIndex] + 1) % letters.length;
            keyReleasedFlag = false;
        }
        if (keyCode == DOWN_ARROW) {
            currentIndex[iIndex] = (currentIndex[iIndex] - 1 + letters.length) % letters.length;
            keyReleasedFlag = false;
        }
        if (keyCode == ENTER) {
            nameHS += letters[currentIndex[0]];
            nameHS += letters[currentIndex[1]];
            nameHS += letters[currentIndex[2]];
            entered = true;
            submit();
            keyReleasedFlag = false;
        }
    }
    if (isDead && keyReleasedFlag && entered) {
        if (keyCode == UP_ARROW) {
            buttonSelectDead -= 1;
            keyReleasedFlag = false;
        }
        if (keyCode == DOWN_ARROW) {
            buttonSelectDead += 1;
            keyReleasedFlag = false;
        }
        if (buttonSelectDead == 0) {
            if (keyCode == RIGHT_ARROW && !submitted) {
                entered = false;
                nameHS = '';
                keyReleasedFlag = false;
            }
            if (keyCode == ENTER) {
                keyReleasedFlag = false;   
            }
        }
        if (buttonSelectDead == 1) {
            if (keyCode == ENTER) {
                //reset all the variables so the game can be played again
                reset();
            }
        }
        if (buttonSelectDead == 2) {
            if (keyCode == ENTER) {
                homescreenOn = true;
                reset();
            }
        }
    }
}

function submit() {
    if (entered == true) {
        sendData(nameHS, int(time));
        console.log(nameHS + ": " + int(time));
        nameHS = '';
        submitted = true;
    }
}

function keyReleased() {
    keyReleasedFlag = true; // Set the flag to true when a key is released
}

function wait(waitTime) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(true);
        }, waitTime);
    });
}

async function Movementloop() {
    //get info from controller and use it to move the player
    window.addEventListener('booleanArrayUpdated', function (event) {
        let booleanArray = event.detail;

        if (booleanArray[1]) {
            playerPosX += playerSpeed;
        }
        if (booleanArray[3]) {
            playerPosX -= playerSpeed;
        }
        if (booleanArray[2]) {
            playerPosY += playerSpeed;
        }
        if (booleanArray[0]) {
            playerPosY -= playerSpeed;
        }
    });
}

// the function draw() is called every frame
function draw() {
    keyPressed();
    gameOver();
    // draw background
    background(0, 0, 0, 100);

    if (homescreenOn == true) {
        homescreen();
    }
    if (homescreenOn == false) {
        game();
    }
    if (isDead == true) {
        if (entered == true) {
            if (buttonSelectDead == 0) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 - 45, height / 2 - 30, 90, 40)
                pop()
            }
            if (buttonSelectDead == 1) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 - 55, height / 2 + 15, 110, 40)
                pop()
            }
            if (buttonSelectDead == 2) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 - 80, height / 2 + 60, 160, 40)
                pop()
            }
        }
        else {
            if (iIndex == 0) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 - 45, height / 2 - 30, 30, 40)
                pop()
            }
            if (iIndex == 1) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 - 15, height / 2 - 30, 30, 40)
                pop()
            }
            if (iIndex == 2) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2 + 15, height / 2 - 30, 30, 40)
                pop()
            }
        }
    }
}
async function randPatern() {
    patern = random(paternArray);
    chosen = true;
    if (patern == 1) {
        await wait(3000);
        chosen = false;
    }
    if (patern == 2) {
        await wait(10000);
        chosen = false;
    }
    if (patern == 3) {
        await wait(1000);
        chosen = false;
    }
    if (patern == 4) {
        await wait(1000);
        chosen = false;
    }
    if (patern == 5) {
        if (phases[0] == true) {
            nextWave = random([1, 2, 3, 4]);
        }
        await wait(3000);
        chosen = false;
    }

}

function randomAttackPattern() {
    if (shot == false || hit == true) {
        for (i = 0; i < bulletAmount; i++) {
            spawnRandomBullet()
        }
    }
}

function phase() {
    switch (true) {
        case (time < 20):
            phases[0] = true;
            paternArray = [1,2,3,4,5];
            shotSpeedAdj = 2;
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 1", 10, 50);
            pop();
            break;
        case (time < 60):
            shotSpeedAdj = 5;
            paternArray = [5];
            phases[0] = false;
            phases[1] = true;
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 2", 10, 50);
            pop();
            break;
        case (time < 90):
            phases[1] = false;
            phases[2] = true;
            paternArray = [2];
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 3", 10, 50);
            pop();
            break;
        case (time < 120):
            phases[2] = false;
            phases[3] = true;
            paternArray = [3, 4];
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 4", 10, 50);
            pop();
            break;
        case (time >= 120):
            phases[3] = false;
            phases[4] = false;
            finalPhase = true;
            paternArray = [1, 2, 3, 4, 5];
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 5", 10, 50);
            pop();
            break;
    }
}

function spawnRandomBullet() {
    if (chosen == false) {
        randPatern();
    }

    if (patern == 1) {
        let nextAttack = random([1, 2, 3, 4, 5]);
        //text(nextAttack, 30, 50);
        if (nextAttack == 1) {
            shotPosX = bossPosX;
            shotPosY = bossPosY;
            bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
        }
        if (nextAttack == 2) {
            shotPosX = random(0, width);
            shotPosY = height;
            bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
        }
        if (nextAttack == 3) {
            shotPosX = 0;
            shotPosY = random(0, height);
            bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
        }
        if (nextAttack == 4) {
            shotPosX = width;
            shotPosY = random(0, height);
            bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
        }
        if (nextAttack == 5) {
            shotPosX = random(0, width);
            shotPosY = 0;
            bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
        }
    }
    if (patern == 2) {
        let suroundChoice = random([1, 2, 3, 4]);
        if (suroundChoice == 1) {
            shotPosX = x2;
            shotPosY = y2;
        } if (suroundChoice == 2) {
            shotPosX = x3;
            shotPosY = y3;
        } if (suroundChoice == 3) {
            shotPosX = x4;
            shotPosY = y4;
        } if (suroundChoice == 4) {
            shotPosX = x5;
            shotPosY = y5;
        }
        bullets.push(new bullet(playerPosX, playerPosY, radius, shotSpeed, shotPosX, shotPosY, hasMoved, 0));
    }
    if (!(patern == 2)) {
        bossPosX = width / 2;
        bossPosY = 100;
    }
    if (patern == 3) {
        shotPosX = bossPosX;
        shotPosY = bossPosY;
        angle = 0;
        // changing the angle of the bullets
        for (let i = 0; i < 86; i++) {
            setTimeout(function () {
                bullets.push(new bullet(0, 100, radius, shotSpeed / 4, shotPosX, shotPosY, hasMoved, angle));
                angle -= 360 / 1;
            }, i * 100);
        }
        angle = 0;
    }
    if (patern == 4) {
        shotPosX = bossPosX;
        shotPosY = bossPosY;
        angle = 0;
        // changing the angle of the bullets
        for (let i = 0; i < 86; i++) {
            bullets.push(new bullet(0, 100, radius, shotSpeed / 4, shotPosX, shotPosY, hasMoved, angle));
            angle -= 360 / 3;
        }
        angle = 0;
    }
    if (patern == 5) {
        if (phases[0] == false) {
            nextWave = random([1, 2, 3, 4]);
            bulletAmount = 10;
        }
        if (nextWave == 1) {
            for (let i = 0; i < random(8, 15); i++) {
                let shotWidth = random(0, width);
                shotPosX = shotWidth;
                shotPosY = height;
                bullets.push(new bullet(shotWidth, 0, radius, shotSpeed / shotSpeedAdj, shotPosX, shotPosY, hasMoved, angle));
            }
        }
        if (nextWave == 2) {
            for (let i = 0; i < random(8, 10); i++) {
                let shotWidth = random(0, width);
                shotPosX = shotWidth;
                shotPosY = 0;
                bullets.push(new bullet(shotWidth, height, radius, shotSpeed / shotSpeedAdj, shotPosX, shotPosY, hasMoved, angle));
            }
        }
        if (nextWave == 3) {
            for (let i = 0; i < random(8, 10); i++) {
                let shotHeight = random(0, width);
                shotPosX = 0;
                shotPosY = shotHeight;
                bullets.push(new bullet(width, shotHeight, radius, shotSpeed / shotSpeedAdj, shotPosX, shotPosY, hasMoved, angle));
            }
        }
        if (nextWave == 4) {
            for (let i = 0; i < random(8, 10); i++) {
                let shotHeight = random(0, width);
                shotPosX = width;
                shotPosY = shotHeight;
                bullets.push(new bullet(0, shotHeight, radius, shotSpeed / shotSpeedAdj, shotPosX, shotPosY, hasMoved, angle));
            }
        }

    } else {
        bulletAmount = 5;
    }
}


function homescreen() {
    textAlign(CENTER);
    button(255, 255, 255, width / 2 - 90, height / 2, 200, 40, "Start Game")
    button(255, 255, 255, width / 2 - 90, height / 2 + 50, 200, 40, "Scores")
    
    push()
    stroke(255, 255, 255)
    strokeWeight(5)
    fill(0, 255, 0, 0)
    rect(100, 150, 300, 400)
    pop()
    //highscores rectangle
    push()
    textSize(50)
    fill(255, 255, 255)
    text("Highscores", 250, 200)
    pop()

    push()
    fill(255, 255, 255)
    textSize(25)
    textAlign(CENTER)
    // if (requesteddata.length > 0) {
    //     text("1. " + requesteddata[0].Naam + ": " + requesteddata[0].Score, 250, 250)
    //     }    
    for (let i = 0; i < requesteddata.length; i++) {
        text(i + 1 + ". " + requesteddata[i].Naam + ": " + requesteddata[i].Score, 250, 250 + (i * 30))
    }
    pop()

    push()
    stroke(255, 255, 255)
    strokeWeight(5)
    fill(0, 255, 0, 0)
    rect(860, 150, 300, 400)
    pop()

    push()
    textSize(50)
    fill(255, 255, 255)
    text("Controls", 1000, 200)
    pop()
}



function button(r, g, b, buttonX, buttonY, buttonWidth, buttonHeight, buttonText) {
    push()
    fill(0, 0, 50)
    rect(buttonX, buttonY, buttonWidth, buttonHeight)
    textSize(25)
    fill(r, g, b)
    text(buttonText, buttonX + 100, buttonY + 30)
    textAlign(CENTER);
    if (mouseX > buttonX - 90 && mouseX < width / 2 + 110 && mouseY > height / 2 && mouseY < buttonY + 40) {
        if (mouseIsPressed) {
            homescreenOn = false;
        }
    }
    pop()
}

function game() {
    if (!(lives == 0)) {
        // draw player
        phase();
        push();
        fill(0, 255, 255)
        circle(constrain(playerPosX, 0 + radius, width - radius), constrain(playerPosY, 0 + radius, height - radius), playerSize);
        pop();
        movementCheck()
        // draw boss
        push();
        fill(255, 165, 0)
        circle(x2, y2, 50);
        pop();
        if (hasMoved == true) {
            push();
            score();
            textSize(10);
            textAlign(LEFT);
            fill(255, 0, 255)
            text(int(time), 10, 20);
            pop();
        }
        if (hasMoved == false) {
            time = 0;
            push();
            score();
            textSize(10);
            textAlign(LEFT);
            fill(255, 0, 255)
            text(0, 10, 20);
            pop();
        }


        randomAttackPattern()
        if (patern == 2) {
            suroundX += 2;
            suroundY += 2;
            let sinX = sin(suroundX);
            let cosY = cos(suroundY);
            x2 = map(sinX, -1, 1, playerPosX - 200, playerPosX + 200);
            y2 = map(cosY, -1, 1, playerPosY - 200, playerPosY + 200);
            x3 = map(-sinX, -1, 1, playerPosX - 200, playerPosX + 200);
            y3 = map(-cosY, -1, 1, playerPosY - 200, playerPosY + 200);
            x4 = map(-sinX, -1, 1, playerPosX - 100, playerPosX + 100);
            y4 = map(cosY, -1, 1, playerPosY - 100, playerPosY + 100);
            x5 = map(sinX, -1, 1, playerPosX - 100, playerPosX + 100);
            y5 = map(-cosY, -1, 1, playerPosY - 100, playerPosY + 100);
            push();
            fill(255, 165, 0)
            circle(x3, y3, 50);
            circle(x4, y4, 50);
            circle(x5, y5, 50);
            pop();


        } else {
            x2 = width / 2;
            y2 = 100;
        }

        bullets.forEach(myBullet => {
            //zolang mybullet bestaat blijft hij drawen en updaten
            ({ hit, shot, isOffScreen, originalPos } = myBullet.update(playerPosX, playerPosY));
            myBullet.draw();

            if (isOffScreen == true) {
                myBullet.hit = true;
                shot = false;
            }
        });
        //blijf de bullet tekenen zolang hit false is
        bullets = bullets.filter(bullet => !bullet.hit);
    }

}

function sendData(naam, score) {
    const request = ( url, params = {}) => {
    url += '?' + ( new URLSearchParams( params ) ).toString();
    fetch( url );
};
    const get = ( url, params ) => request( url, params);

    get('https://oege.ie.hva.nl/~hossan/postData.php', { name: naam, score: score } );

}

function getData(){
    // Fetch data from the database, put it in an array, and log it to the console
    return fetch ('https://oege.ie.hva.nl/~hossan/getData.php') // Add return here
    .then(response => response.json())
    .then(data => {
        requesteddata = data;
    });
}
