package org.treesched.schedules;

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

import org.apache.log4j.Logger;
import org.treesched.AbstractSchedule;
import org.treesched.DateUtils;
import org.treesched.Interval;
import org.treesched.Schedule;

/**
 * This schedule will return it's last due child schedule within the 
 * given parent interval.
 * <p>
 * This would typically be used to return the last working day of the
 * month.
 * <p>
 * See the test cases for an example.
  * 
 * @author Rob Gordon
*/

final public class LastSchedule extends AbstractSchedule implements Serializable {

    private static final long serialVersionUID = 20050226;
    
    private static final Logger logger = Logger.getLogger(LastSchedule.class);
    
	/**
	 * Calculate the next due interval within the given interval.
	 */
	public Interval nextDue(Date now) {
	    if (now == null) {
	        throw new NullPointerException();
	    }
		if (getChildSchedule() == null) {
		    throw new IllegalStateException("Last must have a child schedule.");
		}
		
		logger.debug(this + ": in date is " + now);
		
		Interval last = null;						
		Date use = now;
		
		Schedule child = getChildSchedule();
		child.setLimits(getLimits());
		while(true) {
			logger.debug(this + ": use date is " + use);
			Interval candidate = child.nextDue(use);			
			if (candidate == null) {
			    break;
			}
			last = candidate;
			use = DateUtils.oneMillisAfter(candidate.getToDate());
		}
		
		return last;
	}

	/**
	 * Override toString.
	 */
	
	public String toString() {
		return "Last Schedule";
	}

}
