def __init__(self,player_id,team,serverIP,serverPort):
                '''State: Players,Buildings, Time, Resourse Pool'''
                LoopingThread.__init__(self)               
		
		self.players 	= {}
		self.buildings 	= {}
		self.TimeLeft = 15*60 
		self.width = 80.0
		self.height = 48.0
		self.view =None
		self.GameOver =False
		self.playerID =player_id
		
		self.player = None
		self.action = 0
		self.attemptedAction = 0
		self.lastAction = 0
		self.ActionTimeout = 1
		
		self.team =team
		self.otherTeam = 2 if self.team==1 else  1 
		self.scores =[0,0]
		self.IsServer = False
		self.ResourcePool = ResourcePool()
		self.client = UDPClient(self)
		self.serverIP =serverIP
		self.serverPort = serverPort
                self.Tick = 0
                self.Position = (0,0)
                self.lastUpdate = 0
                self.controller = None
class Environment(LoopingThread): #in an MVC system , this would be a controller
    ''' The environment class contains the state of the game. The server has the master version, the clients have slave versions (updated through the network) '''
    ATTACK_RADIUS = 3
    SCAN_RADIUS = 3
    FPS=30
    

    def __init__(self,player_id,team,serverIP,serverPort):
                '''State: Players,Buildings, Time, Resourse Pool'''
                LoopingThread.__init__(self)               
		
		self.players 	= {}
		self.buildings 	= {}
		self.TimeLeft = 15*60 
		self.width = 80.0
		self.height = 48.0
		self.view =None
		self.GameOver =False
		self.playerID =player_id
		
		self.player = None
		self.action = 0
		self.attemptedAction = 0
		self.lastAction = 0
		self.ActionTimeout = 1
		
		self.team =team
		self.otherTeam = 2 if self.team==1 else  1 
		self.scores =[0,0]
		self.IsServer = False
		self.ResourcePool = ResourcePool()
		self.client = UDPClient(self)
		self.serverIP =serverIP
		self.serverPort = serverPort
                self.Tick = 0
                self.Position = (0,0)
                self.lastUpdate = 0
                self.controller = None


    def createPlayer(self, player_id,team):
                '''add a player to the given team'''
                player = Player()
                player.team = team

                playerId = id(player)
                player.player_id = player_id
               
                self.players[playerId] = player
        
                return player

    def createBuilding(self, team,pos):
                '''add a building to the given team'''
                building = Building()
                building.team = team
                building.position =pos
                bid = id(building)
                building.building_id = 0
                self.buildings[bid] = building
                
        
                return building
            
    def readGestures(self):
        self.controller._handleInput()
        if(self.player<>None):
            #print self.player.action
            if(self.player.action == Player.ATTACK): #ATTACK
                                    self.handleAttack()

            elif(self.player.action == Player.BUILD): #building
                                    self.handleBuild()

            elif(self.player.action == Player.UPGRADE): #building
                                    self.handleUpgrade()

            elif(self.player.action == Player.SCAN): #building
                                    self.handleScan()

            elif(self.player.action == Player.IDLE):
                                    self.handleIdle()



    def handleAttack(self):
                if(self.player.sides>=3):
                        self.player.performAttack(self.Tick)  
                       
    def handleBuild(self):
                ACTION = "BUILD"
                if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size):
                        ACTION ="MINE"
                else:
                        for b in self.buildings.itervalues():
                                
                                if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- player.getPosition()).length <b.size):
                                        ACTION ="MINE"
                                        break      
                if( ACTION =="MINE"):
                        self.player.performBuild(self.Tick)  
                        
                                         
                else:
                        if(self.player.resources>0):
                                BUILDING =None
                                for b in self.buildings.itervalues():
                                        if   (b.getPosition() - self.player.getPosition()).length < b.size:
                                                BUILDING =b
                                                break
                                

                                if BUILDING.team ==self.player.team:
                                        self.player.performBuild(self.Tick) 
        
    def handleUpgrade(self):
                allowedUpgradeLoc = False
                if((self.ResourcePool.getPosition()-self.player.getPosition()).length< self.ResourcePool.size):
                        allowedUpgradeLoc=True
                else:
                        for b in self.buildings.itervalues():
                                if(b.team == self.player.team and b.isPolyFactory() and b.resources == 5 and (b.getPosition()- self.player.getPosition()).length <b.size): 
                                        allowedUpgradeLoc=True
                                        break
                if(allowedUpgradeLoc):
                       self.player.upgrade(self.Tick) 

    def handleScan(self):
             self.player.scan(self.Tick)    

    def handleIdle(self):

             pass  
      
    def updateTime(self):
		self.Tick+= 1.0/Environment.FPS
		#if( self.TimeLeft<=0):
		#    self.GameOver =True
            
    def task(self):
                
		#self.deSerialize()
		self.readGestures()
		self.updateTime()
		self.updatePositions()
		self.makeRequest()
		self.view.paint(self.Tick )
                for event in pygame.event.get():
                        if event.type == pygame.QUIT:
                                self.Exit()
                        
    def Exit(self):
        self.shutdown()
        pygame.quit()

       
    def makeRequest(self):
        #print self.action
        
        self.client.MakeRequest(self.playerID,self.team,self.action,self.Position)
        
        self.action = 0
    
    def updatePositions(self):
            for playerId in self.players:
                     
                     if self.players[playerId].player_id <> self.playerID:
                         
                         self.players[playerId].updatePosition( 1.0/Environment.FPS)
                     
    def start(self):
		'''controls the environment by initiating the looping calls'''

		self.lastUpdate =time.time()
		self.view.start('client-'+str(self.playerID))
		self.client.start(self.serverIP,int(self.serverPort),self.playerID)
		
                #if os.path.exists(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1]):		
                #    os.remove(CLIENTLOCALDATA.split('.')[0]+str(self.playerID)+'.'+CLIENTLOCALDATA.split('.')[1])

		self.setInterval(1.0/Environment.FPS)
		self.run()
		#self._renderCall = LoopingCall(self.Update) 
		#self._requestCall = LoopingCall(self.makeRequest) 
		#self._renderCall.start(1.0/Environment.FPS)	
		#self._requestCall.start(1.0/Environment.FPS)	


	#FUNCTIONS FOR NETWORKING
	
    def deSerialize(self,state):
       
        try:
                
            '''
                assume the following message structure
                players$buildings$resourcepool$scores$timeleft$gameover

                    players->player1@player2@..@playern
                        player1->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3&action
            '''
            if(state<>None):
                
                t = state.split('$')
                
                if(len(t)>0):
                    
                    players =  t[0].split('@') #update players
                    
                    players.remove('')
                    for p in players:
                          
                        found =False
                        pkey = 0
                        player = p.split('&')

                        pId     = int(player[0])
                        pTeam   = int (player[1])
                        pSides  = int(player[2])
                        pResources  = int(player[3])
                        pPartialResources = int(player[4])
                        pPosition = Vector2D( (float(player[5].split('^')[0]),(float(player[5].split('^')[1]))))
                        AnimationList = player[6].split('^')
                        AnimationList.remove('')
                        pAnimations=[]
                        for a in AnimationList:
                            a = a.split('#')
                            pAnimations.append( (int(a[0]),bool(a[1]),float(a[2])))
                        pAction = int(player[7])
                        
                        for ep in self.players.itervalues():
                            if ep.player_id == pId:
                                found = True
                                pkey = id(ep)
                                break
                        if found:
                            
                            self.players[pkey].sides = pSides
                            self.players[pkey].resources = pResources
                            self.players[pkey].partialResources = pPartialResources
                            
                            
                            
                            if pId == self.playerID:
                                
                                self.players[pkey].position = Vector2D(self.Position)
                                
                                self.players[pkey].action = self.action
                            else:
                                self.players[pkey].animations.extend(pAnimations)
                                self.players[pkey].targetPosition = pPosition
                                self.players[pkey].action = pAction
                        else:
                            
                            newplayer = self.createPlayer(pId,pTeam)
                            if(pId == self.playerID):
                                self.player=newplayer
                            newplayer.targetPosition=pPosition
                            newplayer.sides = pSides
                            newplayer.resources = pResources
                            newplayer.partialResources = pPartialResources
                            newplayer.animations.extend(pAnimations)
                            newplayer.action = pAction

                    '''
                    assume the following message structure
                    players$buildings$resourcepool$scores$timeleft$gameover

                        buildings->buildings@buildings@..@buildings
                            buildings->id&Team&sides&resources&partialResources&pos_x^pos_y&anim1^anim2^anim3
                    '''
                 

                if(t[1]<>''):
                    
                    buildings  =  t[1].split('@')
                    
                    self.buildings.clear()
                    for b in buildings:
                        building = b.split('&')
                        bId = int(building[0])
                        bTeam = int(building[1])
                        bSides  = int(building[2])
                        bResources  = int(building[3])
                        bPartialResources = int(building[4])
                        AnimationList = building[6].split('^')
                        
                        AnimationList.remove('')
                        bAnimations=[]
                        for a in AnimationList:
                            a = a.split('#')
                            bAnimations.append( (int(a[0]),bool(a[1]),float(a[2])))
                            
                        bPosition = Vector2D( (float(building[5].split('^')[0]),(float(building[5].split('^')[1]))))

                        newbuilding = self.createBuilding(bTeam,bPosition)
                        newbuilding.building_id = bId
                        newbuilding.sides = bSides
                        newbuilding.resources = bResources
                        newbuilding.animations.extend(bAnimations)
                if(t[2]<>''):
                    self.scores =(int(t[2].split('^')[0]),int(t[2].split('^')[1]))
                if(t[3]<>''):
                    self.TimeLeft =int(t[3])
                if(t[4]<>''): 
                    self.GameOver = not bool(t[4])
                   
              
        except:
            print "Unexpected error:", sys.exc_info()[0]