/* $Id$
 *
 * Copyright (c) 1999 Xenonsoft Limited. All Rights Reserved.
 *
 * This software is protected by copyright. You are hereby notified from
 * now by reading this message. This software is also the confidential 
 * and proprietary information of Xenonsoft Limited.  ("Confidential
 * Information"). 
 *
 * This software is distributed under the Xenonsoft Public end user 
 * License ("XPeL"), where the machine-readable source code is provided 
 * under the "Open Source" model.
 * For more information, please read the file "LICENSE-XPL.txt" 
 */

// File:`Explosion.java'
//
//
// DESCRIPTION
//	Explosion
// 
// Author
//
//	Peter Pilgrim
//	Fri Jun 19 00:09:21 BST 1998
// 
// RCS HEADER ``Explosion.java''
// 
//	$Author$
//	$Date$
//	$Source$
//	$Revision$    $State$    $Locker$
//

package xenon.humanoid;

import java.awt.*;
import java.awt.event.*;

import xenon.gamekit.*;				// for GameEngine, WorldObject, etc
import xenon.soundkit.*;			// for SoundEngine, PPMCAudioPlayer, etc

/**
 * This class is another world object but animate the Explosion effect
 * where a starship or other entity suddenly appears to be
 * materialising before your very eyes.
 *
 * This object is special because it <em>carrys a surrogate</em> world
 * object. When the materialising is done, the Explosion object
 * disappears, and the <em>surrogate</em> appears.
 *
 * @author Peter Pilgrim
 * @version Fri May 21 00:35:51 BST 1999 */
public class Explosion extends WorldObject
{
    public final static int	NUMBER_POINTS=12;
    public final static int	FRAME_COUNT=24;
    
    protected static Envelope	env1=null, env2=null;
    protected static SoundEngine se1=null, se2=null;


    protected WorldObject	surrogate;	// surrogate

    protected Point []		points;		// points
    protected Point []		velocity;	// velocity of the points
    protected Color		color;
    protected int		initialDelay;	// initial delay before animation

    protected int		frameCount;	// Number of frames for the animation    

    protected boolean		exploded=false;
    
    public Explosion( GameEngine gameEngine, WorldObject surrogate,
		      int wx, int wy, Color color )
    {
	this( gameEngine, surrogate, wx, wy, color, 0 );
    }
    
    public Explosion( GameEngine gameEngine, WorldObject surrogate,
		      int wx, int wy, Color color, int initialDelay )
    {
	super( gameEngine );

	if (initialDelay < 1) initialDelay=0;

	this.surrogate = surrogate;
	this.wx = wx;
	this.wy = wy;
	this.color = color;
	this.initialDelay = initialDelay;
	
	frameCount = FRAME_COUNT;
	points = new Point[NUMBER_POINTS];
	for (int j=0; j<points.length ; ++j)
	    points[j] = new Point( 0, 0 );
    }

    public boolean loadAudioClips()
    {
	// FIXME: whoosh sound
	if (env1 == null ) {
	    /* 
	       public Envelope( int pitch_step_unit, 
		     int pi1, int pn1, int pi2, int pn2, int pi3, int pn3,
		     int amplitude_step_unit , 
		     int ad, int an, int dd, int dn, int sd, int sn, int rd, int rn ) 
	       public SoundEngine( int sampling_rate, double time_duration, 
			int volume, int pitch, int duration,
			Wave wave, Envelope envelope )
	    */
	    env1 = new Envelope( 
		1,  4,2, -4,4, 8,4,     1, 25 ,7, -1, 10, 0, 0, -2, 128 );
	    
	    se1 = new SoundEngine( 
		8000, 1.11, 
		85, 225, 70,
		StaticWave.SQUARE_WAVE, env1 );
	    se1.setFlags( se1.getFlags() | SoundEngine.NOISE_MIX_GATE_FLAG );
	    se1.makeWave();
	}
	
	return (true);
    }
    
    public WorldObject getSurrogate()
    {
	return (surrogate);
    }
    
    public void setSurrogate( WorldObject newSurrogate )
    {
	surrogate = newSurrogate;
    }

    public WorldObject update()
    {
	if ( initialDelay > 0 ) {
	    // Ignore update until initial delay is passed
	    --initialDelay;
	    return (this);
	}
	
	if ( !exploded ) {
	    points = new Point[NUMBER_POINTS];
		velocity = new Point[NUMBER_POINTS];
	    int xrange = 3 * gameEngine.screen_width / 2;
	    int yrange = 2 * gameEngine.screen_height / 3;
	    int xpos, ypos, xdelta, ydelta;
	    for ( int j=0; j<NUMBER_POINTS; ++j) {
		xpos = (int)((Math.random() - 0.5) * xrange );
		// xpos = ( j < NUMBER_POINTS/2 ?  300 : -300 );
		// THIS IS THE CLASSIC EFFECT
		ypos = (int)((Math.random() - 0.5) * yrange );
		points[j] = new Point( 0, 0 );
		xdelta = xpos / frameCount;
		ydelta = ypos / frameCount;
		velocity[j] = new Point( xdelta, ydelta );
	    }

	    PPMCAudioPlayer mcap = gameEngine.getMCAudioPlayer();
	    mcap.play( 8, se1.getSoundData() );

	    exploded = true;			/* !!! */
	}
	else {
	    wx += dx_vel;
	    wy += dy_vel;

	    for ( int j=0; j<NUMBER_POINTS; ++j) {
		points[j].x += velocity[j].x;
		points[j].y += velocity[j].y;
	    }

	    if (frameCount == 0 ) {
		// The Explosion destroys itself and adds the surrogate
		// world object to the game engine.
		destroy();
		if ( surrogate != null ) {
		    gameEngine.addWorldObject( surrogate );
		    // surrogate.wx = wx;
		    // surrogate.wy = wy;
		    surrogate.setVisible( true );
		    surrogate.setActive( true );
		}
	    }

	    if (frameCount > 0 ) --frameCount;
	}
	
	return (this);
    }
    
    public WorldObject  drawObject( Graphics g )
    {
	// paint the Explosion
	if ( isVisible() && exploded ) {

	    translateWorldToScreen();

	    g.setColor( color );
	    for ( int j=0; j<NUMBER_POINTS; ++j) {
		g.fillRect( scrx + points[j].x, scry + points[j].y, 2, 2 );
	    }
	}

	return (this);
    }


    /** Returns a boolean true if this object can be seen byte the radar */
    public boolean isRadarable()
    {
	return (false);
    }
}

// fini
