/* $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:`Swarmer.java'
//
//
// DESCRIPTION
//	Swarmer World Object
// 
// Author
//
//	Peter Pilgrim
//	Tue May 18 23:09:23 BST 1999
// 
// RCS HEADER ``Swarmer.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 Swarmer extends EnemyObject
{
    public final static int	NUMBER_SWARMER_IMAGES=1;
    public final static Color	SWARMER_RADAR_COLOR = new Color( 255, 64, 64 );
    
    // Images of these type of world
    protected static Image		swarmer_west_image=null;
    protected static Image		swarmer_east_image=null;


    /** magnitude velocity of swarmer movement */
    protected int			magnitude;
    /** the responsiveness 1=fastest and 5=slowest */ 
    protected int			response;
    
    protected int			move_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 Swarmer( 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 swarmer reacts.
     */
    public Swarmer( GameEngine gameEngine, 
		    int wx, int wy, int magnitude, int response ) 
    {
	super( gameEngine );

	this.wx = wx;
	this.wy = wy;
	this.image_index = 0;
	setMagnitude( Math.abs(magnitude) );
	setResponse( response );
	dx_vel = ( Math.random() < 0.5 ) ? this.magnitude : -this.magnitude;
	dy_vel = ( Math.random() < 0.5 ) ? 3 : -3;

	move_counter = 4+(int)( Math.random() * 13.0 );
	
	// Get the bounds
	width  = swarmer_west_image.getWidth(component);
	height = swarmer_west_image.getHeight(component);
    }

    /** Gets type description type */
    public String getDescriptionType()
    {
	return ("Swarmer");
    }
    
    /** 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 (swarmer_east_image);
    }
    
    public boolean loadImages()
    {
	if (swarmer_west_image == null) {

	    // Load swarmer images
	    swarmer_west_image = 
		GraphicsUtils.getImageAsClassResource(
		    this, "images/swarmer-w.gif" );
	    swarmer_east_image = 
		GraphicsUtils.getImageAsClassResource(
		    this, "images/swarmer-e.gif" );
	    
	    GraphicsUtils.loadImageCompletely( component, swarmer_west_image );
	    GraphicsUtils.loadImageCompletely( component, swarmer_east_image );
	}
	
	return (true);
    }

    public boolean loadAudioClips()
    {

	if (env1 == null ) {
	    // Generating sound ...
	    env1 = new Envelope(
		1,  -2,1, 5,1, -1,1,
		1,51,5, -1,10, 0,128, -8,128 );
	    se1 = new SoundEngine(
		8000, 2.5, 67, 2000, 23,
		StaticWave.SQUARE_WAVE, env1 );
	    se1.setFlags( 0x0 | SoundEngine.HOLD_PITCH_MODULATION | SoundEngine.FM_DELTA_RANDOM_FLAG );
	    se1.makeWave();
	}
	return (true);
    }

    /** Gets the sound engine when Swarmer died */
    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 ( move_counter > 0 ) 
	    --move_counter;
	WorldObject playerObject = gameEngine.playerObject;
	if ( playerObject != null && move_counter < 1) {
	    move_counter = 8+(int)( Math.random() * 8.0 );
	    if ( playerObject.wx > wx ) 
		dx_vel = this.magnitude;
	    if ( playerObject.wx < wx )
		dx_vel = -this.magnitude;
	    if ( playerObject.wy > wy )
		dy_vel = 3;
	    if ( playerObject.wy < wy )
		dy_vel = -3;
	}

	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( 
		    dx_vel >= 0 ? swarmer_east_image : swarmer_west_image, 
		    scrx, scry, component );

	    if ( GameUtilities.isResponsive( response, gameEngine ) )
		image_index = (image_index+1) % NUMBER_SWARMER_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 (150);
    }
    
    /** Get the radar color for this world object */
    public Color  getRadarColor()
    {
	return SWARMER_RADAR_COLOR;
    }

}

// fini
