

dofile("mainConstants.lua")
dofile("mainApp.lua")
dofile("defaultConfigs.lua")

app.initGarbageCollect()

-- GLOBALS
window = {width = 0, height = 0}

dofile("lib/lib.lua")
dofile("sprites.lua")

dofile("state.lua")
dofile("pixelShaders.lua")
dofile("entity.lua")
dofile("sound.lua")
dofile("musicstate.lua")
dofile("gamestate.lua")
dofile("menustate.lua")

dofile("classes/classes.lua")

math.initRandom()

local function mainInit()
	
	-- parse commandLine
	cmdLine.parse()
	
	-- init app
	app.init()
	
	-- init window
	window.init()
	
	-- init fonts
	fonts.init()
	
	-- init fonts
	sprites.init()
	
	-- init render helpers
	video.initHelpers()

	-- init sound
	sound.init()
	
	-- init configs
	if DEFAULT_CONFIG then
		config.load(_args.config or "config", DEFAULT_CONFIG, _config)
	end
	
	if DEFAULT_DEBUG then
		config.load(_args.debugConfig or "debug", DEFAULT_DEBUG, DEBUG)
	end
	
	if DEFAULT_APP then
		config.load(_args.app or "app", DEFAULT_APP, _app)
	end
	
	-- init token
	if not _config.token then
		_config.token = string.randomText(10)
	end
	
	-- init sound
	audio.setOpenAlDistanceModel(6)
	audio.setGlobalRolloffFactor(1)
	audio.setSoundListenerOrientation(0, 0, 1, 0, -1, 0)
	

	local soundstate = states.add(SoundState:new(), "sound")
	states.protect("sound")
	states.hide("sound")
	

	-- init music
	local musicState = states.add(MusicState:new(), "music")
	states.protect("music")
	states.hide("music")
	
	-- init app starting point
	states.add(MenuState:new(), "menu")
	--Or use game directly?
	
	--states.add(GameState:new(), "game")
	--states.get("game"):setMap("16x16:100")
	--[[
	
	states.get("game"):executeLoadMap("128x128:100")
	
	if _args.host then
		states.get("game"):startHost(_config.port, 2)
	end
	if _args.join then
		states.get("game"):startClient("localhost", _config.port)
	end]]
end

hook.add("gameInit", mainInit)

local function mainUpdate(time)
	if debug.enterUpdate(time) then
		app.collectGarbage(time)
		return
	end
	
	app.update(time)	
		
	debug.enterGc()

	app.collectGarbage(time)
	
	debug.exitUpdate(time)
end

hook.add("frameUpdate", mainUpdate)

local function mainRender()
	debug.enterRender()
	
	app.render()
	
	if app.started then
		debug.exitRender()
	end
	
	app.postRender()
end

hook.add("frameRender", mainRender)

local function keyCharacter(byte)
	if debug.keyCharacter(byte) then
		return
	end
	
	states.keyCharacter(byte)
end

hook.add("keyCharacter", keyCharacter)

local function keyPressed(key)
	--[[ ]] if debug then
	--[[ ]] 	debug.keyPressed(key)
	--[[ ]] end
	
	states.keyPressed(key)	
end

hook.add("keyPress", keyPressed)

local function mouseClick(x, y, button, clickCount)
	--[[ ]] if debug then
	--[[ ]] 	debug.mouseClicked(button)
	--[[ ]] end
	states.mouseClick(x, y, button, clickCount)
end

hook.add("mouseButton", mouseClick)

local function mainClose()
	
	config.saveAll()
	
	states.destroyAllForced()
	
	debug.onClose()
end

hook.add("gameClose", mainClose)

local function joyButtonPressed(joy, btn)
	--[[ ]] if debug then
	--[[ ]] 	debug.joyPressed(button)
	--[[ ]] end
	states.joyPressed(joy, btn)
end

hook.add("joystickButtonPressed", joyButtonPressed)

local function joyButtonReleased(joy, btn)
	states.joyReleased(joy, btn)
end

hook.add("joystickButtonReleased", joyButtonReleased)
