   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  Tom Kowaleski
 * @version 1.8
 */
    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         prepared;//amount of prepared-food tax
      	double         food;    //amount of food tax
      	double         other;	//amount of non-food tax
      	
			//declaring strings
      	String         prepS;
      	String         foodS;
      	String         otheS;
      	
			//Strings for use in the output(printf)
      	prepS    =     "Prepared: ";
      	foodS    =     "Food: ";
      	otheS    =     "Other: ";
      
         File           tapeFile;
         TaxCalculator  calc;
         int            index = 0;
			
			//declaring the arrays, instantiated after
			// the user input
         double[]       priceList;
         int[]          catList;
         
			//Creating a TaxCalculator object
      	calc = new TaxCalculator();      
      
      
       // 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;          
               }
         }
         // Otherwise, use System.out
         else
         {
            tape = System.out;          
         }
       
      
       
       // The application logic
         index = requestInt("Enter the number of items. ");
			tape.println("You have entered: " + index);
			
			//instantiating the arrays to the size of the user index
         priceList  =  new double[index];
         catList    =  new int[index];
      	
			//runs a loop adding the user inputs to the arrays created
         for(int i = 0; i < index; i++)
         {
            catList[i]   =  requestCategory();
				tape.println("You have entered: " + catList[i]);
				
            priceList[i] =  requestDouble("Enter the price. ");
				tape.println("You have entered: " + priceList[i]);
         }
      
      	
      
       // Generate the required output
      
      	//calling upon and saving the information from the
			//	TaxCalculator class
      	food      =  calc.foodTax(priceList, catList);
      	prepared  =  calc.preparedfoodTax(priceList, catList);
      	other     =  calc.nonfoodTax(priceList, catList);
      
			//output
      	tape.println("Summary");
      	tape.printf("%10s%8.4f\n", foodS, food);
      	tape.printf("%10s%8.4f\n", prepS, prepared);
      	tape.printf("%10s%8.4f\n", otheS, other);
			
      	tape.println("This program has ended normally.");
      
      }
    /**
     * 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          value = 0;
         boolean      isValid = false;
         tape.print("Enter 0 for non-food, 1 for food, or 2 for prepared: ");
			//checks to see if the next value is an int
         if (keyboard.hasNextInt())
         {
            value = keyboard.nextInt();
            keyboard.nextLine();
				//checks to see if the value is 0,1 or 2
				if((value == 0)||(value == 1)||(value == 2))
					isValid = true;
         }
         else
         {
				//while the value entered is not an int, this loop runs
            while(isValid == false)
            {
               tape.println("Incorrect entry, Enter 0 for " +
                  "non-food, 1 for food, or 2 for prepared: ");
            	//once again, checking to see if the 
					//	next value is an int
               if (keyboard.hasNextInt())
               {
                  value = keyboard.nextInt();
                  keyboard.nextLine();
						
						if ((value == 0)||(value == 1)||(value == 2))
                  	isValid = true;
						else
							isValid = false;
               }
               else
               {
                  keyboard.nextLine();
                  isValid = false;
               }
            }
         } 
      
         return value;
      }
   
   
   
   
    /**
     * 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 = 0;
         boolean      isValid = false;
      	
         tape.print(prompt);
         if (keyboard.hasNextDouble())
         {
            value = keyboard.nextDouble();
            keyboard.nextLine();
         }
         else
         {
            do
            {
               tape.println("Incorrect entry, please enter the " +
                  "price of the item again.");
               if (keyboard.hasNextDouble())
               {
                  value = keyboard.nextDouble();
                  keyboard.nextLine();
                  isValid = true;
               }
               else
               {
                  keyboard.nextLine();
                  isValid = false;
               }
            }while (isValid == false);
         } 
      
         return value;
      }
   
   
   
    /**
     * 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 = 0;
         boolean      isValid = false;
         tape.print(prompt);
         if (keyboard.hasNextInt())
         {
            value = keyboard.nextInt();
            keyboard.nextLine();
         }
         else
         {
            do
            {
               tape.println("Incorrect entry, please enter the " +
                  "number of items again.");
               if (keyboard.hasNextInt())
               {
                  value = keyboard.nextInt();
                  keyboard.nextLine();
                  isValid = true;
               }
               else
               {
                  keyboard.nextLine();
                  isValid = false;
               }
            }while (isValid == false);
         } 
      
         return value;
      }
   }