"""
player.py - Player class
"""

import sys,os
import common
import object,levels
import shotA,shotC,shotE,shotG
import shieldA
import pygame,pygame.image
import explosionC
from pygame.locals import *

class Player(object.Object):

    def __init__(self,rect):
        object.Object.__init__(self,rect,100-common.diff*30)
        self.images    = common.images['Player']
        self.last_rect = rect
        self.speed     = 4
        self.lives     = 3
        self.moving    = 0
        self.invincible = 0
        self.maxshield = 80-common.diff*25
        self.shield    = self.maxshield
        self.maxhealth = 100-common.diff*30
        self.weapons    = [{ 'Delay':1,
                             'Type' :0,
                             'Level':0 }]
        self.points    = 0
        self.text_font = pygame.font.Font('bluebold.ttf', 16)
        self.healthbar = pygame.Surface((10,common.resolution[1])).convert()
        self.shieldbar = pygame.Surface((10,common.resolution[1])).convert() 
        self.healthbar.fill((255,0,0))
        self.healthbar.set_alpha(128)
        self.shieldbar.fill((0,0,255))
        self.shieldbar.set_alpha(128)
        self.ship_small = pygame.image.load("images%sship_small.gif"%os.sep).convert()
        self.ship_small.set_colorkey((0,0,0))
        self.ship_small.set_alpha(128)

    # from object.py
    def show(self):
        self.showPoints()
        if self.alive <= 0: return []
        self.showHealthBar()
        r = common.screen.blit(self.currentImage(),self.rect)
        return self.optimizeDirtyRect(r)

    # from object.py
    def hide(self):
        res = common.resolution
        r = (10,res[1]-20,128,16)
        common.screen.blit(common.current_bg, r, r)
        if self.alive <= 0: return
        self.last_rect = common.screen.blit(common.current_bg, self.rect, self.rect)
        r = (res[0]-20,0,res[0],res[1])
        common.screen.blit(common.current_bg, r, r)        

    # from object.py
    def move(self):
        if self.invincible:
            self.invincible -= 1
        if self.alive <= 0:
            self.restart_time -= 1
            if self.restart_time <= 0:
                self.nextLife()
            else: return
        self.moving = 0
        if common.key_state[K_DOWN]:
            self.moving = 1
            self.rect[1] += self.speed
            if self.rect[1]+self.rect[3] > common.resolution[1]:
                self.rect[1] = common.resolution[1]-self.rect[3]
        if common.key_state[K_UP]:
            self.moving = 1
            self.rect[1] -= self.speed
            if self.rect[1] < 0:
                self.rect[1] = 0
        if common.key_state[K_RIGHT]:
            self.moving = 3
            self.rect[0] += self.speed
            if self.rect[0]+self.rect[2] > common.resolution[0]:
                self.rect[0] = common.resolution[0]-self.rect[2]
        if common.key_state[K_LEFT]:
            self.moving = 2
            self.rect[0] -= self.speed
            if self.rect[0] < 0:
                self.rect[0] = 0        
        if common.key_state[K_SPACE]:
            self.shoot()
        else:
            for w in self.weapons:
                w['Delay'] -= 1
                if w['Delay'] < 0:
                    w['Delay'] = 0

    # from object.py
    def currentImage(self):
        return self.images[self.moving]

    def addPoints(self,points):
        self.points += points

    def shoot(self):
        r = self.rect
        for w in self.weapons:
            w['Delay'] -= 1
            if w['Delay'] <= 0:
                if w['Type'] == 0:
                    if w['Level'] == 0:
                        w['Delay'] = 5
                        shotA.ShotA([r[0]+r[2]/2-8,r[1]+5],0)                        
                    elif w['Level'] == 1:
                        w['Delay'] = 4
                        shotA.ShotA([r[0]+r[2]/2-18,r[1]+5],1)
                        shotA.ShotA([r[0]+r[2]/2+2,r[1]+5],1)
                elif w['Type'] == 1:
                    w['Delay'] = 15
                    if w['Level'] == 0:                        
                        shotC.ShotC([r[0]+r[2]/2,r[1]],0)
                    elif w['Level'] == 1:
                        shotC.ShotC([r[0]+r[2]/2-3,r[1]],1)
                        shotC.ShotC([r[0]+r[2]/2+3,r[1]],1)
                elif w['Type'] == 2:                    
                    if w['Level'] == 0:
                        w['Delay'] = 10
                    elif w['Level'] == 1:
                        w['Delay'] = 5
                    shotE.ShotE([r[0],r[1]+r[3]/2],-1,0)
                    shotE.ShotE([r[0]+r[2],r[1]+r[3]/2],1,0)
                elif w['Type'] == 3:
                    w['Delay'] = 50
                    if w['Level'] == 0:
                        shotG.ShotG([r[0],r[1]+r[3]/2],0)
                    elif w['Level'] == 1:
                        shotG.ShotG([r[0],r[1]+r[3]/2-3],0)
                        shotG.ShotG([r[0],r[1]+r[3]/2+3],0)
                
    def gotHit(self,shot):
        if self.invincible: return
        if self.shield:
            self.shield -= shot.damage
            if self.shield < 0: self.shield = 0
            shieldA.ShieldA(self.rect[:2])
        else:
            self.alive -= shot.damage
            if self.alive <= 0:
                self.alive = 0
                self.kill()
                if self.lives <= 0:
                    print "G A M E   O V E R  !"
                    common.game_finished = 1

    def showHealthBar(self):
        p = self.alive / float(self.maxhealth)
        res = common.resolution
        height = res[1]*p        
        common.screen.blit(self.healthbar,(res[0]-10,res[1]-height),(0,res[1]-height,10,res[1]))
        if self.shield:
            p = self.shield/float(self.maxshield)
            height = res[1]*p
            common.screen.blit(self.shieldbar,(res[0]-20,res[1]-height),(0,res[1]-height,10,res[1]))
        pygame.display.update((res[0]-20,0,res[0],res[1]))
        res = common.resolution
        live_rect = (res[0]-50-15*self.lives,res[1]-25,15*(self.lives+1),25)
        common.screen.blit(common.current_bg,live_rect,live_rect)
        for x in range(self.lives):
            common.screen.blit(self.ship_small,(res[0]-50-x*15,res[1]-25))
        pygame.display.update(live_rect)

    def showPoints(self):
        tmp = self.text_font.render(`self.points`,1,(0,255,0),(0,0,0)).convert()
        tmp.set_colorkey((0,0,0))
        tmp.set_alpha(192)
        pygame.display.update(common.screen.blit(tmp, (10,common.resolution[1]-20)))

    def gotGoodie(self, goodie):
        # goodieAs are working equally
        # first level upgrade if possible
        # else weapon upgrade if possible
        # and if everything else fails the goodies
        # will fill up the shields again by a
        # certain amount :)
        if goodie.type == 0: # goodieA
            for w in self.weapons:
                if w['Level'] == 0:
                    w['Level'] = 1
                    return
            if len(self.weapons) < levels.level:
                self.weapons.append({'Delay':1,
                                     'Type':len(self.weapons),
                                     'Level':0})
                return
            # now improve shield
            self.shield += 5
            if self.shield > self.maxshield:
                self.shield = self.maxshield
            
    def kill(self):
        r = self.rect
        self.hide()
        r = self.optimizeDirtyRect(r)
        pygame.display.update(r)

        self.showHealthBar()
        
        self.explode()
        common.sound.big_explode()
        
        self.lives -= 1
        self.restart_time = 150

    def explode(self):
        explosionC.ExplosionC(self.rect[:2],5)
        explosionC.ExplosionC([self.rect[0]+20,self.rect[1]+25],4)

    def nextLife(self):
        self.alive   = self.maxhealth
        self.shield  = self.maxshield
        self.rect[0] = 300
        self.rect[1] = common.resolution[1]-40
        self.last_rect = self.rect
        self.invincible = 50
