--[[
	I.Q.S. (an "Excite QTE2" -Shenmue Mini Game- Clone)
		Programming: Gianluca Giacalone
		Graph: Gianluca Giacalone
		Sound & Music: Thomas Becker
]]

--[[
	Todo:
		Engine
		[x] Timer per il calcolo della velocità
		[x] Timer per impostare la difficoltà
		[x] Gestione dei tasti nel gioco
		[x] Gestione dei punteggi
		[x] Salvataggio dei punteggi su file separato
		
		Grafica
		[x] Capire come poter inserire elementi animati nello sfondo
		[ ] Aggiungere altre animazioni di sfondo
		[x] Migliorare la grafica dei pulsanti
		
		Audio
		[x] Musica
		[x] Effetti sonori
		[ ] Aggiungere effetti sonori sui menù
		
		Rete (...Forse...)
		[ ] Criptazione del file dei punteggi ...
		[ ] Tabellone ON LINE ... (!!!)
		[ ] Criptazione di eventuale collegamento a sever con tabellone on line ...
]]

dofile("functions.lua")

-- funzione per il menu principale
function mainMenu()
	oldmainMenuPad = Controls.read()
	mainMenuSelection = 1

	x1 = 156
	y1 = 161
	x2 = 180
	y2 = 191
	time = 0

	while true do
		screen:blit(0, 0, background2, false)

		-- animazione tasti - TEST -
		x1 = (math.sin((time+100)/50) * 12) + 156
		x2 = (math.sin((time)/50) * 12) + 180
		time = time + 1
		if time >= 10000 then
			time = 0
		end

		if mainMenuSelection == 1 then
			screen:blit(x1, y1, mainStartGameON, true)
			screen:blit(x2, y2, mainOptionsOFF, true)
		elseif mainMenuSelection == 2 then
			screen:blit(x1, y1, mainStartGameOFF, true)
	    screen:blit(x2, y2, mainOptionsON, true)
		end
		screen.flip()
		screen.waitVblankStart()

		mainMenuPad = Controls.read()
		if mainMenuPad ~= oldmainMenuPad then
			if mainMenuPad:down() then
		      	mainMenuSelection = mainMenuSelection + 1
				if mainMenuSelection > 2 then
					mainMenuSelection = 1
				end
			elseif mainMenuPad:up() then
		    	mainMenuSelection = mainMenuSelection - 1
				if mainMenuSelection < 1 then
		    	mainMenuSelection = 2
		    end
			elseif mainMenuPad:cross() then
				if mainMenuSelection == 1 then
					startGame()
				elseif mainMenuSelection == 2 then
		    	menuOpzioni()
				end
			end
			oldmainMenuPad = mainMenuPad
		end
	end
end 

-- menu opzioni
function menuOpzioni()
	selectedOptionNumber = 0
	deactiveColor = Color.new(175, 175, 175)
	activeColor = Color.new(0, 0, 255)
	oldPad = Controls.read()
   
	while true do
		-- screen:clear()
		screen:blit(0, 0, background4,  false)
		y = 0
		selectedOptionValues = nil
		selectedOptionIndex = nil
		selectedOptionName = nil
      
		yOffset = 80
		yInter = 20
      
		-- leggo le opzioni dall'array
		for optionKey, possibleOption in possibleOptions do
			color = deactiveColor
			if selectedOptionNumber == y then
				color = activeColor
				selectedOptionValues = possibleOption.values
			end
         
			-- visualizzo l'opzione corrente
			screen:print(80, (y * yInter)+yOffset, possibleOption.displayName, color)
       
			for i, value in possibleOption.values do
				color = deactiveColor
				if options[optionKey] == value then
					color = activeColor
					if selectedOptionNumber == y then
						selectedOptionIndex = i
						selectedOptionName = optionKey
					end
				end
				screen:print(i * 40 + 250, (y * yInter)+yOffset, value, color)
			end
			y = y + 1
		end
		screen:print(270, 200, "Press X to exit", activeColor)

		pad = Controls.read()
		if pad ~= oldPad then
			len = table.getn(selectedOptionValues)
			if pad:cross() then
				screen:blit(0, 0, background4,  false)
				screen:print(300, 6, ":: Saving settings...", whiteColor)
				screen:print(10, 6, appName .. " v" .. appVer, whiteColor)
				screen.flip()
				screen.waitVblankStart(30)
				if saveSettings() then
					screen:blit(0, 0, background4,  false)
					screen:print(10, 6, appName .. " v" .. appVer, whiteColor)
					screen:print(300, 6, ":: Settings saved!", whiteColor)
					screen.flip()
					screen.waitVblankStart()
				else
					screen:blit(0, 0, background4,  false)
					screen:print(10, 6, appName .. " v" .. appVer, whiteColor)
					screen:print(300, 6, ":: Error while saving options...", redColor)
					screen.flip()
					screen.waitVblankStart()
				end
				screen.waitVblankStart(30)
				break
			elseif pad:up() then
				selectedOptionNumber = selectedOptionNumber - 1
				if selectedOptionNumber < 0 then selectedOptionNumber = y - 1 end
			elseif pad:down() then
				selectedOptionNumber = selectedOptionNumber + 1
				if selectedOptionNumber >= y then selectedOptionNumber = 0 end
			elseif pad:left() then
				selectedOptionIndex = selectedOptionIndex - 1
				if selectedOptionIndex <= 0 then selectedOptionIndex = len end
				options[selectedOptionName] = selectedOptionValues[selectedOptionIndex]
			elseif pad:right() then
				selectedOptionIndex = selectedOptionIndex + 1
				if selectedOptionIndex > len then selectedOptionIndex = 1 end
				options[selectedOptionName] = selectedOptionValues[selectedOptionIndex]
			end
			oldPad = pad
		end

		selectedMusic = (options["music"])

		-- if per visualizzare il messaggio di caricamento della musica
		if songplaying ~= selectedMusic then
			screen:print(140, 240, "Loading selected song...", whiteColor)
		end
		screen:print(10, 6, appName .. " v" .. appVer, whiteColor)
		screen.flip()
		screen.waitVblankStart()

		-- if il caricamento della musica
		if songplaying ~= selectedMusic then
			screen:print(140, 240, "Loading selected song...", whiteColor)
			Music.stop()
			if selectedMusic == 1 then
				Music.playFile("./sounds/song1.mod", true)
				songplaying = 1
			elseif selectedMusic == 2 then
				Music.playFile("./sounds/song2.mod", true)
				songplaying = 2
			elseif selectedMusic == 3 then
				Music.playFile("./sounds/song3.mod", true)
				songplaying = 3
			end
			Music.volume(75)
		end
	end
end 

-- funzione gioco
function startGame()
	resetVar()
	-- gestione del tempo
	if options["difficulty"] == 1 then
		maxTime2 = maxTime
	elseif options["difficulty"] == 2 then
		maxTime2 = maxTime / 1.5
	elseif options["difficulty"] == 3 then
		maxTime2 = maxTime / 2
	end
	oldPad = Controls.read()
	while true do
		screen:clear()
		-- carico lo sfondo selezionato nelle opzioni
		screen:blit(0, 0, background3[options["background"]], false)

		-- visualizzo vari elementi su schermo
		curveAnim()
		
		-- visualizzo il bottone da premere
		showBT(currentBT)

		-- visualizzo il quadratino del timer
		quadTimerX = 260 + quadTimerCount
		screen:blit(quadTimerX, 200, quadTimer, true)
		quadTimerCount = quadTimerCount + 12

		-- visualizzo i dati sullo schermo
		displayDataFunc()

		screen.flip()
		screen.waitVblankStart()

		-- avvio il timer
		timer:start()

		if timer:time() > maxTime2 then
			timer:stop()
			if not errorFunc() then break end
		end

		-- gestione dei tasti
		pad = Controls.read()
		if pad ~= oldPad then
			if pad:select() then
				-- se premo select esco
				screen.waitVblankStart(10)
				break
			end
			if options["difficulty"] >= 1 then
				if pad:cross() then
					timer:stop()
					if currentBT == 1 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:circle() then
					timer:stop()
					if currentBT == 2 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:triangle() then
					timer:stop()
					if currentBT == 3 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:square() then
					timer:stop()
					if currentBT == 4 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				end
			end
			if options["difficulty"] >= 2 then
				if pad:left() then
					timer:stop()
					if currentBT == 5 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:right() then
					timer:stop()
					if currentBT == 6 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:up() then
					timer:stop()
					if currentBT == 7 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:down() then
					timer:stop()
					if currentBT == 8 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				end
			end
			if options["difficulty"] == 3 then
				if pad:l() then
					timer:stop()
					if currentBT == 9 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				elseif pad:r() then
					timer:stop()
					if currentBT == 10 then
						correctFunc()
					else
						if not errorFunc() then break end
					end
				end
			end
			oldPad = pad
		end
	end
end

-- app code	

-- variabili
appName = "I.Q.S."
appVer = "0.12"
maxTime = 2000

-- punteggio massimo - da inserire in un file
topScore = 0
userName = "noone"
dofile("scores.ini")

-- colori
blackColor = Color.new(0, 0, 0)
whiteColor = Color.new(255, 255, 255)
redColor = Color.new(255, 0, 0)

-- opzioni
options = { difficulty = 1, background = 1, music = 1 }
possibleOptions = {
   difficulty = {
      displayName = "Difficulty",
      values = { 1, 2, 3} },
   background = {
      displayName = "Background Image",
      -- impostare il numero di background disponibili qui
      values = { 1, 2} },
   music = {
      displayName = "Music",
      values = { 1, 2, 3} }
}
dofile("settings.ini")

-- linea animata - TEST -
l1X = -12
l1Y = 180
curveTime = 0

-- inizializzo le variabili
loading(0)

-- immagini
background1 = Image.load("./images/luasplash.jpg")
background2 = Image.load("./images/backgroundMain.jpg")
-- sfondi della schermata di gioco
background3 = { Image.load("./images/backgroundGame1.jpg"),
							Image.load("./images/backgroundGame2.jpg") }
background4 = Image.load("./images/backgroundOpzioni.jpg")
loading(40)
-- tasti del gioco
tasti = { Image.load("./images/tastoRosso.png"),
					Image.load("./images/tastoGiallo.png"),
					Image.load("./images/tastoBlu.png"),
					Image.load("./images/tastoVerde.png"),
					Image.load("./images/tastoFrecciaSX.png"),
					Image.load("./images/tastoFrecciaDX.png"),
					Image.load("./images/tastoFrecciaUP.png"),
					Image.load("./images/tastoFrecciaDW.png"),
					Image.load("./images/tastoL.png"),
					Image.load("./images/tastoR.png")
				}
tastoOmbraTonda = Image.load("./images/tastoOmbra.png")
loading(60)
-- tasti mainmenu
mainStartGameOFF = Image.load("./images/mainStartGameOFF.png")
mainStartGameON = Image.load("./images/mainStartGameON.png")
mainOptionsOFF = Image.load("./images/mainOptOFF.png")
mainOptionsON = Image.load("./images/mainOptON.png")
mainExitOFF = Image.load("./images/mainExitOFF.png")
mainExitON = Image.load("./images/mainExitON.png")
loading(80)
-- elementi vari
quadTimer = Image.load("./images/quadratinoTimer.png")
quadEndGame = Image.load("./images/quadEndGame.png")
linea01 = Image.load("./images/linea01.png")
loading(90)
-- suoni
soundCorrect = Sound.load("./sounds/correct.wav")
soundError = Sound.load("./sounds/wrong.wav")
--soundCorrect:volume(25)
--soundError:volume(25)
loading(100)

screen:blit(0, 0, background1)
screen.flip()
screen.waitVblankStart(120)

-- pausa per 4 secondi
--screen.flip()
--screen.waitVblankStart(30)

-- avvio la musica
if options.music == 1 then
	Music.playFile("./sounds/song1.mod", true)
elseif options.music == 2 then
	Music.playFile("./sounds/song2.mod", true)
elseif options.music == 3 then
	Music.playFile("./sounds/song3.mod", true)
end
Music.volume(75)
songplaying = options.music

while true do
	mainMenu()
end
