function stage.load(map)
	if stage.loaded stage.unload() end

	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]
	if #h.title > 0
		console.debug("Found '"..h.file.."' ("..h.title..")")
	else
		console.debug("Found '"..h.file.."'")
	end

	camera = {
		x = 168, y = 128, -- Camera position
		focus = nil, -- Entity the camera is focused on.
		speed = 16 -- Camera focus speed
	}

	bk = {
		move = 4, -- Background movement/drawing type
		ticks = 0 -- Background movement ticks
	}

	if h.tiles ~= '0'
		if io.exists("Stage/Prt"..h.tiles.."2x")
			graphics[Tiles] = pbm.load("wiidata/Stage/Prt"..h.tiles.."2x",1)
		else
			graphics[Tiles] = pbm.load("Stage/Prt"..h.tiles)
		end
	end
	bk.move = h.bkMove
	graphics[bkImg] = pbm.load("bk"..h.bkImg)
	if h.npc1 ~= '0'
		graphics[Npc1] = pbm.load("Npc/Npc"..h.npc1)
	end
	if h.npc2 ~= '0'
		graphics[Npc2] = pbm.load("Npc/Npc"..h.npc2)
	end
	console.debug("Stage graphics loaded.")

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

	if stage.width <= 21*16 and stage.height <= 16*16
		bk.color = 0x000000
	end

	stage.time = 0
	stage.ents = {}
	stage.loaded = true
end

function stage.unload()
	stage.loaded = false
	fade.reset()

	graphics[Tiles] = nil
	graphics[bkImg] = nil
	graphics[Npc1] = nil
	graphics[Npc2] = nil

	camera = nil
	bk = nil
	stage.tiles = nil
	stage.width = nil
	stage.height = nil
	stage.ents = nil
end


function stage.think()
	if not stage.loaded return end
	stage.time = stage.time + 1
	for k,v in pairs(stage.ents)
		NPC.think(v)
	end
end

local function drawTiles(screen,cx,cy)
	if not graphics[Tiles] return end
	local tw = graphics[Tiles]:w()
	for y = 0,240/16
		if math.floor(cy/16)+y > stage.height-1 break end -- draw nothing to the bottom (safety precaution)
		for x = 0,320/16
			if math.floor(cy/16)+y < 0 break end -- draw nothing to the top (safety precaution)
			if math.floor(cx/16)+x > stage.width-1 break end -- draw nothing to the right (safety precaution)
			if math.floor(cx/16)+x >= 0 -- draw nothing to the left (safety precaution)
				local num = (math.floor(cx/16)+x+(math.floor(cy/16)+y)*stage.width)+1
				local tile = stage.tiles:byte(num)
				local tx = tile*16
				local ty = math.floor(tx/tw)*16
				tx = tx%tw
				screen.draw(graphics[Tiles],{tx,ty,16,16},{(x*16-cx%16),(y*16-cy%16)})
			end
		end
	end
end

function stage.draw(screen)
	if not stage.loaded return end
	local cx = camera.x - 160
	local cy = camera.y - 120
	drawTiles(screen,cx,cy)
	for k,v in pairs(stage.ents)
		NPC.draw(v,screen,cx,cy)
	end
end
