/*
PROGRAM NAME:   Program #3 - Classes
PROGRAMMER:     Daniel Yim
CLASS:          CSC 202.002
INSTRUCTOR:     Dr. Robert G. Strader
DATE DEVELOPED: February 12, 2008
DATE COMPLETED: February 18, 2008
REFERENCES:     Computer Science -
                    Introduction to Java Programming
                    Y. Daniel Liang

STATEMENT:
    This program will build an inventory system capable of being ordered
    in different ways the user wishes.

    The data provided will be:

        1101 Dryer 7 12 5 A 599.99
        1100 Washer  10  12 4 A 799.99
        1001 WoodPannels 25 1 2 B 25.37
        1012 SheetRock 73 2 7 C 18.25
        1206 Tile 248 7 3 C 24.95
        1033 Wood2x4x6 500 1 5 A 10.75
        1314 Bolts 3000 6 2 B 3.27
        1315 Nuts 2500 6 2 C 0.89
        1819 Refrigerator 4 11 1 A 1449.99
        1438 Saw 12 9 3 C 325.00
        1500 Lamp 30 8 1 B 59.95
        1218 Grout 15 7 5 C 34.95
        1603 Pipe 155 5 2 C 12.87
        1650 Connector 385 5 3 B 3.85


    The data provides the item ID number, the item description, the
    quantity of the item stocked, the location of the item (aisle,
    section, and shelf), and the price of each item respectively on
    individual lines.

    The program will then output the following: the highest priced item
    and its record information, all of the records read from the data
    file in their proper formats, and a listing of the items by aisle,
    section, and shelf.

SAMPLE OUTPUT:

        The highest priced item:

            Item:        1819
            Description: Refrigerator
            Quantity:    4
            Location:    Aisle 11, Section 1, Shelf A
            Price:       $1449.99

        Items found on shelf 'C':

            Item: 1603
                Pipe
                155
                Aisle 5, Section 2, Shelf C
                $12.87

            Item: 1315
                Nuts
                2500
                Aisle 6, Section 2, Shelf C
                $0.89

            Item: 1206
                Tile
                248
                Aisle 7, Section 3, Shelf C
                $24.95

            Item: 1218
                Grout
                15
                Aisle 7, Section 5, Shelf C
                $34.95
        
            Item: 1438
                Saw
                12
                Aisle 9, Section 3, Shelf C
                $325.0
        
        
        All items in the inventory:
        
            Item: 1001
                WoodPannels
                25
                Aisle 1, Section 2, Shelf B
                $25.37
        
            Item: 1033
                Wood2x4x6
                500
                Aisle 1, Section 5, Shelf A
                $10.75
        
            Item: 1603
                Pipe
                155
                Aisle 5, Section 2, Shelf C
                $12.87
        
            Item: 1650
                Connector
                385
                Aisle 5, Section 3, Shelf B
                $3.85
        
            Item: 1314
                Bolts
                3000
                Aisle 6, Section 2, Shelf B
                $3.27
        
            Item: 1315
                Nuts
                2500
                Aisle 6, Section 2, Shelf C
                $0.89
        
            Item: 1206
                Tile
                248
                Aisle 7, Section 3, Shelf C
                $24.95
        
            Item: 1218
                Grout
                15
                Aisle 7, Section 5, Shelf C
                $34.95
        
            Item: 1500
                Lamp
                30
                Aisle 8, Section 1, Shelf B
                $59.95
        
            Item: 1438
                Saw
                12
                Aisle 9, Section 3, Shelf C
                $325.0
        
            Item: 1819
                Refrigerator
                4
                Aisle 11, Section 1, Shelf A
                $1449.99
        
            Item: 1100
                Washer
                10
                Aisle 12, Section 4, Shelf A
                $799.99
        
            Item: 1101
                Dryer
                7
                Aisle 12, Section 5, Shelf A
                $599.99



METHODS USED: 
    readValues(Scanner inputFile, ArrayList<Record> arrayListOfRecords)
                This method reads in all the values inside the data
                file and stores them into appropriate data types
                and then into an individual record.
    sortRecords(ArrayList<Record> arr, String method)
                This method will recursively sort all the record
                entries by aisle, section, or shelf according to a
                parameter that is given.
    findItemsOnShelf(ArrayList<Record> arr, char shelf)
                Finds every item placed on a given shelf
    findHighestPrice()
                Finds the highest priced item in the inventory
    printRecords(ArrayList<Record> arr)
                This method prints every record in the array.

DICTIONARY OF VARIABLES:
    public class Program1
        final boolean debug
            A switch to output every action to aid the development
            process
        final int MAX
            A pre-defined maximum of the inventory size
    public static main void
        File dataFile
            A wrapper for the input file to be used
        ArrayList<Record> recordAList
            An ArrayList of type Record used to store each record of
            the inventory
    public static void readValues
        int id
            A temporary storage of an integer for the ID number
        String description
            A temporary storage of a String for the description
        int quantity
            A temporary storage of an integer for the quantity
        double price
            A temporary storage of a double for the price
        int locAisle
            A temporary storage of an integer for the aisle number
        int locSection
            A temporary storage of an integer for the section number
        char locShelf
            A temporary storage of a char for the shelf
        Location loc
            A temporary storage of type Location for a Location object
    public static void sortRecords
        final int MAXAISLES
            Constant set to the maximum number of aisles in the inventory
        final int MAXSECTIONS
            Constant set to the maximum sections in the inventory
        final char MAXSHELVES
            Constant set to the maximum number of shelves in the inventory
        ArrayList<Record> tempAL
            A temporary ArrayList used to be a copy of the unsorted list
            as the method sorts
        ArrayList<Record> tempAisle/tempSection/tempShelf
            Temporary storage for each type (aisle, section, or shelf)
            that is sorted and is awaiting another sort for a subtype
    public static void findItemsOnShelf
        final char MAXSHELVES
            A constant for the maximum number of shelves in the inventory
---------------------------------------------------------------------------
*/

import java.util.*;
import java.io.*;

public class Program3
{
            // Switch to activate the many debug statements in this
            // program
    private static boolean debug = false;
            // A constant to set the max number of records allowed
    public final static int MAX = 25;

// ============================= method main ==============================
    public static void main (String[] args)
    {
        try
        {
                    // Initialize the file
            FileInputStream dataFile 
                = new FileInputStream("prog3.dat"); 
                    // Initialize the scanner
            Scanner in = new Scanner(dataFile);
                    // Initialize an ArrayList where all the records will
                    // be stored.
            ArrayList<Record> recordAList = new ArrayList<Record>();
                    // Reads the values from the file
            readValues(in, recordAList);
                    // Finds the highest priced item
            findHighestPrice();
                    // Sorts the records
            sortRecords(recordAList, "aisle");
                    // Finds all items on a shelf
            findItemsOnShelf(recordAList, 'C');
                    // Prints the records
            printRecords(recordAList);
                    // Closes the file
            in.close();
        }
        catch(FileNotFoundException e)
        {
                    // Display an error if the data file cannot be found
            System.out.println("/////////// ERROR! ///////////");
            System.out.println("The data file cannot be found!");
        }

                // Add lines to the end of the program.
        System.out.println ("\n");
                // Returns to the OS
        return;
    }   // End of public static void main
    

// ========================== method readValues ===========================
/*
METHOD DESCRIPTION:
    This method reads in all the values inside the data file and stores
    them into appropriate data types and then into an individual record
*/
    public static void readValues(Scanner in, ArrayList<Record> arr)
    {
                // General declarations
        int id;
        String description;
        int quantity;
        double price;
        int locAisle;
        int locSection;
        char locShelf;
        Location loc;

        do {
                    // Read in the ID as an integer
            id = Integer.parseInt(in.next());
                    // Read in the description as a string
            description = in.next();
                    // Read in the quantity as an integer
            quantity = Integer.parseInt(in.next());
                    // Read in the location as an int, int, char
            locAisle = Integer.parseInt(in.next());
            locSection = Integer.parseInt(in.next());
            locShelf = in.next().charAt(0);
            loc = new Location(locAisle, locSection, locShelf);
                    // Read in the price as a double
            price = Double.parseDouble(in.next());

                    // Store all the data collected into one record entry
            arr.add(new Record(id, description, quantity, price, loc));


                    // Debug outputs
            if(debug){
                System.out.println("\n== NEW ENTRY ==");
                System.out.println("id: " + id);
                System.out.println("description: " + description);
                System.out.println("quantity: " + quantity);
                System.out.println("locAisle: " + locAisle);
                System.out.println("locSection: " + locSection);
                System.out.println("locShelf: " + locShelf);
                System.out.println("loc: " + loc);
                System.out.println("price: " + price);
            }
        } while(in.hasNext());
                // Continue while there are values to be read

    }           // End of public static void readValues

// =========================== method sortRecords =========================
/*
METHOD DESCRIPTION:
    This method will recursively sort all the record entries by aisle,
    section, or shelf according to a parameter that is given
*/
    public static void sortRecords(ArrayList<Record> arr, String method)
    {
        final int MAXAISLES = 12;       // Assumes 1 to 12
        final int MAXSECTIONS = 5;      // Assumes 1 to 5
        final char MAXSHELVES = 'C';    // Assumes A to C


                // Sort by aisle
        if(method == "aisle")
        {
            if (debug) System.out.println("<<< SORTING BY AISLE >>>");
                    // Copy of the original ArrayList
            ArrayList<Record> tempAL = new ArrayList<Record>();
                    // Copy of the sorted aisle
            ArrayList<Record> tempAisle;
                    // Copies all of the elements of the unsorted array
            tempAL.addAll(arr); 
                    // Clears the array of its unsorted records
            arr.clear();

            Iterator<Record> it;
            for(int k = 1; k <= MAXAISLES; k++)
            {
                        // Creates a new storage medium for a sorted
                        // aisle
                tempAisle = new ArrayList<Record>();
                it = tempAL.iterator();
                while(it.hasNext())
                {
                            // Placeholder for the next entry
                    Record currentRec = (Record)it.next();
                    if(currentRec.getLocation().getAisle() == k)
                                // Adds to the sorted aisle ArrayList
                        tempAisle.add(currentRec);
                }
                        // Sorts this recently sorted aisle by section
                sortRecords(tempAisle, "section");
                        // Appends the sorted aisle that is sorted by
                        // section
                arr.addAll(tempAisle);
            }
        }

                // Sort by section
        else if(method == "section")
        {
            if (debug) System.out.println("<<< SORTING BY SECTION >>>");
                    // Copy of the original ArrayList
            ArrayList<Record> tempAL = new ArrayList<Record>();
                    // Copy of the sorted section
            ArrayList<Record> tempSection;
                    // Copies all of the elements of the unsorted array
            tempAL.addAll(arr); 
                    // Clears the array of its unsorted records
            arr.clear();

            Iterator<Record> it;
            for(int k = 1; k <= MAXSECTIONS; k++)
            {
                        // Creates a new storage medium for a sorted
                        // section
                tempSection = new ArrayList<Record>();
                it = tempAL.iterator();
                while(it.hasNext())
                {
                            // Placeholder for the next entry
                    Record currentRec = (Record)it.next();
                    if(currentRec.getLocation().getSection() == k)
                        tempSection.add(currentRec);
                }
                        // Sorts this recently sorted section by shelf
                sortRecords(tempSection, "shelf");
                        // Appends the sorted section that is sorted by
                        // shelf
                arr.addAll(tempSection);
            }
        }

                // Sort by shelf
        else if(method == "shelf")
        {
            if (debug) System.out.println("<<< SORTING BY SHELF >>>");
                    // Copy of the original ArrayList
            ArrayList<Record> tempAL = new ArrayList<Record>();
                    // Copies all of the elements of the unsorted array
            tempAL.addAll(arr); 
                    // Clears the array of its unsorted records
            arr.clear();

            Iterator<Record> it;
            for(char k = 'A'; k <= MAXSHELVES; k++)
            {
                it = tempAL.iterator();
                while(it.hasNext())
                {
                            // Placeholder for the next record
                    Record currentRec = (Record)it.next();
                    if(currentRec.getLocation().getShelf() == k)
                        arr.add(currentRec);
                }
            }
        }
    }           // End of public static void sortRecords


// ======================= method findItemsOnShelf ========================
/*
METHOD DESCRIPTION:
    Finds every item placed on a given shelf
*/
    public static void findItemsOnShelf(ArrayList<Record> arr, char shelf)
    {
        final char MAXSHELVES = 'C';    // Assumes A to C

        System.out.println("Items found on shelf '" + shelf + "':\n");
        Iterator<Record> it = arr.iterator();
        while(it.hasNext())
        {
            Record currentRec = (Record)it.next();
            if(currentRec.getLocation().getShelf() == shelf)
               currentRec.printRecord("    ");
        }
    }           // End of public static void findItemsOnShelf


// ======================= method findHighestPrice ========================
/*
METHOD DESCRIPTION:
    Finds the highest priced item in the inventory
*/
    public static void findHighestPrice()
    {
                    // Prints the highest priced item's record data
            System.out.println("\f\n\nThe highest priced item:\n");
            System.out.println("    Item:        "
                + Record.getHighPrice().getId());
            System.out.println("    Description: "
                + Record.getHighPrice().getDescription());
            System.out.println("    Quantity:    "
                + Record.getHighPrice().getQuantity());
            System.out.println("    Location:    "
                + Record.getHighPrice().getLocation());
            System.out.println("    Price:       $"
                + Record.getHighPrice().getPrice() + "\n");

    }           // End of public static void findHighestPrice


// =========================== method printRecords ========================
/*
METHOD DESCRIPTION:
    This method prints every record in the array
*/
    public static void printRecords(ArrayList<Record> arr)
    {
        System.out.println("\nAll items in the inventory:\n");
        for(int k = 0; k < arr.size(); k++)
            arr.get(k).printRecord("    ");

    }           // End of public static void printRecords

}   // End of public class Program3


