/******************************************************************************
 *  Name:    Kevin Wayne
 *  NetID:   wayne
 *  Precept: P00
 *
 *  Description: This mutable data type represents time on a 24-hour clock.
 *               You add one minute to the time on a clock or determine whether
 *               the time on one clock is earlier than the time on another.
 *
 *  The test client takes two string command-line arguments start and stop;
 *  interprets them as times on a 24-hour clock; and prints all of the times
 *  in the interval [start, stop)
 *
 *  % java Clock 12:30 12:35
 *  12:30
 *  12:31
 *  12:32
 *  12:33
 *
 *  % java Clock 00:00 20:00
 *  00:00
 *  00:01
 *  00:02
 *  ...
 *  19:58
 *  19:59
 *
 ******************************************************************************/

public class Clock { 
    private static final int HOURS_PER_DAY = 24;
    private static final int MINUTES_PER_HOUR = 60;

    private int hours;     // the hour   (between 0 and 23)
    private int minutes;   // the minute (between 0 and 59)

    // creates a clock whose initial time is h hours and m minutes
    public Clock(int h, int m) {
        hours = h;
        minutes = m;
        validateTime(hours, minutes);
    }

    // creates a clock whose initial time is specified by the string argument
    public Clock(String time) {
        if (!time.matches("[0-9][0-9]:[0-9][0-9]")) {
            throw new IllegalArgumentException("invalid time: " + time);
        }
        hours   = Integer.parseInt(time.substring(0, 2));
        minutes = Integer.parseInt(time.substring(3, 5));
        validateTime(hours, minutes);
    }

    // throws an IllegalArgumentException h hours and m minutes is an invalid time
    private static void validateTime(int h, int m) {
        if (h < 0 || h >= HOURS_PER_DAY) {
            throw new IllegalArgumentException("hours is invalid: " + h);
        }
        if (m < 0 || m >= MINUTES_PER_HOUR) {
            throw new IllegalArgumentException("minutes is invalid: " + m);
        }
    }


    // returns a string representation of this clock, using the format HH:MM
    public String toString() {
        return String.format("%02d:%02d", hours, minutes);
    }

    // adds 1 to the time of this clock
    public void tic() {
        minutes++;
        if (minutes == MINUTES_PER_HOUR) {
            minutes = 0;
            hours++;
        }
        if (hours == HOURS_PER_DAY) {
            hours = 0;
        }
    }

    // is the time on this clock earlier than the time on that one?
    public boolean isEarlierThan(Clock that) {
        if (this.hours < that.hours) return true;
        if (this.hours > that.hours) return false;
        return this.minutes < that.minutes;
    }

    // tests all of the instance methods in this class
    public static void main(String[] args) {
        Clock start = new Clock(args[0]);
        Clock stop  = new Clock(args[1]);
        for (Clock x = start; x.isEarlierThan(stop); x.tic()) {
            StdOut.println(x);
        }
    }
}