<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This is class is for calculating date periods.
 *
 * @package    OSB
 * @subpackage Utilities
 * @category   Helpers
 * @author     Deon George
 * @copyright  (c) 2010 Deon George
 * @license    http://dev.leenooks.net/license.html
 */
class Period {
	/**
	 * Calculate both the start and end dates for a billing period
	 * and the pro-rata percentage.
	 *
	 * See [StaticList_RecurSchedule]
	 *
	 * @param StaticList_RecurSchedule Period Type [StaticList_RecurSchedule]
	 * @param int Starting date if recurring must start on a day of the month
	 * @param datetime Date to start calculating from, otherwise now() is used
	 * @param boolean Show dates in 'Y-m-d' format
	 * @return array
	 */
	public static function details($type,$weekday=NULL,$start=NULL,$df=FALSE) {
		// Our precision for the pro-rata percentage
		$precision = 4;
		// Make the period consistent, eg: Quarterly = Jan-Mar,Apr-Jun; HalfYearly = Jan-Jun,Jul-Dec
		$strict = FALSE;

		// Round the time integer to a whole day.
		if (is_null($start))
			$start = strtotime('today');
		else
			$start = strtotime(date('Y-m-d',$start));

		switch ($type) {
			// Weekly
			// @todo Make Weekly pro-rata to a day of the week
			case 0:
				$period_end = $start+(86400*(7-1));
				return array('start'=>$start,'date'=>$start,'end'=>$period_end,'prorate'=>1);

			# Monthly
			case 1:
				$inc_months = 1;
				break;

			# Quarterly
			case 2:
				# @todo Make this configurable.
				$strict = TRUE;
				$inc_months = 3;
				break;

			# Half Yearly
			case 3:
				# @todo Make this configurable.
				$strict = TRUE;
				$inc_months = 6;
				break;

			# Yearly
			case 4:
				$inc_months = 12;
				break;

			# Biennial
			case 5:
				$inc_months = 24;
				break;

			# Triennial
			case 6:
				$inc_months = 36;
				break;

			default:
				return FALSE;
		}

		// If workout a day of week we calculate to.
		if (is_null($weekday))
			$weekday = date('d',$start);

		$used_months = 0;
		if ($strict && $type > 0 && $type < 5)
			$used_months = $inc_months-(($inc_months-(date('n',$start)%$inc_months))%$inc_months+1);

		$d = mktime(0,0,0,date('m',$start)-$used_months,$weekday,date('y',$start));
		if ($d <= $start)
			$period_start = $d;
		else
			$period_start = mktime(0,0,0,date('m',$d)-1-$used_months,$weekday,date('y',$d));

		$period_end = mktime(0,0,0,date('m',$period_start)+$inc_months,$weekday,date('y',$period_start));

		$total_time = $period_end-$period_start;
		$remain_time = $period_end-$start;
		$used_time = $start-$period_start;

		// Change our end date to the day before
		$period_end -= 86400;

		$return = array(
				'start'=>$period_start,
				'start_time'=>$start,
				'date'=>$start,
				'end'=>$period_end,
				'end_time'=>$period_end,
				'weekday'=>$weekday,
				'prorata'=>round($remain_time/$total_time,$precision),
				'total_time'=>sprintf('%3.1f',$total_time/86400),
				'remain_time'=>sprintf('%3.1f',$remain_time/86400),
				'used_time'=>sprintf('%3.1f',$used_time/86400));

		// @todo Use the configured data format
		if ($df)
			foreach (array('start','date','end') as $key)
				$return[$key] = date('Y-m-d',$return[$key]);

		return $return;
	}
}
?>
