/* 
 * compute how much change is due
 * @author	Biagioni, Edoardo
 * @assignment	lecture 2
 * @date	January 16, 2008
 * @bugs	none
 */

import javax.swing.*;

import java.util.Scanner;
import java.util.InputMismatchException;


public class ChangeDue {
    /* definition of money available */
    /* first define available bills: */
    final static int bills [] = {100, 50, 20, 10, 5, 1};
    final static String billNames [] = {"hundred", "fifty", "twenty",
					"ten", "five", "single"};
    final static String billPlurals [] = {"hundreds", "fifties", "twenties",
					  "tens", "fives", "singles"};

    /* definition of coins available */
    final static int coins [] = {25, 10, 5, 1};
    final static String coinNames [] = {"quarter", "dime", "nickle", "penny"};
    final static String coinPlurals [] = {"quarters", "dimes",
					  "nickles", "pennies"};

    /* main method is invoked when the program is started
     *
     * @param arguments  command-line arguments, not used
     *
     */
    public static void main(String [] arguments) {
	/* the cashier enters the amount due */
	int due = requestAmount("total charge");
	int paid = requestAmount("dollars paid");
	printDollar("charge", due);
	printDollar(", amount paid", paid);
	if (paid < due) {     /* make sure the amount is sufficient */
	    System.out.println(" which is insufficient");
	} else {
	    int difference = paid - due;
	    printDollar(", change is", difference);
	    System.out.println("");
	    /* print the bills */
	    printChange(difference / 100, bills, billNames, billPlurals);

	    difference = difference % 100;
	    /* print the coins */
	    printChange(difference, coins, coinNames, coinPlurals);
	    System.out.println("");
	    
    /* alternative way of doing almost the same thing
     *      if (difference > 100) {
     *  	System.out.println("$" + (difference / 100) + " in bills");
     *  	difference = difference % 100;
     *      }
     *      if (difference > 25) {
     *  	System.out.println((difference / 25) + " quarters");
     *  	difference = difference % 25;
     *      }
     *      if (difference > 10) {
     *  	System.out.println((difference / 10) + " dimes");
     *  	difference = difference % 10;
     *      }
     *      if (difference > 5) {
     *  	System.out.println((difference / 5) + " nickles");
     *  	difference = difference % 5;
     *      }
     *      if (difference > 0) {
     *  	System.out.println( difference      + " pennies");
     *      }
     */
	}
    }

    /* open a dialog window and ask the user for an amount
     *
     * @param question	question to ask the user
     * @return		the amount in cents
     *
     * calls System.exit(1) in case of errors
     */
    private static int requestAmount(String question) {
	String amount = JOptionPane.showInputDialog(question);
	Scanner amountScan = new Scanner(amount);
	int cents = 0;
	try {
	    double dollars = amountScan.nextFloat();
	    cents = ((int) (dollars * 100.0 + 0.005));
	    /* these are used in case debugging is needed */
	    /* System.out.print("you entered $" + dollars); */
	    /* System.out.println(", which is " + cents + " cents"); */
	} catch(InputMismatchException ex) {
	    System.out.println("illegal value for dollars due");
	    /* exit the program if the value is not a dollar amount */
	    System.exit(1);
	} catch(java.lang.RuntimeException ex) {
	    /* exit the program in case of other errors as well */
	    System.out.println("unexpected exception " + ex);
	    System.exit(1);
	}
	return cents;
    }

    /* print a dollar amount
     *
     * @param comment	comment to print before the dollar amount
     * @param cents	amount to print in cents
     *
     */
    private static void printDollar(String comment, int cents) {
	System.out.print(comment + " $" + (cents / 100) + ".");
	cents = cents % 100;
	if (cents < 10) {
	    System.out.print("0" + cents);
	} else {
	    System.out.print(cents);
	}
    }

    /* print exact coins or bills to give back
     *
     * @param amount	amount to return using bills or coins
     * @param values	numeric values for the bills or coins
     * @param singulars	name for one bill or coin in each denomination
     * @param plurals	name for multiple bills or coins in each denomination
     *
     */
    private static void printChange(int amount, int [] values,
				    String [] singulars, String [] plurals) {
	/* sanity check: all arrays should have same size */
	if ((values.length != singulars.length) ||
	    (values.length != plurals.length)) {
	    System.out.println("wrong number of names");
	    System.exit(1);
	}
	/* code only works for positive amounts */
	if (amount <= 0) {
	    return;
	}
	/* now print the actual values */
	for (int i = 0; i < values.length; i++) {
	    /* System.out.println("i " + i + ", values [i] " + values [i]); */
	    if (amount >= values [i]) {
		if (amount >= values [i] * 2) {
		    System.out.print((amount / values [i]) + " " +
				     plurals [i] + ", ");
		} else {
		    System.out.print("1 " + singulars [i] + ", ");
		}
		amount = amount % values [i];
	    }
	}
    }

}