function preload() {
    controlsImage = loadImage('./contols.png');
}

// the function setup() is called once when the page is loaded
function setup() {
    // create a canvas element and append it to the body
    DB.getData()
    createCanvas(width, height);
    frameRate(framerate);
    angleMode(DEGREES);
    rectMode(CENTER);
    // disable the outline of shapes
    noStroke();
}
function score() {
    time += 3 / framerate;
}
function reset() {
    lives = 1;
    time = 0;
    initialPlayerPosX = playerPosX;
    initialPlayerPosY = playerPosY;
    hasMoved = false;
    bullets = [];
    shot = false;
    chosen = false;
    finalPhase = false;
    isDead = false;
    entered = false;
    buttonSelect = 0;
    nameHS = '';
    submitted = false;
    escaped = false;
    bossPosX = width / 2;
    bossPosY = height / 6;
    bossVelX = 5;
    bossVelY = 5;
    dataIsCalled = false;
    DB.getData();

}

function movementCheck() {
    //check if the player has moved
    if (playerPosX != initialPlayerPosX || playerPosY != initialPlayerPosY) {
        hasMoved = true;
    }
}
async function keyPressed() {
    if (!isDead && !homescreenOn && !pausescreenOn) {
        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) {
        nameSubmit();
    }
    if (isDead && keyReleasedFlag && entered) {
        buttonSelect = constrain(buttonSelect, 0, 2);
        if (keyCode == UP_ARROW) {
            buttonSelect -= 1;
            keyReleasedFlag = false;
        }
        if (keyCode == DOWN_ARROW) {
            buttonSelect += 1;
            keyReleasedFlag = false;
        }
        if (buttonSelect == 1) {
            if (keyCode == ENTER) {
                //reset all the variables so the game can be played again
                reset();
            }
        }
        if (buttonSelect == 2) {
            if (keyCode == ENTER) {
                homescreenOn = true;
                reset();
                keyReleasedFlag = false;
                DB.getData()
                return;
            }
        }
    }
    if (homescreenOn && keyReleasedFlag) {
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (keyCode == UP_ARROW) {
            buttonSelect -= 1;
            keyReleasedFlag = false;
        }
        if (keyCode == DOWN_ARROW) {
            buttonSelect += 1;
            keyReleasedFlag = false;
        }
        if (buttonSelect == 0) {
            if (keyCode == ENTER) {
                console.log("start game");
                homescreenOn = false;
                gamescreenOn = true;
                reset();
            }
        }
        if (buttonSelect == 1) {
            if (keyCode == ENTER) {
                homescreenOn = false;
                scorescreenOn = true;
                reset();
                keyReleasedFlag = false;
            }
        }
    }
    if (scorescreenOn && keyReleasedFlag && entered) {
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (keyCode == UP_ARROW) {
            buttonSelect -= 1;
            keyReleasedFlag = false;
        }
        if (keyCode == DOWN_ARROW) {
            buttonSelect += 1;
            keyReleasedFlag = false;
        }
        if (buttonSelect == 1 && entered) {
            if (keyCode == ENTER) {
                homescreenOn = true;
                scorescreenOn = false;
                reset();
                keyReleasedFlag = false;
            }
        }
    }
    if (!homescreenOn && !isDead && !scorescreenOn && keyReleasedFlag) {
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (keyCode == 27 && !escaped) {
            escaped = true;
            console.log("pause");
            pausescreenOn = true;
            keyReleasedFlag = false;
        }
        if (escaped) {
            if (keyCode == UP_ARROW) {
                buttonSelect -= 1;
                keyReleasedFlag = false;
                console.log(buttonSelect)
            }
            if (keyCode == DOWN_ARROW) {
                buttonSelect += 1;
                keyReleasedFlag = false;
                console.log(buttonSelect)
            }
            if (buttonSelect == 0) {
                if (keyCode == ENTER) {
                    console.log("resume");
                    pausescreenOn = false;
                    keyReleasedFlag = false;
                    escaped = false;
                }
            }
            if (buttonSelect == 1) {
                if (keyCode == ENTER) {
                    console.log("main menu");
                    homescreenOn = true;
                    pausescreenOn = false;
                    escaped = false;
                    reset();
                    keyReleasedFlag = false;
                }
            }
        }
    }

}
function submit() {
    if (entered == true) {
        DB.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);
    });
}
function nameSubmit() {
    iIndex = constrain(iIndex, 0, 2);
    if ((!(iIndex > 2)) || (!(iIndex < 0))) {
        if (keyCode == LEFT_ARROW) {
            console.log(iIndex);
            iIndex -= 1;
            keyReleasedFlag = false;
        }
        if (keyCode == RIGHT_ARROW) {
            console.log(iIndex);
            iIndex += 1;
            keyReleasedFlag = false;
        }
    }
    if (keyCode == UP_ARROW) {
        currentIndex[iIndex] = (currentIndex[iIndex] + 1) % letters.length;
        console.log(currentIndex[iIndex])
        keyReleasedFlag = false;
    }
    if (keyCode == DOWN_ARROW) {
        currentIndex[iIndex] = (currentIndex[iIndex] - 1 + letters.length) % letters.length;
        console.log(currentIndex[iIndex])
        keyReleasedFlag = false;
    }
    if (keyCode == ENTER) {
        nameHS += letters[currentIndex[0]];
        nameHS += letters[currentIndex[1]];
        nameHS += letters[currentIndex[2]];
        entered = true;
        if (isDead) {
            submit();
        } else {
            // do nothing
        }
        keyReleasedFlag = false;
    }
}
function nameDraw(positiony) {
    if (iIndex == 0) {
        push()
        stroke(205, 205, 205)
        strokeWeight(2)
        fill(0, 0, 0, 0)
        rect(width / 2 - 30, height / positiony, 30, 40)
        pop()
    }
    if (iIndex == 1) {
        push()
        stroke(205, 205, 205)
        strokeWeight(2)
        fill(0, 0, 0, 0)
        rect(width / 2, height / positiony, 30, 40)
        pop()
    }
    if (iIndex == 2) {
        push()
        stroke(205, 205, 205)
        strokeWeight(2)
        fill(0, 0, 0, 0)
        rect(width / 2 + 30, height / positiony, 30, 40)
        pop()
    }

}
// the function draw() is called every frame
function draw() {
    keyPressed();
    Menus.gameOver();
    // draw background
    background(0, 0, 0, 100);
    ffps = frameRate();
    shotSpeed = 1000 / ffps;
    playerSpeed = 300 / ffps;

    if (homescreenOn) {
        Menus.homescreen();
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (buttonSelect == 0) {
            push()
            stroke(205, 205, 205)
            strokeWeight(2)
            fill(0, 0, 0, 0)
            rect(width / 2, height / 2, buttonWidth, buttonHeight)
            pop()
        }
        if (buttonSelect == 1) {
            push()
            stroke(205, 205, 205)
            strokeWeight(2)
            fill(0, 0, 0, 0)
            rect(width / 2, height / 2 + height / 12, buttonWidth, buttonHeight)
            pop()
        }
    }
    if (!homescreenOn && !scorescreenOn && !isDead) {
        game();
    }
    if (scorescreenOn) {
        Menus.scoreMenu();
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (buttonSelect == 1 && entered) {
            push()
            stroke(205, 205, 205)
            strokeWeight(2)
            fill(0, 0, 0, 0)
            rect(width / 2, height / 2, buttonWidth, buttonHeight)
            pop()
        }
    }
    if (pausescreenOn) {
        Menus.pauseMenu();
        buttonSelect = constrain(buttonSelect, 0, 1);
        if (buttonSelect == 0) {
            push()
            stroke(205, 205, 205)
            strokeWeight(2)
            fill(0, 0, 0, 0)
            rectMode(CENTER);
            rect(width / 2, height / 2, buttonWidth, buttonHeight)
            pop()
        }
        if (buttonSelect == 1) {
            push()
            stroke(205, 205, 205)
            strokeWeight(2)
            fill(0, 0, 0, 0)
            rectMode(CENTER);
            rect(width / 2, height / 2 + height / 12, buttonWidth, buttonHeight)
            pop()
        }
    }
    if (isDead) {
        buttonSelect = constrain(buttonSelect, 0, 2);
        if (entered) {
            if (buttonSelect == 0) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2, height / 2, 90, 40)
                pop()
            }
            if (buttonSelect == 1) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2, height / 2 + height / 12, 110, 40)
                pop()
            }
            if (buttonSelect == 2) {
                push()
                stroke(205, 205, 205)
                strokeWeight(2)
                fill(0, 0, 0, 0)
                rect(width / 2, height / 2 + height / 6, 160, 40)
                pop()
            }
        }
        else {
            nameDraw(2);
        }
    }

    if (!hasMoved && !isDead && !homescreenOn && !pausescreenOn && !scorescreenOn) {
        Menus.dodgeBanner();
    }
}
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 = [5];
            shotSpeedAdj = 2;
            push();
            fill(255, 0, 255);
            textSize(10);
            textAlign(LEFT);
            text("phase 1", 10, 50);
            pop();
            break;
        case (time < 60):
            shotSpeedAdj = 3;
            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 == 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 bouncing() {
    // Update position
    bossPosX += bossVelX;
    bossPosY += bossVelY;
    // Check for bounce
    if (bossPosX > width - 25) {
        bossVelX = random([-4, -5, -6, -7]);
    }
    if (bossPosX < 25) {
        bossVelX = random([4, 5, 6, 7]);
    }
    if (bossPosY > height - 25) {
        bossVelY = random([-4, -5, -6, -7]);
    }
    if (bossPosY < 25) {
        bossVelY = random([4, 5, 6, 7]);
    }

    // Draw the boss
    circle(bossPosX, bossPosY, 50);

    if ((dist(bossPosX, bossPosY, playerPosX, playerPosY) <= 25 + radius) && hasMoved) {
        lives -= 1;
    }
}

function game() {
    if (!(lives == 0)) {
        // draw player
        phase();
        movementCheck();

        push();
        fill(0, 255, 0);
        if (!pausescreenOn) {
            push();
            fill(0, 255, 255);
            circle(constrain(playerPosX, 0 + radius, width - radius), constrain(playerPosY, 0 + radius, height - radius), playerSize);
            stroke('yellow');
            strokeWeight(1);
            noFill();
            circle (playerPosX, playerPosY, playerSize*2);
            pop();
            if (phases[2] == false || phase[3] == false) {
                bouncing();
            } else if (phases[2] = true) {
                bossPosX = x2;
                bossPosY = y2;
            } else {
                bossPosX = width / 2;
                bossPosY = height / 6;
            }

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

                if (isOffScreen == true) {
                    myBullet.hit = true;
                    shot = false;
                }
            });
            //blijf de bullet tekenen zolang hit false is
            bullets = bullets.filter(bullet => !bullet.hit);
        }
        pop();
        if (hasMoved == true) {
            push();
            if (!pausescreenOn) {
                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(0, 255, 0);
            circle(x3, y3, 50);
            circle(x4, y4, 50);
            circle(x5, y5, 50);
            pop();
        } else {
            x2 = width / 2;
            y2 = 100;
        }
    }

}