import pygame as P
import Numeric as N
import Event as E
class Model:
    
    def __init__(self, evManager):
        """__init__(self) -> returns nothing
        is for iniatilaizing evrethyings the model needs"""
        
        # regist in the event EventManager
        self.evManager = evManager
        self.evManager.RegisterListener( self, "model" )

        # set the creatures dict and groups
        self.creatures = P.sprite.RenderUpdates()
        self.dictCreatures = dict()
        self.z = 0
        self.a = 0
        self. xx = 0
        #--------------------------------------
    
    def Notify(self, event):
        """ def Notify(self, event)
        this method permit the model to listen events risen and posted in
        the EventManager, is the door to comunicate the model with the view
        and controler"""
        # hear for set events and call the needed methods
        if event.name  == 'SetCreatureEvent':
            self.setCreature(event.xpos, event.ypos)
        elif event.name ==  'SetBackgroundEvent':
            self.setBackground(event.width, event.heigth)

        # hear for update events and call the needed methods
        elif event.name == 'UpdateCreatureEvent':
            self.updateCreature(event.creatureName)
        elif event.name == 'UpdateBackgroundEvent':
            self.updateBackground()            
        elif event.name == 'UpdateCreturesGroupEvent':
            self.updateGroup()
        elif event.name == 'UpdateAll':
            self.updateAll(event.bacground, event.group)
            #--------------------------------------

    
    def setCreature(self, xpos, ypos):
        """setCreature(self, name, properties)
        this metod is for add a creature in the dict and group containers
        and raises the AddSpriteEvent() to the view """
        #for now set and create a filling rectangle in the
        #future do something diferent
        self.xx +=1
        print self.xx
        self.dictCreatures[self.z] = Creature(self.z, self.creatures)         
        self.dictCreatures[self.z].image = P.Surface([15, 15])
        self.dictCreatures[self.z].image.fill([0, 255, 0])
        self.dictCreatures[self.z].rect = self.dictCreatures[self.z].image.get_rect()
        self.dictCreatures[self.z].rect.topleft = [xpos, ypos]        
        self.creatures.add( self.dictCreatures[self.z] )
        self.creatures.update()

        #post this event 
        self.evManager.post(E.AddSpriteEvent(self.creatures))
        self.z = self.z+1
        #-------------------------------------
        
    def setBackground(self, width, heigth):
        """setBackground(self, width, heigth)
        this metod if for create the 2d array in the model as the background
        and raises the SetSurfaceEvent to the view"""

        #for now the bakground is only a 2D array in the future gona be
        #a cellular automata 
        self.striped = N.zeros((width, heigth, 3))
        self.striped[:] = (255, 0, 0)
        self.striped[:,::3] = (0, 255, 255)
        self.evManager.post(E.SetSurfaceEvent(self.striped)) 
        #--------------------------------------

    def updateCreature(self, name):
        """updateCreature(self, name)
        this metod is for update only one creature"""
        # only call update in the creature and raise the event for the view
        self.dictCreatures[name].update()
        self.evManager.post(E.UpdateSpriteEvent(self.creatures))        
        #--------------------------------------
           
    def updateBackground(self ):
        """updateBackground(self, array )"""

        #for now only change the values in the 2D array in iteration == 25
        #and in iteration == 50, in the future call the next step function
        #in the cellular automata (bakground)  
        if  self.z  == 25:
            
            self.striped[:,::3] = (255, 0, 0)
            self.striped[:] = (0, 255, 255)
            self.evManager.post(E.UpdateSurfaceEvent(self.striped, self.creatures))
            
        elif self.z == 50:
            
            self.striped[:,::3] = (0, 0, 255)
            self.evManager.post(E.UpdateSurfaceEvent(self.striped, self.creatures))
        self.z = self.z+1
        if self.z == 51:
            self.z = 0
        #--------------------------------------
        
        
    def updateGroup(self):
        """updateGroup(self, group)"""
        # this metod update all the creauteres at same time and rise
        # the ivent for the view
        self.creatures.update()
        self.evManager.post(E.UpdateSpriteGroupEvent(self.creatures))
        #--------------------------------------
        
    def updateAll(self, background, group):
        """updateAll(self, background, group)"""
        # for now do nothing in the future update all creatures and
        #background at the same time
        self.creatures.update()
        self.updatackground()
        #--------------------------------------

#------------------------------------------------------------------------------------------------------------------------
#     ________________________End__Model__Class______________________________
#------------------------------------------------------------------------------------------------------------------------


class Entity:
    """class Entity is the higest class for make some "object" that has internal
    state, a input and a nextStepFunction (Turing machine)"""
    def __init__():
        self.internalState
    def NextStepfunction(input, internalState):
        return output
#   _____________________________________________________________________


class SpatialEntity(Entity,  P.sprite.Sprite):
    """class SpatialEntity(Entity,  P.sprite.Sprite):
        this class change the Entity class to a espatial entity so
        the input come from the neighborhood """
    def __init__():
        """"""
#   _____________________________________________________________________

class Creature(SpatialEntity):
    """class Creature(SpatialEntity)"""
   
    def __init__(self, name, group):
        #for now have to iniatilize sprite class in the future
        #the creatures will not depends on the pygame.sprite.Sprite class
        P.sprite.Sprite.__init__(self)

        #all creatures have a name and have a group to belong to
        self.name = name
        self.group = group
        #--------------------------------------
    def update(self):
        """update(self) this metod is called as the next state function in a cellular
        automata"""
        # for now the update only move the position of creature in the
        # future will be the most complex function in all the program
        # because determine the behavior of the creature related with the
        #core modules "see documentation"
        self.rect.x += 1
        self.rect.y+= 1
#   _____________________________________________________________________

        
    

   




