Appendix C- Warehouse Simulation Code

BehaviorSpace.java

package team64.madkit;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Console;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.UUID;
/**
 * This is a utility used to launch Warehouse multiple times. It sets up the
 * simulation, changing one parameter, then starts the Warehouse main.
 *
 * @author Team 64 New Mexico Supercomputing Challenge
 * @2012
 *
 */
public class BehaviorSpace {

        UUID setID = UUID.randomUUID();
        public static void main (String args[]){
                BehaviorSpace space = new BehaviorSpace();
        }
        //args in order of: WarehouseName, # of items, # of orders, max orders at one time, speed, shelf height, MultiPick ("true"/"false"), UUID, show graphics ("true"/"false")
        public String[] toArray(String WarehouseName, int numberOfItems, int numberOfOrders, int maxOrdersAtSameTime, int updateSpeed, int shelfHeight, boolean Multipick, UUID setID, boolean showGraphics, String notes){
                String[] args = new String[10];
                args[0] = WarehouseName;
                args[1] = numberOfItems+"";
                args[2] = numberOfOrders+"";
                args[3] = maxOrdersAtSameTime+"";
                args[4] = updateSpeed+"";
                args[5] = shelfHeight+"";
                if (Multipick){
                        args[6] = "true";
                }else{
                        args[6] = "false";
                }
                args[7] = setID.toString().replace('-', '0');
                if (showGraphics){
                        args[8] = "true";
                }else{
                        args[8] = "false";
                }
                args[9] = notes;
                return args;
        }

        

int simulationsRun = 0;
int simulationsLaunched = 0;

        public BehaviorSpace(){
                System.out.println("Args in order of: WarehouseName, # of items, # of orders, max orders at one time, speed, shelf height, MultiPick (true/false), UUID, showGraphics (true/false), notes, totecapacity");
                for (int x = 0; x < 3; x++){
                for (int i = 0; i < 5; i++){
                        //String[] args = toArray("large3.t64",200,10,4,5,1,true,setID);
                        //new RunThread(i) {
                               
                                //@Override public void run() {

                                        String[] args = toArray("large3.t64",100,25,5,5,1,true,setID,false,"Iterating number of orders at the same time with multipick");

                                        System.out.println("Simulation "+i+" is starting with parameters " + Arrays.toString(args));
                                        try {

                                                Runtime r = Runtime.getRuntime();
                                                //System.out.println("java -classpath ./team64.jar;./madkitkernel-5.0.0.14.jar; team64.madkit.Warehouse ../database/hsqldb_1_8_1_1.jar "+args[0]+" "+args[1]+" "+args[2]+" "+args[3]+" "+args[4]+" "+args[5]+" "+args[6]+" "+args[7], null, null)");
                                                final Process p = r.exec("cmd /k java -classpath ./bin;./madkitkernel-5.0.0.14.jar;./database/hsqldb_1_8_1_1.jar; team64.madkit.Warehouse "+args[0]+" "+args[1]+" "+args[2]+" "+args[3]+" "+args[4]+" "+args[5]+" "+args[6]+" "+args[7]+" "+args[8]+" "+args[9]+"", null, null);

                                                //System.out.println(p);

                    final BufferedReader stdOut = new BufferedReader(new InputStreamReader(p.getInputStream()));
                    final BufferedReader stdErr = new BufferedReader(new InputStreamReader(p.getErrorStream()));


                                                // Thread that reads std out and feeds the writer given in input
                                                new Thread() {
                                                        @Override public void run() {

                                                        }
                                                }.start(); // Starts now

                                                // Thread that reads std out and feeds the writer given in input
                                                new Thread() {
                                                        @Override public void run() {
                                                                String line;
                                                                try {
                                                                        while ((line = stdErr.readLine()) != null) {
                                                                        //             System.err.println(line );
                                                                        }
                                                                } catch (Exception e) {throw new Error(e);}
                                                                try {                          
                                                                        stdErr.close();

                                                                } catch (IOException e) { /* Who cares ?*/ }
                                                        }
                                                }.start(); // Starts now

                                                String line = "";
                                                try {
                                                        while ((line) != null) {
                                                                line = stdOut.readLine();
                                                        //       System.out.println(line) ;
                                                                if (line.contains("Your simulation is now ready to exit for the enjoyment of the world.")){
                                                                        System.out.println("Simulation "+i+" is closing");
                                                                        try {
                                                                                //out.flush();
                                                                                stdOut.close();
                                                                        } catch (IOException e) { /* Who cares ?*/ }
                                                                        line = null;
                                                                }
                                                        }
                                                } catch (Exception e) {throw new Error(e);}
                                                try {
                                                        //out.flush();
                                                        stdOut.close();
                                                } catch (IOException e) { /* Who cares ?*/ }


                                                // System.out.println("</ERROR>");
                                                //this.wait();
                                                //int exitVal = p.waitFor();
                                                //System.out.println("Process exitValue: " + p.exitValue());
                                        } catch (IOException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }// catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        //e.printStackTrace();
                                        //catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        // e.printStackTrace();
                                        //}
                        //   }
                        //}.start();
                        //simulationsLaunched++;
                }
                //while(simulationsRun<simulationsLaunched){
                        //delay
                //}
                }
                System.exit(0);
        }
         
        private class RunThread extends Thread{
                int runNumber;
                public RunThread(int i){
                        runNumber = i;
                }
        }
        //}
}

Warehouse.java

package team64.madkit;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;

import madkit.kernel.Agent;
import madkit.kernel.AgentAddress;
import madkit.kernel.Madkit;
import madkit.kernel.Madkit.LevelOption;
import madkit.kernel.Madkit.Option;
import madkit.kernel.Message;
import team64.madkit.messages.GoToDestinationMessage;
import team64.madkit.messages.LunchMessage;
import team64.madkit.messages.MoveTote;
import team64.madkit.messages.NewLocationMessage;
import team64.madkit.messages.NewOrder;
import team64.madkit.messages.SetLocationMessage;
import team64.madkit.messages.ToteMessage;


/**
 * Warehouse contains the Main for running the simulation. It sets up the
 * simulation and launches all the agents
 *
 * @author Team 64 New Mexico Supercomputing Challenge
 * @2012
 *
 */
public class Warehouse extends Agent {

        /**
         * time in milliseconds for conveyor updates. Workers work at a multiple
         * (5x) rate
         */
        protected static int updateSpeed = 50;
        /**
         * Delay between repaints of the watcher
         */
        protected static int graphicsSpeed = 50;
        /** the number of orders to process for this run */
        public static int numberOfOrders = 10;
        /** the number of items to store in the warehouse */
        public static int numberOfItemsInWarehouse = 100;
        /** the maximum number of orders we can have on the conveyor system */
        private static int maxOrdersInProcess = 2;
        /** the number of conveyor segments between totes */
        protected static int toteSpacing = 2;
        /** flag for simulation in run state */
        static boolean simulationRunning = true;
        /** frame to display while initializing */
        static JFrame waitDialog = new JFrame();
        /** option to run without the graphical display */
        protected static boolean showWarehouseGraphics;
        /**
         * only for the Test Demo - whether or not to make a path through the
         * shelves
         */
        protected static boolean usingPath = true;
        /**
         * This is a note in the database about how we selected items from the
         * database. It will usually be 'database asc order' or 'random'
         */
        protected static String itemSetup = "database asc order";
        /**
         * sort items on shelves by popularity (more popular closer to picking
         * station
         */
        protected static boolean sortByPopularity = false;
        /**
         * try to give each item stop an equal number of items if set to true.
         * Otherwise we fill up the shelves in each item stop then go on to the next
         * one. This only works if each item stop domain has equal access to shelves
         */
        protected static boolean distributeItemsEvenly = false;

        // static AgentAddress myOwnAddress=null;
        /**
         * size of the warehouse in grid units (basically a grid unit holds one
         * tote, one conveyor segment, one worker, or a tote + conveyor segment)
         */
        protected static int warehouseWidth;
        protected static int warehouseHeight;
        /** the number of pickers is generally the same as the item stops */
        protected static int numberOfPickers = 0;
        /** item stops in the simulation layout */
        protected static int numberOfItemStops = 0;
        /**
         * the number of active picking stations will be less than or equal to the
         * number of item stops. If not all shelves are filled in the warehouse then
         * an picking stations (item stop) may not be in use.
         */
        protected static int activeStations = 0;
        protected static ArrayList<ItemStop> itemStops;
        protected static String stopListString = "";
        /** set of item stop locations so we can easily find a close one when needed */
        protected static HashSet<Point> itemStopLocations = new HashSet<Point>();
        protected static Point workerStartingLocation;
        /**
         * this is the layout file used to generate the warehouse. If null we use a
         * default test layout
         */
        protected static String layoutFileName = null;
        /** number of steps in the simulation from the simulation scheduler */
        protected static long steps = 0;
        /** step number when we launch the first order tote */
        protected static long startStep = 0;
        /** step number when all orders are filled */
        protected static long endStep = 0;

        /** set to true to signal the first order */
        private boolean firstOrder = true;

        /** the simulation scheduler. Each tic is a simulation step. */
        protected Timer simulationScheduler;

        /** random number generator */
        protected Random r = new Random();

        /** schedules worker actions for the simulation */
        protected WorkerScheduler workerScheduler;

        protected ConveyorScheduler conveyorScheduler;

        /** schedules the conveyor system actions for the simulation */
        protected ConveyorSystem conveyorSystem;

        /** schedules the painting of the main warehouse graphics */
        protected DisplayScheduler displayScheduler;
        /**
         * sets up probes for the agents in the warehouse and sets up the main
         * graphical display
         */
        protected WarehouseWatcher warehouseWatcher;

        /** order in progres panel */
        protected OrderWatcher orderWatcher;

        /**
         * sets up the layout of the warehouse
         */
        protected WarehouseLayout warehouseLayout = new WarehouseLayout();
        /**
         * rand is used to randomly move an agent 1 grid step when needed 0=no
         * movement, 1=+1, 2=-1
         */
        protected static Random rand = new Random();
        /** keep a set of totes to process later that have incomplete orders */
        public static List<Tote> incompleteToteList = new ArrayList<Tote>();

        /** an x-y array of grid units */
        private static GridUnit[][] grid = null; // the environment grid
        /** database connection */
        static Connection conn; // connection to the database
        protected String dburl = "jdbc:hsqldb:hsql://localhost/DistriButionCenter";
        protected String user = "SA";
        protected String password = "";
        /** the id from the "runs" table (known after we store the start timestamp) */
        protected static int runID = 0;
        /** the total number of simulation steps from start to finish */
        protected long processSteps;

        /** the hashtable of orders to pick */
        static private Hashtable<Integer, List<Integer>> orders;
        /** enumeration of the orders hashtable so we can iterate through it */
        protected Enumeration orderIDs;
        /**
         * the next order that will be processed. If this is -1 no orders have been
         * started If this is -99 then all orders are in process or finished
         */
        protected static int nextOrderID = -1;
        /**
         * the set of orders that are in process. If this set is empty either the
         * order process has not been started OR it is all finished
         */
        protected static ArrayList<Integer> ordersInProcess = new ArrayList<Integer>();

        /** hashtable of an item id and which bin it is stored in */
        static private Hashtable<Integer, StorageBin> itemLocations;

        // private List tasks = new ArrayList();
        /** the maximum number of items for a tote */
        static final int toteCapacity = 15;

        /** the default number of bins in a shelf */
        static int shelfHeight = 1;

        protected static int zoneSingle = 1;
        protected static int zoneMulti = 2;
        protected static int discreteSingle = 3;
        protected static int discreteMulti = 4;
        public static int workerSteps;

        /**
         * the picking mode, one of discrete (0), zoneSingle (1), zoneMulti (2).
         * zone = picker assigned to a station zoneMulti = picker has a list of
         * items to get then returns to tote at the item stop zoneSingle = picker
         * gets one item at a time from the shelves discrete = picker has no
         * specific area for picking items discreteMulti = picker has a list of
         * items to get then returns to tote at the item stop discreteSingle =
         * picker gets one item at a time from the shelves
         *
         * */
        protected static int pickingMode = zoneSingle;

        /** used for demo layout */
        protected static boolean useDemoStop1;
        protected static boolean useDemoStop2;
        protected static boolean useDemoStop3;
        protected static boolean useDemoStop4;

        public static GridUnit[][] getGrid() {
                if (grid == null) {
                        grid = new GridUnit[warehouseWidth][warehouseHeight];
                }
                return grid;
        }

        /** public access method for getting a Grid Unit in the grid */
        public static GridUnit getGridUnit(int x, int y) {
                return grid[x][y];
        }

        protected void activate() {
                waitDialog.setVisible(false);
                getLogger().setWarningLogLevel(Level.INFO);
                setLogLevel(Level.FINE);
                createGroupIfAbsent("warehouse", "conveyorsystem", true, null);// needs
                // to be
                // in
                // this
                // group
                // to
                // send
                // messages
                // to
                // conveyors
                createGroupIfAbsent("warehouse", "workers", true, null); // needs to be
                // in this
                // group to
                // send
                // messages
                // to
                // workers
                createGroupIfAbsent("warehouse", "warehouse", true, null);

                requestRole("warehouse", "warehouse", "warehouse");
                requestRole("warehouse", "workers", "warehouse");
                requestRole("warehouse", "conveyorsystem", "warehouse");

                // requestRole("warehouse","conveyorsystem","manager");
                setOrders(new Hashtable());
                // Make the database connection ...
                try {
                        // System.out.println( Class.forName("org.hsqldb.jdbcDriver"));
                        Class.forName("org.hsqldb.jdbcDriver").newInstance();

                        conn = DriverManager.getConnection(dburl, user, password);
                        System.out.println("Database connection established");
                } catch (Exception ex) {
                        ex.printStackTrace();
                        System.out.println("Exception: " + ex.getMessage()
                                        + ". Did you forget to start the database?");
                        System.exit(99);
                }

                // the master warehouse layout
                launchAgent(warehouseLayout);
                // now we can launch other agents from the initialize method
                warehouseLayout.initialize(true);
                workerStartingLocation = warehouseLayout.entranceLocation;
                itemStops = new ArrayList<ItemStop>();
                itemStops = warehouseLayout.itemStops;

                // we can either randomly stock shelves or apply an algorithm to stock
                // in a logical manner by popularity or "on sale" items
                // randomlyStockShelves(numberOfItemsInWarehouse);
                // stock shelves the same way every run
                stockShelves(numberOfItemsInWarehouse);
                // domains must be calculated AFTER the shelves are stocked
                calculateDomains();
                System.out.println("getting orders from database");
                getOrders(numberOfItemsInWarehouse, numberOfOrders);
                // Now we are ready to start processing orders
                // launch a picker for each item stop
                for (int i = 0; i < warehouseLayout.itemStops.size(); i++) {
                        Picker picker = new Picker();
                        picker.destination = warehouseLayout.itemStops.get(i)
                                        .getSegmentInfo().getSegmentLocation();
                        // Point behind = stop.segmentInfo.getBehindLocation();
                        warehouseLayout.itemStops.get(i).picker = picker;
                        picker.setPickerStopAssignment(warehouseLayout.itemStops.get(i));
                        // set picker color to match domain color
                        Color domainColor = warehouseLayout.itemStops.get(i).stopInfo.domainColor;
                        picker.workerInfo.setWorkerColor(domainColor);
                        launchAgent(picker, 10, false);
                        warehouseLayout.itemStops.get(i).picker = picker;
                        picker.workerInfo.setLocation(warehouseLayout.itemStops.get(i)
                                        .getBehindLocation());
                        picker.sendMessage("warehouse", "workers", "warehouse",
                                        new SetLocationMessage(warehouseLayout.itemStops.get(i)
                                                        .getBehindLocation()));
                        numberOfPickers++;
                }
                numberOfItemStops = warehouseLayout.itemStops.size();
                stopListString = "";

                for (int i = 0; i < warehouseLayout.itemStops.size(); i++) {
                        Point stopLocation = warehouseLayout.itemStops.get(i)
                                        .getSegmentInfo().getSegmentLocation();
                        String stopString = "[" + stopLocation.x + "," + stopLocation.y
                                        + "] ";
                        stopListString = stopListString + stopString;
                        itemStopLocations.add(stopLocation);
                }

                // System.out.println("initiate a tote");
                // initiateBasicTote(toteLauncherLocation);
                // ArrayList order = new ArrayList();

                // order.add(30);
                // orders.put(0,order);
                // conveyorSystem= new ConveyorSystem();
                // launchAgent(conveyorSystem,false);AddTask
                // launchTotes(2);

                // test only

                /*
                 * AgentAddress s = getAgentWithRole("warehouse", "workers", "sorter");
                 * grid[0][0].addAgent(p); boolean result =
                 * grid[0][0].checkOccupantCompatibility(s); result =
                 * grid[0][1].checkOccupantCompatibility(s);
                 *
                 * AgentAddress t = getAgentWithRole("warehouse", "container", "tote");
                 *
                 * AgentAddress cs = getAgentWithRole("warehouse","conveyorsystem",
                 * "segment");
                 *
                 * grid[2][2].addAgent(cs); result =
                 * grid[2][2].checkOccupantCompatibility(t); result =
                 * grid[2][2].checkOccupantCompatibility(s);
                 */

                simulationScheduler = new Timer();
                if (logger != null) {
                        logger.info("Started the Simulation Scheduler");
                }
                launchAgent(simulationScheduler, false);
                workerScheduler = new WorkerScheduler();
                if (logger != null) {
                        logger.info("Launching worker scheduler");
                }
                launchAgent(workerScheduler, false);

                conveyorScheduler = new ConveyorScheduler();
                if (logger != null) {
                        logger.info("Launching conveyor scheduler");
                }
                launchAgent(conveyorScheduler);

                if (showWarehouseGraphics) {
                        /** set up a watcher for the warehouse with a graphical display */
                        warehouseWatcher = new WarehouseWatcher(this);
                        launchAgent(warehouseWatcher, true);
                        /** set up a scheduler for the watcher */
                        displayScheduler = new DisplayScheduler();
                        launchAgent(displayScheduler, false);

                        orderWatcher = new OrderWatcher();
                        launchAgent(orderWatcher, true);

                }

        }

        /**
         * this attempts to distribute the inventory items evenly to all item stops
         * 
         * @param numberOfItems
         */
        protected void evenlyStockShelves(int numberOfItems) {
                itemSetup = "database asc order";
                // get items from database
                // hashtable keyed on bin slots
                setItemLocations(new Hashtable(numberOfItems));
                // precalculte a set of shelves that are closest to each item stop

                for (int s = 0; s < numberOfItemStops; s++) {

                }

                ResultSet rs = null;
                try {
                        if (conn != null) {
                                System.out.println("Database connection exists");
                        }
                        Statement st = conn.createStatement();

                        String table = "Items";
                        // Select items (0-99) from the database in a random order
                        String sql = "SELECT id,popularity,size FROM items where id<"
                                        + numberOfItems + " ORDER BY id asc";
                        rs = st.executeQuery(sql); // run the query

                        int stopIndex = 0;
                        for (int i = 0; i < numberOfItems; i++) {
                                rs.next();
                                int itemID = rs.getInt("id");
                                int popularity = rs.getInt("popularity");
                                int size = rs.getInt("size");
                                // use the next item stop for this item
                                // ItemStop stop =

                                getItemLocations().put(itemID,
                                                (StorageBin) warehouseLayout.allBins.get(i));
                                ((StorageBin) warehouseLayout.allBins.get(i)).setItemId(itemID);
                                ((StorageBin) warehouseLayout.allBins.get(i))
                                                .setQuantity(((StorageBin) warehouseLayout.allBins
                                                                .get(i)).getMax());
                                logger.fine("Stocked item "
                                                + itemID
                                                + " in bin at "
                                                + ((StorageBin) warehouseLayout.allBins.get(i))
                                                                .getLocation());
                        }
                        System.out.println("Stocked " + numberOfItems
                                        + " items in the warehouse.");
                } catch (SQLException se) {
                        System.out.println("SQLException: " + se.getMessage());
                        se.printStackTrace();
                }

        }

        /**
         * distributes items into the shelves (bins) with the more popular items
         * closer to the item stop
         */
        protected void stockShelvesbyPopularity(int numberOfItems) {
                // get items from database
                // hashtable keyed on bin slots
                itemSetup = "random by popularity";
                setItemLocations(new Hashtable(numberOfItems));

                ResultSet rs = null;
                try {
                        if (conn != null) {
                                System.out.println("Database connection exists");
                        }
                        Statement st = conn.createStatement();

                        String table = "Items";
                        // Select items (0-99) from the database in a random order
                        String sql = "SELECT id,popularity,size FROM items where id<"
                                        + numberOfItems + " ORDER BY RAND()";
                        rs = st.executeQuery(sql); // run the query

                        for (int i = 0; i < numberOfItems; i++) {
                                rs.next();
                                int itemID = rs.getInt("id");
                                int popularity = rs.getInt("popularity");
                                int size = rs.getInt("size");
                                getItemLocations().put(itemID,
                                                (StorageBin) warehouseLayout.allBins.get(i));
                                ((StorageBin) warehouseLayout.allBins.get(i)).setItemId(itemID);
                                ((StorageBin) warehouseLayout.allBins.get(i))
                                                .setQuantity(((StorageBin) warehouseLayout.allBins
                                                                .get(i)).getMax());
                                logger.fine("Stocked item "
                                                + itemID
                                                + " in bin at "
                                                + ((StorageBin) warehouseLayout.allBins.get(i))
                                                                .getLocation());
                        }
                        System.out.println("Stocked " + numberOfItems
                                        + " items in the warehouse.");
                } catch (SQLException se) {
                        System.out.println("SQLException: " + se.getMessage());
                        se.printStackTrace();
                }
        }

        /** distributes items into the shelves (bins) */
        protected void randomlyStockShelves(int numberOfItems) {
                // get items from database
                // hashtable keyed on bin slots
                setItemLocations(new Hashtable(numberOfItems));
                itemSetup = "database random order";
                ResultSet rs = null;
                try {
                        if (conn != null) {
                                System.out.println("Database connection exists");
                        }
                        Statement st = conn.createStatement();

                        String table = "Items";
                        // Select items (0-99) from the database in a random order
                        String sql = "SELECT id,popularity,size FROM items where id<"
                                        + numberOfItems + " ORDER BY RAND()";
                        rs = st.executeQuery(sql); // run the query

                        for (int i = 0; i < numberOfItems; i++) {
                                rs.next();
                                int itemID = rs.getInt("id");
                                int popularity = rs.getInt("popularity");
                                int size = rs.getInt("size");
                                getItemLocations().put(itemID,
                                                (StorageBin) warehouseLayout.allBins.get(i));
                                ((StorageBin) warehouseLayout.allBins.get(i)).setItemId(itemID);
                                ((StorageBin) warehouseLayout.allBins.get(i))
                                                .setQuantity(((StorageBin) warehouseLayout.allBins
                                                                .get(i)).getMax());
                                logger.fine("Stocked item "
                                                + itemID
                                                + " in bin at "
                                                + ((StorageBin) warehouseLayout.allBins.get(i))
                                                                .getLocation());
                        }
                        System.out.println("Stocked " + numberOfItems
                                        + " items in the warehouse.");
                } catch (SQLException se) {
                        System.out.println("SQLException: " + se.getMessage());
                        se.printStackTrace();
                }
        }

        /** distributes items into the shelves (bins) */
        protected void stockShelves(int numberOfItems) {
                itemSetup = "database asc order";
                // get items from database
                // hashtable keyed on bin slots
                setItemLocations(new Hashtable(numberOfItems));

                ResultSet rs = null;
                try {
                        if (conn != null) {
                                System.out.println("Database connection exists");
                        }
                        Statement st = conn.createStatement();

                        String table = "Items";
                        // Select items (0-99) from the database in a random order
                        String sql = "SELECT id,popularity,size FROM items where id<"
                                        + numberOfItems + " ORDER BY id asc";
                        rs = st.executeQuery(sql); // run the query

                        for (int i = 0; i < numberOfItems; i++) {
                                rs.next();
                                int itemID = rs.getInt("id");
                                int popularity = rs.getInt("popularity");
                                int size = rs.getInt("size");
                                getItemLocations().put(itemID,
                                                (StorageBin) warehouseLayout.allBins.get(i));
                                ((StorageBin) warehouseLayout.allBins.get(i)).setItemId(itemID);
                                ((StorageBin) warehouseLayout.allBins.get(i))
                                                .setQuantity(((StorageBin) warehouseLayout.allBins
                                                                .get(i)).getMax());
                                logger.fine("Stocked item "
                                                + itemID
                                                + " in bin at "
                                                + ((StorageBin) warehouseLayout.allBins.get(i))
                                                                .getLocation());
                        }
                        System.out.println("Stocked " + numberOfItems
                                        + " items in the warehouse.");
                } catch (SQLException se) {
                        System.out.println("SQLException: " + se.getMessage());
                        se.printStackTrace();
                }
        }

        /**
         * this calculates the shortest path between the picking station (item stop)
         * and an item bin. the item id with the shortest path is added to the
         * "domain" of the item stop
         */
        public void calculateDomains() {
                // calculate domains only if there is at least one item stop AND there
                // is at least one storage bin
                activeStations = 0;
                if (warehouseLayout.itemStops.size() > 0
                                && warehouseLayout.allBins.size() > 0) {
                        // for each bin find the closest item stop
                        for (int i = 0; i < warehouseLayout.allBins.size(); i++) {
                                StorageBin bin = warehouseLayout.allBins.get(i);
                                if (bin.getItemId() > 0) { // skip item ids of -1 (no items in
                                                                                        // the bin)
                                        Router pather = new Router();
                                        int bestPath = 9999;
                                        ItemStop bestStop = null;
                                        // find which stop is closest to this bin
                                        for (int p = 0; p < warehouseLayout.itemStops.size(); p++) {
                                                ItemStop stop = warehouseLayout.itemStops.get(p);
                                                List<Point> path = pather.getBestPath(
                                                                bin.getLocation(),
                                                                stop.segmentInfo.getSegmentLocation());
                                                pather.overlayElement[bin.getLocation().x][bin
                                                                .getLocation().y].setStart(false);
                                                pather.overlayElement[stop.segmentInfo
                                                                .getSegmentLocation().x][stop.segmentInfo
                                                                .getSegmentLocation().y].setEnd(false);
                                                if (path.size() == 0) {
                                                        System.out.println("Skipping");

                                                }
                                                // System.out.println("Is "+ path.size() +" less than "
                                                // + bestPath+"?");
                                                if (path.size() < bestPath) {
                                                        bestPath = path.size();
                                                        bestStop = stop;
                                                }

                                        }
                                        bestStop.stopInfo.domain.add(bin.getItemId());
                                        // set color of the grid for this bin to the domain color
                                        grid[bin.getLocation().x][bin.getLocation().y]
                                                        .setStopDomainColor(bestStop.stopInfo
                                                                        .getDomainColor());
                                        logger.fine("Added item " + bin.getItemId()
                                                        + " to domain for item stop at "
                                                        + bestStop.segmentInfo.getSegmentLocation().x + ","
                                                        + bestStop.segmentInfo.getSegmentLocation().y);

                                }

                        }

                        for (int p = 0; p < warehouseLayout.itemStops.size(); p++) {
                                ItemStop stop = warehouseLayout.itemStops.get(p);
                                if (stop.stopInfo.domain.size() > 0) {
                                        activeStations++;
                                }
                                logger.fine("Item Stop at "
                                                + stop.segmentInfo.getSegmentLocation().x + ","
                                                + stop.segmentInfo.getSegmentLocation().y + " has "
                                                + stop.stopInfo.domain.size() + " items in its domain");
                        }
                        /*
                         * //set the domain color for each bin for (int p = 0; p <
                         * warehouseLayout.itemStops.size(); p++){ ItemStop stop =
                         * warehouseLayout.itemStops.get(p); Color domainColor =
                         * stop.stopInfo.domainColor; for (int b = 0; b <
                         * warehouseLayout.allBins.size(); b++){ StorageBin bin =
                         * warehouseLayout.allBins.get(b); int itemID = bin.getItemId(); if
                         * (itemID >-1 && stop.stopInfo.domain.contains(itemID)){
                         * bin.setBinColor(domainColor); } }
                         */

                }
        }

        /**
         * read a number of orders from the pre-generated order database table ...
         * which table depends on number of items
         */
        protected void getOrders(int numberOfItems, int numberOfOrders) {

                String orderTableName = "OrdersFor" + numberOfItems + "Items";
                ResultSet rs = null;
                try {
                        // System.out.println(conn);
                        Statement st = conn.createStatement();

                        String table = "Items";
                        // orders in a specific sequence
                        String sql = "SELECT id,qty,items FROM " + orderTableName
                                        + " where id<" + numberOfOrders + " ORDER BY ID ASC";
                        // orders in a random sequence (but still same orders as above)
                        // String sql = "SELECT id,qty,items FROM " + orderTableName +
                        // " where id<" + numberOfOrders + " ORDER BY RAND()";
                        rs = st.executeQuery(sql); // run the query

                        for (int i = 0; i < numberOfOrders; i++) {
                                rs.next();
                                int orderID = rs.getInt("id");
                                int qyt = rs.getInt("qty");
                                String orderList = rs.getString("items");
                                // make the list of item Integers...
                                List<Integer> order = new ArrayList();
                                String[] items = orderList.split(",");
                                for (int item = 0; item < qyt; item++) {
                                        order.add(Integer.parseInt(items[item]));
                                }
                                orders.put(orderID, order);
                                logger.fine("Order " + orderID + " contains items " + orderList);
                        }
                } catch (SQLException se) {
                        System.out.println("SQLException: " + se.getMessage());
                        se.printStackTrace();
                }
                orderIDs = orders.keys();
        }

        /**
         * This is called by the Timer scheduler. This checks if a new tote needs to
         * be spawned and keeps track of the orders in process.
         */
        protected void orderProcessor() {

                if (firstOrder == true) {
                        recordStart();
                        firstOrder = false;
                }
                if (ordersInProcess.size() < maxOrdersInProcess && spawnerExists()
                                && !orders.isEmpty()) {
                        if (orderIDs.hasMoreElements()) {
                                nextOrderID = (Integer) orderIDs.nextElement();
                                ordersInProcess.add(nextOrderID);
                                sendMessage("warehouse", "conveyorsystem", "spawner",
                                                new NewOrder(nextOrderID));
                        } else {
                                if (!incompleteToteList.isEmpty()) {
                                        sendMessage("warehouse", "conveyorsystem", "spawner",
                                                        new ToteMessage(incompleteToteList.get(0)));
                                        ordersInProcess.add(incompleteToteList.get(0).toteInfo
                                                        .getOrderNumber());
                                        incompleteToteList.remove(0);
                                }
                        }
                }
        }

        /** checks to see if the tote spawner has been launched yet */
        protected boolean spawnerExists() {

                if (getAgentsWithRole("warehouse", "conveyorsystem", "spawner") != null) {
                        return true;
                }
                return false;
        }

        /** runs continuously while the Warehouse is running */
        protected void live() {
                boolean color = false;
                while (simulationRunning) {
                        pause(updateSpeed);
                        if (getOrders().isEmpty() && ordersInProcess.isEmpty()) {
                                recordEnd();
                        }
                }

        }

        /** returns a GridUnit with an agent of this specific AgentAddress */
        private GridUnit findAgent(AgentAddress address) {
                for (int i = 0; i < warehouseWidth; i++) {
                        for (int p = 0; p < warehouseHeight; p++) {
                                if (grid[i][p].getOccupants().contains(address)) {
                                        return grid[i][p];
                                }
                        }
                }
                return null;
        }

        /** returns 0, +1 or -1 for a random grid movement */
        public static int getRandomStep() {
                int step = rand.nextInt(3);
                return step - 1;
        }

        private AgentAddress getPickerAtLocation(int x, int y) {
                this.sendMessage("warehouse", "workers", "pickers", new Message());
                return null;

        }

        private List<Point> addPoints(List<List<Point>> points, List<Point> list) {
                for (int i = 0; i < points.size(); i++) {
                        List<Point> innerList = points.get(i);
                        for (int p = 0; p < innerList.size(); p++) {
                                list.add(innerList.get(p));
                        }
                }
                // System.out.println("added list = " +list.size());
                return list;
        }

        /**
         * Returns an array list of valid grid units surrounding the grid unit at
         * Point p
         */
        public static List<Point> getSorrounding(Point p) {
                List<Point> open = new ArrayList<Point>();
                open.add(new Point(p.x + 1, p.y));
                open.add(new Point(p.x, p.y + 1));
                open.add(new Point(p.x + 1, p.y + 1));
                open.add(new Point(p.x - 1, p.y));
                open.add(new Point(p.x - 1, p.y - 1));
                open.add(new Point(p.x, p.y - 1));
                open.add(new Point(p.x + 1, p.y - 1));
                open.add(new Point(p.x - 1, p.y + 1));

                // System.out.println("valid open size = " + validOpen.size());
                return open;
        }

        public static List<Point> getAdjacent(Point p) {
                List<Point> open = new ArrayList<Point>();
                open.add(new Point(p.x + 1, p.y));
                open.add(new Point(p.x, p.y + 1));
                open.add(new Point(p.x - 1, p.y));
                open.add(new Point(p.x, p.y - 1));

                // System.out.println("valid open size = " + validOpen.size());
                return open;
        }

        private void launchPickers(int numberOfPickers) {
                if (logger != null)
                        logger.info("Launching " + numberOfPickers + " pickers");

                for (int i = 0; i < numberOfPickers; i++) {
                        launchAgent(new Picker(), 10, false);
                }
        }

        /** End Agent */
        protected void end() {
                simulationRunning = false;
                // pickersList=null;
                // sortersList=null;
                if (logger != null) {
                        logger.info("Stopping Warehouse Simulation");
                }
                // stop all the schedulers
                conveyorScheduler.end();
                workerScheduler.end();
                displayScheduler.end();
        }

        /** called by framework to set up graphics for this Agent */
        public void setupFrame(JFrame frame) {
                JPanel panel = new JPanel();
                panel.setBounds(0, 0, 240, 280);
                panel.add(new JLabel(
                                "Please wait while the simulation is initialized..."));
                frame.setTitle("Please Wait...");
                frame.add(panel);
                frame.setSize(500, 350);
                waitDialog = frame;
        }

        protected void lunch() {
                broadcastMessage("warehouse", "workers", "picker",
                                new GoToDestinationMessage(new Point(warehouseWidth - 1, 2)));
        }

        public void receiveMessage(Message m) {
                getLogger().setWarningLogLevel(Level.INFO);
                setLogLevel(Level.FINE);
                // System.out.println("Warehouse got a message: " + m);
                if (m != null) {
                        if (logger != null) {
                                logger.finest("Warehouse got a Message from " + m.getSender()
                                                + " says: " + m.toString());
                        }

                        // used for testing - make workers go to the lunchroom
                        if ((m instanceof LunchMessage)) {
                                lunch();
                        }

                        // this message is sent by the conveyors to request a tote movement
                        if ((m instanceof MoveTote)) {
                                handleMoveToteMessage(m);
                        }

                        // this message is sent constantly by the pickers when moving
                        else if ((m instanceof NewLocationMessage)) {
                                AgentAddress address = m.getSender();
                                logger.finest("New Location Message Received by Warehouse, reply will be sent back to sender.");
                                Point oldLocation = ((NewLocationMessage) m).getOldLocation();
                                Point newLocation = ((NewLocationMessage) m).getNewLocation();
                                logger.finer("Worker moving from " + oldLocation + " to "
                                                + newLocation);
                                // make sure location request is within warehouse bounds
                                boolean locationInBounds = checkBounds(newLocation);
                                if (locationInBounds) {
                                        GridUnit newLoc = grid[newLocation.x][newLocation.y];
                                        GridUnit oldLoc = grid[oldLocation.x][oldLocation.y];
                                        if (!newLoc.isBlocked()) {
                                                oldLoc.removeAgent(address);
                                                newLoc.addAgent(address);
                                                // send back message confirming move
                                                sendReply(m, new NewLocationMessage(oldLocation,
                                                                newLocation));
                                        } else {// could not move
                                                // send back message with old location (agent did not
                                                // move)
                                                logger.severe("Agents not compatible (move not completed) at "
                                                                + oldLocation + " to " + newLocation);
                                                sendReply(m, new NewLocationMessage(oldLocation,
                                                                oldLocation));
                                        }
                                } else {// new location was not in the bounds of the warehouse
                                        // send back message with old location (agent did not
                                        // move)
                                        logger.fine("New Location was not in the warehouse bounds (move not completed) at "
                                                        + oldLocation + " to " + newLocation);
                                        sendReply(m, new NewLocationMessage(oldLocation,
                                                        oldLocation));
                                }
                        }
                        // used when warehouse objects are first set into the Grid
                        else if (m instanceof SetLocationMessage) {
                                AgentAddress address = m.getSender();
                                logger.finer("Set Location Message Received by Warehouse.");
                                Point location = ((SetLocationMessage) m).getlocation();
                                GridUnit loc = grid[location.x][location.y];
                                loc.addAgent(address);
                        } else {// no handler for this kind of message
                                System.out.println("Warehouse got a strange message from "
                                                + m.getSender());
                        }
                }
        }

        /** handler for the MoveTote message */
        protected void handleMoveToteMessage(Message m) {
                Point p2 = ((MoveTote) m).getDestination();
                MoveTote mt = (MoveTote) m;
                Tote tote = mt.getTote();

                if (tote == null) {
                        System.out.println("tote is null, cannot move tote");
                }

                try {
                        int orderNumber = tote.toteInfo.orderNumber;
                        if (getOrders().get(orderNumber).isEmpty()) {
                                logger.finest("tote has a complete order ...");
                                // keep tote moving along to the End segment
                                if (grid[p2.x][p2.y].containsConveyor()) {
                                        sendMessage((grid[p2.x][p2.y].occupants.get(0)),
                                                        new ToteMessage(((MoveTote) m).getTote()));
                                }
                                return;
                        }

                        else if (orderNumber != -1
                                        && (tote.toteInfo.filled < Warehouse.toteCapacity)) {
                                // check for an item stop next to the segment where this tote
                                // is...
                                List<Point> neighbors = getAdjacent(((MoveTote) m).getFrom());// checks
                                                                                                                                                                // neighbors
                                                                                                                                                                // of
                                                                                                                                                                // the
                                                                                                                                                                // destination
                                ArrayList<Point> intersection = new ArrayList<Point>(neighbors);
                                intersection.retainAll(itemStopLocations);
                                if (!intersection.isEmpty()) {
                                        // stop is next to us so we need to check if the orde
                                        // contains an item in this stop's domain
                                        // which stop is this?
                                        Point stopLocation = intersection.get(0); // there should be
                                                                                                                                // only one
                                        // get the the item stop at this location
                                        ItemStop stop = getItemStopAtLocation(stopLocation);
                                        if (stop != null) {// it should not be null, but better
                                                                                // check
                                                if (getNextItemAtStop(orderNumber, stop) != -1
                                                                && stop.tote == null) {
                                                        // send tote to the item stop if there is no tote
                                                        // there already
                                                        sendMessage(
                                                                        (grid[stopLocation.x][stopLocation.y].occupants
                                                                                        .get(0)), new ToteMessage(tote));
                                                        return;
                                                }
                                                // send the tote to the next conveyor segment, this stop
                                                // is not in our order
                                                else if (grid[p2.x][p2.y].containsConveyor()) {
                                                        sendMessage((grid[p2.x][p2.y].occupants.get(0)),
                                                                        new ToteMessage(tote));
                                                        return;
                                                }
                                        }
                                }
                        }

                } catch (NullPointerException e) {
                        System.err.println(e);
                        System.err.println(((MoveTote) m).getTote());
                        System.out
                                        .println("Warehouse NPE in message handler .. THIS IS THE ONE ^^^^^^^^^^^^^^^^^^^^^");
                }
                if (grid[p2.x][p2.y].containsConveyor()) {
                        sendMessage((grid[p2.x][p2.y].occupants.get(0)), new ToteMessage(
                                        tote));
                }

        }

        /** provides access to lunchroom layout */
        protected Point getLunchroomLocation() {
                return warehouseLayout.lunchroomLocation;
        }

        /** provides access to lunchroom layout */
        protected Dimension getLunchroomSize() {
                return new Dimension(warehouseLayout.lunchroomWidth,
                                warehouseLayout.lunchroomDepth);
        }

        /**
         * convenience method to check if a location point is OK (within the
         * warehouse bounds)
         */
        private boolean checkBounds(Point location) {
                if ((location.x > Warehouse.warehouseWidth - 1) || (location.x < 0)) {
                        return false;
                }
                if ((location.y > Warehouse.warehouseHeight - 1) || (location.y < 0)) {
                        return false;
                }

                return true;
        }

        /** startup per instructions in the Madkit kernal API */
        public static void startupSimulation() {
                // executeThisAgent(args, 1, true);
                String[] argss = { LevelOption.agentLogLevel.toString(), "FINE",
                                Option.launchAgents.toString(),// gets the -- launchAgents
                                                                                                // string
                                Warehouse.class.getName() + ",false,1;" };
                Madkit.main(argss);
        }

        static String notes;

        /**
         * @param args
         */

        public static void main(String[] args) {
                // args in order of: WarehouseName, # of items, # of orders, max orders
                // at one time, speed, shelf height, MultiPick ("true"/"false")
                if (args.length > 0) {
                        // if these trys catch anything it will simple revert to the
                        // defaults as already set
                        layoutFileName = args[0];
                        System.out.println("filename of warehouse is " + layoutFileName);
                        try {
                                numberOfItemsInWarehouse = Integer.parseInt(args[1]);
                        } catch (Exception e) {

                        }
                        try {
                                numberOfOrders = Integer.parseInt(args[2]);
                        } catch (Exception e) {

                        }
                        try {
                                maxOrdersInProcess = Integer.parseInt(args[3]);
                        } catch (Exception e) {

                        }
                        try {
                                updateSpeed = Integer.parseInt(args[4]);
                        } catch (Exception e) {

                        }
                        try {
                                shelfHeight = Integer.parseInt(args[5]);
                        } catch (Exception e) {

                        }
                        try {
                                if (args[6].equals("true")) {
                                        pickingMode = zoneMulti;
                                } else {
                                        pickingMode = zoneSingle;
                                }

                        } catch (Exception e) {

                        }
                        try {
                                setID = args[7];
                        } catch (Exception e) {

                        }
                        try {
                                if (args[8].equals("true")) {
                                        showWarehouseGraphics = true;
                                } else {
                                        showWarehouseGraphics = false;
                                }

                        } catch (Exception e) {

                        }
                        try {
                                notes = args[9];
                        } catch (Exception e) {

                        }
                        startupSimulation();

                } else {
                        final JFrame setup = new SetupFrame();
                        setup.setName("SetupFrame");
                        setup.setSize(600, 500);
                        final ParameterPanel pp = new ParameterPanel();
                        setup.add(pp);
                        setup.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                        // create custom close operation
                        setup.addWindowListener(new WindowAdapter() {
                                public void windowClosing(WindowEvent e) {
                                        maxOrdersInProcess = Integer
                                                        .parseInt(pp.txtMaxOrdersInProcess.getText());
                                        updateSpeed = Integer.parseInt(pp.txtUpdateSpeed.getText());
                                        numberOfOrders = Integer.parseInt(pp.textFieldOrders
                                                        .getText());
                                        shelfHeight = Integer.parseInt(pp.txtShelfHeight.getText());
                                        numberOfItemsInWarehouse = (int) ((Integer) pp.comboBoxItems
                                                        .getSelectedItem());
                                        useDemoStop1 = pp.chkLoc1.isSelected();
                                        useDemoStop2 = pp.chkLoc2.isSelected();
                                        useDemoStop3 = pp.chkLoc3.isSelected();
                                        useDemoStop4 = pp.chkLoc4.isSelected();

                                        if (pp.comboBox.getSelectedItem() == null) {
                                                layoutFileName = "Demo Test";
                                        } else {
                                                layoutFileName = (String) pp.comboBox.getSelectedItem();
                                        }

                                        boolean useZone = pp.chckbxZone.isSelected();
                                        boolean useMulti = pp.chckbxMulti.isSelected();
                                        if (useZone && useMulti) {
                                                pickingMode = zoneMulti;
                                        } else if (useZone && !useMulti) {
                                                pickingMode = zoneSingle;
                                        } else if (!useZone && useMulti) {
                                                pickingMode = discreteMulti;
                                        } else if (!useZone && !useMulti) {
                                                pickingMode = discreteSingle;
                                        }

                                        if (layoutFileName.equals("Browse...")) {
                                                JFileChooser chooser = new JFileChooser();

                                                FileFilter filter = new FileFilter() {

                                                        public boolean accept(File f) {
                                                                String ext = "";
                                                                String s = f.getName();
                                                                int i = s.lastIndexOf('.');

                                                                if (i > 0 && i < s.length() - 1) {
                                                                        ext = s.substring(i + 1).toLowerCase();
                                                                }
                                                                if (ext.toLowerCase().equals("t64")) {
                                                                        return true;
                                                                }
                                                                return false;
                                                        }

                                                        public String getDescription() {
                                                                // TODO Auto-generated method stub
                                                                return "Team 64 Warehouse Layout Files";
                                                        }

                                                };
                                                chooser.setFileFilter(filter);
                                                chooser.setCurrentDirectory(new File("./"));
                                                chooser.showDialog(pp, "Open Layout File (*.t64)");
                                                layoutFileName = chooser.getSelectedFile().getPath();
                                        }
                                        setup.dispose();
                                        // start the database
                                        Runtime r = Runtime.getRuntime();
                                        try {
                                                r.exec("org.hsqldb.Server");
                                        } catch (IOException e1) {
                                                // error could be that it is running already or some
                                                // other problem
                                                // check if port 9001 is open
                                                try {
                                                        ServerSocket srv = new ServerSocket(9001);
                                                        srv.close();
                                                        srv = null;
                                                } catch (java.net.BindException e3) {
                                                        // socket is in use, good...
                                                        System.out.println("HSQLDB already running (OK)");
                                                } catch (IOException e2) {
                                                        // really is not running :(
                                                        System.out
                                                                        .println("Could  not start the HSQLDB Server");
                                                        System.exit(99);
                                                }
                                        }

                                        startupSimulation();
                                }
                        });

                        setup.setVisible(true);
                }
                /*
                 * try{ updateSpeed = Integer.parseInt(JOptionPane.showInputDialog
                 * ("What speed would you like to run at?",50)); }catch(Exception e){
                 * updateSpeed = 50; } try{ numberOfOrders =
                 * Integer.parseInt(JOptionPane.showInputDialog
                 * ("How many orders should be processed?",10)); }catch(Exception e){
                 * numberOfOrders = 10; } try{ numberOfItemsInWarehouse =
                 * Integer.parseInt(JOptionPane.showInputDialog
                 * ("How many items should be placed in the warehouse?",100));
                 * }catch(Exception e){ numberOfItemsInWarehouse = 100; } try{
                 * shelfHeight = Integer.parseInt(JOptionPane.showInputDialog
                 * ("How many bins should be in each shelf?",1)); }catch(Exception e){
                 * shelfHeight = 1; } try{ maxOrdersInProcess =
                 * Integer.parseInt(JOptionPane.showInputDialog
                 * ("How many orders should be processed at the same time?",1));
                 * }catch(Exception e){ maxOrdersInProcess = 1; }
                 *
                 * //waitDialog.add(new
                 * JLabel("Please wait while the simulation is initiated..."));
                 * //waitDialog.setSize(400, 100); //waitDialog.setVisible(true);
                 */

        }

        // results in order of: steps,

        public void sendEndToListeners() {
                System.out.println("Trying to run end listeners");
                for (BehaviorSpace space : listeners) {
                        System.out.println("Running end listener");
                }
        }

        ArrayList<BehaviorSpace> listeners = new ArrayList<BehaviorSpace>();

        public void addEndListener(BehaviorSpace space) {
                System.out.println("Adding end listener");
                listeners.add(space);
        }

        /**
         * a method called every simulation tic by Timer so we can increment a
         * counter
         */
        public void tic() {
                steps++;
        }

   /** public access to the orders */
        public static Hashtable<Integer, List<Integer>> getOrders() {
                return orders;
        }

        /** public access the orders */
        public static void setOrders(Hashtable<Integer, List<Integer>> orders) {
                Warehouse.orders = orders;
        }

        /** get the itemLocations hashtable */
        public static Hashtable<Integer, StorageBin> getItemLocations() {
                return itemLocations;
        }

        /** set the itemLocations hashtable */
        public static void setItemLocations(
                        Hashtable<Integer, StorageBin> itemLocations) {
                Warehouse.itemLocations = itemLocations;
        }

        /**
         * removes all orders from the order list and ordersInProcess list. This
         * means all orders are complete.
         */
        public static void removeOrderFromLists(int orderNumber) {
                orders.remove((Object) orderNumber);
                ordersInProcess.remove((Object) orderNumber);
                System.out.println("ORDER " + orderNumber + " IS COMPLETE");
        }

        /** when a tote has an item added to it, it is removed from the order */
        public static void removeItemFromOrder(int orderNumber, int itemID) {
                List<Integer> orderList = orders.get(orderNumber);
                if (orderList != null) {
                        if (orderList.isEmpty()) {
                                // the next time botherworker is called we will send the tote
                                // away
                                System.out.println("Order list is empty for order "
                                                + orderNumber + ". This order is complete");

                        } else {
                                orderList.remove((Object) itemID);
                                // logger.fine("removed item " + itemID +
                                // " from order "+orderNumber);
                        }
                }
        }

        /** gets the next item in the order */
        public static int getNextItem(int orderNumber) {
                List orderList = orders.get(orderNumber);
                if (orderList.isEmpty()) {
                        return -1;
                }
                return (Integer) orderList.get(0);
        }

        /** the picker needs to know which item is next in the order */
        public static int getNextItemAtStop(int orderNumber, ItemStop is) {
                // System.out.println(
                // "stop domain before selecting next item "+is.stopInfo.domain);
                int itemToReturn = -1;
                List<Integer> orderList = orders.get(orderNumber);
                // System.out.println(orderList);

                if (orderList != null) {
                        if (orderList.isEmpty()) {
                                itemToReturn = -1;
                        } else {
                                int nextItem = (Integer) orderList.get(0);
                                if (is.stopInfo.domain.contains((Object) nextItem)) {
                                        itemToReturn = nextItem;
                                }
                        }
                } else {
                        itemToReturn = -1;
                }
                // System.out.println("Next item to pick --->> " + itemToReturn +
                // " stop domain "+is.stopInfo.domain);
                return itemToReturn;
        }

        /**
         * the whole list of items for the Item Stop. Had to make sure we returned a
         * copy of the items, not the items themselves
         */
        public static ArrayList<Integer> getItemsAtStop(int orderNumber, ItemStop is) {
                List orderList = orders.get(orderNumber);
                ArrayList<Integer> ordersForThisStop = new ArrayList<Integer>();
                if (orderList != null) {
                        if (orderList.isEmpty()) {
                                return ordersForThisStop; // will be empty
                        }

                        for (int i = 0; i < orderList.size(); i++) {
                                int nextItem = (Integer) orderList.get(i);
                                if (is.stopInfo.domain.contains(nextItem)) {
                                        ordersForThisStop.add(new Integer(nextItem));
                                }
                        }
                        return ordersForThisStop;
                }
                return null; // only sends back null if warehouse orders is null
        }

        /** gets the location of the bin that has this item with itemID */
        public static Point getItemLocation(int itemID) {
                StorageBin bin = getItemLocations().get(itemID);
                Point itemLocation = bin.getLocation();
                return itemLocation;
        }

        /** returns the item stop agent at the specified location */
        public ItemStop getItemStopAtLocation(Point loc) {
                ItemStop stop = null;
                for (int x = 0; x < warehouseLayout.itemStops.size(); x++) {
                        if (warehouseLayout.itemStops.get(x).segmentInfo
                                        .getSegmentLocation().equals(loc)) {
                                stop = warehouseLayout.itemStops.get(x);
                                // System.out.println("found a stop");
                                x = warehouseLayout.itemStops.size();
                        }
                }
                return stop;
        }

        /**
         * this is called exactly one time per simulation to log the staring step
         * from when the first order tote is launched
         */
        public static void recordStart() {
                Statement st;
                ResultSet rs = null;
                // store start step in the database
                startStep = steps;
                // store the timestamp and get the runID from the database
                long timeMillis = System.currentTimeMillis();
                Timestamp startTime = new Timestamp(timeMillis);
                try {
                        st = conn.createStatement();
                        String sql = "insert into xruns (rundate) values ('" + startTime
                                        + "')";
                        System.out.println(sql);
                        st.executeQuery(sql);
                } catch (SQLException e) {
                        e.printStackTrace();
                        System.out
                                        .println("Could not start a simulation run because couuld not record start time in database");
                        System.exit(99);
                }
                // get the runid
                try {
                        st = conn.createStatement();
                        rs = st.executeQuery("select id from xruns where rundate='"
                                        + startTime + "'");
                        rs.next();
                        runID = rs.getInt("id");
                } catch (SQLException e) {
                        e.printStackTrace();
                        System.out
                                        .println("Could not start a simulation run because couuld not get run id from the database");
                        System.exit(99);
                }

        }

        static String setID = null;

        /**
         * this is called exactly one time per simulation to log the ending step
         * when all orders are filled
         */
        public static void recordEnd() {
                endStep = steps;
                // store the timestamp and get the runID from the database
                long timeMillis = System.currentTimeMillis();
                Date startTime = new Date(timeMillis);
                try {
                        Statement st = conn.createStatement();
                        String sql = "update xruns set steps = " + (endStep - startStep)
                                        + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);
                        // number of pickers is number of item stops

                        sql = "update xruns set pickers = " + numberOfPickers
                                        + " ,stations =" + numberOfItemStops + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        sql = "update xruns set orders = " + numberOfOrders + " ,items ="
                                        + numberOfItemsInWarehouse + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        sql = "update xruns set systemMax = " + maxOrdersInProcess
                                        + ", speed=" + updateSpeed + ",shelfheight=" + shelfHeight
                                        + "  where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        if (pickingMode == zoneSingle || pickingMode == zoneMulti) {
                                sql = "update xruns set zone = true where id=" + runID;
                        } else {
                                sql = "update xruns set zone = false where id=" + runID;
                        }
                        System.out.println(sql);
                        st.executeQuery(sql);

                        if (pickingMode == zoneMulti || pickingMode == discreteMulti) {
                                sql = "update xruns set multi = true where id=" + runID;
                        } else {
                                sql = "update xruns set multi = false where id=" + runID;
                        }

                        System.out.println(sql);
                        st.executeQuery(sql);

                        sql = "update xruns set itemsorting = '" + itemSetup
                                        + "',distributeEvenly = " + distributeItemsEvenly
                                        + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        sql = "update xruns set activestations = " + activeStations
                                        + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        String pathAdd = "";
                        if (layoutFileName == null || layoutFileName == "Demo Test") {
                                layoutFileName = "default";
                                if (usingPath) {
                                        pathAdd = " with path";
                                }
                        }

                        // if the layout file has a path, remove the path for storing in
                        // database
                        File layout = new File(layoutFileName);
                        layoutFileName = layout.getName();
                        sql = "update xruns set layout = '" + layoutFileName
                                        + "' where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        sql = "update xruns set graphics = " + showWarehouseGraphics
                                        + " where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);

                        String notes = "stops " + stopListString + pathAdd;
                        sql = "update xruns set notes = '" + notes + "' where id=" + runID;
                        System.out.println(sql);
                        st.executeQuery(sql);
                        if (setID != null) {

                                sql = "update xruns set RUNSETID = '" + setID + "' where id="
                                                + runID;
                                System.out.println(sql);
                                st.executeQuery(sql);
                        }

                } catch (SQLException e) {
                        e.printStackTrace();
                        System.out
                                        .println("FAILURE: Could not record end data in database");
                        System.exit(99);
                }

                // now it will end the simulation
                System.out
                                .println("Your simulation is now ready to exit for the enjoyment of the world.");
                System.exit(0);

        }

}

WarehouseLayout.java

                      * Warehouse layout initializes the areas and systems of the warehouse.
 * It can be done manually or by reading a file from the Warehouse Layout Designer.
 * This uses the Warehouse.grid for the layout template. The constructor does a lot
 * of the work and needs to be called before any schedulers are started.
 * (c) 2012 Team 64 New Mexico Supercomputing Challenge
 */
package team64.madkit;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;
import java.util.zip.GZIPInputStream;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import madkit.kernel.AbstractAgent;
import team64.madkit.messages.SetLocationMessage;

/**
 * @author team64 New Mexico Supercomputing Challenge
 * @2012
 *
 */
public class WarehouseLayout extends AbstractAgent  {

        /**
         * size of the warehouse in grid units (basically a grid unit holds one
         * tote, one conveyor segment, one worker, or a tote + conveyor segment)
         */
        protected  int warehouseWidth;
        protected  int warehouseHeight;
        protected  Random r=new Random();

        protected  int lunchroomWidth;
        protected  int lunchroomDepth;
        protected  Point lunchroomLocation;
        protected  Point entranceLocation;
        protected  Point toteLauncherLocation;

        protected Hashtable <Integer,StorageBin> itemLocations;
        protected ArrayList <StorageBin> allBins = new ArrayList<StorageBin>();
        protected ArrayList <ConveyorSegment> conveyorSegments = new ArrayList<ConveyorSegment>();
        protected ArrayList <ItemStop> itemStops = new ArrayList<ItemStop>(); //a separate list of just the item stops
        
        protected Point demoStop1 = new Point(4,4);
        protected Point demoStop2 = new Point (10,4);
        protected Point demoStop3 = new Point(4,11);
        protected Point demoStop4 = new Point (14,11);
        protected boolean useStop1 = true;
        protected boolean useStop2 = true;
        protected boolean useStop3 = false;
        protected boolean useStop4 = false;
        

        /** Generic Constructor */
        void WarehouseLayout() {

        };

        /** only needed so that this can be launched and launch the warehouse agents in the layout */
        public void activate() {

        }

        /** Start layout with a layout file or use defaults if no file */
        public  void initialize(boolean inputFile) {

                if (Warehouse.layoutFileName.equals("Demo Test")) {
                        //use test defaults
                        if (Warehouse.usingPath) {
                                setupWarehouseWithTestDefaultsAndPathway();                        
                        } else {
                                setupWarehouseWithTestDefaults();                          
                        }
                }else if (Warehouse.layoutFileName.equals("Warehouse 1")){
                        Warehouse.layoutFileName="large3.T64";
                }
                else if (Warehouse.layoutFileName.equals("Warehouse 2")){
                        Warehouse.layoutFileName="large3.T64";
                }
                else if (Warehouse.layoutFileName.equals("Warehouse 3")){
                        Warehouse.layoutFileName="large3.T64";
                }
                if (!Warehouse.layoutFileName.equals("Demo Test")){
                        importGrid(Warehouse.layoutFileName);
                }

                System.out.println("Initialized Warehouse Layout");
        }

        public void setupGrid(){
                Warehouse.warehouseWidth = getWarehouseWidth();
                Warehouse.warehouseHeight = getWarehouseHeight();
                Warehouse.getGrid();
                for (int column = 0; column < warehouseWidth; column++) {
                        for (int row = 0; row < warehouseHeight; row++) {
                                Warehouse.getGrid()[column][row] = new GridUnit();
                        }
                }
        }

        public void placeShelf(Point p){
                for (int i = 0; i < Warehouse.shelfHeight; i++){
                        StorageBin bin = new StorageBin(100, p);
                        Warehouse.getGrid()[p.x][p.y].addBin(bin);                                                                          
                        bin.setItemId(-1);//indicate no item in the bin yet
                        allBins.add(bin);
                }
        }

        /** returns whether or not the point is in the lunchroom */
        public  boolean inLunchRoom(Point p){
                //creates an arbitrary rectangle that can be checked to contain a point
                Rectangle lunch = new Rectangle(lunchroomLocation.x,lunchroomLocation.y,lunchroomWidth,lunchroomDepth);
                if (lunch.contains(p)){
                        return true;
                }
                return false;
        }

        /** Creates the conveyor segments in specified locations and directions */

        private List<ConveyorSegment> setupConveyorSystem() {          
                List<ConveyorSegment> conveyorSegments = null;

                return conveyorSegments;
        }


        /** sets up the default conveyor system */
        private  void createDefaultConveyorCircle() {

                // create, launch, and configure a bunch of conveyor segments
                //conveyor segment needs to know which one is its NEXT link
                //public static int right=0;  
                //public static int up=1;
                //public static int left=2;
                //public static int down=3;

                Point location = new Point (0,0);
                for (int x = 2; x < 20; x++) {
                        location = new Point(x, 3);
                        addConveyorSegment(ConveyorSegment.right,location);
                        location = new Point(x, 10);
                        addConveyorSegment(ConveyorSegment.left,location);                  
                }

                location = new Point(20, 10);
                addConveyorSegment(ConveyorSegment.left,location);    

                location = new Point(1,3);
                addConveyorSegment(ConveyorSegment.right,location);  

                for (int y = 4; y < 10; y++){

                        location = new Point(20, y);
                        addConveyorSegment(ConveyorSegment.up,location);    

                        if (y!=8&&y!=7&&y!=6){                      
                                location = new Point(1, y);
                                addConveyorSegment(ConveyorSegment.down,location);
                        }
                }

                location = new Point(20, 3);
                addConveyorSegment(ConveyorSegment.up,location);      

                location = new Point(1, 10);
                addConveyorSegment(ConveyorSegment.down,location);    

                //for all the conveyor segments, automatically find the next
                //segment in the flow direction


        }

        /** instantiates and launches a conveyor segment at the specified location */
        protected void addConveyorSegment(int direction,Point location){
                ConveyorSegment cs = new ConveyorSegment(direction);
                cs.segmentInfo.setSegmentLocation(location);
                cs.segmentInfo.setNextSegmentLocation(cs.findNextLocation());
                launchAgent(cs);              
                //This sends a message to the warehouse to add this to the grid
                cs.sendMessage("warehouse","conveyorsystem","warehouse", new SetLocationMessage(new Point(cs.segmentInfo.getSegmentLocation().x,cs.segmentInfo.getSegmentLocation().y)));
                conveyorSegments.add(cs);        
        }


        /** arrange the storage bins for default warehouse setup */
        private void placeBinsWhereOpen(){    
                for (int i = 0; i < warehouseWidth; i=i+1){
                        for (int p = 0; p < warehouseHeight; p++){                          
                                if (Warehouse.getGrid()[i][p].occupants.isEmpty()){                                
                                        try{
                                                if(!inLunchRoom(new Point(i,p)) && Warehouse.getGrid()[i][p].path==false){
                                                        if ((Warehouse.getGrid()[i+1][p].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i-1][p].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i][p+1].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i][p-1].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i+1][p-1].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i-1][p-1].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i-1][p+1].occupants.isEmpty()&&
                                                                        Warehouse.getGrid()[i+1][p+1].occupants.isEmpty())){
                                                                if ((Warehouse.getGrid()[i+1][p].bins.isEmpty()&&
                                                                                Warehouse.getGrid()[i-1][p].bins.isEmpty()
                                                                                )){
                                                                        if ((Warehouse.getGrid()[i][p+1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i+1][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i-1][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i-1][p+1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i+1][p+1].bins.isEmpty())){

                                                                                placeShelf(new Point (i,p));
                                                                        }
                                                                }else{
                                                                        if ((Warehouse.getGrid()[i][p+1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i+1][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i-1][p-1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i-1][p+1].bins.isEmpty()&&
                                                                                        Warehouse.getGrid()[i+1][p+1].bins.isEmpty())){

                                                                                StorageBin bin = new StorageBin(100, new Point (i,p));
                                                                                Warehouse.getGrid()[i][p].addBin(bin);                                                                                
                                                                                bin.setItemId(-1);//indicate no item in the bin yet
                                                                                placeShelf(new Point (i,p));
                                                                        }

                                                                }
                                                        }
                                                }
                                        } catch (ArrayIndexOutOfBoundsException e){

                                        }
                                }
                        }
                }
        }


        /** Creates a path of layout that cannot contain shelves */
        private void makeAPathThroughShelves(Point start, Point end){
                //Lets use A* (why not)
                Router pathGenerator = new Router();
                List <Point> path = pathGenerator.getBestPath(start,end);

                for (int p = 0; p < path.size(); p++){        
                        int x = path.get(p).x;
                        int y = path.get(p).y;                              
                        if (!Warehouse.getGrid()[x][y].isBlocked()){
                                Warehouse.getGrid()[x][y].addPath();
                        }
                }
        }

        /** import warehouse layout with a filename */
        public void importGrid(String filename){              
          try {
                        String state=null;
                        ArrayList<String> s1= new ArrayList<String>(200);
                        int sx=0;
                        int sy=0;    
                        System.out.println(filename);
                        FileInputStream fis = new FileInputStream(filename);
                        GZIPInputStream gzis = new GZIPInputStream(fis);
                        ObjectInputStream in = new ObjectInputStream(gzis);
                        s1=(ArrayList<String>) in.readObject();
                        int cx=(Integer) in.readObject();
                        int cy=(Integer) in.readObject();
                        in.close();
                        int maxX = 00;
                        int maxY = 00;
                        for(String s: s1){
                                sx=(int) Double.parseDouble(s.substring(0, 4));
                                sy=(int) Double.parseDouble(s.substring(5, 9));
                                if (sx>maxX){
                                        maxX = sx+0;
                                }
                                if (sy>maxY){
                                        maxY = sy+0;
                                }
                        }
                        
                        setWarehouseWidth(maxX+2);
                        setWarehouseHeight(maxY+2);
                        setupGrid();
                        entranceLocation = new Point(0, warehouseHeight / 2);
                        for(String s: s1){
                                sx=(int) Double.parseDouble(s.substring(0, 4));
                                sy=(int) Double.parseDouble(s.substring(5, 9));
                                
                                if(s.substring(10,15).equals("start")){
                                        state="images/BoxStart.png";
                                        System.out.println("miracle");
                                        conveyorSegments.add(this.initiateBasicSpawn(new Point(sx,sy)));
                                        
                                }
                                else if(s.substring(10, 15).equals("end00")){
                                        state="images/BoxEnd.png";
                                        conveyorSegments.add(this.initiateBasicEnd(new Point(sx,sy)));
                                }
                                else if(s.substring(10, 15).equals("cn090")){
                                        state="images/ConveyerStraight.png";                      
                                        this.addConveyorSegment(3, new Point(sx,sy));

                                }
                                else if(s.substring(10, 15).equals("cn180")){
                                        state="images/ConveyerLeft.png";
                                        this.addConveyorSegment(2, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("cn270")){
                                        state="images/ConveyerBack.png";
                                        this.addConveyorSegment(1, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("cn360")){
                                        state="images/ConveyerRight.png";
                                        this.addConveyorSegment(0, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("iddwn")){
                                        state="images/itemdrop-down.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 1));
                                }
                                else if(s.substring(10, 15).equals("idlft")){
                                        state="images/itemdrop-left.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 2));
                                }
                                else if(s.substring(10, 15).equals("idrgt")){
                                        state="images/itemdrop-right.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 0));
                                }
                                else if(s.substring(10, 15).equals("idup0")){
                                        state="images/itemdrop-up.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 3));
                                }
                                else if(s.substring(10, 15).equals("shelf")){
                                        state="images/Shelf.png";
                                        placeShelf(new Point (sx,sy));

                                }
                                else {
                                        state="images/ConveyerIntersection.png";
                                }



                        }

                }
                catch (Exception e) {
                        System.out.println(e);
                        //
                        e.printStackTrace();
                }
        }
        

        public void importGrid(){              
                JFileChooser chooser=new JFileChooser();
                FileFilter filter = new FileFilter(){

                        @Override
                        public boolean accept(File f) {
                                 String ext = "";
                                String s = f.getName();
                                int i = s.lastIndexOf('.');

                                if (i > 0 &&  i < s.length() - 1) {
                                    ext = s.substring(i+1).toLowerCase();
                                }
                               if (ext.equals("t64")){
                                   return true;
                               }
                                return false;
                        }

                        @Override
                        public String getDescription() {
                                // TODO Auto-generated method stub
                                return "*.t64";
                        }
                        
                };
                chooser.setFileFilter(filter);
                chooser.showOpenDialog(null);
                String filename=chooser.getSelectedFile().getPath();
                try {
                        String state=null;
                        ArrayList<String> s1= new ArrayList<String>(200);
                        int sx=0;
                        int sy=0;    
                        FileInputStream fis = new FileInputStream(filename);
                        GZIPInputStream gzis = new GZIPInputStream(fis);
                        ObjectInputStream in = new ObjectInputStream(gzis);
                        s1=(ArrayList<String>) in.readObject();
                        int cx=(Integer) in.readObject();
                        int cy=(Integer) in.readObject();
                        in.close();
                        int maxX = 00;
                        int maxY = 00;
                        for(String s: s1){
                                sx=(int) Double.parseDouble(s.substring(0, 4));
                                sy=(int) Double.parseDouble(s.substring(5, 9));
                                if (sx>maxX){
                                        maxX = sx+0;
                                }
                                if (sy>maxY){
                                        maxY = sy+0;
                                }
                        }
                        
                        setWarehouseWidth(maxX+2);
                        setWarehouseHeight(maxY+2);
                        setupGrid();
                        entranceLocation = new Point(0, warehouseHeight / 2);
                        for(String s: s1){
                                sx=(int) Double.parseDouble(s.substring(0, 4));
                                sy=(int) Double.parseDouble(s.substring(5, 9));
                                
                                if(s.substring(10,15).equals("start")){
                                        state="images/BoxStart.png";
                                        System.out.println("miracle");
                                        conveyorSegments.add(this.initiateBasicSpawn(new Point(sx,sy)));
                                        
                                }
                                else if(s.substring(10, 15).equals("end00")){
                                        state="images/BoxEnd.png";
                                        conveyorSegments.add(this.initiateBasicEnd(new Point(sx,sy)));
                                }
                                else if(s.substring(10, 15).equals("cn090")){
                                        state="images/ConveyerStraight.png";                      
                                        this.addConveyorSegment(3, new Point(sx,sy));

                                }
                                else if(s.substring(10, 15).equals("cn180")){
                                        state="images/ConveyerLeft.png";
                                        this.addConveyorSegment(2, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("cn270")){
                                        state="images/ConveyerBack.png";
                                        this.addConveyorSegment(1, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("cn360")){
                                        state="images/ConveyerRight.png";
                                        this.addConveyorSegment(0, new Point(sx,sy));
                                }
                                else if(s.substring(10, 15).equals("iddwn")){
                                        state="images/itemdrop-down.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 1));
                                }
                                else if(s.substring(10, 15).equals("idlft")){
                                        state="images/itemdrop-left.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 2));
                                }
                                else if(s.substring(10, 15).equals("idrgt")){
                                        state="images/itemdrop-right.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 0));
                                }
                                else if(s.substring(10, 15).equals("idup0")){
                                        state="images/itemdrop-up.png";
                                        conveyorSegments.add(this.initiateBasicStop(new Point(sx,sy), 3));
                                }
                                else if(s.substring(10, 15).equals("shelf")){
                                        state="images/Shelf.png";
                                        placeShelf(new Point (sx,sy));

                                }
                                else {
                                        state="images/ConveyerIntersection.png";
                                }



                        }

                }
                catch (Exception e) {
                        System.out.println(e);
                        //
                        e.printStackTrace();
                }
        }



        /** Launches the item stops (where the totes stop to get filled) */
        protected  ItemStop initiateBasicStop(Point p, int direction){
                ItemStop stop = new ItemStop(direction);              
                itemStops.add(stop);
                stop.segmentInfo.setSegmentLocation(p);
                stop.segmentInfo.setNextLocation(stop.findNextLocation());
                //random color but not too light and not too dark
                stop.stopInfo.setDomainColor(new Color(r.nextInt(130)+50,r.nextInt(130)+50,r.nextInt(130)+50));
                launchAgent(stop);

                //This sends a message to the warehouse to add this to the grid
                stop.sendMessage("warehouse","conveyorsystem","warehouse", new SetLocationMessage(new Point(stop.segmentInfo.getSegmentLocation().x,stop.segmentInfo.getSegmentLocation().y)));
                conveyorSegments.add(stop); //add the stop so that we can generically check for it            

                return stop;
        }


        protected  End initiateBasicEnd(Point p){
                End end = new End(3);
                end.segmentInfo.setSegmentLocation(p);        
                //ends do not have a next loctation...?
                //Since this is an "End" segment, we really need the Start segment location for the next
                // NOOOO -- end.segmentInfo.setNextLocation(end.findNextLocation());          
                launchAgent(end);            
                //get the "next location" for the end segment based on what the End class does to get this
                end.getNextLocation();                
                //This sends a message to the warehouse to add this to the grid. There is a chance that the
                //spawner does not exist yet, but if so the next location will remain null and we will check
                //later for this information
                end.sendMessage("warehouse","conveyorsystem","warehouse", new SetLocationMessage(new Point(end.segmentInfo.getSegmentLocation().x,end.segmentInfo.getSegmentLocation().y)));
                conveyorSegments.add(end); //add the segment so that we can generically check for it  
                return end;
        }

        protected  ToteSpawn initiateBasicSpawn(Point p){
                System.out.println("Spawner Made!");
                ToteSpawn spawn = new ToteSpawn(3);
                spawn.segmentInfo.setSegmentLocation(p);
                List <Point> neighbors = Warehouse.getAdjacent(p);
                for (int i = 0; i < neighbors.size(); i ++){
                        if (!Warehouse.getGrid()[neighbors.get(i).x][neighbors.get(i).y].occupants.isEmpty()){
                                if (Warehouse.getGrid()[neighbors.get(i).x][neighbors.get(i).y].occupants.get(0).getRole().equals("segment")){
                                        spawn.segmentInfo.setNextLocation(neighbors.get(i));
                                }
                        }
                }

                launchAgent(spawn);          

                //This sends a message to the warehouse to add this to the grid
                spawn.sendMessage("warehouse","conveyorsystem","warehouse", new SetLocationMessage(new Point(spawn.segmentInfo.getSegmentLocation().x,spawn.segmentInfo.getSegmentLocation().y)));
                conveyorSegments.add(spawn); //add the segment so that we can generically check for it        
                return spawn;
        }



        /** convenience method to check if a location point is OK */
        private boolean checkBounds(Point location) {
                if ((location.x>warehouseWidth-1) || (location.x<0)) {
                        return false;
                }
                if ((location.y>warehouseHeight-1) || (location.y<0)) {
                        return false;                }

                return true;
        }


        private  void setupWarehouseWithTestDefaults() {      
                System.out.println("warehouse using test defaults");
                setWarehouseWidth (25);
                setWarehouseHeight(25);
                setupGrid();
                entranceLocation = new Point(0, warehouseHeight / 2);
                lunchroomWidth = 4;
                lunchroomDepth = 4;
                lunchroomLocation = new Point(warehouseWidth- lunchroomWidth, 0);

                toteLauncherLocation = new Point (1,3);

                createDefaultConveyorCircle();

                
                useStop1 = Warehouse.useDemoStop1;
                useStop2 = Warehouse.useDemoStop2;
                useStop3 = Warehouse.useDemoStop3;
                useStop4 = Warehouse.useDemoStop4;
                
                if (useStop1) {
                        ItemStop itemStop = initiateBasicStop(new Point(4,4), 3);
                        conveyorSegments.add(itemStop);
                }

                if (useStop2) {
                        ItemStop itemStop2 = initiateBasicStop(new Point(10,4), 3);
                        conveyorSegments.add(itemStop2);
                }

                if (useStop3) {
                        ItemStop itemStop3 = initiateBasicStop(new Point(4,11), 3);
                        conveyorSegments.add(itemStop3);
                }


                if (useStop4) {
                        ItemStop itemStop4 = initiateBasicStop(new Point(14,11), 3);
                        conveyorSegments.add(itemStop4);
                }
                        

                ToteSpawn spawn = initiateBasicSpawn(new Point(1,6));
                conveyorSegments.add(spawn);
                
                End end = initiateBasicEnd(new Point(1,8));
                conveyorSegments.add(end);    

                placeBinsWhereOpen();
        }

        private  void setupWarehouseWithTestDefaultsAndPathway() {    
                System.out.println("warehouse using test defaults and a path through shelves");
                setWarehouseWidth (25);
                setWarehouseHeight(25);
                setupGrid();
                entranceLocation = new Point(0, warehouseHeight / 2);
                lunchroomWidth = 4;
                lunchroomDepth = 4;
                lunchroomLocation = new Point(warehouseWidth- lunchroomWidth, 0);

                toteLauncherLocation = new Point (1,3);

                createDefaultConveyorCircle();
                
                
                useStop1 = Warehouse.useDemoStop1;
                useStop2 = Warehouse.useDemoStop2;
                useStop3 = Warehouse.useDemoStop3;
                useStop4 = Warehouse.useDemoStop4;
                
                if (useStop1) {
                        ItemStop itemStop = initiateBasicStop(new Point(4,4), 3);
                        conveyorSegments.add(itemStop);
                }

                if (useStop2) {
                        ItemStop itemStop2 = initiateBasicStop(new Point(10,4), 3);
                        conveyorSegments.add(itemStop2);
                }

                if (useStop3) {
                        ItemStop itemStop3 = initiateBasicStop(new Point(4,11), 3);
                        conveyorSegments.add(itemStop3);
                }


                if (useStop4) {
                        ItemStop itemStop4 = initiateBasicStop(new Point(14,11), 3);
                        conveyorSegments.add(itemStop4);
                }
                        
                
                End end = initiateBasicEnd(new Point(1,8));
                conveyorSegments.add(end);            

                ToteSpawn spawn = initiateBasicSpawn(new Point(1,6));
                conveyorSegments.add(spawn);

                Point pathStart = new Point(10,12);
                Point pathEnd = new Point(10,22);


                //place path where shelves cannot be put
                makeAPathThroughShelves(pathStart,pathEnd);

                placeBinsWhereOpen();

        }

        /** convenience method for warehouse setup */
        private  void setWarehouseHeight(int wh) {
                warehouseHeight = wh;

        }

        /** convenience method for warehouse setup */
        private void setWarehouseWidth(int ww) {
                warehouseWidth = ww;

        }


        /** convenience method for warehouse setup */
        public int getWarehouseWidth() {      
                return warehouseWidth;
        }

        /** convenience method for warehouse setup */
        public int getWarehouseHeight() {
                return warehouseHeight;
        }

        /** This reads the Warehouse Layout save file into the various layout items */
        private void readInputFile(String inputFileName) {
                setupGrid();
                //parse the file and do similar actions to setting up default warehouse
                //do not launch the conveyor agents here, but set all their grid locations
                //add all conveyor type agents to the conveyorSegments list

        }

}

 

SetupFrame.java (used by Main in Warehouse)

package team64.madkit;

import javax.swing.JFrame;

public class SetupFrame extends JFrame {

}

ParameterPanel.java

/** Panel to change simulation defaults on startup */
package team64.madkit;

/**
 * @author team64 New Mexico Supercomputing Challenge
 * @2012
 *
 */

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ParameterPanel extends JPanel {
        protected JFormattedTextField txtMaxOrdersInProcess;
        protected JFormattedTextField txtUpdateSpeed;
        protected JFormattedTextField txtShelfHeight;
        protected JFormattedTextField textFieldOrders;
        protected JComboBox comboBoxItems; //number of items in the warehouse
        protected JComboBox comboBox; //warehouse layout
        protected JCheckBox chckbxZone;
        protected JCheckBox chckbxMulti;
        protected JCheckBox chkRandomSorting;
        protected JCheckBox chckbxUsePopularity;
        protected JCheckBox chkLoc1;
        protected JCheckBox chkLoc2;
        protected JCheckBox chkLoc3;
        protected JCheckBox chkLoc4;
        private boolean enableChange=false;
        private JLabel lblNewLabel_7;
        

        public ParameterPanel() {
                setLayout(null);
                
                JLabel lblNewLabel = new JLabel("Warehouse Simulation Parameters");
                lblNewLabel.setForeground(Color.BLUE);
                lblNewLabel.setFont(new Font("Arial", Font.PLAIN, 18));
                lblNewLabel.setBounds(10, 0, 353, 38);
                add(lblNewLabel);
                
                comboBox = new JComboBox();
                
                comboBox.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                                if (enableChange) {
                                        if (!comboBox.getSelectedItem().equals("Demo Test")) {
                                                chkLoc1.setEnabled(false);
                                                chkLoc2.setEnabled(false);
                                                chkLoc3.setEnabled(false);
                                                chkLoc4.setEnabled(false);
                                        }else {
                                                chkLoc1.setEnabled(true);
                                                chkLoc2.setEnabled(true);
                                                chkLoc3.setEnabled(true);
                                                chkLoc4.setEnabled(true);
                                        }
                                }
                                
                        }
                });
                comboBox.setToolTipText("select a pre-configured warehouse or use default for the test layout");
                comboBox.setBounds(20, 38, 247, 32);
                comboBox.addItem(new String("Demo Test"));
                comboBox.addItem(new String("Warehouse 1"));
                comboBox.addItem(new String("Warehouse 2"));
                comboBox.addItem(new String("Warehouse 3"));
                comboBox.addItem(new String("Browse..."));
                add(comboBox);
                
                JLabel lblNewLabel_1 = new JLabel("Warehouse Layout");
                lblNewLabel_1.setBounds(277, 43, 123, 22);
                add(lblNewLabel_1);
                
                chckbxZone = new JCheckBox("Zone Picking");
                chckbxZone.setBounds(20, 316, 133, 23);
                chckbxZone.setSelected(true);
                add(chckbxZone);
                
                 comboBoxItems = new JComboBox();
                comboBoxItems.addItem(new Integer(100));
                comboBoxItems.addItem(new Integer(200));
                comboBoxItems.addItem(new Integer(300));
                comboBoxItems.addItem(new Integer(400));
                comboBoxItems.addItem(new Integer(500));
                comboBoxItems.addItem(new Integer(1000));
                comboBoxItems.addItem(new Integer(1200));
                comboBoxItems.addItem(new Integer(2000));
                comboBoxItems.addItem(new Integer(4000));
                comboBoxItems.addItem(new Integer(10000));    
                
                comboBoxItems.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                        }
                });
                comboBoxItems.setBounds(20, 103, 123, 32);
                add(comboBoxItems);
                
                JLabel lblNewLabel_2 = new JLabel("Items in Warehouse");
                lblNewLabel_2.setBounds(30, 138, 123, 22);
                add(lblNewLabel_2);
                
                JLabel lblOrdersToProcess = new JLabel("Orders To Process");
                lblOrdersToProcess.setBounds(214, 138, 123, 22);
                add(lblOrdersToProcess);
                
                txtMaxOrdersInProcess = new JFormattedTextField(2);
                txtMaxOrdersInProcess.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                        }
                });
                txtMaxOrdersInProcess.setBounds(30, 171, 58, 30);
                add(txtMaxOrdersInProcess);
                txtMaxOrdersInProcess.setColumns(10);
                
                JLabel lblNewLabel_3 = new JLabel("Maximum Orders In Process at the Same Time");
                lblNewLabel_3.setToolTipText("Orders in the conveyor system at one time");
                lblNewLabel_3.setBounds(30, 203, 302, 22);
                add(lblNewLabel_3);
                
                txtUpdateSpeed = new JFormattedTextField(50);
                txtUpdateSpeed.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                        }
                });
                txtUpdateSpeed.setColumns(10);
                txtUpdateSpeed.setBounds(31, 247, 58, 32);
                add(txtUpdateSpeed);
                
                JLabel lblUpdateSpeedms = new JLabel("Update Speed (ms)");
                lblUpdateSpeedms.setToolTipText("Orders in the conveyor system at one time");
                lblUpdateSpeedms.setBounds(99, 255, 161, 22);
                add(lblUpdateSpeedms);
                
                txtShelfHeight = new JFormattedTextField(1);
                txtShelfHeight.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                        }
                });
                txtShelfHeight.setColumns(10);
                txtShelfHeight.setBounds(277, 244, 58, 32);
                add(txtShelfHeight);
                
                JLabel lblNumberOfShelves = new JLabel("Number of Storage Bins Per Storage Shelf");
                lblNumberOfShelves.setToolTipText("Orders in the conveyor system at one time");
                lblNumberOfShelves.setBounds(287, 287, 269, 22);
                add(lblNumberOfShelves);
                
                chckbxMulti = new JCheckBox("Multiple Item Pick Per Order");
                chckbxMulti.setBounds(20, 348, 230, 23);
                add(chckbxMulti);
                
                chkRandomSorting = new JCheckBox("Random Sorting on Shelves");
                chkRandomSorting.setSelected(true);
                chkRandomSorting.setBounds(277, 316, 256, 23);
                add(chkRandomSorting);
                
                chckbxUsePopularity = new JCheckBox("Use Item Popularity to Sort");
                chckbxUsePopularity.setBounds(277, 348, 247, 23);
                add(chckbxUsePopularity);
                
                JLabel lblNewLabel_4 = new JLabel("Conveyor runs 2x worker walking speed");
                lblNewLabel_4.setBounds(21, 290, 246, 14);
                add(lblNewLabel_4);
                
                textFieldOrders = new JFormattedTextField(10);
                textFieldOrders.setColumns(10);
                textFieldOrders.setBounds(204, 103, 112, 32);
                add(textFieldOrders);
                
                JLabel txt = new JLabel("Close this Panel afer you set the parameters to start the simulation");
                txt.setForeground(Color.RED);
                txt.setFont(new Font("Arial", Font.BOLD, 14));
                txt.setBounds(30, 378, 503, 47);
                add(txt);
                
                JLabel lblNewLabel_5 = new JLabel("Demo Picking Stations");
                lblNewLabel_5.setFont(new Font("Arial", Font.PLAIN, 12));
                lblNewLabel_5.setBounds(376, 120, 142, 14);
                add(lblNewLabel_5);
                
                JLabel lblNewLabel_6 = new JLabel("(only applies to Demo Test layout)");
                lblNewLabel_6.setFont(new Font("Arial", Font.ITALIC, 12));
                lblNewLabel_6.setBounds(347, 138, 206, 14);
                add(lblNewLabel_6);
                
                chkLoc1 = new JCheckBox("(4,4)");
                chkLoc1.setSelected(true);
                chkLoc1.setBounds(350, 165, 58, 23);
                add(chkLoc1);
                
                chkLoc2 = new JCheckBox("(10,4)");
                chkLoc2.setSelected(false);
                chkLoc2.setBounds(347, 202, 60, 23);
                add(chkLoc2);
                
                chkLoc4 = new JCheckBox("(14,11)");
                chkLoc4.setSelected(true);
                chkLoc4.setBounds(433, 202, 85, 23);
                add(chkLoc4);
                
                chkLoc3 = new JCheckBox("(4,11)");
                chkLoc3.setSelected(false);
                chkLoc3.setBounds(433, 165, 85, 23);
                add(chkLoc3);
                
                lblNewLabel_7 = new JLabel("If you select \"Browse...\" you will be able to select a layout after closing this panel.");
                lblNewLabel_7.setForeground(Color.BLUE);
                lblNewLabel_7.setBounds(30, 76, 503, 14);
                add(lblNewLabel_7);
                enableChange=true;
        }
}

Router.java

/*
 *Router.java is class based on A* (A Star) which
 *returns the best path from a start point to an end point
 * (c) 2012 Team 64 New Mexico Supercomputing Challenge
 */
package team64.madkit;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import javax.swing.JFrame;

import madkit.kernel.Agent;
import madkit.kernel.Message;
import team64.madkit.messages.RequestStatusMessage;
import team64.madkit.messages.StatusMessage;
import team64.madkit.notused.DirectionQuery;
import team64.madkit.notused.Directions;

/**
 * @author  Team 64 New Mexico Supercomputing Challenge
 * @2012
 *
 */
public class Router{    

        /** overlay the grid to calculate paths */

        private List<WarehouseGridOverlay> opened = new ArrayList<WarehouseGridOverlay>();
        private List<WarehouseGridOverlay> closed = new ArrayList<WarehouseGridOverlay>();
        private List<WarehouseGridOverlay> bestList = new ArrayList<WarehouseGridOverlay>();

        /** The overlay uses same coordinates as the warehouse grid but
         * contains information needed to find the path
         */
        WarehouseGridOverlay[][] overlayElement = null;
        
        /** testing reversed paths */
        public boolean reversedPath=false;
        /** busy is true if currently finding a path - DO NOT DISTURB!*/
        public boolean busy=false;

        public Router(){
                resetPather ();

        }
        
        public void resetPather (Point p, Point p2){
                overlayElement[p.x][p.y].setStart(false);
                overlayElement[p2.x][p2.y].setEnd(false);
                opened = new ArrayList<WarehouseGridOverlay>();
                closed = new ArrayList<WarehouseGridOverlay>();
                bestList = new ArrayList<WarehouseGridOverlay>();
                
                overlayElement = new WarehouseGridOverlay[Warehouse.warehouseHeight][Warehouse.warehouseWidth];

                for (int row = 0; row < Warehouse.warehouseHeight; row++) {// rows
                        for (int column = 0; column < Warehouse.warehouseWidth; column++) {// columns
                                overlayElement[column][row] = new WarehouseGridOverlay(column,row);
                                overlayElement[column][row].setStart(false);
                                overlayElement[column][row].setEnd(false);
                        }
                }
        }
        public void resetPather (){
                opened = new ArrayList<WarehouseGridOverlay>();
                closed = new ArrayList<WarehouseGridOverlay>();
                bestList = new ArrayList<WarehouseGridOverlay>();
                
                overlayElement = new WarehouseGridOverlay[Warehouse.warehouseWidth][Warehouse.warehouseHeight];
                for (int row = 0; row < Warehouse.warehouseHeight; row++) {// rows
                        for (int column = 0; column < Warehouse.warehouseWidth; column++) {// columns
                                overlayElement[column][row] = new WarehouseGridOverlay(column,row);
                                overlayElement[column][row].setStart(false);
                                overlayElement[column][row].setEnd(false);
                        }
                }
        }

        

        /**
         * get best Path using A* (AStar). Modified from Maze example in AI
         * Application Programming, M. Tim Jones (Charles River Media Programming,
         * 1995) C code implemented in Java from
         *
http://memoization.com/2008/11/30/a-star-algorithm-in-java/
         *
         * @param start
         * @param end
         * @return
         */
        protected List<Point> getBestPath(Point start, Point end) {
                resetPather ();
        busy = true;
                WarehouseGridOverlay gridStart;
                WarehouseGridOverlay goal;
                bestList.clear();
                opened.clear();
                closed.clear();
                //make new local copies of the points or they get changed for the next run
                Point thisStart = new Point(start.x,start.y);
                Point thisEnd = new Point(end.x,end.y);

                //System.out.println("Finished adjancent");
                gridStart = overlayElement[thisStart.x][thisStart.y];
                gridStart.setStart(true);
                gridStart.setEnd(false);
                goal = overlayElement[thisEnd.x][thisEnd.y];
                goal.setEnd(true);
                goal.setStart(false);
                
                
                //calculate adjacencies (must do this after setting the start and end points)
                for (int i = 0; i < Warehouse.warehouseHeight; i++) {// rows
                        for (int j = 0; j < Warehouse.warehouseWidth; j++) {// columns
                                //overlayElement[j][i].clearAdjacencies();
                                //overlayElement[j][i].setParent(null);
                                overlayElement[j][i].calculateNewAdjacencies(overlayElement);
                        }
                }

                Set<WarehouseGridOverlay> adjacencies = gridStart.getAdjacencies();

                //System.out.println("got adjancent");
                for (WarehouseGridOverlay adjacency : adjacencies) {
                        adjacency.setParent(gridStart);
                        //gridStart.setChild(adjacency);
                        if (adjacency.isStart() == false) {
                                opened.add(adjacency);
                        }
                }//System.out.println("Finished opened");
                


                //System.out.println(adjacencies);
                while (opened.size() > 0) {
                        WarehouseGridOverlay best = findBestPassThrough(goal);
                        //System.out.println("Best is: " + best.getColumn() + ","+best.getRow());
                        //System.out.println("found best pass through");
                        opened.remove(best);
                        closed.add(best);                    
                        if (best.isEnd()) {
                                //System.out.println("Best is the goal!");
                                // fill list with the path before returning
                                //System.out.println(start+" to "+end);
                                populateBestList(goal);
                                overlayElement[thisStart.x][thisStart.y].setStart(false);
                                overlayElement[thisEnd.x][thisEnd.y].setEnd(false);
                                List<Point> adjacents = Warehouse.getAdjacent(thisEnd);
                                for (int i = 0; i < adjacents.size(); i++){
                                        WarehouseGridOverlay adjacent = overlayElement[adjacents.get(i).x][adjacents.get(i).y];
                                        //adjacent.clearAdjacencies();
                                        adjacent.getAdjacencies().remove(overlayElement[thisStart.x][thisStart.y]);
                                }                      

                                //convert from overlay grid locations to a list of points for the path      
                                overlayElement[thisStart.x][thisStart.y].setStart(false);
                                overlayElement[thisEnd.x][thisEnd.y].setEnd(false);
                                //System.out.println("returning bestList of size " +bestList.size());
                                
                                return generateBestPathPoints();
                        } else {
                                Set<WarehouseGridOverlay> neighbors = best.getAdjacencies();                                
                                //check if any of the neighbors IS the parent of the best and remove that neighbor!!!! or get stack overflow
                        /*   for (WarehouseGridOverlay neighbor : neighbors) {
                                        if (neighbor.getParent()!= null) {
                                                if (neighbor == best.getParent()) {
                                                    System.out.println("neighbor of the best is best's parent === BAD");
                                                    best.removeAdjacency(neighbor);                                                
                                                }
                                                
                                        }
                                }*/
                                
                        
                                //if one of the neighbors of best is the END point, then we are finished
                                if (neighbors.contains(goal)) {
                                        //System.out.println("Neighbors contains the goal!");
                                        opened.remove(goal);
                                        closed.remove(goal);
                                        opened.add(0, goal);
                                        goal.setParent(best);
                                        // fill list with the path before returning
                                        //System.out.println(thisStart+" to "+thisEnd);
                                        populateBestList(goal);
                                        //print out the path      
                                        //reset the overlays
                                        List<Point> adjacents = Warehouse.getAdjacent(end);
                                        
                                        //overlayElement[thisStart.x][thisStart.y].setStart(false);
                                        //overlayElement[thisEnd.x][thisEnd.y].setEnd(false);
/*                                      for (int i = 0; i < adjacents.size(); i++){
                                                WarehouseGridOverlay adjacent = overlayElement[adjacents.get(i).x][adjacents.get(i).y];
                                                //adjacent.clearAdjacencies();
                                                adjacent.getAdjacencies().remove(goal);
                                        }*/
                                        //convert from overlay grid locations to a list of points for the path    
                                        //System.out.println("returning bestList of size " + bestList.size());
                                        return generateBestPathPoints();
                                } else {
                                for (WarehouseGridOverlay neighbor : neighbors) {
                                        if (opened.contains(neighbor)) {
                                                WarehouseGridOverlay tmp = new WarehouseGridOverlay(neighbor.getColumn(), neighbor.getRow());
                                                tmp.setParent(best);
                                                //best.setChild(tmp);
                                                if (tmp.getPassThrough(goal) >= neighbor.getPassThrough(goal)) {
                                                        continue;
                                                }
                                        }

                                        if (closed.contains(neighbor)) {
                                                WarehouseGridOverlay tmp = new WarehouseGridOverlay(neighbor.getColumn(), neighbor.getRow());
                                                tmp.setParent(best);
                                                //best.setChild(tmp);
                                                if (tmp.getPassThrough(goal) >= neighbor.getPassThrough(goal)) {
                                                        continue;
                                                }
                                        }
                                        //if (neighbor.getChild()!=null&&best.getParent()!=null){
                                        //if(!neighbor.getChild().equals(best.getParent())){
                                                

                                                neighbor.setParent(best);
                                                //best.setChild(neighbor);

                                                opened.remove(neighbor);
                                                closed.remove(neighbor);
                                                opened.add(0, neighbor);
                                        }
                                /*  }else{
                                                neighbor.setParent(best);
                                                best.setChild(neighbor);

                                                opened.remove(neighbor);
                                                closed.remove(neighbor);
                                                opened.add(0, neighbor);
                                        }}*/
                                
                        }
                        }
                }//should not get here (it will be null)
                System.out.println("BAD!");
                return null;

        }

        
        //intended to check list if already added and if so return -- should solve stack overflow because it will stop things from running through more than once.
        private List<WarehouseGridOverlay> added = new ArrayList<WarehouseGridOverlay>();
        private void populateBestList(WarehouseGridOverlay overlay) {  
                bestList.add(overlay);
                //added.add(overlay);
                if (overlay.getParent().isStart() == false) {
                        //System.out.println("Parent of overlay is: "+ overlay.getParent().getColumn()+","+overlay.getParent().getRow());
                        //System.out.println(overlay.getParent()+" 9999999999999999999999 "+overlay);
                        //System.out.println(overlay.getParent().toPoint()+" 9999999999999999999999 "+overlay.toPoint());
                        populateBestList(overlay.getParent());
                }
                return;
        }

        /** Generates a List with the path points */
        private List<Point> generateBestPathPoints(    ) {
                List<Point> pointList = new ArrayList<Point>();
                if (reversedPath==false) {
                        for (int i = 0; i<bestList.size(); i++) {
                                int row = bestList.get(bestList.size()-i-1).getRow();
                                int column = bestList.get(bestList.size()-i-1).getColumn();
                                //System.out.println("Column,Row "+column+" "+row);
                                pointList.add(new Point(column,row));
                        }
                } else { //for the reversed case
                        for (int i = 0; i<bestList.size(); i++) {
                                int row = bestList.get(i).getRow();
                                int column = bestList.get(i).getColumn();
                                //System.out.println("Column,Row "+column+" "+row);
                                pointList.add(new Point(column,row));
                        }
                }
                busy = false;
                return pointList;
        }

        private WarehouseGridOverlay findBestPassThrough(WarehouseGridOverlay goal) {
                WarehouseGridOverlay best = null;
                for (WarehouseGridOverlay overlay : opened) {
                        if (best == null || (overlay.getPassThrough(goal) < best.getPassThrough(goal))) {
                                best = overlay;
                        }
                }
                return best;
        }


        protected void end() {
                opened = null;
                closed = null;
                
                bestList = null;              
                overlayElement = null;
        
        }
        /** not currently used */
        public void setupFrame(JFrame frame) {        
                frame.setSize(500, 350);
        }



}

 

Comments