/* $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:`Baiter.java'
//
//
// DESCRIPTION
//	Baiter World Object
// 
// Author
//
//	Peter Pilgrim
//	Wed Jun 09 01:03:45 BST 1999
// 
// RCS HEADER ``Baiter.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 Baiter extends EnemyObject
{
    public final static int	NUMBER_BAITER_IMAGES=1;

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

    
    /** magnitude velocity of Baiter movement */
    protected int			magnitude;

    /** the responsiveness 1=fastest and 5=slowest */ 
    protected int			response;
    
    protected int			move_counter=0;
    protected int			killingRange;

    /** probability to fire a bomblet */
    protected double			bombletProbability = 0.0750;

    /** Simple Constructor take a single game object 
     * 
     * @param gameEngine the game engine
     */
    public Baiter( 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 Baiter reacts.
     */
    public Baiter( 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 = 0;
	
	// Get the bounds
	width = baiterImages[0].getWidth(component);
	height = baiterImages[0].getHeight(component);
	
	killingRange = 3* gameEngine.screen_width / 4;
    }

    /** Gets type description type */
    public String getDescriptionType()
    {
	return ("Baiter");
    }
    
    /** 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 (baiterImages[0]);
    }
    
    public boolean loadImages()
    {
	if (baiterImages == null) {

	    // Load Baiter images
	    baiterImages = new Image[NUMBER_BAITER_IMAGES];

	    for ( int j=0; j<NUMBER_BAITER_IMAGES; ++j) {
		baiterImages[j] = 
		    GraphicsUtils.getImageAsClassResource( 
			this, "images/baiter"+j+".gif" );
	    }
	    
	    GraphicsUtils.loadImageListCompletely( component, baiterImages );
	}
	
	return (true);
    }

    /** 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;

	WorldObject playerObject = gameEngine.playerObject;
	if ( move_counter > 0 ) 
	    --move_counter;
	if ( playerObject != null && move_counter < 1) {
	    move_counter = 8+(int)( Math.random() * 8.0 );
	    int horz_vel;
	    if ( Math.abs( wx - playerObject.wx ) < killingRange )
		horz_vel = Math.abs( playerObject.dx_vel ) + 8;
	    else
		horz_vel = this.magnitude;
	    if ( playerObject.wx > wx ) 
		dx_vel = horz_vel;
	    if ( playerObject.wx < wx )
		dx_vel = -horz_vel;
	    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;
	}
	
	if ( scrx < gameEngine.screen_width &&
	     gameEngine.playerObject != null &&
	     Math.abs( gameEngine.playerObject.wx - wx ) < gameEngine.screen_width/2 &&
	     Math.random() < bombletProbability ) {
	    if ( Bomblet.getInstanceCount() < Bomblet.OPTIMAL_NUMBER ) {
		int xvelocity = (gameEngine.playerObject.wx - wx) / 20;
		int yvelocity = (gameEngine.playerObject.wy - wy) / 18;
		
		Bomblet bomblet = new Bomblet( 
		    gameEngine, wx + xvelocity, wy + yvelocity, 
		    xvelocity, yvelocity, 48 );
		gameEngine.addWorldObject( bomblet );
	    }
	}
	
	return (this);
    }
    
    /** draw object if displayed */
    public WorldObject	drawObject( Graphics g ) 
    {
	if ( isVisible() ) {
	    translateWorldToScreen();
	    
	    if ( isViewable() )
		g.drawImage( baiterImages[image_index], scrx, scry, component );

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


}

// fini
