import java.io.*;
import java.util.*;

/**
 * A command-line application that can be used to calculate sales taxes
 * on different kinds of items.
 *
 * This application accepts one command-line argument, containing the
 * name of the output file.  If the command-line argument is omitted,
 * this application will send all output to the console 
 * (i.e., standard output).
 *
 *
 * This work complies with the JMU Honor Code.
 *
 * @author  Pan He
 * @version 1.0 09/10/2008
 */
public class TaxOnomy
{
    private static PrintStream    tape;
    private static Scanner        keyboard = new Scanner(System.in);

    /**
     * The entry point of the application
     * @param args   The command-line arguments
     */
    public static void main(String[] args)
    {
       File           tapeFile;       
      
       // Code that handles the command-line arguments
       tape = null;

       // If there is a command-line argument, use it as the
       // file name (if possible)
       if ((args != null) && (args.length > 0))
       {
          tapeFile = new File(args[0]);
          try
          {
             tape  = new PrintStream(tapeFile);
          }
          catch (IOException ioe)
          {
             tape  = System.out;          
          }
       }  // end if
       // Otherwise, use System.out
       else
       {
          tape = System.out;          
       }  //end else
       
       
       
       // prompt the program
       System.out.println("Welcome the Tax System!");
       System.out.println(); // make a break
       
       // store the number of item
       int number;
       
       // declare variables to store total tax in certain type
       double preparedfood;
       double food;
       double nonfood;
       
       // declare prompt words
       String prompt;
       prompt = "Enter the number of items: ";
       
       number = requestInt(prompt); // get the number of items 
       int [] item = new int[0];
       double [] prices = new double [0];
       int [] categories = new int[0];
       
       // store the information of category
       item = new int[number];  
       prompt = "Enter the price: ";
       // to store the information of the prices
       prices = new double [number];  
       // to store the information of the categories
       categories = new int [number];
       
       // get the category and price of each item
       for(int i = 0; i < item.length; i++)
       {
    	   categories [i] = requestCategory();
    	   prices [i] = requestDouble(prompt);
       }  // end for
       
       // get tax of certain type
       preparedfood = TaxCalculator.preparedfoodTax(prices, categories);
       food = TaxCalculator.foodTax(prices, categories);
       nonfood = TaxCalculator.nonfoodTax(prices, categories);
       
       // Generate the required output
       String s1 = "Summary";
       String s2 = "Food:";
       String s3 = "Prepared:";
       String s4 = "Other:";
       tape.printf("\n%10s\n",s1);
       tape.printf("%10s %8.4f\n", s2, food);
       tape.printf("%10s %8.4f\n", s3, preparedfood);
       tape.printf("%10s %8.4f\n", s4, nonfood);
       
       // prompt the end of the program
       System.out.println("\nThis program has ended normally "); 
   }  //end main   
  






    /**
     * Prompt the user to enter a category and then
     * read it in (using the Scanner named keyboard).
     *
     * This method will/must continue to prompt the user
     * until she/he enters a valid category
     *
     * @exception InputMismatchException the token retrieved does not
     *  match the pattern for the expected type, or that the token is
     *  out of range for the expected type. 
     * @return         The value 
     */
    private static int requestCategory()
    {
       int        category;
       String     wrong;   // if type wrong data, use it to retrieve
       // store the type of the item for echo
       String  foodtype;
       category = -1;
       wrong = null;
       foodtype = "wrong";  // default value
       
       while(TaxCalculator.isValid(category) != true)
       {
    	   System.out.print  //prompt
           ("Enter 0 for non-food, 1 for food, or 2 for prepared: ");
    	   try
    	   {
    		   category = keyboard.nextInt(); 
    		   
    		   switch(category)  // get the category of this item
    		   {
    			   case 0: foodtype = "not food"; break;
    			   case 1: foodtype = "(non-prepared) food"; break;
    			   case 2: foodtype = "preparedfood"; break;
    		   }  // end swich
    		   
    		   // handle the situation if the user type a number
    		   //  but out of the range.
    		   if(TaxCalculator.isValid(category) != true)  
    			   System.out.print("please type a number between 0~2: ");
    	   }  // end try
    	   catch (InputMismatchException ime)
           {
    		   System.out.print("wrong input, please try it again: ");
    		   wrong = keyboard.nextLine();
           }  // end catch
    	   
    	   System.out.println("The type of item is " + foodtype); // echo
		   System.out.println(); // make a break
       }  // end while
       return category;
    }  // end method




    /**
     * Prompt the user to enter a double and then
     * read it in (using the Scanner named keyboard)
     *
     * @param prompt   The custom portion of the prompt
     * @exception InputMismatchException the token retrieved does not
     *  match the pattern for the expected type, or that the token is
     *  out of range for the expected type. 
     * @return         The value 
     */
    private static double requestDouble(String prompt)
    {
       double       value;       
       value = 0.0;
       String error; // store the wrong type.
       error = null;
       boolean done; // if wrong, keep type numbers
       done = false;
       
       System.out.print(prompt);
       while(!done)
       {
    	   try
    	   {
    		   value = keyboard.nextDouble(); // get the price
    		   done = true;  // right type , go out of the loop
    	   }  // end try
    	   catch (InputMismatchException ime)
    	   {
    		   System.out.print("wrong input, retype it: ");
    		   // obtain the wrong-type value 
    		   error = keyboard.nextLine();  
    	   }  // end catch
       }   // end while
      
       System.out.println("The price of this items is " + value); //echo
       System.out.println(); // make a break
       
       return value;
    }  // end method



    /**
     * Prompt the user to enter an int and then
     * read it in (using the Scanner named keyboard)
     *
     * @param prompt   The custom portion of the prompt
     * @exception InputMismatchException the token retrieved does not
     *  match the pattern for the expected type, or that the token is
     *  out of range for the expected type. 
     * @return         The value 
     */
    private static int requestInt(String prompt)
    {
       int          value;
       value = 0;        
       String error; // to hold the wrong input
       error = null;
       boolean done; // if wrong, keep type numbers
       done = false;
       
       System.out.print(prompt);  // prompt type words
       
       while (!done) // if item is not a correct number, keep typing
       {
    	   try
           {
        	   do
        	   {
        		   value = keyboard.nextInt(); //get the number of items
        		   if(value < 0)  // the number of item cannot be negative
            	      System.out.print("Item is less than 0, retype it: ");
        	   }  // end do
        	   while(value < 0);
        	   
        	   done = true;  // right type , go out of the loop
           }  // end try
           catch (InputMismatchException ime)
           {
        	   System.out.print("wrong input, retype it: ");
        	   error = keyboard.nextLine();  // hold the wrong input
           }  // end catch    	  
       }  // end while
       
       System.out.println("The number of items is " + value);  // echo
       System.out.println(); // make a break
       
       return value;
    }  // end method

    
}   // end class
