stages = {}

function stage.load(map)
	console.debug("Loading stage "..map.."...")
	if not stage.header[map]
		-- TODO: If the header isn't found, try loading it from a file by name
		console.print("Map changed failed, stage header is missing.")
		return
	end

	local h = stage.header[map]
	map = h.file
	if #h.title > 0
		console.debug("Found '"..map.."' ("..h.title..")")
	else
		console.debug("Found '"..map.."'")
	end

	if stages[map] return map end -- Already loaded
	stages[map] = {
		id = map,
		header = stage.header[map],
		width = 0,
		height = 0,
		tiles = "",
		tileflags = "",
		players = {},
		spawn_ents = {},
		ents = {},
		time = 0
	}

	do
		local pxm = io.open("Stage/"..map..".pxm",IO.READ,ENDIAN.LITTLE)
		local header = pxm:getstr(0x04,true)
		if header ~= "PXM\x10"
			console.print("WARNING: PXM header is '"..header.."'")
		end
		stages[map].width = pxm:getnum(2,UNSIGNED)
		stages[map].height = pxm:getnum(2,UNSIGNED)
		stages[map].tiles = pxm:getstr(stages[map].width*stages[map].height,true)
		pxm:close()
		--console.debug("Stage tiles loaded.")
	end

	do
		local pxa = io.open("Stage/"..h.tiles..".pxa",IO.READ,ENDIAN.LITTLE)
		pxa:seek(0,SEEK.END)
		local len = pxa:tell()
		pxa:seek(0,SEEK.SET)
		stages[map].tileflags = pxa:getstr(len,true)
		pxa:close()
	end

	do
		local pxe = io.open("Stage/"..map..".pxe",IO.READ,ENDIAN.LITTLE)
		local header = pxe:getstr(0x04,true)
		if header ~= "PXE\x00"
			console.print("WARNING: PXE header is '"..header.."'")
		end
		local discard = 0
		local count = pxe:getnum(4,UNSIGNED)
		for i = 1,count
			local e = {
				x = pxe:getnum(2,UNSIGNED),
				y = pxe:getnum(2,UNSIGNED),
				flagnum = pxe:getnum(2,UNSIGNED),
				event = pxe:getnum(2,UNSIGNED),
				type = pxe:getnum(2,UNSIGNED),
				flags = pxe:getnum(2,UNSIGNED),
				stage = stages[map]
			}
			if e.event == 0 and e.type == 0 and e.flags == 0
				-- Discard useless object
				discard = discard + 1
				continue
			end
			if not NPC[e.type].id and e.type ~= 0
				console.debug("WARNING: Incomplete NPC class "..e.type)
				discard = discard + 1
				continue
			end
			table.insert(stages[map].spawn_ents,e)
		end
		pxe:close()
		console.debug("Read "..(count-discard).." map entities, discarding "..discard)
	end

	stages[map].tsc = tsc.load("Stage/"..map..".tsc")

	for i,v in ipairs(stages[map].spawn_ents)
		table.insert(stages[map].ents,NPC.spawn(v))
	end
	for i,v in ipairs(stages[map].ents)
		v.id = i
	end

	console.debug("Finished loading stage "..map)
	return map
end
