<?php
////////////////////////////////////////////////////////////////////////
// Breeze Website Builder
// Copyright Silver Dolphin Solutions, LLC, Edward Lemmers, P.E.
// For licensing, see license.txt.
// Created: 2/21/2014
//
// start_date: First day of event.
// end_date: Last day of event, or more accurately, cuttoff for calculating recurring dates.
// recurrence_freq: daily, weekly, monthly, yearly --> If daily, then nothing to do. Just span from start to end.
// recurrence_byday: day of week to repeat on, Sun thru Sat, 0 thru 6 --> Used when recurrence_freq = 'monthly' or 'weekly'.  May be comma-separated list if 'weekly'.
// recurrence_byweekno: week of month, first thru fourth, last, 1 trhu 5 --> Used when recurrence_freq = 'monthly'
// recurrence_days: number of days event lasts --> Used when recurrence_freq = 'yearly'

function GetRecurringDates($start_date, $end_date, $recurrence_freq, $recurrence_byday = -1, $recurrence_byweekno = -1, $recurrence_days = -1)
{
	$start_ts = strtotime($start_date);
	$end_ts = strtotime($end_date);
//		echo "$end_ts<br/>";
	$last_date_ts = $start_ts;
	$dates = array();
	
	if ($start_ts > $end_ts)
		return ("-end date before start date-");
	elseif ($recurrence_freq == "daily")
	{
		$ts = $start_ts;
		while ($ts < $end_ts)
		{
			$ts = strtotime('+1 day', $ts);
			$next_date = date("Y-m-d", $ts);
			$dates[] = $next_date;
		}
		return ($dates);
	}
	elseif ($recurrence_freq == "weekly")
	{
		if ($recurrence_byday > -1)
		{
			$start_ts = strtotime('+1 day', $start_ts);	// Skip parent date.
			while ($last_date_ts < $end_ts)
			{
				$start_day_of_week = date('w', $start_ts);
//					echo "$start_day_of_week<br/><br/>\n";
				$start_day = date('d', $start_ts);
				$recurrence_bydays = explode(",", $recurrence_byday);
				foreach ($recurrence_bydays as $day_of_week)
				{
					$days_from = $day_of_week - $start_day_of_week;
					if ($days_from < 0)
						$days_from = $days_from + 7;
//						echo "$days_from = $day_of_week - $start_day_of_week<br/>\n";
					$day_add_str = '+' . $days_from . ' day';
//						echo $day_add_str . "<br/>\n";
					$ts = strtotime($day_add_str, $start_ts);
					if ($ts <= $end_ts)
					{
						$next_date = date("Y-m-d", $ts);
						$dates[] = $next_date;
//							echo "$next_date<br/>\n";
//							echo "$ts<br/><br/>\n";
					}
					if ($ts > $last_date_ts)
						$last_date_ts = $ts;
				}
				$start_ts = strtotime('+1 day', $last_date_ts);
			}
			return ($dates);
		}
		else
			return ("-no day of week specified-");
	}
	elseif ($recurrence_freq == "monthly")
	{
		if (($recurrence_byday > -1) && ($recurrence_byweekno > -1))
		{
			$start_ts = strtotime('+1 month', $start_ts);
//				echo date("Y-m-d", $start_ts) . "<br/>\n";
			while ($last_date_ts < $end_ts)
			{
				switch ($recurrence_byday)	{
					case 0:
						$day_of_week = "Sunday";
						break;
					case 1:
						$day_of_week = "Monday";
						break;
					case 2:
						$day_of_week = "Tuesday";
						break;
					case 3:
						$day_of_week = "Wednesday";
						break;
					case 4:
						$day_of_week = "Thursday";
						break;
					case 5:
						$day_of_week = "Friday";
						break;
					case 6:
						$day_of_week = "Saturday";
						break;
					default:
						return("-day of week out of range-");
				}
				
				switch ($recurrence_byweekno)	{
					case 1:
						$week_no = "first";
						break;
					case 2:
						$week_no = "second";
						break;
					case 3:
						$week_no = "third";
						break;
					case 4:
						$week_no = "fourth";
						break;
					case 5:
						$week_no = "last";
						break;
					default:
						return("-week number out of range-");
				}

//					$day_add_str = $week_no . " " . $day_of_week;
//					echo $day_add_str . "<br/>\n";
//					$ts = strtotime($day_add_str, $start_ts);
//					echo $ts . "<br/>\n";
				$ts = GetDateFromWeekNoAndDay($week_no, $day_of_week, $start_ts);
//					echo $ts . "<br/>\n";
				if ($ts <= $end_ts)
				{
					$next_date = date("Y-m-d", $ts);
					$dates[] = $next_date;
//						echo "$next_date<br/>\n";
				}
				if ($ts > $last_date_ts)
					$last_date_ts = $ts;

				$start_ts = strtotime('+1 month', $start_ts);
//					echo date("Y-m-d", $start_ts) . "<br/><br/>\n\n";
			}
			return ($dates);
		}
		elseif($recurrence_byday < 0)
			return ("-no day of week specified-");
		elseif($recurrence_byweekno < 0)
			return ("-no week number specified-");
	}
	elseif ($recurrence_freq == "yearly")
	{
		if ($recurrence_days > -1)
		{
			$first_yr = true;
			while ($last_date_ts < $end_ts)
			{
				$day_add_str = '+' . $recurrence_days . ' day';
//					echo $day_add_str . "<br/>\n";
				$ts = strtotime($day_add_str, $start_ts);
				if ($ts <= $end_ts)
				{
					if (!$first_yr)	{
						$next_date = date("Y-m-d", $start_ts);
						$dates[] = $next_date;
//							echo "$next_date<br/>\n";
					}
					$next_date = date("Y-m-d", $ts);
					$dates[] = $next_date;
//						echo "$next_date<br/>\n";
//						echo "$ts<br/><br/>\n";
				}
				$first_yr = false;
				if ($ts > $last_date_ts)
					$last_date_ts = $ts;

				$start_ts = strtotime('+12 month', $start_ts);
			}
			return ($dates);
		}
		else
			return ("-no event day span specified-");
	}
	else
		return ("-no recurrence type specified-");
}

function GetDateFromWeekNoAndDay($week_no, $day_of_week, $ts)
{
	$month = date("m", $ts);
	$year = date("Y", $ts);
	$adj_ts = strtotime($month . "/01/" . $year);
//		echo $adj_ts . "<br/>\n";
	for ($i = 1; $i < 8; $i++)
	{
		$tmp_ts = strtotime($month . "/" . $i . "/" . $year);
		$tmp_day = date("l", $tmp_ts);
		if ($tmp_day == $day_of_week)
		{
//				echo "Got day: $tmp_day<br>\n";
			if ($week_no == "first")
				return ($tmp_ts);
			elseif ($week_no == "second")
				$date_no = $i + 7;
			elseif ($week_no == "third")
				$date_no = $i + 14;
			elseif ($week_no == "fourth")
				$date_no = $i + 21;
			elseif ($week_no == "last")	{
				if (($i < 25 ) && ( ($month == "01") || ($month == "03") || ($month == "05") || ($month == "07") || ($month == "08") || ($month == "10") || ($month == "12") ))
					$date_no = $i + 28;
				elseif (($i < 24 ) && ( ($month == "04") || ($month == "06") || ($month == "09") || ($month == "11") ))
					$date_no = $i + 28;
				elseif (($i < 22 ) && ($month == "02") && !is_leap_year($year))
					$date_no = $i + 28;
				elseif (($i < 23 ) && ($month == "02") && is_leap_year($year))
					$date_no = $i + 28;
				else
					$date_no = $i + 21;
			}
			
			$tmp_ts = strtotime($month . "/" . $date_no . "/" . $year);
			return ($tmp_ts);
		}
	}
	
}

function is_leap_year($year)
{
	return ((($year % 4) == 0) && ((($year % 100) != 0) || (($year %400) == 0)));
}
	
//	GetRecurringDates("2015-07-01", "2015-07-04", "daily");
//	GetRecurringDates("2015-07-01", "2015-08-01", "weekly", "0,2,4");
//	GetRecurringDates("2015-05-01", "2015-12-31", "monthly", 1, 2);
//	GetRecurringDates("2015-07-01", "2016-07-01", "yearly", -1, -1, 3);
?>

