/******************************* FILE HEADER **********************************
    File:        Piranha.java
    Main Class:  Aquarium.java
    
    Author:      James D. Skrentny
                 copyright 2000, all rights reserved
    Course:      CS302: Lectures 1 & 2
    
    Compiler:    CodeWarrior IDE 4.0 (JDK 1.2)
    Platform:    Windows NT 4.0
 **************************** 80 columns wide *********************************/

import java.awt.Color;


/** 
 * Represents a Piranha.
 * 
 * Bugs: Known bugs :)
 **/ 

class Piranha {           
           
    private int    foodPoints; // piranha's energy, 0 to Tank.PIRANHA_MAX_POINTS
    private Location location; // piranha's Location in the tank
    private boolean direction; // piranha's heading, Tank.RIGHT or Tank.LEFT


    /** 
     * Constructs a new Piranha at a random Location and randomly facing either
     * in the left or right direction.
     **/
    public Piranha ( ) {           
        foodPoints = Tank.PIRANHA_MAX_POINTS;
        location   = new Location((int)(Math.random()*Tank.TANK_WIDTH   + 1), 
                                  (int)(Math.random()*Tank.WATER_HEIGHT + 1));
        direction  = (int) (Math.random()*2) == 0 ? Tank.RIGHT : Tank.LEFT;
    }           


    /**
     * Returns the Location of this Piranha.
     *
     * @return this piranha's Location
     **/
    public Location getLocation () {           
        return location;
    }           


    /**
     * Get the Color of this Piranha.
     * A hungry piranha is white, otherwise it's gray.
     *
     * @return this piranha's Color
     **/
    public Color getColor () {           
        if (isHungry()) return Color.white;
        else          return Color.gray;
    }           


    /**
     * Get the direction of this Piranha
     *
     * @return this piranha's direction
     **/
    public boolean getDirection () {           
        return direction;
    }           


    /**
     * Get the number of food points of this Piranha.
     *
     * @return this piranha's food points
     **/
    public int getFoodPoints () {           
        return foodPoints;
    }           


    /**
     * Determine is this Piranha is alive.
     *
     * @return true if this piranha is alive, false otherwise
     */
    public boolean isAlive () {           
        return foodPoints > 0;
    }           


    /**
     * Determine if this Piranha is dead.
     *
     * @return true if this piranha is dead, false otherwise
     */
    public boolean isDead () {           
        return !isAlive();
    }          


    /**
     * Determine if this Piranha is hungry.
     *
     * @return true if this piranha is hungry, false otherwise
     */
    public boolean isHungry () {           
        return foodPoints < (Tank.PIRANHA_MAX_POINTS * Tank.HUNGER_THRESHOLD);

    }           


    /**
     * Move this Piranha, if living, one step from its current location, but it
     * can't move backwards.
     **/
    public void move ( ) {           
        if (isAlive()) {
            int x = location.getX();   // Piranha's current x-coord
            int y = location.getY();   // Piranha's current x-coord
        
           // change directions if at wall
            if ( ((x <= 0) && (direction == Tank.LEFT)) 
              || ((x >= Tank.TANK_WIDTH) && (direction == Tank.RIGHT)) )                   
            {
                      direction = !direction;
            }
            else {  
                // Simple Move Algorithm:
                //    randomly choose a move until a valid move is found
                // This isn't a very efficient moving algorithm (we may have
                // to choose a lot of moves if the Piranha is in a corner), but 
                // it is easy to code.
                boolean invalidMove = true; // true iff a valid move found
                int dx, dy; //change in x and y coordinates
                do {
                    // randomly choose a change of location
                    switch ((int)(Math.random()*5)) {   // 5 ways to move
                        case 0:  dx = 0; dy =  1; break; // straight down
                        case 1:  dx = 1; dy =  1; break; // diagonal down 
                        case 2:  dx = 1; dy =  0; break; // straight across
                        case 3:  dx = 1; dy = -1; break; // diagonal up
                        default: dx = 0; dy = -1; break; // straight up
                    }
        
                    // if facing left, make dx negative
                    if (direction == Tank.LEFT) {
                        dx = -dx;
                    }
                    
                    // compute new coordinates
                    int newX = x + dx;
                    int newY = y + dy;
                    
                    // check if new location is valid
                    if ((newX >= 0) && (newX <= Tank.TANK_WIDTH) &&
                        (newY >= 0) && (newY <= Tank.WATER_HEIGHT)) {
                          invalidMove = false;
                    }
                } while (invalidMove);
            
                // move Piranha
                location.move(dx, dy);
            }
            // decrement foodPoints
            foodPoints -= Tank.PIRANHA_MOVE_COST;
        }        
    }           


    /**
     * This Piranha attempts to eat a specified Fish.  Piranha eat when
     * they are hungry and near a weak fish.
     *
     * @param f the specified fish
     **/
    public void eat (Fish f) {           
        if (isAlive() && isHungry()) {
            foodPoints += f.getFoodPoints();
            f.gotEatten();
	}
    }           


    /**
     * Get the information about this Piranha.
     *
     * @return a String representation of this piranha
     **/
    public String toString () {           
        String info = "Piranha ";

        if (isAlive()) {
            info += "  Direction: ";
            if (direction == Tank.RIGHT) info += "Right";
            else                         info += "Left";
            info += "  Location: "    + location;
            info += "  Food points: " + foodPoints;
        }
        else {
            info += " is dead";
        }

        return info;
    }           
           
}           
