/* $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:`Bomber.java'
//
//
// DESCRIPTION
//	Bomber World Object
// 
// Author
//
//	Peter Pilgrim
//	Tue May 18 23:09:23 BST 1999
// 
// RCS HEADER ``Bomber.java''
// 
//	$Author$
//	$Date$
//	$Source$
//	$Revision$    $State$    $Locker$
//

package xenon.humanoid;

import java.util.Vector;
import java.awt.*;
import java.awt.image.*;

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

public class Bomber extends EnemyObject
{
    public final static int	NUMBER_BOMBER_IMAGES=1;
    public final static Color	BOMBER_RADAR_COLOR = new Color( 155, 48, 255 );

    // Images of these type of world
    // Object are stored in an array
    protected static Image[]		bomberImages=null;

    /** magnitude velocity of bomber movement */
    protected int			magnitude;
    /** the responsiveness 1=fastest and 5=slowest */ 
    protected int			response;
    
    protected int			state_counter=0;
    
    /** probability to fire a bomblet */
    protected double			bombletProbability = 0.0512;

    protected static Envelope		env1=null;
    protected static SoundEngine	se1=null;

    /** Simple Constructor take a single game object 
     * 
     * @param gameEngine the game engine
     */
    public Bomber( GameEngine gameEngine ) 
    {
	super( gameEngine );
    }
    
    
    /** Constructor take a single game object 
     * 
     * @param gameEngine the game engine
     * @param wx the world x coodinate
     * @param wy the world x coodinate
     * @param magnitude the magnitude (overall speed)
     * @param response the responsive factor the lower the number 
     * the quicker the bomber reacts.
     */
    public Bomber( GameEngine gameEngine, 
		   int wx, int wy, int magnitude, int response ) 
    {
	super( gameEngine );

	this.wx = wx;
	this.wy = wy;
	this.image_index = 0;
	this.magnitude = Math.abs(magnitude);
	this.response = response;
	setResponse( response );
	dx_vel = ( Math.random() < 0.5 ) ? this.magnitude : -this.magnitude;
	dy_vel = ( Math.random() < 0.5 ) ? 3 : -3;
	
	// Get the bounds
	width = bomberImages[0].getWidth(component);
	height = bomberImages[0].getHeight(component);
    }

    /** Gets type description type */
    public String getDescriptionType()
    {
	return ("Bomber");
    }
    
    /** retrieves a default image used for placating an image of
     * the world object on the screen. For example displaying image
     * on the left of the display and the number of points scored
     * destroying this world object on the right.
     * <b>Subclassers</b> should override this methods.
     */
    public Image getDefaultImage() 
    {
	return (bomberImages[0]);
    }
    
    public boolean loadImages()
    {
	if (bomberImages == null) {

	    // Load bomber images
	    bomberImages = new Image[NUMBER_BOMBER_IMAGES];

	    for ( int j=0; j<NUMBER_BOMBER_IMAGES; ++j) {
		bomberImages[j] = 
		    GraphicsUtils.getImageAsClassResource( 
			this, "images/bomber"+j+".gif" );
	    }
	    
	    GraphicsUtils.loadImageListCompletely( component, bomberImages );
	}

	return (true);
    }
    
    public boolean loadAudioClips()
    {
	if (env1 == null ) {
	    // Generating sound ...
	    env1 = new Envelope(
		1,  1,2, -3,1, -3,3,
		1,128,1, 0,128, 0,128, -8,128 );
	    se1 = new SoundEngine(
		8000, 3.5, 115, 250, 25,
		StaticWave.RAMP_BACKWARD_WAVE, env1 );
	    se1.setFlags( SoundEngine.HOLD_PITCH_MODULATION );
	    se1.makeWave();
	}
	
	return (true);
    }

    public SoundEngine getDiedSound() 
    {
	return (se1);
    }

    /** Sets the response */
    public void setResponse( int newResponse )
    {
	response = newResponse;
	if (response < 0) response = 0;
	if (response > GameUtilities.RESPROW ) response = GameUtilities.RESPROW;
    }
    
    /** Gets the response */
    public int getResponse()
    {
	return (response);
    }
    
    /** Sets the magnitude */
    public void setMagnitude( int newMagnitude )
    {
	magnitude = newMagnitude;
    }
    
    /** Gets the magnitude */
    public int getMagnitude()
    {
	return (magnitude);
    }
    
    /** Sets the bomblet probability */
    public void setBombletProbability( double newValue )
    {
	bombletProbability = newValue;
    }
    
    /** Gets the bomblet probability */
    public double getBombletProbability()
    {
	return (bombletProbability);
    }
    
    /** update world object */
    public WorldObject	update()
    {
	if ( !GameUtilities.isResponsive( response, gameEngine ) )
	    return this;

	if ( wy < 15 )
	    dy_vel = 3;
	else if ( wy > gameEngine.screen_height - 15 )
	    dy_vel = -3;

	if ( Math.random() < bombletProbability &&
	     Bomblet.getInstanceCount() < Bomblet.OPTIMAL_NUMBER &&
	     scrx > 0 && scrx < gameEngine.screen_width )
	{
	    Bomblet bomblet = new Bomblet( 
		gameEngine, wx, wy, 0, 0, 40 );
	    gameEngine.addWorldObject( bomblet );
	}
	
	wx = ( wx + dx_vel + gameEngine.world_width ) % gameEngine.world_width;
	wy += dy_vel;
	if ( wy < 0 ) { 
	    wy = 0; dy_vel =-dy_vel;
	}
	else if ( wy > gameEngine.world_height ) {
	    wy = gameEngine.world_height; dy_vel =- dy_vel;
	}
	
	return (this);
    }
    
    /** draw object if displayed */
    public WorldObject	drawObject( Graphics g ) 
    {
	if ( isVisible() ) {
	    
	    translateWorldToScreen();
	    
	    if ( isViewable() )
		g.drawImage( bomberImages[image_index], scrx, scry, component );


	    if ( GameUtilities.isResponsive( response, gameEngine ) )
		image_index = (image_index+1) % NUMBER_BOMBER_IMAGES;
	}

	return (this);
    }
    
    /** undraw object if displayed */
    public WorldObject	undrawObject( Graphics g )
    {
	return (this);
    }

    
    /** Gets the points score for this world object */
    public int getPointsScored()
    {
	return (250);
    }
    
    /** Get the radar color for this world object */
    public Color  getRadarColor()
    {
	return BOMBER_RADAR_COLOR;
    }

}

// fini
