from background import *
from floortile import *
from man import *
from woman import *
from collectible import *
from score_object import *

class Level(object):
    FPS = 80

    LEVEL_RESULT_QUIT = 0
    LEVEL_RESULT_WIN = 1
    LEVEL_RESULT_LOSE = 2

    def __init__(self, game, level_filename, screen):
        self.game = game
        
        self.screen = screen
        self.offset = 0

        self.lost = False
        self.won = False

        self.num_potions = 0

        self.background = Background(WINDOW_SIZE)

        self.score_objects = pygame.sprite.RenderUpdates()
        img = DollarScoreImage(self, 2, 0)
        self.score_objects.add(img)
        self.score_objects.add(DollarScoreCounter(self, img))
        img = PotionScoreImage(self, 7, 0)
        self.score_objects.add(img)
        self.score_objects.add(PotionScoreCounter(self, img))

        for s in self.score_objects:
            s.rect = s.arect # Forever.

        # Load level from file...
        rows = [row.rstrip() for row in
                file(os.path.join("data", level_filename), "r").readlines()]

        self.level_width = max([len(row) for row in rows]) * TILE_WIDTH

        self.walls = pygame.sprite.RenderUpdates()
        self.decals = pygame.sprite.RenderUpdates()
        self.women = pygame.sprite.RenderUpdates()
        self.men = pygame.sprite.RenderUpdates()
        self.collectibles = pygame.sprite.RenderUpdates()

        for rownum, row in enumerate(rows):
            for colnum, col in enumerate(row):
                if col == '#':
                    self.walls.add(Wall(self, colnum, rownum))
                elif col == '%':
                    self.walls.add(Floor(self, colnum, rownum))
                elif col == 'H':
                    self.decals.add(House(self, colnum, rownum))
                elif col == '1':
                    self.decals.add(HelpText("Arrow keys or W/A/D", self, colnum, rownum))
                elif col == '2':
                    self.decals.add(HelpText("to move and jump", self, colnum, rownum))
                elif col == '3':
                    self.decals.add(HelpText("Space to use ugliness potion", self, colnum, rownum))
                elif col == '4':
                    self.decals.add(HelpText("Take girls' money while under its effect", self, colnum, rownum))
                elif col == '5':
                    self.decals.add(HelpText("You need $5,000 to enter.", self, colnum, rownum))
                elif col == '6':
                    self.decals.add(HelpText("The potion makes you kind of evil.", self, colnum, rownum))
                elif col == 'P':
                    self.man = Man(self, colnum, rownum)
                    self.men.add(self.man)
                elif col == 'W':
                    self.women.add(Woman.random()(self, colnum, rownum))
                elif col == 'p':
                    self.collectibles.add(Potion(self, colnum, rownum))
                elif col == 'E':
                    self.collectibles.add(EndLevel(self, colnum, rownum))
                elif col == 'S':
                    self.collectibles.add(StripClub(self, colnum, rownum))
                elif col == '$':
                    self.collectibles.add(Dollar(self, colnum, rownum))

    def update_rect_from_arect(self, sprite):
        sprite.rect = sprite.arect.move(self.offset, 0)

    def update_screen_offset(self):
        # First, set the offset so that "man" is centered
        self.offset = (WINDOW_WIDTH / 2) - self.man.arect.centerx

        # Correction in case we're too far to the left
        if self.offset > 0:
            self.offset = 0

        # Correction in case we're too far to the right
        if self.offset < WINDOW_WIDTH - self.level_width:
            self.offset = WINDOW_WIDTH - self.level_width

    def lose(self, girl):
        self.lost_girl = girl
        self.lost = True

    def win(self):
        self.won = True
        
    def loop(self):
        # Draw background
        self.background.draw(self.screen)
        pygame.display.update() # 1st time for the background to draw
        
        clock = pygame.time.Clock()

        while True:
            update_rects = []
            
            # Handle events
            for event in pygame.event.get():
                if not self.handle_event(event):
                    return self.LEVEL_RESULT_QUIT
            
            # Update & draw the objects
            self.background.draw(self.screen)

            self.men.update()
            self.women.update()
            self.walls.update()
            self.decals.update()
            self.score_objects.update()
            self.collectibles.update()

            self.update_screen_offset()
            [self.update_rect_from_arect(s) for s in self.men]
            [self.update_rect_from_arect(s) for s in self.women]
            [self.update_rect_from_arect(s) for s in self.walls]
            [self.update_rect_from_arect(s) for s in self.decals]
            # Skip self.score_objects
            [self.update_rect_from_arect(s) for s in self.collectibles]

            update_rects += self.walls.draw(self.screen)
            update_rects += self.decals.draw(self.screen)
            update_rects += self.collectibles.draw(self.screen)
            update_rects += self.women.draw(self.screen)
            update_rects += self.men.draw(self.screen)
            update_rects += self.score_objects.draw(self.screen) # Above everything

            # Refresh screen
            pygame.display.update(update_rects)

            if self.lost:
                return self.LEVEL_RESULT_LOSE
            elif self.won:
                return self.LEVEL_RESULT_WIN

            # Wait a tick
            clock.tick(self.FPS)
    
    def handle_event(self, event):
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            return False

        elif event.type == KEYDOWN and (event.key == K_LEFT or event.key == K_a):
            self.man.start_move_left()

        elif event.type == KEYDOWN and (event.key == K_RIGHT or event.key == K_d):
            self.man.start_move_right()

        elif event.type == KEYUP and (event.key == K_LEFT or event.key == K_a):
            self.man.stop_move_left()

        elif event.type == KEYUP and (event.key == K_RIGHT or event.key == K_d):
            self.man.stop_move_right()

        elif event.type == KEYDOWN and (event.key == K_UP or event.key == K_w):
            self.man.jump()

        elif event.type == KEYDOWN and (event.key == K_SPACE):
            self.man.uglify()

        return True

    def potion_up(self):
        self.num_potions += 1