   import java.io.*;
   import java.util.Scanner;

/**
 * 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  Greg Tamargo
 * @version 2.0
 */
    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)
      {
         double         foodTax;
         double         preparedTax;
         double         otherTax;
         File           tapeFile;       
         int            purchases;
         String         output;
         int[]          arrayCategories;
         double[]       arrayPrices;
         
       // Code that handles the command-line arguments
       
         tape         = null;
         output       = new String();
         foodTax      = 0;
         preparedTax  = 0;
         otherTax     = 0;
         
       // 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;          
               }
         }
         // Otherwise, use System.out
         else
         {
            tape = System.out;          
         }
         
       // The application logic
      
         purchases=requestInt
            ("Enter the number of items:");//first prompt
            
         System.out.println
            ("echo number of items: "+purchases);//echo
      
         arrayCategories  = new     int[purchases];
         arrayPrices      = new  double[purchases];
         //the arrays are initialized here so they are 
        //the proper lengths, set by the user
          
         for(int x=0;x<(purchases);x++)
         {
            arrayCategories [x]=requestCategory();
            //collects the category of each item
         	
            System.out.println
               (" echo category:"+arrayCategories[x]);
         		
            arrayPrices [x]=requestDouble
               ("Enter the price: ");
            //collects the price of each item
         	
            System.out.println
               (" echo price:"+arrayPrices[x]);
         }
         
        //determines the tax on all of the food items
         foodTax = TaxCalculator.foodTax
            (arrayPrices ,arrayCategories );
         System.out.println(" echo food tax: "+foodTax);
         
        //determines the tax on all of the prepared items
         preparedTax = TaxCalculator.preparedfoodTax
            (arrayPrices ,arrayCategories );
         System.out.println
            (" echo prepared food tax:"+preparedTax);
      		
        //determines the tax on all non-food items   
         otherTax = TaxCalculator.nonfoodTax
            (arrayPrices ,arrayCategories );
         System.out.println
            (" echo non-food tax:"+otherTax);
      
         System.out.println();//blank line
      
        // Generate the required output by loading it
       //into the "tape" PrintStream
         tape.print ("   Summary\n");
         tape.printf("     Food:%8.4f\n",foodTax);
         tape.printf(" Prepared:%8.4f\n",preparedTax);
         tape.printf("    Other:%8.4f\n",otherTax);
         
         tape.flush();
       //empties the PrintStream to the user
         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
     *
     * @return         The value 
     */
       private static int requestCategory()
      {
         int        category;
       
         category = -1;
         while(!(TaxCalculator.isValid(category)))
          //uses isValid to repeat the prompt until an
         //appropriate category is entered
         {
            System.out.print
               ("Enter 0 for non-food, "+//the prompt
               "1 for food, or 2 for prepared: ");
               
            try{//tries to collect the category
               category=keyboard.nextInt();
            }
                catch
                (java.util.InputMismatchException ime)
               {//gets rid of bad input
                  keyboard.next();
               }
         }//end while
                
         return category;//returns int representation of
                        //the category
      }//end of 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
     * @return         The value 
     */
       private static double requestDouble(String prompt)
      {
         double       value;
       
         value = 0.0;//zero by default
         System.out.print(prompt);//"Enter the price: "
         
         try
         {//tries to collects the price
            value=keyboard.nextDouble();
         }
             catch(java.util.InputMismatchException ime)
            {//in case of bad input
               keyboard.next();
               //gets rid of the bad input
               requestDouble(prompt);//tries again
            }
            
         return value;//returns the price
      }//end of 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
     * @return         The value 
     */
       private static int requestInt(String prompt)
      {
         int          value;
       
         value = 0;
         
         System.out.print(prompt);//prompts the user
         
         try
         {//tries to collect the number of items
            value=keyboard.nextInt();
         }
             catch(java.util.InputMismatchException ime)
            {
               keyboard.next();//gets rid of bad input
               value=requestInt(prompt);//tries again
            }
      
         return value;//returns the number of items
      }//end of method
   }
