--import config.lua
--import utils.lua
--import uiLib.lua

--import userConfig.lua

GamePlayer = {}

function start()
	UILib.init()

	GamePlayer.gameRunning = false

	GamePlayer.screenWidth = 320.0
	GamePlayer.screenHeight = 280.0 + 8.0

	GamePlayer.gameWidth = 320.0
	GamePlayer.gameHeight = 280.0

	GamePlayer.windowPos = vec2(0.0, 0.0)
	GamePlayer.gameViewPos = vec2(0.0, 0.0)

	GamePlayer.statusText = ""
	GamePlayer.currentPageId = 1

	GamePlayer.bilinearInterp = false
	GamePlayer.ditherEnabled = false
	
	GamePlayer.renderRegionPos = vec2(0.0, 0.0)
	GamePlayer.renderRegionSize = vec2(GamePlayer.gameWidth, GamePlayer.gameHeight)

	GamePlayer.backgroundSprite = allocSprite()
	GamePlayer.backgroundSpriteData = {}
	GamePlayer.backgroundSpriteData.position = vec3(0.0, 8.0, -0.1)
	GamePlayer.backgroundSpriteData.size = vec2(GamePlayer.gameWidth, GamePlayer.gameHeight)
	GamePlayer.backgroundSpriteData.color = Config.paletteNames.black
	setSprite(GamePlayer.backgroundSprite, GamePlayer.backgroundSpriteData)

	GamePlayer.renderSprite = allocSprite()
	GamePlayer.renderSpriteData = {}
	GamePlayer.renderSpriteData.position = vec3(0.0, 0.0, -0.1)
	GamePlayer.renderSpriteData.size = vec2(GamePlayer.gameWidth, GamePlayer.gameHeight)
	GamePlayer.renderSpriteData.color = Config.paletteNames.black
	setSprite(GamePlayer.renderSprite, GamePlayer.renderSpriteData)

	GamePlayer.topBarSprite = allocSprite()
	GamePlayer.topBarSpriteData = {}
	GamePlayer.topBarSpriteData.color = Config.uiColors.panel
	GamePlayer.topBarSpriteData.size = vec2(GamePlayer.screenWidth, 8)
	setSprite(GamePlayer.topBarSprite, GamePlayer.topBarSpriteData)

	GamePlayer.fpsSprite = allocSprite()
	GamePlayer.fpsSpriteData = {}
	GamePlayer.fpsSpriteData.position = vec3(GamePlayer.screenWidth - (8.0 * 12), 0.0, 0.2)
	GamePlayer.fpsSpriteData.size = vec2(48.0, 8.0)
	GamePlayer.fpsSpriteData.color = vec4(0.0, 0.0, 0.0, 0.0)
	GamePlayer.fpsSpriteData.text = "0 fps"
	GamePlayer.fpsSpriteData.textColor = vec4(255.0, 255.0, 255.0, 255.0)
	setSprite(GamePlayer.fpsSprite, GamePlayer.fpsSpriteData)

	GamePlayer.fpsTimer = 0.0
	GamePlayer.fpsFrameCount = 0
	GamePlayer.fpsLastTime = getTime()

	GamePlayer.playIconTexturePos = vec2(8.0 * 4.0, 8.0 * 6.0)
	GamePlayer.stopIconTexturePos = vec2(8.0 * 14.0, 0.0)

	GamePlayer.playButton = UILib.buttonIcon(
		vec3(0.0, 0.0, 0.1), vec2(8.0, 8.0),
		Config.uiColors.panel,
		vec2(0.0, 0.0), vec2(8.0, 8.0),
		GamePlayer.playIconTexturePos, vec2(8.0, 8.0),
		Config.uiColors.icon, function() togglePlayGame() end)
	GamePlayer.playButton.desc = "start/stop game"

	GamePlayer.codeButton = UILib.button("code",
		vec3(GamePlayer.screenWidth - (8 * 4), 0.0, 0.1), 
		vec2(8.0 * 4, 8.0), 
		Config.uiColors.button, function() openCodeEditor() end)
	GamePlayer.codeButton.desc = "open default text editor"

	GamePlayer.descPanel = UILib.panel("", vec3(0.0, GamePlayer.screenHeight - 8, 1.0), vec2(GamePlayer.screenWidth - 30, 8.0), Config.uiColors.descPanel)
	GamePlayer.descPanel.visible = false
	GamePlayer.descPanel.changed = true

	local programId = getProgramId()
	invokeProgram(MAIN_PROGRAMID, "setViewTitle", programId, "game player")
	-- invokeProgram(MAIN_PROGRAMID, "registerShortcut", {desc = "stop game", key = KEY_ESCAPE, callback = "shortcutEsc", programId = programId})
	
	Utils.registerShortcut("start/stop game", "shortcutStart", "SPACE", nil, Config)
end

function setPage(pageId)
	GamePlayer.currentPageId = pageId
end

function programActive(state)
	if state == false then
		GamePlayer._stop()
	end
end

function escPressed()
	if GamePlayer.forceCursorHidden == true then
		UILib.setCursor(UILib.CURSOR)
		GamePlayer.forceCursorHidden = false

		return
	end

	GamePlayer._stop()
end

function shortcutStart()
	if GamePlayer.gameRunning == false then
		GamePlayer._start()
	end
end

function togglePlayGame()
	if GamePlayer.gameRunning == true then
		GamePlayer._stop()
	else
		GamePlayer._start()
	end
end

function GamePlayer._start()
	if GamePlayer.gameRunning == true then
		return
	end
	
	GamePlayer.gameRunning = true

	GamePlayer.descPanel.visible = false

	GamePlayer.playButton.iconSpriteData.texturePos = GamePlayer.stopIconTexturePos
	GamePlayer.playButton.iconSpriteData.color = Config.paletteNames.greenLight
	setSprite(GamePlayer.playButton.iconSprite, GamePlayer.playButton.iconSpriteData)
	
	invokeProgram(MAIN_PROGRAMID, "setGameRunning", true)
	
	loadProgram("projects/" .. getProjectName() .. "/gameMain.lua", GAME_PROGRAMID)
	
	if GamePlayer.gameRunning == false then
		-- return if loading the game caused an error already
		-- when that happends _stop() is immediately called
		return
	end

	GamePlayer.bilinearInterp = invokeProgram(MAIN_PROGRAMID, "getProjectVar", "video_bilinearInterpEnabled")
	GamePlayer.ditherEnabled = invokeProgram(MAIN_PROGRAMID, "getProjectVar", "video_ditherEnabled")
	
	if GamePlayer.bilinearInterp == true then
		setBilinearInterpEnabled(true)
	end
end

function GamePlayer._stop()
	if GamePlayer.gameRunning == false then
		return
	end

	GamePlayer.gameRunning = false

	GamePlayer.playButton.iconSpriteData.texturePos = GamePlayer.playIconTexturePos
	GamePlayer.playButton.iconSpriteData.color = Config.uiColors.icon
	setSprite(GamePlayer.playButton.iconSprite, GamePlayer.playButton.iconSpriteData)

	invokeProgram(MAIN_PROGRAMID, "setGameRunning", false)

	clearProgramMemory(GAME_PROGRAMID);
	
	setMouseLocked(false)
	UILib.setCursor(UILib.CURSOR)	

	local voice = {}
	voice.active = false

	for i = 1, SYNTH_VOICE_COUNT do
		setSynth(voice, i)
	end

	if GamePlayer.bilinearInterp == true then
		setBilinearInterpEnabled(false)
	end
end

function _updateGame()
	startRenderToSprite(GamePlayer.renderSprite, GamePlayer.renderRegionPos, GamePlayer.renderRegionSize)

	invokeProgram(GAME_PROGRAMID, "update")

	if GamePlayer.ditherEnabled == true then
		setDitherEnabled(true)
	end

	drawSprite2D(GamePlayer.renderSprite)

	if GamePlayer.ditherEnabled == true then
		setDitherEnabled(false)
	end
end

function _updateStatusBar()
	local showDesc = false

	local desc = nil

	local hovered = UILib.hoveredSpriteWidget
	if hovered ~= nil then
		if hovered.desc ~= nil then
			if GamePlayer.statusText ~= hovered.desc then
				desc = hovered.desc

				GamePlayer.statusText = desc

				local shortcut = Utils.registeredShortcuts[desc] 
				
				if shortcut ~= nil then
					if shortcut.modifier ~= nil then
						desc = desc .. " - ( " .. shortcut.modifier .. " + " .. shortcut.key .. " )"
					else
						desc = desc .. " - ( " .. shortcut.key .. " )"
					end
				end

				GamePlayer.descPanel.text = desc
				GamePlayer.descPanel.visible = true
				GamePlayer.descPanel.changed = true
			else
				desc = GamePlayer.statusText
			end
		end
	end

	if GamePlayer.descPanel.visible == true and desc == nil then
		GamePlayer.descPanel.text = ""
		GamePlayer.statusText = ""
		GamePlayer.descPanel.visible = false
		GamePlayer.descPanel.changed = true
	end
end

function windowMoved(posX, posY)
	GamePlayer.windowPos.x = posX
	GamePlayer.windowPos.y = posY

	GamePlayer.gameViewPos.x = posX + round((GamePlayer.screenWidth - GamePlayer.gameWidth) / 2)
	GamePlayer.gameViewPos.y = posY + round((GamePlayer.screenHeight - GamePlayer.gameHeight) / 2)
end

function update()
	local currentTime = getTime()
	local dt = currentTime - GamePlayer.fpsLastTime
	GamePlayer.fpsLastTime = currentTime
	GamePlayer.fpsFrameCount = GamePlayer.fpsFrameCount + 1
	GamePlayer.fpsTimer = GamePlayer.fpsTimer + dt

	if GamePlayer.fpsTimer >= 0.5 then
		local fps = round(GamePlayer.fpsFrameCount / GamePlayer.fpsTimer)
		GamePlayer.fpsSpriteData.text = fps .. " fps"
		setSprite(GamePlayer.fpsSprite, GamePlayer.fpsSpriteData)

		GamePlayer.fpsTimer = 0.0
		GamePlayer.fpsFrameCount = 0
	end

	if GamePlayer.gameRunning == false then
		drawSprite2D(GamePlayer.backgroundSprite)
	end

	drawSprite2D(GamePlayer.topBarSprite)

	if GamePlayer.gameRunning == true then
		if getLastKeyPressed() == KEY_ESCAPE then
			-- shortcutEsc()
		end

		drawSprite2D(GamePlayer.fpsSprite)

		setViewport(GamePlayer.gameViewPos.x, GamePlayer.gameViewPos.y + 4.0, GamePlayer.gameWidth, GamePlayer.gameHeight)

		_updateGame()

		local mouseLocked = getMouseLocked()

		if mouseLocked == true and GamePlayer.forceCursorHidden == nil then
			GamePlayer.forceCursorHidden = true
		end

		if mouseLocked == true and GamePlayer.forceCursorHidden == true then
			UILib.setCursor(UILib.CURSOR_HIDDEN)
		end

		-- if mouseLocked == true and GamePlayer.forceCursorHidden == false then
		-- 	local mousePos = getMousePosition()
			
		-- 	if mousePos.x < 0 or mousePos.x > GamePlayer.gameWidth or mousePos.y < 8 or mousePos.y > GamePlayer.gameHeight then
		-- 		UILib.setCursor(UILib.CURSOR)
		-- 	else
		-- 		UILib.setCursor(UILib.CURSOR_HIDDEN)
		-- 	end

		-- end

		setViewport(GamePlayer.windowPos.x, GamePlayer.windowPos.y, GamePlayer.screenWidth, GamePlayer.screenHeight)
	end

	if GamePlayer.gameRunning == false then
		_updateStatusBar()
	end

	UILib.update()
end
