import pygame
from pygame.locals import *
import math
import time

from map import *
from character import Character
from gui import Gui
from locals import *
from zombie import Zombie
import util

def run(screen):
    mode = 0

    maps = {}

    map = load_map("base")
    maps["base"] = map

    spawnpoint = map.getspawn("default")

    characters = []

    char = Character("ilmarinen", (spawnpoint[0]+0.5, spawnpoint[1]))
    map.objects.append(char)
    characters.append(char)

    char = Character("walker", (spawnpoint[0]-0.5, spawnpoint[1]))
    map.objects.append(char)
    characters.append(char)
    
    char.selected = True

    #Loading GUI as a separate class now
    gui = Gui(screen)

    load_tilesets()

    done = False
    lost = False
    victory = False

    dy = 0
    dx = 0
    x =300
    y = 50

    at_spawnpoint = None

    paused = False

    #background = pygame.image.load("images/background.png")

    lastupdate = pygame.time.get_ticks()
    while not done:
        if char.dead:
            #This is mostly duplicate code...
            choose_next = False
            first_usable_found = None
            chartouse = None
            for c in characters:
               if not c.dead:
                   if not first_usable_found:
                      first_usable_found = c
                   if choose_next:
                      chartouse = c
                      choose_next = False
                   if c.selected:
                      choose_next = True
            char.selected = False
            if chartouse:
               chartouse.selected = True
               char = chartouse
            else:
               if first_usable_found:
                   first_usable_found.selected = True
                   char = first_usable_found
               elif not lost:
                   print "player lost."
                   lost = True
                   return get_score(0)
        screen.fill((0,0,0))
        #for xx in range(0, 800, background.get_width()):
        #    for yy in range(0, 600, background.get_height()):
        #        screen.blit(background, (xx,yy))

        for e in pygame.event.get():
            if e.type == QUIT:
                done = True
            elif e.type == KEYDOWN and e.key == K_ESCAPE:
                done = True
            elif e.type == KEYDOWN and e.key == K_s:
                tmp = pygame.Surface((SCREENWIDTH,SCREENHEIGHT)).convert()
                tmp.blit(screen,(0,0))
                pygame.image.save(tmp, "sshot.tga")
            elif e.type == MOUSEBUTTONDOWN:
                if e.button == 1:
                    #print get_map_pos((x,y), e.pos)
                    if (e.pos[1] > screen.get_height() - gui.rect.height):
                      obj = gui.click(e.pos, characters)
                    else:
                      obj = map.select_object((x,y), e.pos)
                    if obj:# and ((not obj.is_walkover()) or obj.objtype == TYPE_SPAWNPOINT):
                        if (obj.objtype == TYPE_CHARACTER) and (not obj.dead):
                           char.selected = False
                           obj.selected = True
                           char = obj
                elif e.button == 3:
                    obj = map.select_object((x,y), e.pos)
                    if obj and char.selected and (not char.dead) and ((not obj.is_walkover()) or obj.objtype == TYPE_SPAWNPOINT):
                        if obj.name == "zombie":
                            #if char.iteminuse.itemtype == "weapon_ranged":
                              char.attack(map, obj)
                              # the character should be smart enough to keep
                              # shooting even if the player stops controlling
                              # the character. the character has an attacktarget variable,
                              # and tries to do stuff to it until it is dead. (attacktarget.dead)
                            #if char.iteminuse.itemtype == "weapon_melee":
                              # char should have a melee attack capability, now it just (tries to walk) walks up to the zombie
                              #char.move_to(map, obj.pos)
                        #Duplicate code
                        if obj.objtype == TYPE_SPAWNPOINT:
			    if at_spawnpoint == obj and obj.spawn_to == "victory":
				if not victory:
				    victory = True
				    Score.objectives_met += 1
                            elif at_spawnpoint == obj:
                                if not maps.has_key(obj.spawn_to):
                                    maps[obj.spawn_to] = load_map(obj.spawn_to)
                                oldmap = map
                                map = maps[obj.spawn_to]
                                spawnpoint = map.getspawn(oldmap.name)
                                if not characters[0].dead:
                                    characters[0].pos = [spawnpoint[0], spawnpoint[1]+0.5]
                                    characters[0].stop()
                                    map.objects.append(characters[0])
                                    oldmap.objects.remove(characters[0])
                                if not characters[1].dead:
                                    characters[1].pos = [spawnpoint[0]+0.5, spawnpoint[1]]
                                    characters[0].stop()
                                    map.objects.append(characters[1])
                                    oldmap.objects.remove(characters[1])
				pos = get_screen_pos((0.0,0.0), (spawnpoint[0], spawnpoint[1]))
				x = -pos[0] + SCREENWIDTH/2
				y = -pos[1] + SCREENHEIGHT/2
                        if obj.objtype == TYPE_OBJECT:
                            if char.distance(obj) < 2:
                                if len(obj.inventory) > 0:
                                    for stuff in obj.inventory:
                                        for stuff2 in char.inventory:
                                            if stuff.name == stuff2.name:
                                                stuff2.amount += stuff.amount
                                                obj.inventory.remove(stuff)
                                                break
                                    for stuff in obj.inventory:
                                        char.inventory.append(stuff)
                                        obj.inventory.remove(stuff)
                                    obj.set_animation("empty")

                    elif char.selected and (not char.dead) and (not (e.pos[1] > screen.get_height() - gui.rect.height)):
                        char.attacktarget = None
                        char.targetobj = None
                        char.move_to(map, get_map_pos((x,y), e.pos))

            elif e.type == MOUSEMOTION:
                if pygame.mouse.get_pressed()[1]:
                    x += e.rel[0]
                    y += e.rel[1]
            elif e.type is KEYDOWN and e.key == K_F10:
                tmp = pygame.Surface((SCREENWIDTH,SCREENHEIGHT)).convert()
                tmp.blit(screen,(0,0))
                mode ^= FULLSCREEN
                screen = pygame.display.set_mode((SCREENWIDTH,SCREENHEIGHT),mode)
                screen.blit(tmp,(0,0))
                pygame.display.flip()
            if e.type is KEYDOWN and e.key == K_TAB:
                choose_next = False
                first_usable_found = None
                chartouse = None
                for c in characters:
                   if not c.dead:
                       if not first_usable_found:
                          first_usable_found = c
                       if choose_next:
                          chartouse = c
                          choose_next = False
                       if c.selected:
                          choose_next = True
                char.selected = False
                if chartouse:
                   chartouse.selected = True
                   char = chartouse
                else:
                   if first_usable_found:
                       first_usable_found.selected = True
                       char = first_usable_found
            elif e.type is KEYDOWN and e.key == K_LSHIFT:
                char.switch_item()
            elif e.type is KEYDOWN and e.key == K_SPACE:
                char.stop()
            elif e.type is KEYDOWN:
                if e.key == K_LEFT:
                    dx -= 10
                elif e.key == K_RIGHT:
                    dx += 10
                elif e.key == K_UP:
                    dy -= 10
                elif e.key == K_DOWN:
                    dy += 10
            elif e.type is KEYUP:
                if e.key == K_LEFT:
                    dx += 10
                elif e.key == K_RIGHT:
                    dx -= 10
                elif e.key == K_UP:
                    dy += 10
                elif e.key == K_DOWN:
                    dy -= 10

        x -= dx
        y -= dy

        if gui.panicbutton_state == 2:
            paused = not paused

        if not paused and not victory:
            map.update()

        map.draw(screen, (x,y), characters)

        #char.update()
        #char.draw(screen, (x,y))

        #Drawing GUI
        gui.draw(screen, characters)

	if paused:
            surf = util.bigfont.render("Tauko. Älä hätäile.", True, COLOR1)
	    rect = surf.get_rect()
	    rect.center = screen.get_rect().center
	    screen.blit(surf,rect)

	if victory:
	    surf = util.bigfont.render("Voitto!", True, COLOR1)
	    rect = surf.get_rect()
	    rect.center = screen.get_rect().center
	    screen.blit(surf, rect)
	    surf = util.bigfont.render("Paina Esciä.", True, COLOR1)
	    rect2 = surf.get_rect()
	    rect2.centerx = rect.centerx
	    rect2.top = rect.bottom
	    screen.blit(surf, rect2)

        at_spawnpoint = None
        for s in map.spawnpoints:
            if s.spawn_to == "default":
                continue
            near = 0
            for c in characters:
                if c.distance(s) < 2 or c.dead:
                    near += 1
            if near == len(characters):
                at_spawnpoint = s

        for c in characters:
            if c.dead and c.death_time != -1:
                if pygame.time.get_ticks() - c.death_time > CHAR_ZOMBIFICATION_DELAY * 1000:
                    map.objects.append(Zombie("zombie", c.pos))
                    c.death_time = -1

        pygame.display.flip()
        sleeptime = (1000 / FPS - (pygame.time.get_ticks() - lastupdate)) * 0.001
        if sleeptime > 0:
           time.sleep(sleeptime)
        lastupdate = pygame.time.get_ticks()
    return get_score(len(characters))

if __name__ == "__main__":
    pygame.init()

    screen = pygame.display.set_mode((SCREENWIDTH,SCREENHEIGHT))
    
    run(screen)
