<?php
/*
 +-------------------------------------------------------------------------+
 | Copyright (C) 2004-2015 The Cacti Group                                 |
 |                                                                         |
 | This program is free software; you can redistribute it and/or           |
 | modify it under the terms of the GNU General Public License             |
 | as published by the Free Software Foundation; either version 2          |
 | of the License, or (at your option) any later version.                  |
 |                                                                         |
 | This program is distributed in the hope that it will be useful,         |
 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
 | GNU General Public License for more details.                            |
 +-------------------------------------------------------------------------+
 | Cacti: The Complete RRDTool-based Graphing Solution                     |
 +-------------------------------------------------------------------------+
 | This code is designed, written, and maintained by the Cacti Group. See  |
 | about.php and/or the AUTHORS file for specific developer information.   |
 +-------------------------------------------------------------------------+
 | http://www.cacti.net/                                                   |
 +-------------------------------------------------------------------------+
*/

/* get_timespan		 		- returns start/end time for given date and timespan
 * 							  do NOT use absolute numbers of seconds but let php
 * 							  do all the time calculations to cover:
 * 							  leap years, daylight savings and weekdays ...
   @arg $span				- array &$timespan (begin_now, end_now)
   @arg $curr_time	 		- base date (time since epoch)
   @arg $timespan_given		- timespan as given by global_arrays.php($graph_timespans)
   @arg $first_weekdayid	- first weekday (numeric representation) */
function get_timespan(&$span, $curr_time, $timespan_given, $first_weekdayid) {
	# unless changed later, $span["end_now"] is always $curr_time
	$span["begin_now"] 	= $curr_time; # initialization only!
	$span["end_now"] 	= $curr_time;

	switch ($timespan_given)  {
		case GT_LAST_HALF_HOUR:
			$span["begin_now"] = strtotime("-30 minutes", $curr_time);
			break;
		case GT_LAST_HOUR:
			$span["begin_now"] = strtotime("-1 hour", $curr_time);
			break;
		case GT_LAST_2_HOURS:
			$span["begin_now"] = strtotime("-2 hours", $curr_time);
			break;
		case GT_LAST_4_HOURS:
			$span["begin_now"] = strtotime("-4 hours", $curr_time);
			break;
		case GT_LAST_6_HOURS:
			$span["begin_now"] = strtotime("-6 hours", $curr_time);
			break;
		case GT_LAST_12_HOURS:
			$span["begin_now"] = strtotime("-12 hours", $curr_time);
			break;
		case GT_LAST_DAY:
			$span["begin_now"] = strtotime("-1 day", $curr_time);
			break;
		case GT_LAST_2_DAYS:
			$span["begin_now"] = strtotime("-2 days", $curr_time);
			break;
		case GT_LAST_3_DAYS:
			$span["begin_now"] = strtotime("-3 days", $curr_time);
			break;
		case GT_LAST_4_DAYS:
			$span["begin_now"] = strtotime("-4 days", $curr_time);
			break;
		case GT_LAST_WEEK:
			$span["begin_now"] = strtotime("-1 week", $curr_time);
			break;
		case GT_LAST_2_WEEKS:
			$span["begin_now"] = strtotime("-2 weeks", $curr_time);
			break;
		case GT_LAST_MONTH:
			$span["begin_now"] = strtotime("-1 month", $curr_time);
			break;
		case GT_LAST_2_MONTHS:
			$span["begin_now"] = strtotime("-2 months", $curr_time);
			break;
		case GT_LAST_3_MONTHS:
			$span["begin_now"] = strtotime("-3 months", $curr_time);
			break;
		case GT_LAST_4_MONTHS:
			$span["begin_now"] = strtotime("-4 months", $curr_time);
			break;
		case GT_LAST_6_MONTHS:
			$span["begin_now"] = strtotime("-6 months", $curr_time);
			break;
		case GT_LAST_YEAR:
			$span["begin_now"] = strtotime("-1 year", $curr_time);
			break;
		case GT_LAST_2_YEARS:
			$span["begin_now"] = strtotime("-2 years", $curr_time);
			break;
		case GT_DAY_SHIFT:
			# take this day, start and end time fetched from config_settings
			$span["begin_now"] = strtotime(date("Y-m-d", $curr_time) . " " . read_graph_config_option("day_shift_start"));
			$span["end_now"]   = strtotime(date("Y-m-d", $curr_time) . " " . read_graph_config_option("day_shift_end"));
			break;
		case GT_THIS_DAY:
			# return Year-Month-Day for given 'time since epoch'
			# and convert this to 'time since epoch' (Hour:Minute:Second set to 00:00:00)
			$span["begin_now"] = strtotime(date("Y-m-d", $curr_time));
			$span["end_now"]   = strtotime("+1 day", $span["begin_now"]) - 1;
			break;
		case GT_THIS_WEEK:
			# compute offset to start-of-week
			# remember: start-of-week may be > current-weekday, so do modulo calc
			$offset = (date("w",$curr_time) - $first_weekdayid + 7) % 7;
			$span["begin_now"] = strtotime( "-" . $offset . " days" . date("Y-m-d", $curr_time));
			$span["end_now"]   = strtotime("+1 week", $span["begin_now"]) - 1;
			break;
		case GT_THIS_MONTH:
			# this date format set day-of-month to 01
			$span["begin_now"] = strtotime(date("Y-m-01", $curr_time));
			$span["end_now"]   = strtotime("+1 month", $span["begin_now"]) - 1;
			break;
		case GT_THIS_YEAR:
			# this date format set day-of-month to 01 and month-of-year to 01
			$span["begin_now"] = strtotime(date("Y-01-01", $curr_time));
			$span["end_now"]   = strtotime("+1 year", $span["begin_now"]) - 1;
			break;
		case GT_PREV_DAY:
			$span["begin_now"] = strtotime("-1 day" . date("Y-m-d", $curr_time));
			$span["end_now"]   = strtotime("+1 day", $span["begin_now"]) - 1;
			break;
		case GT_PREV_WEEK:
			# compute offset to start-of-week
			# remember: start-of-week may be > current-weekday, so do modulo calc
			$offset = (date("w",$curr_time) - $first_weekdayid + 7) % 7;
			$span["begin_now"] = strtotime( "-1 week -" . $offset . " days" . date("Y-m-d", $curr_time));
			$span["end_now"]   = strtotime("+1 week", $span["begin_now"]) - 1;
			break;
		case GT_PREV_MONTH:
			$span["begin_now"] = strtotime("-1 month" . date("Y-m-01", $curr_time));
			$span["end_now"]   = strtotime("+1 month", $span["begin_now"]) - 1;
			break;
		case GT_PREV_YEAR:
			$span["begin_now"] = strtotime("-1 year" . date("Y-01-01", $curr_time));
			$span["end_now"]   = strtotime("+1 year", $span["begin_now"]) - 1;
			break;
		default:
			$span["begin_now"] = $curr_time - DEFAULT_TIMESPAN;
			break;
	}

	# reformat time-since-epoch start/end times to human readable format
	$span["current_value_date1"] = date("Y-m-d H:i",$span["begin_now"]);
	$span["current_value_date2"] = date("Y-m-d H:i",$span["end_now"]);
}

/* month_shift		- check for shifting one or more months
 * @arg $shift_size	- requested shift amount
 * returns			- true, if month shifting required, else false
 */
function month_shift($shift_size) {
	# is monthly shifting required?
	return ( strpos(strtolower($shift_size), "month") > 0);
}

/* check_month_boundaries 	- check given boundaries for begin/end of month matching
 * @arg $span				- array $timespan with given boundaries
 * returns					- true, if begin AND end match month begin/end boundaries
 */
function check_month_boundaries(&$span) {
	# check left boundary -----------------------------------------------
	$begin_of_month = strtotime(date("Y-m-01", $span["begin_now"]));
	$begin_match 	= ( $begin_of_month == $span["begin_now"]);

	# check right boundary ----------------------------------------------
	# first, get a defined date of the month, $span["end_now"] belongs to
	$begin_of_month = strtotime(date("Y-m-01", $span["end_now"]));
	# do "end of month" magic to get end_of_month for arbitrary months
	$end_of_month = strtotime("+1 month", $begin_of_month) - 1;

	# accept end of month if no seconds given (adjust for 59 missing seconds)
	$end_match = ( (($end_of_month - 59) <= $span["end_now"]) && ($span["end_now"] <= $end_of_month));

	return ( $begin_match && $end_match );
}

/* shift_right_boundary	- shift right boundary with end-of-month adjustment
 * @arg $span			- timespan array
 * @arg $direction		- shift left/right (-/+)
 * @arg $shift_size		- amount of shift
 * returns				- time-since-epoch for shifted right boundary
 */
function shift_right_boundary(&$span, $direction, $shift_size) {
	# first, get begin of the month, $span["end_now"] belongs to
	$begin = date("Y-m-01", $span["end_now"]);

	# shift the begin date to correct month
	$begin_of_shifted_month	= strtotime($direction . $shift_size . " " . $begin);

	# do "end of month" magic
	return strtotime("+1 month", $begin_of_shifted_month) - 1;
}

/* shift_time		- shift given timespan left/right
 * @arg &$span		- given timespan (start/end time as time-since-epoch and human readable)
 * @arg $direction	- "-" for shifting left, "+" for shifting right
 * @arg $timeshift	- amount of shifting
 */
function shift_time(&$span, $direction, $shift_size) {
	# move left/right according to $direction
	# amount to be moved is derived from $shift_size
	# base dates are taken from array $span

	# is this a month shift AND current timespane is on month boundaries?
	if ( month_shift($shift_size) && check_month_boundaries($span) ) {
		# shift left boundary
		$span["begin_now"] 	= strtotime($direction . $shift_size . " " . $span["current_value_date1"]);
		# shifting right boundary is somewhat complicated
		$span["end_now"] 	= shift_right_boundary($span, $direction, $shift_size);
	} else {
		# 'normal' time shifting: use strtotime magic
		$span["begin_now"] 	= strtotime($direction . $shift_size . " " . $span["current_value_date1"]);
		$span["end_now"] 	= strtotime($direction . $shift_size . " " . $span["current_value_date2"]);
	}

	# convert to human readable format
	$span["current_value_date1"] = date("Y-m-d H:i", $span["begin_now"]);
	$span["current_value_date2"] = date("Y-m-d H:i", $span["end_now"]);

	# now custom time settings in effect
	$_SESSION["sess_current_timespan"] = GT_CUSTOM;
	$_SESSION["custom"] = 1;
	$_POST["predefined_timespan"] = GT_CUSTOM;
}

/** date_time_format		create a format string for date/time
 * @param string returns	date time format
 */
function date_time_format() {
	global $config;

	$graph_date = "";

	/* setup date format */
	$date_fmt = read_graph_config_option("default_date_format");
	$datechar = read_graph_config_option("default_datechar");

	switch ($datechar) {
		case GDC_HYPHEN: 	$datechar = "-"; break;
		case GDC_SLASH: 	$datechar = "/"; break;
		case GDC_DOT:	 	$datechar = "."; break;
	}

	switch ($date_fmt) {
		case GD_MO_D_Y:
			$graph_date = "m" . $datechar . "d" . $datechar . "Y H:i:s";
			break;
		case GD_MN_D_Y:
			$graph_date = "M" . $datechar . "d" . $datechar . "Y H:i:s";
			break;
		case GD_D_MO_Y:
			$graph_date = "d" . $datechar . "m" . $datechar . "Y H:i:s";
			break;
		case GD_D_MN_Y:
			$graph_date = "d" . $datechar . "M" . $datechar . "Y H:i:s";
			break;
		case GD_Y_MO_D:
			$graph_date = "Y" . $datechar . "m" . $datechar . "d H:i:s";
			break;
		case GD_Y_MN_D:
			$graph_date = "Y" . $datechar . "M" . $datechar . "d H:i:s";
			break;
	}
	return $graph_date;
}

?>
