// Spaceship2000: A new and improved Spaceship class
// Author: Kiri Wagstaff, wkiri@cs.cornell.edu
// Date: July 16, 2001
// Note this file only includes enough methods so that
// the new method, moveFormation(), will work.
// Also note that isValidPosition is now a STATIC method!
// (Can you figure out why?) 

public class Spaceship2000
{
    // The fuel tank has a maximum capacity
    static final double MAXFUEL = 30.0;
    
    // Keep track of the amount of fuel the spaceship has
    private double tonsOfFuel;
    // Keep track of the current position of the spaceship
    private Position pos;
    // New variable: each Spaceship can have a name
    private String name;

    // constructor: create a new Spaceship at 
    // the specified location, with a full fuel tank,
    // and not landed on anything, with no name.
    // assume that x and y are valid location values.
    public Spaceship2000(int x, int y)
    {
    	// Instead of just assigning, we need to create a new
    	// Position object.
    	pos = new Position(x, y);
        // Starts with a full tank.
        tonsOfFuel = MAXFUEL;
        name = "";
    }
    
    // move: move the spaceship 'horiz' units horizontally
    //       and 'vert' units vertically.  Also, decrement
    //       the current fuel level appropriately.
    //       If the specified movement is invalid, do not
    //       update the ship's position or its fuel level.
    // Input: two integers, as described above
    // Output: if this succeeds, return 0.  Otherwise:
    //   1) If moving as dictated by 'horiz' and 'vert' would
    //      cause the ship to go outside the boundaries of the
    //      10x10 grid, return 1.
    //      Hint: use isValidPosition().
    //   2) If the ship does not have enough fuel to move
    //      as dictated by 'horiz' and 'vert', return 2.
    public int move(int horiz, int vert)
    {
        // Check for a valid move
        int newX = pos.getX() + horiz;
        int newY = pos.getY() + vert;
        if (!isValidPosition(newX, newY))
            {
	    	// Error!  Out of bounds move.
	    	return 2;
            }
	
        // Check that we have enough fuel to move.
        // First, calculate the diagonal distance we would
        // need to travel, using the Pythagorean theorem:
        double dist = Math.sqrt(horiz*horiz + vert*vert);
        
        // Since we consume one ton of fuel for every unit
        // traveled, check if this movement would exceed the
        // fuel supply:
        if (dist > tonsOfFuel)
            {
	    	// Error! Not enough fuel.
	    	return 3;
            }
        
        // Otherwise, move the ship by updating the location:
        pos = new Position(newX, newY);
        
        // Don't forget to update the fuel level.
        tonsOfFuel -= dist;
        
        // Return 0 to indicate success.
        return 0;
    }

    // toString: Used by Java to print the spaceship nicely
    // Input: none
    // Output: a String describing the ship
    public String toString()
    {
        Position pos = getLocation();
        // Note that because Position now has a toString()
        // method, we can just print it out directly!
        return new String("[" + name + ": position " + pos +
                          "; " + getFuel() + " tons of fuel]");
    }
    
    // getFuel: return the current fuel amount.
    // Input: none
    // Output: a double representing the fuel amount.
    // 1 point correctness, 1 point style
    public double getFuel()
    {
        return tonsOfFuel;
    }
    
    // isValidPosition: check if (x,y) is a valid position
    //                  on the 10x10 grid.
    // Input: two integers representing the position to check
    // Output: true if the position is valid, otherwise false
    // NOTE: this method is now static!
    public static boolean isValidPosition(int x, int y)
    {
        if (x >= 1 && x <= 10 && y >= 1 && y <= 10)
            {
	    	// This is a valid grid position.
	    	return true;
            }
        // You could also have an 'else' statement here.
        return false;
    }
    
      // getLocation: returns the current position of the spaceship,
    // in (x,y) coordinates
    // Input: none
    // Output: a Position object (see Position.java)    
    public Position getLocation()
    {
        // Create a new Position object, setting its x and y
        // values to the current location of the spaceship.
        Position thePos = new Position(pos.getX(), pos.getY());
        
        // Return this pair of values to the user.
        return thePos;
    }


    // ---------------------------------------------------- //
    // Now, let's enable the Spaceships to fly in formation
    // moveFormation: takes in an array of ships and moves
    //                them all in the specified way 
    //                (horizontally h, vertically v)
    // Input: an array of ships and the horiz and vert values
    // Output: 0 on success, 1 if it would be an invalid move
    //         for any ship, 2 if any ship doesn't have enough fuel.
    public static int moveFormation(Spaceship2000 ship[], int h, int v)
    {
    	// Check that this is a valid move for all ships
    	// If it's invalid for any ship, return 1 immediately
 			for (int i=0; i<ship.length; i++)
			{
				Position p = ship[i].getLocation();
				if (!isValidPosition(p.getX() + h, p.getY() + v))
				{
					return 1;
				}
			}
    	
    	// Calculate the fuel needed for the move
    	double fuelNeeded = Math.sqrt(h*h + v*v);
    	
    	// Check that each ship has enough fuel
    	// If any ship doesn't, return 2 immediately
 			for (int i=0; i<ship.length; i++)
			{
				if (fuelNeeded > ship[i].getFuel())
				{
					return 2;
				}
			}

			// Move the ships
			for (int i=0; i<ship.length; i++)
			{
			  ship[i].move(h, v);
			}    
    	// Return 0 for success!
    	return 0;
    }
    
    public static void main(String args[])
    {
    	// Note we need a "new" here!
			Spaceship2000[] fleet = new Spaceship2000[5];
			
			// Set 'em up!
			System.out.println("Initial configuration:");
			for (int i=0; i<fleet.length; i++)
			{
				fleet[i] = new Spaceship2000(5, i+2);
				System.out.println(fleet[i]);
			}   
			System.out.println();
			// Now try moving them all together, 3 to the right
			System.out.println("Moving 3 to the right.");
			moveFormation(fleet, 3, 0); 
			for (int i=0; i<fleet.length; i++)
			{
				System.out.println(fleet[i]);
			}   
			System.out.println();
			// Now try moving them all together, 5 down
			// This should fail, since it would push some of them
			// off the grid
			System.out.println("Attempting to move 5 down.");
			moveFormation(fleet, 0, 5); 
			for (int i=0; i<fleet.length; i++)
			{
				System.out.println(fleet[i]);
			}   
    }
}
