import cocos
import random
from cocos.actions import *

class Npc:

    def __init__(self, map_layer, item_layer):

        self.pos = None

        self.map = map_layer
        self.item_layer = item_layer

        self.sprites = {}
        self.sprites['hat'] = cocos.sprite.Sprite('img/hat.png')
        self.sprites['torso'] = cocos.sprite.Sprite('img/torso.png')
        self.sprites['legs'] = cocos.sprite.Sprite('img/legs.png')
        self.sprites['head'] = cocos.sprite.Sprite('img/head.png')


        self.shapes = { 'hat':'_npc1',\
                        'torso':'_npc1',\
                        'legs':''}

        self.colors = { 'hat':'_black',\
                        'torso':'_black',\
                        'legs':'_black'}

        self.current = {'hat':['',''],\
                        'torso':['',''],\
                        'legs':['','']}

        self.visible = True
        self.is_target = False

        self.randomize()

    def randomize(self):
        colors = ['_black', '_grey']
        shapes1 = ['_npc1']
        shapes2 = ['_npc1', '_npc2']

        self.shapes['hat'] = random.choice(shapes2)
        self.shapes['torso'] = random.choice(shapes1)

        self.colors['hat']   = random.choice(colors)
        self.colors['torso'] = random.choice(colors)
        self.colors['legs']  = random.choice(colors)

    def __eq__(self, other):
        if isinstance(other, Npc):
            return self.shapes['hat'] == other.shapes['hat'] and\
                    self.shapes['torso'] == other.shapes['torso'] and\
                    self.colors['hat'] == other.colors['hat'] and\
                    self.colors['torso'] == other.colors['torso'] and\
                    self.colors['legs'] == other.colors['legs']
        return NotImplemented

    def __ne__(self, other):
        result = self.__eq__(other)
        if result is NotImplemented:
            return result
        return not result

    def reveal_shape(self, what, criteria):
        if what in self.sprites and self.shapes[what] == criteria:
          self.current[what][0] = self.shapes[what]
          self.remove_from_layer(self.item_layer)
          self.sprites[what] = cocos.sprite.Sprite('img/'+what+self.current[what][0]+self.current[what][1]+'.png')
          self.sprites[what].visible = self.sprites['head'].visible
          self.add_to_layer(self.item_layer)

    def reveal_color(self, what, criteria):
        if what in self.sprites and self.colors[what] == criteria:
          self.current[what][1] = self.colors[what]
          self.remove_from_layer(self.item_layer)
          self.sprites[what] = cocos.sprite.Sprite('img/'+what+self.current[what][0]+self.current[what][1]+'.png')
          self.sprites[what].visible = self.sprites['head'].visible
          self.add_to_layer(self.item_layer)




    def reveal(self, what):
        if what in self.sprites:
            self.sprites[what].color = self.colors[what]

    def set_pos(self, i, j, force=False):
        self.pos = i,j
        for s in self.sprites:
            if force:
                self.sprites[s].position = i*32+16, j*32+16
            else:
                self.sprites[s].do(MoveTo((i*32+16, j*32+16), duration=0.2))

    def update(self):
        if self.pos is not None:
            self.updated = True
            directions = [(-1,0),(1,0),(0,-1),(0,1)]
            direction = directions[random.randint(0,3)]
            new_pos = self.pos[0]+direction[0], self.pos[1]+direction[1]
            if self.map.is_passable(*new_pos):
                self.item_layer.items[new_pos[0]][new_pos[1]].append(self)
                self.item_layer.items[self.pos[0]][self.pos[1]].remove(self)
                self.set_pos(*new_pos)

    def update_visibility(self, value):

        for s in self.sprites:
            self.sprites[s].visible = value

    def add_to_layer(self, layer):
        layer.add(self.sprites['head'], z=5)
        layer.add(self.sprites['legs'], z=6)
        layer.add(self.sprites['torso'], z=7)
        layer.add(self.sprites['hat'], z=8)
        self.set_pos(*self.pos, force=True)

    def remove_from_layer(self, layer):
        for s in self.sprites:
            layer.remove(self.sprites[s])