/**
 * @(#)Rack.java	11/03/05
 * 
 * Copyright 2005 3GP01, KCL.  All unmodified code is copyright of its respective owner.
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * The GNU General Public Licence should be contained within licence.txt;
 * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA  02110-1301, USA.
 */

import java.util.*;

/**
 * This class defines a Rack - a list of Letters.  Each Player has a Rack.
 * The methods defined in the class operate on Racks, so that a Letter can be extracted
 * from an index, an index from a Letter, and so forth.
 * 
 * @author 3GP01 - Hardev Bhamra, Deepak Chandarana, James Tompkin
 * @version 2.0
 * @see Game
 * @see Player
 */

public class Rack 
{
	/**
	 * List containing all Letters in the Rack.
	 */
	private List letters = new ArrayList(); // of Letter

	/**
	 * Adds letters to the Rack.
	 * 
	 * @param l List containing the letters to be added.
	 */
	public void addLetters(List l) 
	{
		letters.addAll(l);
	}

	/**
	 * Removes letters from the Rack.
	 * If a letter cannot be found in the Rack, index = -1.
	 * There are certain situations whereby this can be beneficial.  A blank letter tile
	 * is often not found in a Rack, in which case we can assume that the letter
	 * that returns index = -1 is a blank letter tile. 
	 * 
	 * @param l The List of Letters to be removed from the Rack.
	 */
	public void removeLetters(List l) 
	{
		for (int i = 0; i < l.size(); i++) 
		{
			Letter lett = (Letter) l.get(i);
			int index = letters.indexOf(lett); // using Equals on Letter
			if (index == -1) 
			{
				for (int j = 0; j < getRackSize(); j++) //isnt in the rack, it
													 // must be a blank.
				{
					if (getLetter(j).isBlank()) //find the first blank in the
												// rack,
					{
						index = j; //use the index of that instead
						break;
					}
				}
			}
			if (index >= 0) 
			{
				letters.remove(index);
			}
		}
	}

	/**
	 * Gets a Letter from the Rack at <b>i</b>.
	 * 
	 * @param i The index of the letter we require.
	 * @return Letter
	 */
	public Letter getLetter(int i) 
	{
		return (Letter) letters.get(i);
	}

	/**
	 * Gets an index from a Letter. Used in the hint move code to
	 * rearrange the rackButtons display of the user (in order to guide them
	 * towards a successful Move).
	 * 
	 * @param lett The Letter we require an index for.
	 * @return int The index of the Letter lett
	 */
	public int getIndexOfLetter(Letter lett) 
	{
		int index = letters.indexOf(lett);
		if (letters.indexOf(lett) == -1) //if computer wants to use a letter
										 // that
		{
			for (int i = 0; i < getRackSize(); i++) //isnt in the rack, it must be
												 // a blank.
			{
				if (getLetter(i).isBlank()) //find the first blank in the rack,
				{
					index = i; //use the index of that instead
					break;
				}
			}
			return index;
		} 
		else 
		{
			return index = letters.indexOf(lett);
		}
	}

	/**
	 * Similar to getIndexOfLetter, but only from the back of the rack.
	 * Useful when we know a rack has more than one letter of the same kind.
	 * 
	 * @param lett The Letter we require an index for.
	 * @return int The index of the Letter lett
	 */
	public int getReverseIndexOfLetter(Letter lett) 
	{
		int index = letters.indexOf(lett);
		if (letters.indexOf(lett) == -1) //if computer wants to use a letter
										 // that
		{
			for (int i = getRackSize(); i > 0; i--) //isnt in the rack, it must be
												 // a blank.
			{
				if (getLetter(i).isBlank()) //find the first blank in the rack,
				{
					index = i; //use the index of that instead
					break;
				}
			}
			return index;
		}
		else 
		{
			return index = letters.lastIndexOf(lett);
		}
	}

	/**
	 * Returns the size of the Rack.
	 * 
	 * @return int
	 */
	public int getRackSize() 
	{
		return letters.size();
	}
	
	/**
	 * Returns the value of the Rack as an int.
	 * 
	 * @return int
	 */
	public int getRackValue() //return the value of the rack
	{
		int rackValue = 0; //new int to store the value of the rack
		for (int i = 0; i < getRackSize(); i++) //for each letter on the rack
		{
			rackValue = rackValue + getLetter(i).getScore(); //add the score of
															 // the letter on
															 // the rack to the
															 // total rack value
		}
		return rackValue; //return the rackValue
	}
	
	/**
	 * Return whether a Rack is empty or not.
	 * 
	 * @return boolean
	 */
	public boolean isEmpty() 
	{
		return letters.size() == 0;
	}
	
	/**
	 * Sets the Letter at <b>i</b> on the Rack.
	 * 
	 * @param i The index of the Rack we'd like to set.
	 * @param lett The letter we'd like to set on the Rack.
	 */
	public void setLetter(int i, Letter lett) 
	{
		letters.remove(i);
		letters.add(i, lett);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() 
	{
		return letters.toString();
	}

}