/***********************************************************************
 * Program:   Word Melt
 * Author:    Mark Rich, richm@cs.wisc.edu
 * Date:      4/2/2000
 ***********************************************************************/
import javabook.*;

/**
 * To play the game of Word Melt, we will use Strings and StringBuffers.
 * Start, with an initial English word, like CAT.  The goal is to 
 * transform this word into another English word of the same length,
 * as in DOG.  Every step of the way, you are allowed to change only
 * one character; also, each change must result in a English word.  For
 * example:
 *
 *     CAT -> CAB -> LAB -> LAG -> LOG -> DOG
 *
 * is a valid game of Word Melt. To verify that each word along the
 * way is valid, we will make use of a (yet unwritten) Dictionary
 * class.  This program makes extensive use of do-while sentinal loops
 * as well as simple manipulations of Strings and StringBuffers.
 */
class WordMelt {

    public static void main(String[] args) {

	// Declaring and Creating javabook objects
	MainWindow mw = new MainWindow();
	InputBox in = new InputBox(mw);
	OutputBox out = new OutputBox(mw);
	mw.show();
	out.show();
	
	// We need a Dictionary to tell us if we have valid words
	Dictionary webster = new Dictionary();

	// Keep trying to get a starting word until it is valid
	String start; 
	boolean valid;
	do {
	    start = in.getString("What is the starting word?");
	    valid = true;
	    if (!webster.isValid(start)) {
		out.printLine("That's not a word.");
		valid = false;
	    }
	} while (!valid);
	
	// Try to get an ending word.  We need to make sure it is 
	// valid as well as the same length as the starting word
	String end;
	boolean matching;
	do {
	    end = in.getString("What is the ending word?");
	    matching = true;
	    if (!webster.isValid(end)) {
		out.printLine("That's not a word.");
		matching = false;
	    }
	    else if (end.length() != start.length()) {
		out.printLine("The lengths are not equal.");
		matching = false;
	    }
	} while (!matching);

	// Make them uppercase, since case doesn't matter
	start = start.toUpperCase();
	end = end.toUpperCase();
	out.printLine("Start   = " + start);

	// Loop and replace characters in the word until the start
	// word is equal to the end word
	int counter = 0;
	while(!start.equals(end)) {
	    
	    out.printLine("Current = " + start);
	    out.printLine("End     = " + end);
	    
	    // Get the index of the character to change in start
	    int toChange;
	    boolean inRange;
	    do {
		toChange = in.getInteger("Which character do you " + 
					 "want to change? (the first " + 
					 "character is 1)");
		inRange = true;
		if (toChange < 1 || toChange > start.length()) {
		    out.printLine("That's out of range, please try again.");
		    inRange = false;
		}
	    } while(!inRange); 

	    // Get the new character, one character only, to replace
	    String newChar;
	    boolean rightSize;
	    do{
		newChar = in.getString("What is your new character?");
		rightSize = true;
		if (newChar.length() != 1) {
		    out.printLine("That's not one character. " + 
				  "Please try again.");
		    rightSize = false;
		}
	    } while(!rightSize);

	    // Temporarily make the switch with a StringBuffer
	    StringBuffer startChange = new StringBuffer(start);
	    startChange.setCharAt(toChange - 1, newChar.charAt(0));

	    // If the new word is valid, make the change and 
	    // increment the counter.  Otherwise declare it an invalid word
	    if (webster.isValid(startChange.toString())) {
		start = startChange.toString();
		start = start.toUpperCase();
		counter++;
	    }
	    else {
		out.printLine("That's not a valid word");
	    }
	}

	// Finally, the words match, and you can say how many
	// character changes were necessary.  The lower the score,
	// the better.
	out.printLine("Solution path found in " + counter + " steps.");
    }
}

