package org.treesched.schedules;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.treesched.AbstractSchedule;
import org.treesched.DateUtils;
import org.treesched.Interval;

/**
 * A schedule that returns the day after when a child schedule is due.
 * This is designed to be used for processing which happens the
 * day after, i.e. processing previous business days data.
 * <p>
 * Typical configuration is:
 * <code><pre>
 * &lt;dayafter&gt;
 *   &lt;dayofmonth from="25" to="0"&gt;
 *     &lt;last&gt;
 *        &lt;dayofweek from="mon" to="fri"&gt;
 *          &lt;daily/gt;
 *        &lt;/dayofweek&gt;
 *     &lt;/last&gth;
 *   &lt;/dayofmonth&gt;
 * &lt;/dayafter&gt;
 * </pre></code>
 * 
 * @author Rob Gordon
 */

final public class DayAfterSchedule extends AbstractSchedule implements Serializable {

    private static final long serialVersionUID = 20050226;
    
    /*
     *  (non-Javadoc)
     * @see org.treesched.Schedule#nextDue(java.util.Date)
     */
	public Interval nextDue(Date now) {
		if (now == null) {
		    throw new NullPointerException();
		}
		if (getChildSchedule() == null) {
		    throw new IllegalStateException("DayAfter must have a child schedule.");
		}

		Interval childInterval = getChildSchedule().nextDue(now);

		Calendar startCal = new GregorianCalendar();
		startCal.setTime(childInterval.getFromDate());
		startCal.add(Calendar.DATE, 1);
		Date dayAfterStart = startCal.getTime();
		
		Calendar endCal = new GregorianCalendar();
		endCal.setTime(childInterval.getFromDate());
		endCal.add(Calendar.DATE, 2);
		Date dayAfterEnd = DateUtils.oneMillisBefore(endCal.getTime());
		
		Interval dayAfter = new Interval(dayAfterStart, dayAfterEnd);

		return dayAfter.limit(getLimits());
	}
	
	/**
	 * Override toString.
	 */
	
	public String toString() {
		
		return "Day After Schedule";
	}
}
