import java.io.*;			//Need for I/O class
import java.util.Scanner;	//Need for Scanner class

/**
 * 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  Yang Yang
 * @version 1.0 Sep,14th,2008
 */
public class TaxOnomy
{
	//Create objects for this program
	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)
    {  	
       //Create a File object  	
       File           tapeFile;   
    	
       //Create a number to control the output for loop
       int controlNum = 2;
      
       // 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))
       {
          //Create a File Object to store the command-line argument
    	  tapeFile = new File(args[0]);       
          
          //Try to output
          try
          {
              //Create a PrintStream object
        	  tape  = new PrintStream(tapeFile);
             
             //Prompt messages
             System.out.print("\n\nFile was found, automatically process...");                     
          
          }//end try
          
          //catch a IOExpection
          catch (IOException ioe)
          {
             tape  = System.out;
             
             System.out.print("\n\nFile was not found, automatically exit.");
             System.exit(0);
          }
       }
       // Otherwise, use System.out
       else
       {
          tape = System.out;
          
          controlNum = 1;//Set controlNum
       }
       
            
      
       
       // The application logic
       
       
          
       //For format, you can ignore these statements
       System.out.println();  
       for(int i=0;i<13;i++){
    	   System.out.print("======");
       }//end for
       System.out.println();

             
       //Hold the preparedfood, food, non-food tax
       double preparedfood, food, nonfood;
       
       //Hold the prompt messages
       String prompt = "Enter the number of items: ";
       
       //Hold the number of items
       int number = requestInt(prompt); 
       
       //Initialization
       int [] item = new int[0];
       double [] prices = new double [0];
       int [] categories = new int[0];
       
       //Store the information in the arraies
       item = new int[number];          
       prices = new double [number];          
       categories = new int [number];
       
       prompt = "Enter the price: ";//Change the prompt message
       
       //Use for loop to write date into arraies
       for(int i = 0; i < item.length; i++){
    	   
    	   categories [i] = requestCategory();
    	   prices [i] = requestDouble(prompt);
    	   
       }//end for
       
       System.out.println();
       //For format, you can ignore these statements
       for(int i=0;i<13;i++){
    	   System.out.print("======");
       }//end for
       System.out.println();
       System.out.println("Total information\n");
       
       //Hold all the result
       double foodtax,foodtotal,
              preparedfoodtax,preparedfoodtotal,
              nonfoodtax,nonfoodtotal;
       
       //Initialization
       foodtax = TaxCalculator.foodTax(prices,categories);
       foodtotal = TaxCalculator.total(prices,categories,1);
       
       preparedfoodtax = TaxCalculator.preparedfoodTax(prices,categories);
       preparedfoodtotal = TaxCalculator.total(prices,categories,2);
       
       nonfoodtax = TaxCalculator.nonfoodTax(prices,categories);
       nonfoodtotal = TaxCalculator.total(prices,categories,0);
       
       //Echo all the result after calculate
       System.out.println("There are(is) "+number+" items you brought.\n");
       
       System.out.printf("\nFood prices:            %8.4f\n",foodtotal);
       System.out.printf("Food taxes:             %8.4f\n",foodtax);
       
       System.out.printf("\nPrepared food prices:   %8.4f\n",preparedfoodtotal);
       System.out.printf("Prepared food taxes:    %8.4f\n",preparedfoodtax);
       
       System.out.printf("\nNon-food prices:        %8.4f\n",nonfoodtotal);
       System.out.printf("Non-food taxes:         %8.4f\n",nonfoodtax);       

       System.out.println();
       
       System.out.println("\nOutput information:");
       //For format, you can ignore these statements
       for(int i=0;i<13;i++){
    	   System.out.print("======");
       }//end for
       System.out.println();

       
       
       // Generate the required output
       
       //Let the program can output the result on disply and file at the same time
       for(int i = 0;i<controlNum;i++){
    	   tape.printf("%10s %10s %8.4f %10s %8.4f %10s %8.4f","Summary",
    			   	   "Food:",foodtax,
		   			   "Prepared:",preparedfoodtax,
		   			   "Other:",nonfoodtax);
    	   tape = System.out;
       }//end for
    		   			 
       
       System.out.println();
       
       //For format, you can ignore these statements
       for(int i=0;i<13;i++){
    	   System.out.print("======");
       }//end for
       System.out.println();
       
       //prompt the end message
       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;//Hold the category (0 or 1 or 2)
     
       category = -1;//Initialization
       
       //Use while loop and call isValid method in TaxCalculator class
       while(TaxCalculator.isValid(category) != true){
    	   
    	   //Prompt message
    	   System.out.print("\nEnter 0 for non-food, 1 for food, or 2 for prepared: ");
    	      	   
    	   //Try to get the number of category
    	   try{
    		   category = Integer.parseInt(keyboard.nextLine());
    		   
    		   //Echo messages
    		   System.out.println("The number you entered is "+category);
    		   
    		   //Determine whether the enter is correct or not
    		   if(category == 0 || category == 1 || category == 2)
    			   
    			   break;//Break the while loop
    		   
    		   else{
    			   System.out.println("Your enter is invalid, " +
		              "please re-enter a valid number.\n"); 
    		   }//end else
    	   
    	   }//end try
    	   
    	   //Catch a NumberFormatException
    	   catch(NumberFormatException nfe){
    		   System.out.println("Your enter is invalid, " +
    		   		              "please re-enter a valid number.\n"); 		   
    	   
    	   }//end catch	   
    	   
       }//end while       
      
       return category;//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
     * @return         The value 
     */
    private static double requestDouble(String prompt)
    {
       double       value;//Hold the entered number       
       value = 0.0;  //initialization
  	  
       //Use while loop to handle the number of price
       while(true){
    	   
    	   System.out.print(prompt);//Prompt messages
    	   
    	   //Try to get the number of price
    	   try{
    		   value = Double.parseDouble(keyboard.nextLine());//Get the price
    		   
    		   //Echo messages
    		   System.out.println("The price you entered is "+value);
    		   
    		   //Output a warning if user enter a negative value
    		   if(value < 0){
    			   
    			   //Echo messages
    			   System.out.println("\nWarning! You have entered a negative value "+value
    					 +".\nSystem will ignore this number and let the value be 0.\n\n" +
    			   		 "Enter your next item...");
    			   
    			   value = 0.0;//Reset the value
    			   
    			   break;//Break the while loop
    		   }
    		   else{
    			   break;//Break the while loop
    		   }
    			     		   
    	   }// end try
    	   
    	   //Catch the NumberFormatException
    	   catch(NumberFormatException nfe){
    		   //Prompt messages
    		   System.out.println("Your enter is invalid," +
    		   		              "please re-enter a valid number.\n");
    		   
    	   }// end catch  	     	   
       }//end while

       return value;//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
     * @return         The value 
     */
    private static int requestInt(String prompt)
    {
       int          value;//Hold the entered number
       value = 0;//initialization       
       

       
       //Use while loop to handle the number of items
       while(true){
    	   
           System.out.print(prompt);//Prompt messages
    	   
    	   //Try to get the number
    	   try{    		   
    		   value = Integer.parseInt(keyboard.nextLine());
    		   
    		   //Echo messages
    		   System.out.println("The number you entered is "+value);
    		   
    		   //Avoid the negative value
    		   if (value < 0)
    			   System.out.println("Your enter is invalid, " +
    			   		              "please re-enter a valid number.\n");
    		   else
    			   break;//Break the while loop
    		   
    	   }//end try
    	   
    	   //Catch the NumberFormatException
    	   catch(NumberFormatException nfe){
    		   
    		   //Prompt messages
    		   System.out.println("Your enter is invalid, " +
	                              "please re-enter a valid number.\n");
    	   
    	   }//end catch
       }//end while

       return value;//Return value
       
    }//end method

    
}   // end class
