// Global variables
let explosionSound; // Sound for explosion
let giegerSound; // Sound for Geiger counter
let nukeImage; // Image for a nuke
let grid; // Grid to hold the game boxes
let columns; // Number of columns in the grid
let rows; // Number of rows in the grid
let w = 20; // Width of each box in the grid
let gameMode = ''; // Empty variable to contain game mode
let totalnukes; // Total number of nukes in the game
let landingPage = true; // Landing page variable
let gameStarted = false; // Game has started? variable

// Preload function to load assets before setup
function preload() {
	soundFormats('mp3'); // Set audio format to mp3
	explosionSound = loadSound('asset/explosion.mp3'); // Load explosion sound
	giegerSound = loadSound('asset/counter.mp3'); // Load Geiger counter sound
	giegerSound.setLoop(false); // Do not loop Geiger counter sound
	nukeImage = loadImage('asset/nukeIcon.jpg'); // Load nuke image
}

// Function to create a nested array Arrays within arrays, 2D arrays! 
function makeNestedArray(columns, rows) { // making nested array function
	let arr = new Array(columns); // Create an array with the number of columns
	for (let i = 0; i < arr.length; i++) { // for every entry in the columns array make a new entry in the rows array loop
		arr[i] = new Array(rows); // Create a nested array with the number of rows
	}
	return arr; // Return the created nested array
}

function setup() { // p5 setup function
	if (landingPage) { //if on the game landingpage
		createCanvas(400, 400); // Create a canvas
		background(200)
		textSize(32); // Set text size
		textAlign(CENTER); // Set the text to centre
		fill(0); // Set the fill color to black
		text('NUKESEEKER', width/2, height/4);
		text('Press 1 for Easy\nPress 2 for Hard', width / 2, height / 2); // Display instructions
		textSize(14); // change size for slogan
		textStyle(ITALIC); // change stlye for slogan 
		text('"Why sweep for mines when you can seek for nukes?"', width / 2, height / 3.2) // slogan text
		image(nukeImage, width / 1.25, height / 5); // nuke logo
		image(nukeImage, width / 6.5, height / 5); // nuke logo
	} else { //otherwise if the gameMode variable =...
		if (gameMode === 'easy') {
			createCanvas(401, 401); // Create the smaller canvas
			totalnukes = 100; // Set the nukes to 100
		} else if (gameMode === 'hard') {
			createCanvas(801, 801); // Create the larger canvas
			totalnukes = 300; // Set the nukes to 300
		}

		columns = floor(width / w); // work out the number of columns based on the canvas and box width
		rows = floor(height / w); // work out number of rows based on the canvas height and box width
		grid = makeNestedArray(columns, rows); // Create a nested array for the grid

		// Loop to create each box in the grid
		for (let i = 0; i < columns; i++) {
			for (let j = 0; j < rows; j++) {
				grid[i][j] = new Box(i, j, w); // Create a box object and assign it to the grid at the current position
			}
		}

		let options = []; // Array to store possible box positions for nukes
		// Loop to populate the options array with all box positions
		for (let i = 0; i < columns; i++) {
			for (let j = 0; j < rows; j++) {
				options.push([i, j]); // creating array with every possible option for a nuke inside it 
			}
		}

		for (let n = 0; n < totalnukes; n++) {// Randomly assign nukes to boxes
			let index = floor(random(options.length)); // create a variable called index based on random value between length of options array, floor to round down
			let choice = options[index]; // set variable choice from the option
			let i = choice[0]; // Get the column from the choice and set to i
			let j = choice[1]; // Get the row from the choice and set to j
			options.splice(index, 1); // Remove the chosen nuke position from the options array so its no longer an option. stops duplicate nuke locations
			grid[i][j].nuke = true; // Set the nuke to true for the box at the chosen position in the grid
		}

		// Loop to count the number of nukes surrounding each box in the grid
		for (let i = 0; i < columns; i++) {
			for (let j = 0; j < rows; j++) {
				grid[i][j].countnukes(); // Count the number of nukes surrounding the current box in the grid
			}
		}
		gameStarted = true; // Set the gamestarted variable to true
	}
}

// Function for game over
function gameOver() {
	if (gameMode === 'easy') {
		createCanvas(401, 401); // Create a canvas with size 401x401 pixels for easy mode
		totalnukes = 100; // Set the total number of nukes to 100 for easy mode
	} else if (gameMode === 'hard') {
		createCanvas(801, 801); // Create a canvas with size 801x801 pixels for hard mode
		totalnukes = 300; // Set the total number of nukes to 300 for hard mode
	}

	// Loop to show state of all boxes in the grid
	for (let i = 0; i < columns; i++) {
		for (let j = 0; j < rows; j++) {
			grid[i][j].revealed = true; // Set revealed to true for every box
		}
	}
}

// Function to handle key presses for easy and hard mode
function keyPressed() {
	if (landingPage) { // if on the game landing page
		if (key === '1') {
			gameMode = 'easy'; // Set the game mode to easy
			landingPage = false; // Hide the landing page
			setup(); // call setup to start the game
		} else if (key === '2') {
			gameMode = 'hard'; // Set the game mode to hard
			landingPage = false; // Hide the landing page
			setup(); // call setup to start the game
		}
	}
}

// handling mouse clicks
function mousePressed() { // using p5 mousePressed function
	if (gameStarted) { // is the game started? 
		// Loop to check each box in the grid for mouse collision
		for (let i = 0; i < columns; i++) {
			for (let j = 0; j < rows; j++) {
				if (grid[i][j].contains(mouseX, mouseY)) { // Check if box contains the mouse position
					grid[i][j].reveal(); // use my 'reveal'
					if (grid[i][j].nuke) { // now check if the revealed box is a nuke
						gameOver(); // call game over
						explosionSound.play(); // Play the explosion sound
					}
				}
			}
		}
	}
}

// Draw function to create the game grid
function draw() { // p5 draw function
	if (!landingPage) { // if we're not loading the landing page then...
		background(255); // Set the background color to white
		for (let i = 0; i < columns; i++) { // Loop to display each box in the grid
			for (let j = 0; j < rows; j++) {
				grid[i][j].show(); // Display the current box
			}
		}
	}
}