import java.io.*;
import java.util.*;

/**
 * A simple driver that can be used to test the Lot and
 * Catalog classes
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Auctioneer
{
    private static boolean          prompt;    
    private static PrintStream      tape;    
    private static String[]         description = {"NA", "NA"};



    /**
     * The entry point for the application
     *
     * Command line arguments:
     *
     *   args[0] contains the catalog #
     *   args[1] contains the prefix of the output file
     *   args[2] contains the prefix of the input  file
     *
     * If the command line arguments are missing, the
     * user will be prompted for the information.
     *
     * @param args   The command line arguments
     */
    public static void main(String[] args)
    {
       BufferedReader     bidReader, keyboard;
       Catalog            catalog;
       String             catFile, number, outputFile, testFile;


       keyboard = new BufferedReader(
          new InputStreamReader(System.in));

       // Get the catalog number
       if ((args.length != 0))
       {
          number = args[0];
       }
       else
       {
          number = requestString(keyboard, "Catalog Number: ", "");
       }
       

       // Get the name of the output file
       outputFile = null;
       if (args.length > 1)
       {
          outputFile = args[1];
       }
       else
       {
          outputFile = requestString(keyboard,
                                     "Output File Prefix "+
                                     "(e.g., actual NOT actual1.txt) "+
                                     " or [Enter]: ",
                                     "actual");
       }
       
       

       // Create the PrintStream for output
       tape = System.out;      
       if ((outputFile != null) && !outputFile.equals(""))
       {
          try
          {
             tape = new PrintStream(new File(outputFile+number+".txt"));     
          }
          catch (IOException ioe)
          {
             tape = System.out;
          }
       }

       

       // Read the Catalog
       catalog = null;       
       catFile = "catalog"+number+".txt";       
       try
       {
          catalog = readCatalog(catFile);
       }
       catch (IOException ioe)
       {
          System.err.println("Unable to read catalog named " + catFile);
          System.exit(0);          
       }
       

       // Get the name of the input file
       testFile = null;
       if (args.length > 2)
       {
          testFile = args[2];
       }
       else
       {
          testFile = requestString(keyboard,
                                   "Input File Prefix "+
                                   "(e.g., test NOT test1.txt) "+
                                   " or [Enter] :",
                                   "test");
       }


       
       // Create the BufferedReader used to read bids
       try
       {
          bidReader = new BufferedReader(
             new InputStreamReader(
                new FileInputStream(testFile+number+".txt")));

          prompt = false;          
       }
       catch (IOException ioe)
       {
          bidReader = keyboard;
          prompt = true;          
       }


       
       // Output before the auction
       tape.println("Before the Auction\n" + catalog.toString());
       

       // Start the auction
       startAuction(catalog, bidReader);

       // Output after the auction
       tape.println();       
       tape.println("After  the Auction\n" + catalog.toString());
       tape.println();       
       tape.printf("Total Sales: %8.2f\n",catalog.totalValue());       

    }




    /**
     * Create a Lot from a String representation
     *
     * Note: This method does no error-checking
     *
     * @param line   The String representation
     * @return       The Lot
     */
    private static Lot parseLot(String line)
    {
       double            reserve;
       Lot               lot;
       String            number, token;
       StringTokenizer   st;
	

       st = new StringTokenizer(line,",");
       number = st.nextToken();
       description[0] = st.nextToken();
       description[1] = st.nextToken();
       token  = st.nextToken();
       reserve = Double.parseDouble(token);

       lot = new Lot(number, description, reserve);

       return lot;
    }



    /**
     * Read a String representation of a Catalog
     * from a file
     *
     * Note: This method does no error-checking
     *
     * @param fileName  The name of the file
     * @return          The Catalog
     */
    private static Catalog readCatalog(String filename) throws IOException
    {
       BufferedReader    in;
       Catalog           catalog;
       Lot               lot;
       String            line;       

       in = new BufferedReader(
          new InputStreamReader(
             new FileInputStream(filename)));
       
       catalog = new Catalog(filename);
		
       while ((line = in.readLine()) != null)
       {
          lot = parseLot(line);
          catalog.addLot(lot);
       }    

       return catalog;       
    }


    /**
     * Request a String from the user
     *
     * @param in      The BufferedReader to read from
     * @param prompt  The prompt
     * @param def     The def return value
     */
    private static String requestString(BufferedReader in, 
                                        String prompt, String def)
    {
       String  result;
       

       System.out.print(prompt);
       try
       {
          result = in.readLine();
       }
       catch (IOException ioe)
       {
          result = def;
       }

       return result;       
    }
    
    


    /**
     * Start an auction using a given Catalog, 
     * reading bids from the given BufferedReader
     *
     * @param catalog        The Catalog to use
     * @param BufferedReader The stream containing the bids
     */
    private static void startAuction(Catalog catalog, BufferedReader bidReader)
    {
       boolean            doneBidding;
       double             bid;
       int                bidder;
       Lot                lot;
       String             line, token;
       StringTokenizer    st;


       while (catalog.hasMoreLots())
       {
          doneBidding = false;
          lot = catalog.nextLot();
          
          tape.printf("Now accepting bids on lot: %5s\n", lot.getNumber());

          do
          {
             if (prompt) tape.printf("Bid (ID,Amount or ID or * to QUIT): ");

             try
             {
                line = bidReader.readLine();
                if (line.indexOf("*") >= 0)
                {
                   doneBidding = true;
                   lot.close();                   
                }
                else
                {
                   st = new StringTokenizer(line, ",");
                   token = st.nextToken();
                   try
                   {
                      bidder = Integer.parseInt(token);
                      
                      if (st.hasMoreTokens()) // Explicit Bid
                      {
                         token = st.nextToken();
                         bid   = Double.parseDouble(token);
                         catalog.acceptBid(bid, bidder);
                      }   
                      else                   // Next acceptable increment
                      {
                         catalog.acceptBid(bidder);
                      }
                   }
                   catch (NumberFormatException nfe)
                   {
                      // Ignore
                   }   
                }
             }    
             catch (IOException ioe)
             {
                // Couldn't read
             }

          } while (!doneBidding);
	       
       }

    }
}
