import operator

from PodSix.Concurrent import Concurrent
from PodSix.RDC import RDC

from Collider import Collider
from Camera import Camera

from Platform import Platform
from Portal import Portal

class Level(Concurrent):
	"""
		Generic level of a platformer.
	"""
	def __init__(self, name):
		Concurrent.__init__(self)
		self.characters = []
		self.layers = {}
		self.player = None
		self.start = None
		self.startPoints = {}
		self.rdc = RDC(Collider)
		self.name = name
		self.gravity = 2.5
	
	def PutPlayerOnStart(self, player, start):
		p = None
		if start in self.startPoints.keys():
			p = self.startPoints[start]
		else:
			for l in self.layers:
				if start in self.layers[l].names.keys():
					p = self.layers[l].names[start]
		if not p:
			raise Exception("Can't find object called %s" % start)
		if isinstance(p, Portal):
			player.rectangle.Bottom(p.rectangle.Bottom())
		else:
			player.rectangle.Bottom(p.rectangle.Top())
		player.rectangle.CenterX(p.rectangle.CenterX())
		self.camera.rectangle.CenterX(player.rectangle.CenterX())
		self.camera.rectangle.CenterY(player.rectangle.CenterY())
	
	def SetCamera(self, camera):
		self.camera = camera
		self.camera.SetLevel(self)
		self.Add(self.camera)
	
	def RemoveCamera(self):
		self.Remove(self.camera)
		self.camera = None
	
	def AddCharacter(self, character):
		self.characters.append(character)
		self.Add(character)
	
	def RemoveCharacter(self, character):
		self.characters.remove(character)
		self.Remove(character)
	
	def AddLayer(self, layerid, layer):
		self.layers[layerid] = layer
		self.Add(layer)
	
	def DoGravity(self, character):
		character.velocity[1] += self.gravity * self.Elapsed(0.1)
	
	def Update(self):
		[self.DoGravity(c) for c in self.characters]
		Concurrent.Update(self)
		colliders = self.characters + reduce(operator.add, [self.layers[l].GetAll() for l in self.layers])
		if self.camera:
			colliders.append(self.camera)
		self.rdc.DoRDC(colliders)
	
	def SetPlayerCamera(self, player, camera, start):
		self.start = start
		self.SetCamera(camera)
		self.player = player
		player.SetLevel(self)
		self.AddCharacter(player)
		self.PutPlayerOnStart(self.player, start)
	
	def RemovePlayerCamera(self):
		self.RemoveCamera()
		self.RemoveCharacter(self.player)
		self.player = None


