#
###
# Application: Pycadia
# File:        player.py
# Description: pycadia Player class
# Copyright (c) 2002-2003   Andy Balcombe <http://www.anti-particle.com>
###
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#

#from math import sqrt, pi
import pygame
from pygame.locals import *

from game_state import Point
from actor import Actor

class HitRect(pygame.sprite.Sprite):
    """hit zones"""
    def __init__(self, surf_size, rel_pos, name, lines):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((surf_size)).convert()
        self.rect = self.image.get_rect()
        self.rel_pos = Point(rel_pos)
        self.hit = 0
        self.lines = lines
        self.name = name

    def update(self, player):
        if not self.hit:
            new_pos = player.rotate_point(self.rel_pos, float(player.spin_deg))
            self.rect.centerx = player.pos.x + new_pos.x
            self.rect.centery = player.pos.y + new_pos.y
            if player.consts.DEBUG:
                r1 = glob_screen.blit(glob_background, self.rect, self.rect)
                r2 = glob_screen.blit(self.image, self.rect)


class Player(pygame.sprite.Sprite, Actor):
    """players class"""
    def __init__(self, consts, surf_size, pos, spin_deg, verts, f_lines, r_lines, l_lines, scale, flame, hit_zone_pos, hz_group):
        Actor.__init__(self, consts, surf_size)
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.consts = consts
        self.verts = verts
        self.lines = f_lines + r_lines + l_lines
        self.scale = scale
        self.flame = flame #flame object
        self.reloading = 0
        self.lives = self.consts.PLAYER_LIVES
        self.alive = 1
        self.exploding = 0
        self.damaged = 0
        self.visible = 1
        self.sound = 0
        self.start_spin_deg = self.spin_deg = spin_deg
        self.speed = Point((0.0, 0.0))
        self.mass = 2.5
        self.hyper_timer = 0
        self.pos = Point((pos[0],pos[1]))
        self.start_pos = Point((pos[0],pos[1]))
        self.rect.centerx = self.pos.x
        self.rect.centery = self.pos.y
        #init action flags (keyboard & joystick handling)
        self.left = self.right = self.thrust = self.fire = 0
        #create hit zones
        self.hit_front = HitRect((10,10), (0,5), 'front', f_lines)
        self.hit_right = HitRect((10,10), (-5,-hit_zone_pos), 'right', r_lines)
        self.hit_left = HitRect((10,10), (5,-hit_zone_pos), 'left', l_lines)
        if consts.DEBUG:
            self.hit_front.image.fill((255,255,255)) #white
            self.hit_left.image.fill((255,0,0)) #red
            self.hit_right.image.fill((0,0,255)) #blue
        self.hit_zones = [self.hit_front, self.hit_left, self.hit_right]
        hz_group.add(self.hit_front)
        hz_group.add(self.hit_left)
        hz_group.add(self.hit_right)

    def update(self):
        """move the player in the direction indicated by speed vector"""
        #correct spin
        self.check_spin_limits()
        #speed & gravity
        self.calc_sun_gravity()
        self.pos.x = self.pos.x + self.speed.x
        self.pos.y = self.pos.y + self.speed.y
        #limits
        self.check_position_limits()       
        #update flame pos & spin
        self.flame.spin_deg = self.spin_deg
        self.flame.pos.x = self.pos.x
        self.flame.pos.y = self.pos.y
        #move to new pos
        temp_x = self.pos.x - self.rect.centerx
        temp_y = self.pos.y - self.rect.centery
        self.draw_obj()
        self.rect.move_ip(temp_x, temp_y)
        #update flame
        temp_fx = self.pos.x - self.flame.rect.centerx
        temp_fy = self.pos.y - self.flame.rect.centery
        self.flame.draw_obj()
        self.flame.rect.move_ip(temp_fx, temp_fy)
        #update hit zone rects
        for hz in self.hit_zones:
            hz.update(self)
        
    def calc_speed(self, dT):
        #set initial speed
        if self.damaged:
            accel = (self.consts.SHIP_ACCEL / dT) * 0.33
        else:
            accel = self.consts.SHIP_ACCEL / dT
        speed = Point((0.0, accel))      
        #rotate distance to correct direction
        speed = self.rotate_point(speed, float(self.spin_deg))
        #update object speed
        speed.x = self.speed.x + speed.x
        speed.y = self.speed.y + speed.y
        #range check
        temp_speed = Point((speed.x,speed.y))
        if (temp_speed.x < 0.0): temp_speed.x = -temp_speed.x
        if (temp_speed.y < 0.0): temp_speed.y = -temp_speed.y
        if (((temp_speed.x) > self.consts.SHIP_MAX_SPEED) or ((temp_speed.y) > self.consts.SHIP_MAX_SPEED)):
            if (temp_speed.x > temp_speed.y):
                temp_speed.y = (temp_speed.x * temp_speed.y)/temp_speed.x
                temp_speed.x = self.consts.SHIP_MAX_SPEED
            elif (temp_speed.y > temp_speed.x):
                temp_speed.x = (temp_speed.y * temp_speed.x)/temp_speed.y
                temp_speed.y = self.consts.SHIP_MAX_SPEED
            else:
                temp_speed.x = self.consts.SHIP_MAX_SPEED
                temp_speed.y = self.consts.SHIP_MAX_SPEED
            if (speed.x < 0.0): temp_speed.x = -temp_speed.x
            if (speed.y < 0.0): temp_speed.y = -temp_speed.y
            speed.x = temp_speed.x
            speed.y = temp_speed.y
        #update ship speed
        self.speed.x = speed.x
        self.speed.y = speed.y

    def reset(self, hz_group):
        """reset player stats and positions for next life"""
        self.visible = 1
        self.exploding = 0
        self.damaged = 0
        self.alive = 1
        self.speed.x=0
        self.speed.y=0
        self.pos.x = self.start_pos.x
        self.pos.y = self.start_pos.y
        self.spin_deg = self.start_spin_deg
        hz_group.empty()
        self.lines = []
        for hz in self.hit_zones:
            hz_group.add(hz)
            self.lines += hz.lines
            hz.hit = 0

            
class Flame(pygame.sprite.Sprite, Actor):
    """player ship flames"""
    def __init__(self, consts, surf_size, verts, lines, scale):
        Actor.__init__(self, consts, surf_size)
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.verts = verts
        self.lines = lines
        self.scale = scale
        self.visible = 0
        self.brightness = consts.MAX_BRIGHT
        self.spin_deg = 0
        self.speed = Point((0.0,0.0))
        self.mass = 0
        self.pos = Point((0,0))
        self.rect.centerx = 0
        self.rect.centery = 0

    def update(self):
        #see player.update() 
        pass

