#
###
# Application: Pycadia
# File:        explosion.py
# Description: pycadia Explosion classes
# 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
from random import Random
import pygame
from pygame.locals import *

from game_state import Point
from actor import Actor

class Debris(pygame.sprite.Sprite, Actor):
    """debris field from explosion"""
    def __init__(self, consts, pos, speed, spin_deg, spin_rate, verts, lines, life):
        Actor.__init__(self, consts, (20,20))
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.rect = self.image.get_rect()
        self.pos = pos
        self.speed = speed
        self.spin_deg = spin_deg
        self.spin_rate = spin_rate
        self.verts = verts
        self.lines = lines
        self.visible = 1
        self.scale = 1.0
        self.life = life
        self.brightness = consts.MAX_BRIGHT

    def update(self):
        self.life=self.life-1
        if self.life <= 0:
            self.kill()
            return
        self.pos.x += self.speed.x
        self.pos.y += self.speed.y
        #self.calc_sun_gravity()
        temp_x = self.pos.x - self.rect.centerx
        temp_y = self.pos.y - self.rect.centery
        self.check_position_limits()
        self.spin_deg += self.spin_rate
        self.check_spin_limits()
        #redraw
        self.rect.move_ip(temp_x, temp_y)
        self.draw_obj()


class Explode(pygame.sprite.Sprite, Actor):
    """explode an object"""
    def __init__(self, consts, obj, lines, spin_life, debris_life, debris):
        Actor.__init__(self, consts, obj.rect.size)
        pygame.sprite.Sprite.__init__(self, self.containers)
        self.visible = 1
        self.life = spin_life 
        self.debris_life = debris_life
        self.pos = Point((obj.pos.x, obj.pos.y))
        self.speed = Point((obj.speed.x, obj.speed.y))
        self.spin_deg = obj.spin_deg
        self.verts = obj.verts
        self.lines = lines
        self.scale = obj.scale
        self.init_brightness = consts.MAX_BRIGHT
        self.expl_brightness = consts.MAX_BRIGHT-50
        self.rnd = Random()
        self.spin_rate = self.rnd.randrange(-consts.SHIP_ROTATE_SPEED*3, consts.SHIP_ROTATE_SPEED*3, 3)
        self.debris = debris
        
    def update(self):
        #finished?
        self.life=self.life-1
        if self.life <= 0:
            #create debris objects
            lines = [(0,1)]
            debrisMaxSpeed = 0.4
            for i in range(len(self.lines)):
                #get initial points...
                xfrom1 = self.verts[self.lines[i][0]][0] 
                yfrom1 = self.verts[self.lines[i][0]][1] 
                xto1 = self.verts[self.lines[i][1]][0] 
                yto1 = self.verts[self.lines[i][1]][1] 
                verts=[(xfrom1, yfrom1), (xto1, yto1)]
                #calc midpoint
                xmid = (xfrom1 + xto1) / 2
                ymid = (yfrom1 + yto1) / 2
                #calc length
                length = (sqrt((xmid*xmid) + (ymid*ymid)))
                #if length == 0:
                #    print 'eeep - length =0'
                #    print 'from=',xfrom1,yfrom1,' to=',xto1,yto1
                #divide the vector by it's length to get the unit vector
                unitx = (xmid / length) * debrisMaxSpeed
                unity = (ymid / length) * debrisMaxSpeed
                #set pos
                pos = Point((self.pos.x+xmid, self.pos.y+ymid))
                #set a random spin direction
                spin_rate = self.rnd.randrange(-self.consts.SHIP_ROTATE_SPEED, self.consts.SHIP_ROTATE_SPEED, 1)
                #set speed - send the debris piece in the direction of its unit vector
                speed=Point((unitx, unity))
                #add current ship speed
                speed.x += self.speed.x
                speed.y += self.speed.y
                #create debris
                self.debris.add(Debris(self.consts, pos, speed, self.spin_deg, spin_rate, verts, lines, self.debris_life))
            self.kill()
            return
        if self.life > 0:
            #update pos
            self.pos.x += self.speed.x
            self.pos.y += self.speed.y
            #self.calc_sun_gravity()
            temp_x = self.pos.x - self.rect.centerx
            temp_y = self.pos.y - self.rect.centery
            self.check_position_limits()
            #display ship brighter
            self.brightness = self.init_brightness
            self.spin_deg += self.spin_rate
            self.check_spin_limits()
            #display it
            self.rect.move_ip(temp_x, temp_y)
            self.draw_obj()

