/**
 * @(#)Bag.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 contains the bag of letters for a current ScrabbleBuilder.
 * Class also provides methods for operating on the bag of letters.
 *
 * @author 3GP01 - Hardev Bhamra, Deepak Chandarana, Kevin Lano, James Tompkin
 * @version 2.0
 * @see Game
 * @see Letter
 */

public class Bag
{ 
	/**
     * Contains all letters currently in the bag.
     */
	private List letters = new ArrayList(); // of Letter

	/**
     * Constructs a new bag for a given Scrabblebuilder
     * 
     * @param builder The ScrabbleBuilder of the game you'd like to create a bag for.
     */
	public Bag(ScrabbleBuilder builder)
	{
		letters = builder.getLetters();
	}

	/**
     * Returns a <b>Letter</b> at a specific <param>i</param> in the bag.
     * 
     * @param i The specific location in the bag of the letter to return.
     * 
     * @return Letter The specific letter in the bag.
     */
	public Letter getLetter(int i) 
	{
		return (Letter) letters.get(i);
	}
  
	/**
     * Returns an <b>int</b> containing the current score sum of the bag.
     * 
     * @return int The total score of the current bag.
     */
	public int getBagValue()
	{
		int bagValue = 0; //new int to store the value of the bag
		for (int i = 0; i < getSize(); i++) //for each letter on the bag
		{	//add the score of the letter in the bag to the total bag value
			bagValue = bagValue + getLetter(i).getScore(); 
		}
		return bagValue; //return the rackValue
	}
  
	/**
     * Returns an <b>int</b> containing the current size of the bag.
     * 
     * @return int The size of the current bag.
     */
	public int getSize() 
	{
		return letters.size();
	}
	
	/**
     * Returns a <b>List</b>, the bag.
     * 
     * @return List The total score of the current bag.
     */
	public List getLetters() 
	{
		return letters;
	}

	/**
     * Tests to see whether the bag of letters is empty.
     * 
     * @return A boolean value (true or false)
     */
	public boolean isEmpty()
	{
		return letters.size() == 0; 
	}
	
	/**
     * Sets the current bag to be the input <b>List</b> <param>letters</param>.
     * 
     * @param letters A <b>List</b> containing the letters the bag should be set to.
     */
	public void setLetters(List letters) 
	{
		this.letters = letters;
	}
	
	/**
     * Returns a <b>String</b> representation of the bag.
     * 
     * @return String The bag.
     */
	public String toString() 
	{
		return letters.toString();
	}
	
	/**
     * Allocates a random selection of new letters to a list, the size of the required number
     * of letters.
     * 
     * @param giving The number of letters needed to be returned to the rack.
     * @return List The list containing the returned letters.
     */
	public List giveLetters(int giving) 
	{
		List res = new ArrayList();
		Random rand = new Random();
		int n = letters.size();
		for (int i = 0; i < giving; i++) {
			int index = rand.nextInt(n);
			Letter l = (Letter) letters.get(index);
			res.add(l); // sort in decreasing score order
			letters.remove(index);
			if (isEmpty()) //added code, did just read n--;
			{
				break;
			} //this caused the program to try and generate
			else //rand.nextInt(-1);, which created an exception
			{
				n--;
			} //when the bag size was 0.
		}
		return res;
	}
  
	/**
     * Overloaded method of giveLetters. If <b>remote</b> is fed,
     * method will return the number of required letters (<b>giving</b>).
     * The method will not return a random selection, as the remote game uses a
     * 'static' bag of pre-randomised letters.
     * 
     * @param giving The number of letters needing to be replaced in the rack.
     * @param remote A field used to denote a call to this overloaded method.
     * 
     * @return List The list containing the required letters.
     */
	public List giveLetters(int giving, boolean remote) 
	{
		List res = new ArrayList();
		int n = letters.size();
		for (int i = 0; i < giving; i++) {
			Letter l = (Letter) letters.get(0);
			res.add(l); // sort in decreasing score order
			letters.remove(0);
			if (isEmpty()) //added code, did just read n--;
			{
				break;
			} //this caused the program to try and generate
			else //rand.nextInt(-1);, which created an exception
			{
				n--;
			} //when the bag size was 0.
		}
		return res;
	}

	/**
     * Method takes a list of letters and replaces
     *  (into the bag) all letters from the <param>list</param>
     * 
     * @param list The list of letters to replace into the bag.
     */
	public void replaceLetters(List list) 
	{
		for (int i = 0; i < list.size(); i++) {
			Letter rackLetter = (Letter) list.get(i);
			letters.add(rackLetter);
		}
	}
}

