import java.util.ArrayList;
import java.util.Iterator;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/** 
 * Container for a list of words, split equally and potentially
 * accessed in a random order 
 *
 * @author Jerod Weinman
 * Grinnell College
 * 19 March 2009
 */
public class WordData implements Iterable<String>
{
  
  /** Construct a word data object from a file name containing a list of words
   *
   * @param fileName The file containing the list of words
   * @throws IOException If reading the file presents any problems
   */
  public WordData(String fileName) throws IOException
  {
    loadData(fileName);
  }
  
  ////////////////////////////////////////////////////////////////////////////////
  // PUBLIC METHODS

  /** Generate a random, even split of the words in this container
   *
   * @return An array of size two, each containing a random half of
   *         the words in a random order
   */
  public WordData[] randomSplit()
  {

    WordData[] data = new WordData[2];

    data[0] = new WordData();
    data[1] = new WordData();

    /* Get a random permutation of the words in this list */
    RandomPermutation perm = new RandomPermutation(words.size());

    /* Alternate placing words in each list. */
    int half = 0;
    for (Integer item : perm)
    {
      data[(half++) % 2].words.add(words.get(item));
    }

    return data;
    
  }

  /** Return an iterator over the words in this container
   * 
   * @return An iterator over the words in this container
   */
  public Iterator<String> iterator()
  {
    //return ((ArrayList<String>)words.clone()).iterator();
    return words.iterator();
  }

  /** Return the number of words in this container 
   *
   * @return the number of words in this container 
   */
  public int size()
  {
    return words.size();
  }

  
  ////////////////////////////////////////////////////////////////////////////////
  // PRIVATE METHODS

  /** Construct a word data object from an existing list of words
   *
   * @param words A List of words for the object to contain
   */
  private WordData(ArrayList<String> words) 
  {
    /* We don't need to create a duplicate of words because this
       constructor is private, we should be able to trust th source of
       the ArrayList not to fiddle with it. */
    this.words = words;
  }

  /** Construct an empty word data object
   */
  private WordData() 
  {
    this.words = new ArrayList<String>();
  }

  /** Initialize this object using file containing a list of words
   *
   * @param fileName The file name containing the list of words
   * @throws IOException If reading the file presents any problems
   */
  private void loadData(String fileName) throws IOException
  {
    BufferedReader wordsIn;

    words = new ArrayList<String>();
    
    wordsIn = new BufferedReader(new FileReader(fileName));
    String word;

      while ( (word = wordsIn.readLine()) != null)
        words.add(word);
  }
  
  ////////////////////////////////////////////////////////////////////////////////
  // PRIVATE FIELDS

  private ArrayList<String> words;
}