/* $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:`PlanetExplosion.java'
//
//
// DESCRIPTION
//	Planet Explosion
// 
// Author:
//
//	Peter Pilgrim
//	Fri Jun 04 00:03:21 BST 1999
// 
// RCS HEADER ``PlanetExplosion.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 PlanetExplosion 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 PlanetExplosion object
 * disappears, and the <em>surrogate</em> appears.
 *
 * @author Peter Pilgrim
 * @version Fri May 21 00:35:51 BST 1999 */
public class PlanetExplosion extends WorldObject
{
    public final static int	FRAME_COUNT=50;
    
    protected static Envelope	env1=null;
    protected static SoundEngine se1=null;

    protected ShredLine	[]	shreds;
    protected int		radius;    
    protected int		delta_radius;
    protected WorldObject	surrogate;	// surrogate
    protected Runnable		runnable;

    
    protected int		initialDelay;	// initial delay before animation

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

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

	if (initialDelay < 1) initialDelay=0;

	this.surrogate = surrogate;
	this.wx = wx;
	this.wy = wy;
	this.frameCount = frameCount;

	color = Color.red;
	shreds = new ShredLine[12];
	for (int j=0; j<shreds.length; ++j) 
	    shreds[j] = new ShredLine();
    }

    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,4, 6,4, 24,4,     1, 25 ,7, -1, 10, 0, 0, -2, 128 );
	    
	    se1 = new SoundEngine( 
		8000, 1.50, 
		85, 432, 95,
		StaticWave.SINE_WAVE, env1 );
	    se1.setFlags( se1.getFlags() | SoundEngine.NOISE_MIX_GATE_FLAG );
	    se1.makeWave();
	}
	
	return (true);
    }
    
    public void setSurrogate( WorldObject newSurrogate )
    {
	surrogate = newSurrogate;
    }

    public WorldObject getSurrogate()
    {
	return (surrogate);
    }

    public WorldObject update()
    {
	if ( initialDelay > 0 ) {
	    // Ignore update until initial delay is passed
	    --initialDelay;
	    return (this);
	}
	
	if ( !exploded ) {
	    PPMCAudioPlayer mcap = gameEngine.getMCAudioPlayer();
	    mcap.play( 6, se1.getSoundData() );

	    exploded = true;			/* !!! */
	}
	else {
	    if (frameCount == 0 ) {
		// The PlanetExplosion 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 );
		}
	    }

	    for (int j=0; j<shreds.length; ++j) 
		shreds[j].update();

	    if ( frameCount < 10 )
		color = Color.orange;
	    else if ( frameCount >= 10 && frameCount < 20 )
		color = Color.cyan;
	    else if ( frameCount >= 20 && frameCount < 30 )
		color = Color.magenta;
	    else 
		color = Color.red;
	    
	    if (frameCount % 10 == 0 ) {
		for (int q=0; q<4; ++q ) {
		    int xpos = gameEngine.world_xpos + 
			(int)( Math.random() * 400.0 - 200 );
		    int ypos = (int)( Math.random() * 50 );
		    Explosion explosion = new Explosion( 
			gameEngine, null, xpos, ypos, color );
		    gameEngine.addWorldObject( explosion );
		}
		for (int q=0; q<7; ++q ) {
		    int xpos = gameEngine.world_xpos + 
			(int)( Math.random() * 800.0 - 400.0 );
		    int ypos = (int)( Math.random() * 50 );
		    OvalExplosion explosion = new OvalExplosion( 
			gameEngine, null, xpos, ypos, color, 0, 12 );
		    explosion.setInnerColor( Color.yellow );
		    gameEngine.addWorldObject( explosion );
		}

		PPMCAudioPlayer mcap = gameEngine.getMCAudioPlayer();
		mcap.play( 6, se1.getSoundData() );
	    }
	    
	    if (frameCount > 0 ) --frameCount;
	}
	
	return (this);
    }
    
    public WorldObject  drawObject( Graphics g )
    {
	// paint the PlanetExplosion
	if ( isVisible() && exploded ) {

	    g.setColor( color );
	    for (int j=0; j<shreds.length; ++j) 
		shreds[j].paint( g);
	}

	return (this);
    }


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


    // =========================================================================
    // I N N E R   C L A S S E S
    // =========================================================================

    /** Planet Explosion's Shred */
    protected class ShredLine {
	private Point p1, p2;			// point position
	private Point vel1, vel2;		// velocity
	
	protected ShredLine() 
	{
	    p1 = new Point();
	    p2 = new Point();
	    vel1 = new Point();
	    vel2 = new Point();
	    
	    init();
	}
	
	protected void init()	
	{
	    p1.x = (int)(Math.random() * gameEngine.screen_width);
	    p1.y = gameEngine.screen_height-64;

	    p2.x = (int)(Math.random() * gameEngine.screen_width);
	    p2.y = gameEngine.screen_height-64;

	    vel1.x = (int)(Math.random() * 10.0 - 5.0 );
	    vel1.y = (int)(Math.random() * -10.0 - 5.0 );

	    vel2.x = (int)(Math.random() * 10.0 - 5.0 );
	    vel2.y = (int)(Math.random() * -10.0 - 5.0 );
	}
	
	public void update() 
	{
	    p1.x += vel1.x;
	    p1.y += vel1.y;
	    p2.x += vel2.x;
	    p2.y += vel2.y;
	    
	    if ( p1.y < 0 || p2.y < 0 )
		init();
	}
	
	public void paint( Graphics g )
	{
	    g.drawLine( p1.x, p1.y, p2.x, p2.y );
	    g.drawLine( p1.x, p1.y-1, p2.x, p2.y-1 );
	    g.drawLine( p2.x, p2.y-2, p2.x, p2.y-2 );
	}
	
    }
}

// fini
