Index: trunk/src/atmsdriver/ConsoleDriver.java
===================================================================
--- trunk/src/atmsdriver/ConsoleDriver.java	(revision 97)
+++ trunk/src/atmsdriver/ConsoleDriver.java	(revision 103)
@@ -1,34 +1,385 @@
 package atmsdriver;
 
+import atmsdriver.model.Highways;
+import atmsdriver.model.Station.DIRECTION;
+import atmsdriver.model.Highway;
+import atmsdriver.model.Station;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
 /**
- *  A console application to drive the ATMS Server.
- * @author jdalbey
+ * A console application to drive the ATMS Server.
+ *
+ * @author jdalbey, John A. Torres
+ * @version 10/11/2017
  */
-public class ConsoleDriver
-{
-//
-//Given
-// <Highway Number> <Dir> <Postmile> <Range> <DotColor> 
-//
-//IF default direction of Highway Number = Dir THEN
-//    Set StartPost = Postmile
-//    Set EndPost = Postmile + Range
-//ELSE
-//    Set StartPost = Postmile - Range
-//    Set EndPost = Postmile
-//END IF
-//
-//FOR each Station in Highway Number LOOP
-//
-//    IF Station.Postmile within range of StartPost:EndPost THEN
-//        IF default direction of Highway Number = Dir THEN
-//            Set ML color to DotColor
-//        ELSE
-//            Set OPP color to DotColor
-//        END IF
-//    END IF
-//
-//END LOOP
-//
-//    
+public final class ConsoleDriver {
+    // highways model
+    private final Highways highways;
+    
+    // lists used for user input validation
+    private final List<Integer> routeNumInputList;
+    private final List<String> dotColorInputList;
+
+    /**
+     * Constructor. Sets the highways model and generates the input validation
+     * lists, and then runs the console driver application.
+     * @param highways 
+     */
+    public ConsoleDriver(Highways highways) {
+        // set highways model
+        this.highways = highways;
+        
+        // set input validation lists
+        routeNumInputList = generateRouteNumInputList();
+        dotColorInputList = new ArrayList<>(Arrays.asList("R", "Y", "G"));
+        
+        // run the console driver
+        runConsole();
+    }
+    
+    /**
+     * Generates the route number list, used for user input validation.
+     * @return list of route numbers.
+     */
+    private ArrayList<Integer> generateRouteNumInputList()
+    {
+        ArrayList<Integer> routeNums = new ArrayList<>();
+        // add the route number for each highway to the list
+        for(Highway hwy : highways.highways)
+        {
+            routeNums.add(hwy.routeNumber);
+        }
+        return routeNums;
+    }
+
+    /**
+     * Runs the console driver application.
+     */
+    public void runConsole() {
+        Scanner sc = new Scanner(System.in);
+        // Run continuously
+        while (true) {
+            // Get necessary values for colorization of highways
+            Integer routeNumber = getRouteNumber(sc);
+            DIRECTION direction = getDirection(sc, routeNumber);
+            Double postmile = getPostmile(sc, routeNumber, direction);
+            Integer range = getRange(sc, postmile);
+            DOTCOLOR dotcolor = getDotColor(sc);
+            
+            // apply colorization to highways
+            applyColorToHighwayStretch(routeNumber, direction, postmile, range, dotcolor);
+        }
+    }
+    
+    /**
+     * Applies specified color to the specified highway stretch. Route number and
+     * direction specify the highway. Postmile and range specify the stretch of
+     * specified highway. Dot color is the color to be applied to the stretch.
+     * 
+     * @param routeNumber highway route number
+     * @param direction highway direction
+     * @param postmile origin postmile value
+     * @param range range from origin postmile
+     * @param dotColor the color to be applied to specified highway stretch
+     */
+    private void applyColorToHighwayStretch(Integer routeNumber, DIRECTION direction, 
+            Double postmile, Integer range, DOTCOLOR dotColor) {
+        System.out.println("Applying " + dotColor.name() + " dots to highway " 
+                + routeNumber + " " + direction.name() + " at postmile " 
+                + postmile + " with a range of " + range + " miles...");
+        
+        // Get the highway by route number
+        Highway highway = highways.getHighwayByRouteNumber(routeNumber);
+        
+        // start value for highway section, and end value for highway section
+        // by postmile
+        Double startPost;
+        Double endPost;
+        
+        // postmiles increase from s to n and w to e
+        
+        // if the direction is south or west
+        if(direction.equals(DIRECTION.SOUTH) || direction.equals(DIRECTION.WEST))
+        {
+            // add range value to startPost to get
+            // the end postmile value of the highway section
+            startPost = postmile;
+            endPost = postmile + range;
+            
+            // iterate through the stations, if within the specified highway
+            // stretch, update the station by direction and apply dot color
+            for(Station station : highway.stations)
+            {
+                if(station.postmile > startPost && station.postmile < endPost)
+                {
+                    station.updateByDirection(direction, dotColor);
+                }
+            }
+        }
+        // if the direction is north or east 
+        else
+        {
+            //subtract range value from startPost
+            // to get the end postmile value of the highway section
+            startPost = postmile;
+            endPost = postmile - range;
+            
+            // iterate through the stations, if within the specified highway
+            // section, update the station by direction and apply dot color
+            for(Station station : highway.stations)
+            {
+                if(station.postmile < startPost && station.postmile > endPost)
+                {
+                    station.updateByDirection(direction, dotColor);
+                }
+            }
+        }
+        System.out.println("");
+    }
+    
+    /**
+     * Gets the highway route number from user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @return highway route number
+     */
+    private Integer getRouteNumber(Scanner sc) {
+        Integer routeNum = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Prints out available route numbers to user to select from
+            System.out.print("Available route numbers: [");
+            for(Integer rtNum : routeNumInputList)
+            {
+                System.out.print(rtNum.toString() + ", ");
+            }
+            System.out.print("]");
+            System.out.println("");
+            
+            // Prompt user to input a route number
+            System.out.println("Enter a route number: ");
+            routeNum = sc.nextInt();
+            System.out.println("");
+            
+            // validate the user's input
+            if(routeNumInputList.contains(routeNum))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid route number, please re-enter: ");
+            }
+        }
+        
+        return routeNum;
+    }
+    
+    /**
+     * Gets the highway direction from the user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @return highway direction
+     */
+    private DIRECTION getDirection(Scanner sc, Integer routeNum) {
+        DIRECTION direction;
+        String directionInput = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Get available directions for route
+            ArrayList<DIRECTION> availDirs = new ArrayList<>();
+            for(Station stn : highways.getHighwayByRouteNumber(routeNum).stations)
+            {
+                if(!availDirs.contains(stn.direction))
+                {
+                    availDirs.add(stn.direction);
+                }
+            }
+            
+            // prompt user for input
+            System.out.print("Available directions for highway " + routeNum + ": [");
+            for(DIRECTION dir : availDirs)
+            {
+                System.out.print(dir.getLetter() + ", ");
+            }
+            System.out.print("]");
+            System.out.println("");
+            System.out.println("Enter a direction:");
+            directionInput = sc.next();
+            System.out.println("");
+            
+            // validate the user's input
+            if(availDirs.contains(DIRECTION.toDirection(directionInput)))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid direction, please re-enter: ");
+            }
+        }
+        
+        return DIRECTION.toDirection(directionInput);
+    }
+    
+    /**
+     * Gets the starting/origin postmile value for the highway section from the 
+     * user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @param routeNumber highway route number
+     * @param dir highway direction
+     * @return highway section start/origin postmile value
+     */
+    private Double getPostmile(Scanner sc, Integer routeNumber, DIRECTION dir) {
+        Double postmile = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // Get highway, and grab the floor and ceiling for postmile values
+            // from the highway stations to present to the user
+            Highway hwy = highways.getHighwayByRouteNumber(routeNumber);
+            Double floorPostmile = hwy.stations.get(0).postmile;
+            Double ceilPostmile = hwy.stations
+                    .get(hwy.stations.size() - 1).postmile;
+            
+            // present user with range of postmiles for given highway
+            System.out.println("Route " + hwy.routeNumber + " " + dir 
+                    + " postmile range: [" + floorPostmile + ", " 
+                    + ceilPostmile + "]");
+            
+            // prompt user for postmile value
+            System.out.println("Enter a postmile value (Integer/Double): ");
+            postmile = sc.nextDouble();
+            System.out.println("");
+            
+            // validate user's input, ensures that the postmile is within given
+            // postmile range (floorPostmile, ceilPostmile)
+            if(postmile >= floorPostmile && postmile <= ceilPostmile)
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Postmile must be within postmile range: [" + floorPostmile + ", " 
+                    + ceilPostmile + "] please re-enter: ");
+            }
+        }
+        
+        return postmile;
+    }
+    
+    /**
+     * Gets the range to extend the highway stretch from the start/origin postmile
+     * value from the user and validates the input.
+     * 
+     * @param sc stdIn scanner
+     * @param postmile origin/start postmile value for highway stretch
+     * @return range value
+     */
+    private Integer getRange(Scanner sc, Double postmile) {
+        Integer range = null;
+        Boolean verified = false;
+        
+        // validation loop
+        while(!verified)
+        {
+            // prompt user for range value
+            System.out.println("Enter a range value (Integer):");
+            range = sc.nextInt();
+            System.out.println("");
+            
+            // range must be greater than or equal to 0
+            if(range >= 0)
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Range must be >= 0");
+            }
+        }
+        
+        return range;
+    }
+
+    /**
+     * Gets the dot color from the user, to be applied to specified highway
+     * stretch and validates the user's input.
+     * 
+     * @param sc stdIn scanner
+     * @return dot color to be applied to highway stretch
+     */
+    private DOTCOLOR getDotColor(Scanner sc) {
+        DOTCOLOR dotColor;
+        String dotColorInput = null;
+        Boolean verified = false;
+        
+        // validationloop
+        while(!verified)
+        {
+            // prompt user for color
+            System.out.println("Enter a dot color (G/Y/R):");
+            dotColorInput = sc.next();
+            System.out.println("");
+            // validate user's input
+            if(dotColorInputList.contains(dotColorInput))
+            {
+                verified = true;
+            }
+            else
+            {
+                System.out.println("Invalid dot color, please re-enter: ");
+            }
+        }
+        
+        return DOTCOLOR.toDotColor(dotColorInput);
+    }
+    
+    /**
+     * Enum for highway status dot colors.
+     *
+     * @author John A. Torres
+     * @version 10/11/2017
+     */
+    public static enum DOTCOLOR {
+
+        RED,
+        YELLOW,
+        GREEN;
+        
+        // All the first letters of the values, in order.
+        private static String allLetters = "RYG";
+        
+        /**
+         * Return the first letter of this enum.
+         *
+         * @return String first letter of this enum.
+         */
+        public String getLetter() {
+            return this.toString().substring(0, 1);
+        }
+
+        /**
+         * Returns a dot color given its first character.
+         *
+         * @param letter the first character of a dot color
+         * @return dot color corresponding to letter
+         * @pre letter must be one of allLetters
+         */
+        public static DOTCOLOR toDotColor(String letter) {
+            return values()[allLetters.indexOf(letter.charAt(0))];
+        }
+    }  
 }
