import math

from person import *
from collectible import *

class Man(Person):
    IMAGES = { "normal" :
                   [ pygame.image.load(os.path.join("data", "guy1.png")),
                     pygame.image.load(os.path.join("data", "guy3.png")),
                     pygame.image.load(os.path.join("data", "guy2.png")),
                     pygame.image.load(os.path.join("data", "guy3.png")) ],
               "ugly" :
                    [ pygame.image.load(os.path.join("data", "ugly1.png")),
                      pygame.image.load(os.path.join("data", "ugly2.png")) ] }
    
    INITIAL_MOVE_VELOC = 50    # pixels per second
    MOVE_ACCEL = 700           # pixels per second^2
    MOVE_ACCEL_DURATION = 0.7 # seconds of acceleration

    INITIAL_JUMP_VELOC = 450  # pixels per second
    GRAVITY_ACCEL = 800       # pixels per second^2

    WIN_VICINITY = 10         # pixels from endlevel

    UGLY_TIME = 6 # seconds
    UGLY_FLICKER_START = 2 # seconds before the end
    UGLY_FLICKER_DURATION = 0.25 # seconds

    def __init__(self, level, colnum, rownum, *groups):
        Person.__init__(self, level, colnum, rownum, *groups)

        self.ugly = False

    def update_position(self):
        Person.update_position(self)

        # Check if we touched a girl
        colliding_girls = [s for s in self.level.women if self.arect.colliderect(s.arect)]

        if colliding_girls and not self.ugly:
            # Lose...
            self.level.lose(colliding_girls[0])
        elif colliding_girls and self.ugly:
            # Win each girl's money
            for g in colliding_girls:
                g.kill()
                self.level.game.money += g.money

        # Check if we touched a collectible
        for s in self.level.collectibles:
            if self.arect.colliderect(s.arect):
                # Endlevel / stripclub?
                if isinstance(s, EndLevel) or isinstance(s, StripClub):
                    # Close enough? Must be near and must be standing on the floor
                    if abs(self.arect.centerx - s.arect.centerx) <= self.WIN_VICINITY and \
                        self.arect.bottom == s.arect.bottom:
                        # In the case of a strip club we also need $5,000
                        if isinstance(s, EndLevel) or self.level.game.money >= 5000:
                            self.level.win()

                # Potion?
                elif isinstance(s, Potion):
                    s.kill()
                    self.level.potion_up()

                # Money?
                elif isinstance(s, Dollar):
                    s.kill()
                    self.level.game.money += 100

    def uglify(self):
        if self.ugly or self.level.num_potions == 0:
            return
        
        self.level.num_potions -= 1
        self.ugly = True
        self.set_animate_keyword("ugly")
        self.ugly_start_time = pygame.time.get_ticks() / 1000.

    def update_image(self):
        Person.update_image(self)

        if self.ugly:
            t = pygame.time.get_ticks() / 1000.
            dt = t - self.ugly_start_time

            if dt >= self.UGLY_TIME:
                # stop being ugly!
                self.ugly = False
                self.set_animate_keyword("normal")
            elif dt >= (self.UGLY_TIME - self.UGLY_FLICKER_START):
                # still ugly, but flicker
                dt -= (self.UGLY_TIME - self.UGLY_FLICKER_START)
                num = int(math.ceil(dt / self.UGLY_FLICKER_DURATION))

                if (num % 2) == 0:
                    # even = ugly
                    self.set_animate_keyword("ugly")
                else:
                    # odd = normal
                    self.set_animate_keyword("normal")