-- Client network messages
net.recv = {}

function GAME:NetRecv(msg)
	local id = msg:bin(1)
	if net.recv[id]
		net.recv[id](msg:sub(2))
	else
		console.print("WARNING: Unhandled message type "..(NETMSG[id] or id).." recieved!")
	end
end

net.recv[NETMSG.CHAT] = function(msg)
	console.print(msg)
end

net.recv[NETMSG.MAP] = function(msg)
	tsc.close()
	stage.load(msg)
	title.reset()
end

net.recv[NETMSG.TITLE] = function(msg)
	title.mode(true)
end

net.recv[NETMSG.CL_SPAWN] = function(msg)
	if not stage.loaded return end
	local cl = {
		id = msg:bin(1),
		x = msg:bin(2,4),
		y = msg:bin(6,4),
		mx = 0,
		my  = 0,
		anim = msg:bin(10),
		flip = msg:bin(11) ~= 0,
		skin = msg:sub(12),
		frame = 1,
		ticks = 0,
		gravity = true,
		player = true
	}
	setmetatable(cl,PLAYER)
	if cl.id == 0 -- id 0 is myself.
		cl.net = {
			mx = 0,
			my = 0,
			anim = cl.anim,
			flip = cl.flip
		}
		camera.x = cl.x
		camera.y = cl.y
	end
	if skins[cl.skin] and skins[cl.skin].anims and skins[cl.skin].sheet
		cl.skin = skins[cl.skin]
		cl.physics = cl.skin.physics[1]
	else
		console.print("WARNING: Invalid skin '"..cl.skin.."' for client "..cl.id..", cannot spawn!")
		return
	end
	stage.players[cl.id] = cl
end

net.recv[NETMSG.CL_MOVE] = function(msg)
	if not stage.loaded return end
	local player = stage.players[msg:bin(1)]
	player.x = msg:bin(2,4)
	player.y = msg:bin(6,4)
	player.mx = msg:bin(10,2)
	if player.mx > 0x7FFF
		player.mx = player.mx - 0xFFFF
	end
	player.mx = player.mx / 0x200
	player.my = msg:bin(12,2)
	if player.my > 0x7FFF
		player.my = player.my - 0xFFFF
	end
	player.my = player.my / 0x200
	local old_anim = player.anim
	player.anim = msg:bin(14)
	if player.anim ~= old_anim
		player.frame = 1
		player.ticks = 0
	end
	local flags = msg:bin(15)
	player.flip = flags & 1 ~= 0
	player.grounded = flags & 1<<1 ~= 0
end

net.recv[NETMSG.CL_REMOVE] = function(msg)
	if not stage.loaded return end
	stage.players[msg:bin(1)] = nil
end

net.recv[NETMSG.ENT_SPAWN] = function(msg)
	if not stage.loaded return end
	local e = {
		id = msg:bin(1),
		type = msg:bin(2,2),
		x = msg:bin(4,4),
		y = msg:bin(8,4),
		flags = msg:bin(12,4),
		anim = msg:bin(16)
	}
	local info = NPC[e.type]
	if info.send_event
		e.event = msg:bin(17,info.send_event)
	end
	--console.debug("Spawning ent "..e.id..": "..e.type)
	NPC.spawn(e)
end

net.recv[NETMSG.ENT_UPDATE] = function(msg)
	if not stage.loaded return end
	local id = msg:bin(1)
	local ent = stage.ents[id]
	if not ent return end
	local change = msg:bin(2)
	ent.x = msg:bin(3,4)
	ent.y = msg:bin(7,4)
	local p = 11
	if change & CHANGE.ANIM
		ent.anim = msg:bin(p)
		ent.frame = 1
		ent.ticks = 0
		p = p + 1
	end
	if change & CHANGE.FLIP
		ent.flip = msg:bin(p) ~= 0
		if ent.flip
			ent.flags = ent.flags | NPC.FLIP
		else
			ent.flags = ent.flags & (~NPC.FLIP)
		end
		p = p + 1
	end
	if change & CHANGE.MX
		ent.mx = msg:bin(p,2)
		if ent.mx > 0x7FFF
			ent.mx = ent.mx - 0xFFFF
		end
		ent.mx = ent.mx / 0x200
		p = p + 2
	end
	if change & CHANGE.MY
		ent.my = msg:bin(p,2)
		if ent.my > 0x7FFF
			ent.my = ent.my - 0xFFFF
		end
		ent.my = ent.my / 0x200
		p = p + 2
	end
end

net.recv[NETMSG.ENT_REMOVE] = function(msg)
	if not stage.loaded return end
	local id = msg:bin(1)
	stage.ents[id] = nil
end

net.recv[NETMSG.TSC_MSG] = function(msg)
	tsc.msgbox = msg:bin(1)
	if tsc.msgbox == 0 -- <CLO
		tsc.close()
	end
end

net.recv[NETMSG.TSC_TEXT] = function(msg)
	local tur = msg:bin(1)
	msg = msg:sub(2)
	if tur == 0
		tsc.tur = false
		tsc.addtext = {0,msg,0}
		if not tsc.msgtext[1]
			table.insert(tsc.msgtext,1,"")
			if not GAME.CompatMode and msg:sub(1,1) == '\n'
				table.insert(tsc.msgtext,1,"")
			end
		end
	else
		tsc.tur = true
		local p = 1
		while p <= #msg
			local char = msg:sub(p,p)
			if char == '\n'
				table.insert(tsc.msgtext,1,"")
				tsc.msgtext[4] = nil
			else
				tsc.msgtext[1] = (tsc.msgtext[1] or "") .. char
			end
			p = p + 1
		end
	end
end

net.recv[NETMSG.TSC_KEY] = function(msg)
	local keylock = msg:bin(1)
	if keylock == 0
		keylock = nil
		if stage.players[0] and stage.players[0].anim == ANIM.CHECK
			self:set_anim(ANIM.STAND)
		end
	end
	if tsc.keylock == keylock
		console.print("WARNING: Duplicate keylock recieved. :x")
	end
	tsc.keylock = keylock
end

net.recv[NETMSG.TSC_MNA] = function(msg)
	tsc.mna = {2.0,msg}
end

net.recv[NETMSG.TSC_NOD] = function(msg)
	tsc.nod = true
end

net.recv[NETMSG.TSC_YNJ] = function(msg)
	tsc.ynj = true
end

net.recv[NETMSG.TSC_CLR] = function(msg)
	tsc.msgtext = {}
end

net.recv[NETMSG.TSC_END] = function(msg)
	local self = stage.players[0]
	if self and self.anim == ANIM.CHECK
		self:set_anim(ANIM.STAND)
	end
	tsc.reset()
end

net.recv[NETMSG.TSC_FAI] = function(msg)
	fade.time = 0
	fade.dir = msg:bin(1)
	fade.move = true
end

net.recv[NETMSG.TSC_FAO] = function(msg)
	fade.time = 0
	fade.dir = msg:bin(1)
	fade.move = false
end

function net.send_chat(text)
	net.send(string.num(NETMSG.CHAT) .. text)
end

function net.send_title(menu)
	net.send(string.num(NETMSG.TITLE) .. string.num(menu),NET.GUARANTEED)
end

function net.send_check(self)
	local x = math.floor(self.x)
	local y = math.floor(self.y)
	if self.checkx ~= x or self.checky ~= y
		net.send(string.num(NETMSG.CL_ANIM) .. string.num(x,4) .. string.num(y,4),NET.GUARANTEED)
		self.checkx = x
		self.checky = y
	end
end

function net.send_move(self)
	self.net = {
		mx = math.floor(self.mx / 0x50),
		my = math.floor(self.my / 0x50),
		anim = self.anim,
		flip = self.flip,
		grounded = self.grounded
	}
	local mx = self.mx
	if self.net.mx == 0
		mx = 0
	end
	local my = self.my
	if self.net.my == 0
		my = 0
	end
	local flags = 0
	if self.flip
		flags = flags | 1
	end
	if self.grounded
		flags = flags | 1<<1
	end
	net.send(string.num(NETMSG.CL_MOVE) .. string.num(math.floor(self.x),4) .. string.num(math.floor(self.y),4) .. string.num(mx,2) .. string.num(my,2) .. string.num(self.anim) .. string.num(flags))
end

function net.tsc_text()
	net.send(string.num(NETMSG.TSC_TEXT),NET.GUARANTEED)
end

function net.tsc_nod()
	net.send(string.num(NETMSG.TSC_NOD),NET.GUARANTEED)
end

function net.tsc_ynj()
	net.send(string.num(NETMSG.TSC_YNJ),NET.GUARANTEED)
end
