import javax.swing.JOptionPane;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;




/**
 * A dictionary, i.e., a set of words that is quick to search.
 * @author Doug Baldwin
 */

public class Dictionary {
	
	
	
	
	// Internally, a dictionary is a chained hash table. Since realistic
	// lists of words are long, the nominal size of the table is around
	// 100,000 entries.
	
	private final static int TABLE_SIZE = 93563; 
	
	private WordList[] hashTable;
	
	
	
	
	// Compute a hash code for a string. This hash function multiplies
	// each character code in the string by its position in the string
	// (counting from 1, to include the first character in the hash code)
	// and adds up all the products. It does all of this modulo the table
	// size to ultimately produce an index into the hash table.
	
	private static int hash( String word ) {
		
		int code = 0;
		
		for ( int c = 0; c < word.length(); c++ ) {
			int product = ((int)word.charAt(c)) * ( c + 1 );
			code = ( code + product ) % TABLE_SIZE;
		}
		
		return code;
	}
	
	
	
	
	/**
	 * Initialize a dictionary to contain all the words in a specified file.
	 * @param pathName The name of the file from which to build the dictionary.
	 * @throws FileNotFoundException If the file from which to initialize the
	 *   dictionary doesn't exist.
	 */
	
	public Dictionary( String pathName ) throws FileNotFoundException {
		
		
		// Create the hash table for this dictionary.
		
		hashTable = new WordList[ TABLE_SIZE ];
		
		for ( int i = 0; i < TABLE_SIZE; i++ ) {
			hashTable[i] = new WordList();
		}
		
		
		// Connect a scanner to the word file.
		
		Scanner in = new Scanner( new File( pathName ) );
			
			
		// Read all the words from the file, adding each to the dictionary
		// hash table.
		
		while ( in.hasNext() ) {	
			String word = in.next();
			this.add( word );
		}
	}
	
	
	
	
	/**
	 * Add a word to a dictionary. The word should not already be in
	 * that dictionary.
	 * @param word The word to add.
	 */
	
	public void add( String word ) {
		hashTable[ Dictionary.hash(word) ].add( word );
	}
	
	
	
	
	/**
	 * Search for a word in a dictionary.
	 * @param word The word to seek.
	 * @return <code>true</code> if the word is in the dictionary, <code>false</code> if not.
	 */
	
	public boolean find( String word ) {
		return hashTable[ Dictionary.hash(word) ].find( word );
	}
	
	
	

	/**
	 * Test the dictionary class.
	 * @param args Command-line arguments; ignored.
	 */
	
	public static void main( String[] args ) {
		
		
		// Create a dictionary from the Unix dictionary file,
		// "/usr/share/dict/web2." That file should always be found,
		// but watch for an exception just in case. (And anyone
		// using this on a non-Mac OS computer may have a dictionary
		// in a different location.)
		
		try {
			
			Dictionary dict = new Dictionary( "/usr/share/dict/web2" );
			
			
			// Get strings from the user and look them up until the user
			// decides to stop.
			
			String word = JOptionPane.showInputDialog( "Enter a word to look up." );
			
			while ( word != null ) {
				
				if ( dict.find( word ) ) {
					System.out.println( "'" + word + "' is in the dictionary." );
				}
				else {
					System.out.println( "'" + word + "' is not in the dictionary." );
				}
				
				word = JOptionPane.showInputDialog( "Enter a word to look up." );
			}
		}
		catch ( FileNotFoundException e ) {
			System.err.println( "That's odd, the dictionary doesn't exist." );
		}
	}

}