package test1;

import java.util.List;

public class TimeUtil {

	private TimeUtil() {
		// empty by design
	}

	/**
	 * The number of minutes in one hour.
	 */
	public static final int MINUTES_PER_HOUR = 60;

	/**
	 * The number of days in a standard year.
	 */
	public static final int DAYS_PER_YEAR = 365;

	/**
	 * The number of days in a leap year.
	 */
	public static final int DAYS_PER_LEAP_YEAR = TimeUtil.DAYS_PER_YEAR + 1;

	/**
	 * Converts a number of minutes to hours rounding up to the nearest number
	 * of hours. For example:
	 * 
	 * <pre>
	 * toHoursRoundedUp(0)   returns   0
	 * toHoursRoundedUp(59)  returns   1
	 * toHoursRoundedUp(60)  returns   1
	 * toHoursRoundedUp(61)  returns   2
	 * toHoursRoundedUp(150) returns   3
	 * </pre>
	 * 
	 * <p>
	 * This is how most service-based businesses calculate how many hours of
	 * labor are charged to the customer (i.e., a job that takes 15 minutes will
	 * cost the customer 1 hour of labor charges).
	 * 
	 * @param minutes
	 *            a number of minutes
	 * @return the equivalent number of hours rounded up to the nearest
	 *         hour 
	 * @pre. minutes is greater than or equal to zero
	 */
	public static int toHoursRoundedUp(int minutes) {
		int hours = minutes / TimeUtil.MINUTES_PER_HOUR;
		if (minutes % TimeUtil.MINUTES_PER_HOUR != 0) {
			hours++;
		}
		return hours;
	}

	/**
	 * Returns true if year is a leap year and false otherwise.
	 * 
	 * <p>
	 * A year is always a leap year if it is evenly divisible by 400; for all
	 * other years, a year is a leap year if it is evenly divisible by 4 and not
	 * evenly divisible by 100. For example:
	 * 
	 * <pre>
	 * isLeapYear(2000)  returns  true   (2000 is divisible by 400)
	 * isLeapYear(1900)  returns  false  (1900 is divisible by 4 and 100)
	 * isLeapYear(2004)  returns  true   (2004 is divisible by 4 but not 100)
	 * isLeapYear(2005)  returns  false  (2005 is not divisible by 4)
	 * </pre>
	 * 
	 * @param year
	 *            a year
	 * @return true if year is a leap year and false otherwise
	 * @throws IllegalArgumentException
	 *             if year is less than zero
	 */
	public static boolean isLeapYear(int year) {
		if (year < 0) {
			throw new IllegalArgumentException();
		}
		boolean result = false;
		if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
			result = true;
		}
		return result;
	}

	/**
	 * Computes the total number of days in the period of time from Jan 1 of the
	 * start year to Dec 31 of the end year accounting for the presence of leap
	 * years.
	 * 
	 * <pre>
	 * totalDays(2000, 2000)  returns  366        (Jan 1, 2000 to Dec 31, 2000)
	 * totalDays(2001, 2002)  returns  365 + 365  (Jan 1, 2001 to Dec 31, 2002)
	 * totalDays(2001, 2004)  returns  365 + 365 + 365 + 366  (Jan 1, 2001 to Dec 31, 2004)
	 * </pre>
	 * 
	 * @param startYear
	 *            the start year
	 * @param endYear
	 *            the end year
	 * @return the number of days from Jan 1 of the start year to Dec 31 of the
	 *         end year 
	 * @pre. endYear is greater than or equal to startYear
	 */
	public static int totalDays(int startYear, int endYear) {
		int days = 0;
		for (int year = startYear; year <= endYear; year++) {
			if (TimeUtil.isLeapYear(year)) {
				days += TimeUtil.DAYS_PER_LEAP_YEAR;
			} else {
				days += TimeUtil.DAYS_PER_YEAR;
			}
		}
		return days;
	}

	/**
	 * Given a sorted list of years, returns the year that occurs
	 * most frequently in the list. You may assume that only one
	 * year occurs the most frequently in the argument list.
	 * The method does not modify the argument list.
	 * 
	 * @param years a sorted list of years
	 * @return the year that occurs most frequently in the list
	 * @pre. years.size() is greater than or equal to 1
	 */
	public static int mostFrequent(List<Integer> years) {
		int maxCount = 1;
		int mostFreq = years.get(0);
		int currCount = 1;
		for (int i = 1; i < years.size(); i++) {
			int prevYr = years.get(i - 1);
			int thisYr = years.get(i);
			if (thisYr == prevYr) {
				currCount++;
				if (currCount > maxCount) {
					maxCount = currCount;
					mostFreq = thisYr;
				}
			} else {
				currCount = 1;
			}
		}
		return mostFreq;
	}
}
