/**
 * A simple class to represent time in hours, minutes, and seconds.
 * This is not time zone aware, and does not account for leap seconds.
 */
public final class NaiveTime {
    final static int SECONDS_IN_DAY = 60 * 60 * 24;
    private int unix; // Not actually unix time

    /**
     * Create a new NaiveTime object with the given time
     */
    public NaiveTime(int h, int m, int s) {
        this.unix = h * 3600 + m * 60 + s;
    }

    /**
     * Create a new NaiveTime object with the given time in seconds
     * 
     * @param unix the time in seconds since midnight
     */
    public NaiveTime(int unix) {
        this.unix = unix;
    }

    /**
     * Create a new NaiveTime object with the time set to midnight
     */
    public NaiveTime() {
        this(0, 0, 0);
    }

    /** Advance the NaiveTime by one second */
    public void tick() {
        this.unix = (this.unix + 1) % SECONDS_IN_DAY;
    }

    /** Set the time */
    public void set(int h, int m, int s) {
        // This sanity check will do for now
        assert h >= 0 && h < 24;
        assert m >= 0 && m < 60;
        assert s >= 0 && s < 60;

        // Wrap around at midnight, if for some reason above assertions fail
        this.unix = (h * 3600 + m * 60 + s) % SECONDS_IN_DAY;
    }

    /** Returns the hour portion */
    public int hour() {
        return this.unix / 3600;
    }

    /** Set the hour */
    public void setHour(int h) {
        this.unix = (h * 3600) + (this.unix % 3600);
    }

    /** Returns the minute portion */
    public int min() {
        return (this.unix % 3600) / 60;
    }

    /** Set minute */
    public void setMin(int m) {
        this.unix = (this.unix / 3600) * 3600 + (m * 60) + (this.unix % 60);
    }

    /** Returns the current second */
    public int sec() {
        return this.unix % 60;
    }

    /** Set second */
    public void setSec(int s) {
        this.unix = (this.unix / 60) * 60 + s;
    }

    /** Equality */
    public boolean equals(NaiveTime other) {
        return this.unix == other.unix;
    }

    /** Comparison */
    public boolean isBefore(NaiveTime other) {
        return this.unix < other.unix;
    }

    /** Comparison */
    public boolean isAfter(NaiveTime other) {
        return this.unix > other.unix;
    }

    /** Returns the current time in seconds */
    public int unix() {
        return this.unix;
    }
}
