<?php
/* $Id: calendar_func.inc.php,v 1.41 2006/04/16 14:40:44 leyeti Exp $ */

// adding file revision into global array
if(function_exists("revisionInit")) revisionInit("\$Revision: 1.41 $", __FILE__);

define('CAL1_INC_DIR', ROOTPATH."/modules/calendar/inc/");
define('CAL1_DIR', ROOTPATH."/modules/calendar/");

// Get username from user with id $userid from db
function getRealUsername($userid) {
    global $conn;
    $sql = "SELECT ".$conn->Concat("lastname", "', '", "firstname")." AS name from mgw_users where id = '".$userid."'";
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row=$res->FetchRow();
    return $row["name"];
}

///// NATYS /////
function str_encode($str){
return urlencode($str);
}

function str_decode($str){
return nl2br(StripSlashes(urldecode($str)));
}

// return Daylight Saving Time in second (summer/winter time shifting according to settings)
function get_DST($timestamp){
	if(date("I",$timestamp)=="1"){ // summer time
		return $_SESSION["MGW"]->settings["Summer_timezone"]*3600;
	}
	else { // winter time
		return $_SESSION["MGW"]->settings["Winter_timezone"]*3600;
	}
}


function get_view_rights($id_user_from, $id_user_to){
// return 0 : limited view (normal)
// return 1 : can view all properties
global $conn;
	if ($id_user_from==$id_user_to) return 1;
	$sql = "SELECT view_all FROM mgw_calendar_rights where id_user = '".$id_user_from."' AND id_owner = '".$id_user_to."'";
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    if ($res->NumRows() > 0) {
    	$row=$res->FetchRow();
		return $row["view_all"];
    }
    else return 0;
}


function get_modify_rights($id_user_from, $id_user_to){
// return 0 : can't modify, create or delete (normal)
// return 1 : can modify, create or delete
global $conn;
	if ($id_user_from==$id_user_to) return 1;
	$sql = "SELECT modify FROM mgw_calendar_rights where id_user = '".$id_user_from."' AND id_owner = '".$id_user_to."'";
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    if ($res->NumRows() > 0) {
    	$row=$res->FetchRow();
		return $row["modify"];
    }
    else return 0;
}

function is_displayable_by_current_user($id_appt){
global $conn;
	//current user:
	$id_user_from = $_SESSION["MGW"]->userid;

	$right = 0;
	//get id_user of id_appt:
	$sql = "SELECT userid FROM mgw_calendar where id = '".$id_appt."'";
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while ($row=$res->FetchRow()){
		$id_user_to = $row["userid"];
		//right "view_all"  OR 	right "modify" :
		$right = $right || ( get_view_rights($id_user_from,$id_user_to) || get_modify_rights($id_user_from,$id_user_to) );
	}

	return $right;
}

function is_modifiable_by_current_user($id_appt,$id_user=""){
global $conn;
	//current user:
	$id_user_from = $_SESSION["MGW"]->userid;

	$inituser_right = 0;
	$simpleuser_right = 0;

	//get id_user of id_appt:
	$sql = "SELECT inituserid FROM mgw_calendar where id = '".$id_appt."'";
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
   	$row=$res->FetchRow();
   	$id_user_to = $row["inituserid"];
	$inituser_right = get_modify_rights($id_user_from,$id_user_to);

	if ($id_user=="") $id_user = $id_user_from;
	if (/*$id_user!="" and */$res->NumRows() == 1) { // only for appointments with 1 participant
	    // verify if id_appt belong to id_user:
		$sql = "SELECT id FROM mgw_calendar where id = '".$id_appt."' AND userid='$id_user'";
    	if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
   		if($res->NumRows() > 0) $simpleuser_right = get_modify_rights($id_user_from,$id_user);
	}
	//current user can modify inituser's appt OR the record "id_appt<->id_user"
	return $inituser_right || $simpleuser_right;

   /* while ($row=$res->FetchRow()){
		$id_user_to = $row["userid"];
		//right "modify" :
		$right = $right || get_modify_rights($id_user_from,$id_user_to);
	}

	return $right;
	*/
}

function current_user_can_create_for($id_user){
global $conn;
	//current user:
	$id_user_from = $_SESSION["MGW"]->userid;

	//right "modify" :
	return get_modify_rights($id_user_from,$id_user);
}
/////////////////

function cal_png_image($imgsrc,$width="",$height="",$alt="",$ahref=0,$border=0){

if ($width=="")
	{
	$size = getimagesize($imgsrc);
	$width= $size[0];
	}
if ($height=="")
	{
	$size = getimagesize($imgsrc);
	$height= $size[1];
	}
if ($ahref==1) $cursor="hand";
else $cursor="";

/*return "<!-- damn you MSFT and your incompatible hacks!! :( -->
		<div title=\"{$alt}\" style=\"cursor:$cursor; border-style:solid;  border-width: {$border}px; width: {$width}px; height: {$height}px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='{$imgsrc}', sizingMethod='scale');\"></div>
		";
*/

return  "<SCRIPT LANGUAGE=\"javascript\">
		var V=navigator.appVersion;
		if(document.all && document.getElementById) { // it's ie5+ but which version ?
			ver=V.substring(V.indexOf(\"MSIE\",0)+5,V.indexOf(\";\",V.indexOf(\"MSIE\",0)));
		}
		else ver=\"\";
		//sorry : for ie 5.01, there's NO solution for displaying PNG correctly
		if(document.all && document.getElementById && ver!=\"5.01\" ) { //it's ie5.5+
		<!-- damn you MSFT and your incompatible hacks!! :( -->
		document.write(\"<div title=\\\"{$alt}\\\" style=\\\"cursor:{$cursor}; border-style:solid;  border-width: {$border}px; width: {$width}px; height: {$height}px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'{$imgsrc}\', sizingMethod=\'scale\');\\\"></div>\");
		}
		else{ //all other browsers
		document.write(\"<img src=\\\"{$imgsrc}\\\" width=\\\"{$width}\\\" height=\\\"{$height}\\\" alt=\\\"{$alt}\\\" title=\\\"{$alt}\\\" border=\\\"{$border}\\\" >\");
		}
		</SCRIPT>";

}

function getCalIconStrings() {
global $appconf;
    $settings=$_SESSION["MGW"]->settings;

	$Cal_icons = array();
    if($settings["iconmode"]==1) {
		$Cal_icons["editserial"] = cal_png_image($appconf["imgpath"]. "/editserial.png","","",Lang::getLanguageString("temp_row_action_label_serialedit"),1);
		$Cal_icons["vcal"] = cal_png_image($appconf["imgpath"]. "/vcal.png","","",Lang::getLanguageString("vcal"),1);

        $Cal_icons["validate"] = cal_png_image($appconf["imgpath"]. "/validate.png","","",Lang::getLanguageString("validate_for_me"),1);
    	$Cal_icons["validateforall"] = cal_png_image($appconf["imgpath"]. "/validateforall.png","","",Lang::getLanguageString("validate_for_all"),1);
    	$Cal_icons["abort"] = cal_png_image($appconf["imgpath"]. "/abort.png","","",Lang::getLanguageString("abort_for_me"),1);
    }
	else {
        $Cal_icons["editserial"] = Lang::getLanguageString("temp_row_action_label_serialedit");
		$Cal_icons["vcal"] = Lang::getLanguageString("vcal");

	    $Cal_icons["validate"] = Lang::getLanguageString("validate_for_me");
    	$Cal_icons["validateforall"] = Lang::getLanguageString("validate_for_all");
    	$Cal_icons["abort"] = Lang::getLanguageString("abort_for_me");
	}
return $Cal_icons;
}


function quoted_printable_encode($input, $tag_len = 0, $line_max = 76) {
	$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
	$eol = "\r\n";
	$linebreak = "=0D=0A";
	$escape = "=";
	$output = "";

	for ($j=0;$j<count($lines);$j++) {
		$line = $lines[$j];
		$linlen = strlen($line);
		$newline = "";
		for($i = 0; $i < $linlen; $i++) {
			$c = substr($line, $i, 1);
			$dec = ord($c);
			if ( ($dec == 32) && ($i == ($linlen - 1)) ) { // convert space at eol only
				$c = $escape."20";
			} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) { // always encode "\t", which is *not* required
				$c = $escape.strtoupper(dechex($dec));
			}
			if ( (strlen($newline.$c)+$tag_len) >= $line_max ) { // CRLF is not counted
				$output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
				$newline = "";
				$tag_len = 0; //afects only first line
			}
			$newline .= $c;
		} //end of input line

		$output .= $newline;
		if ($j<count($lines)-1) {
			if ( strlen($newline.$linebreak) >= $line_max ) $output .= $escape.$eol;
			$output .= $linebreak;
		}
	}
	return trim($output);
}

function jsencode($str){
	//return strtr($str, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
	$str = str_replace("\"","''" ,$str);
	return strtr($str, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
}

// in_array for php < 4.2.0
function in_array_buggyphp($needle,$haystack) {
	$ret=FALSE;
	for ($i=0;$i<count($haystack);$i++) {
		if ($needle==$haystack[$i]) {
			$ret=TRUE;
			break;
		}
	}
	return $ret;
}

// perhaps we should make it configurable (in settings)
$max_subject_length=100;

// Return substring of s with length and '...'
function short_string($s,$length) {
	if (strlen($s)>$length) {
		return substr($s,0,$length-3)."...";
	} else {
		return $s;
	}
}

// =====================================================
// array get_appt_type_legend()
// get properties of each appointment type for the legend
// ======================================================
function get_appt_type_legend(){
	global $conn;

	$appt_types = array();
	$sql = "SELECT * FROM mgw_calendar_appt_type";
	if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
		while ($row = $res->FetchRow()) {
			$appt_types []= array( 	"color" => $row["color"],
									"text" => Lang::getLanguageString("gentemp_".$row["type"])
								);
		}
	return $appt_types;
}


// ======================================================
// boolean is_leap_year ( int year )
// checks wether a year is a leap year
// ======================================================
function is_leap_year($year){
    if ((($year % 4) == 0 and ($year % 100)!=0) or ($year % 400)==0)
	return 1;
    else
	return 0;
}

// ======================================================
// timestamp get_weektimestamp( integer week_number, integer year)
// returns the timestamp of the first day of the week_number of the year
// ======================================================
function get_weektimestamp ($week_number, $year){
if ($week_number>53) {
    echo "get_weektimestamp : INVALID ARGUMENT : week_number=$week_number !<BR>";
	return 0;
}
if ($week_number==53) {
    $t = mktime(0,0,0,12,31,$year);
	if (get_weeknumber($t)!=53){
		echo "get_weektimestamp : INVALID ARGUMENT : week_number=$week_number but there are only 52 weeks in $year !<BR>";
		return 0;
		}
}
//timestamp of the 1st january of year:
$d = 1;
$ts = mktime(0,0,0,1,$d,$year)+1;
//be sure to be in week n° 01:
if (get_weeknumber($ts)!="01") {
	 $d = 8;
	 $ts = mktime(0,0,0,1,$d,$year)+1;
	}
//now we are in week n°1 -> we want now to be on the 1st day(MON) of the 1st week:
$m=1;$y=$year;
while(date("D",$ts)!="Mon") { // we are between 28/12/(y-1) and 8/01/y
	$d = (($d-1)>0) ? ($d-1) : 31;
	$m = ($d==31) ? 12 : $m;
	$y = ($d==31) ? ($y-1) : $y;
	$ts = mktime(0,0,0,$m,$d,$y)+1; //decrease per 1 day
	}
//debug: echo "1st day of 1st week : $d $m $y<br>";
// now $ts is the timestamp of the first day of the week n°01:

return mktime(0,0,0,$m,$d + ($week_number-1)*7,$y)+1;
}

// ======================================================
// Integer get_weeknumber( timestamp timestamp)
// returns the calendar week number from timestamp according to ISO 8601:1988
// ======================================================
function get_weeknumber($timestamp) {

/***************************
*   OLD FUNCTION :

	$week = strftime("%W", mktime(0, 0, 0, $m, $d, $y));

	//last_week of this year:
	$last_week = strftime("%W", mktime(0, 0, 0, 12, 31, $y));
	//day of week of 1st january of this year :
	$dow0101=getdate(mktime(0, 0, 0, 1, 1, $y));
	//day of week of 31 december of this year :
	$dow3112=getdate(mktime(0, 0, 0, 12, 31, $y));

	//en: 	Day :	Sun Mon Tue	Wed	Thu	Fri Sat
	//		wday:	0	1	2	3	4	5	6
	//		The week n°1 is the week which contain the 1st january between monday and friday
	//	  	if the 1st january is a saturday, the week containing this saturday is week n°5x (52 or 53)

	//fr: 	jour:	Dim Lun Mar Mer Jeu Ven Sam
	//		wday:	0	1	2	3	4	5	6
	//		La semaine n°1 est la semaine qui contient le 1er janvier entre lundi et vendredi
	//		si le 1er janvier est un samedi, la semaine contenant ce samedi est la semaine n°5x (52 ou 53)

	//week shifting :
	if ($dow0101["wday"]>0 && $dow0101["wday"]<6)
	{
		//  week is last week of the year AND 31/12 is not friday, saturday, sunday
		// -> so it's that 1st january is in this week and beetween monday and friday -> it's week n°1
		if ($week==$last_week and $dow3112["wday"]<5 and $dow3112["wday"]!=0 )
		    $week = 1;
		else
			if ($dow0101["wday"]!=1) $week++;
	}
***********************************/
$y = date("Y",$timestamp);
$m = date("m",$timestamp);
$d = date("d",$timestamp);

//Week according to the system :
$week=strftime("%W", mktime(0, 0, 0, $m, $d, $y));

//Day of week of 1st january of this year :
$dow0101=getdate(mktime(0, 0, 0, 1, 1, $y));

//Day of week of 1st january of next year :
$next0101=getdate(mktime(0, 0, 0, 1, 1, $y+1));


if ( $dow0101["wday"]>1 &&
     $dow0101["wday"]<5)
  $week++;

if ( $next0101["wday"]>1 &&
     $next0101["wday"]<5 &&
  	 $week==53)
  $week=1;

if ($week==0)
  $week = get_weeknumber(mktime(0, 0, 0, 12, 31, $y-1));

return(substr("00" . $week, -2));


}

// ======================================================
// Get Easter Date
// ======================================================
function get_easter_date($date) {
    if(function_exists("easter_date") && date("Y", $date)>=1970 && date("Y", $date)<=2037) return easter_date(date("Y", $date));

    $ja = date("Y", $date);
    $m = ($ja < 1900 ? 23 : ($ja < 2100 ? 24 : ($ja < 2200 ? 25 : ($ja < 2300 ? 26 : 27))));
    $n = ($ja < 1800 ? 3 : ($ja < 1900 ? 4 : ($ja < 2100 ? 5 : 6)));
    $a  = $ja % 19;
    $b  = $ja % 4;
    $c  = $ja % 7;
    $d = (19 * $a + $m) % 30;
    $e = (2 * $b + 4 * $c + 6 * $d + $n) % 7;
    $om = 3;
    $ot = 22 + $d + $e;

    if ($ot > 31){
	$ot = $ot - 31;
	$om = 4;
	if ($ot == 26) $ot = 19;
	if ($ot == 25 && $d == 28 && $a > 10) $ot = 18;
    }
    $ostern = mktime(0,0,0, $om, $ot, $ja);
    return $ostern;
}

// ======================================================
// Get Weekday On or Before
//
// Parameters:
//      weekday:   week day as for date()
//                   "0" (Sunday) to "6" (Saturday)
//      date:      the date to find the first monday before
//
// Returns:
//      The first date falling on $weekday on or before $date
// ======================================================
function get_weekday_onorbefore($weekday, $date) {
    $dayofweek = date("w", $date);

    $day = date("d", $date) + $weekday - $dayofweek;
    $month = date("m", $date);
    $year = date("Y", $date);

    return mktime(0,0,0,$month,$day,$year);
}

// ======================================================
// Get First Weekday
//
// Parameters:
//      weekday:   week day as for date()
//                   "0" (Sunday) to "6" (Saturday)
//      month:     the month to find the first weekday in
//                   "01" (January) to "12" (December)
//      year:      the year
//
// Returns:
//      The first date falling on $weekday in $month in $year
// ======================================================
function get_first_weekday($weekday, $parm_month, $parm_year) {
    $firstday = mktime(0,0,0,$parm_month,1,$parm_year);
    $dayofweek = date("w", $firstday);

    if ($dayofweek != 0) {
	$day = date("d", $firstday) + $weekday + 7 - $dayofweek;
    }
    else {
	$day = date("d", $firstday) + $weekday - $dayofweek;
    }
    $month = date("m", $firstday);
    $year = date("Y", $firstday);

    return mktime(0,0,0,$month,$day,$year);
}

// ======================================================
// String get_celebrate_days(timestamp date)
//
// returns the celebration day label from a timestamp
// if timestamp is no celebration day function returns empty string
// ======================================================
function get_celebrate_days($date, $lang){
    $holiday = "";
    $easter = get_easter_date($date);

    $file = "holidays.$lang.inc.php";
    if(file_exists(ROOTPATH."/modules/calendar/inc/".$file)) require(ROOTPATH."/modules/calendar/inc/".$file);
    return $holiday;
}

// ======================================================
// array get_year53_list(Integer year_begin, Integer year_end)
//
// returns a list of years (between year_begin and year_end) which contains 53 weeks
// ======================================================
function get_year53_list($year_begin, $year_end){

 //// WARNING ! //////////////////////////
 // PHP native DATE function is limited over 2038 (due to 32 bits integer)!!
 // after 19 january 2038, we must use adodb_date function (work with 64 bits integer)
 if ($year_end>=2038) $year_end=2037;
 /////////////////////////////////////////

 for ($y=$year_begin;$y<=$year_end;$y++){
	 $t = mktime(0,0,0,12,31,$y);
	 if (get_weeknumber($t)==53){
	 	$year53_list[]=$y;
	 	}
 }
 return $year53_list;
}


// ======================================================
// String get_monthview_static( timestamp date, Integer year, Integer, month)
//
// returns a HTML table representing a calendar month
// liefert eine HTML-Tabelle zur Darstellung eines Kalendermonats
// ======================================================
function get_monthview_static($date, $year, $month){
	global $appconf, $conn, $calendarid, $PHP_SELF;

	$today = date("Ymd", time());
	//$today = $conn->DBTimeStamp(time());

	if ($_SESSION['calendarid']=="all") $sql_owner_part="";
	else $sql_owner_part="userid = ".$_SESSION['calendarid']." AND";

	$zeit = getdate($date);
	$day  = $zeit["mday"];						// Date im aktuellen Monat ?
	/// NATYS ///
	// no difference :
	/*
	if ($zeit["mon"] == $month  &&	$zeit["year"] == $year) {
		$header_class = "navlinkon"; // "stand";
	}	else {
		$header_class = "edit";
	}
	*/
	$header_class = "navlinkon";
	//// /NATYS ////

	// compute array for actual month holding the weekdays
	$num_days = date("t",strtotime($month . "/1/". $year));

	$starts_at = 1; //0=su, 1=mo, ... from settings
	$trim_month = true; // from settings

	$days_before =  $starts_at-date("w",strtotime($month . "/1/". $year))+1;
	if($days_before>1) $days_before -= 7;

	if($starts_at > 0) $ends_at = $starts_at - 1;
	else $ends_at = 6;

	$days_after = $ends_at-date("w",strtotime("$month/$num_days/$year"));
	if($days_after < 0) $days_after += 7;

	$month_days = array();
	for($o=$days_before; $o<=$num_days+$days_after; $o++) {
		$day = array();
		$day["timestamp"] =  mktime(0,0,1,$month,$o,$year);
		//$day["sql_tag"] =  date("Ymd", $day["timestamp"]);
		$day["sql_tag"] =  $conn->DBTimeStamp($day["timestamp"]);
		$day["day_number"] =  date("j", $day["timestamp"]);
		$day["day_of_week"] =  date("w", $day["timestamp"]);

		$month_days[] = $day;
	}

    $mymonth = $month;
    if ($mymonth < 10 and strlen($mymonth) == 2) { $mymonth = substr($mymonth,1); }

	// HTML-Tabelle Überschriften Monat / Jahr
	$out = "<table border=\"0\" width=\"180\" cellpadding=\"0\" cellspacing=\"0\">\n";
	$out .= "<tr><td class=\"lines\" width=\"1\" height=\"1\" colspan=\"10\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td></tr>";
	$out .= "<tr class=\"stand\" height=\"20\">";
	$out .= "	<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	$out .= "	<td class=\"subnavback\">&nbsp;<a class=\"$header_class\" href=\"$PHP_SELF?action=mback&date=$date&".SID."\" ><strong>&lt;&lt;&lt;</strong></a></td>";
	$out .= "	<td class=\"subnavback\" colspan=\"6\" align=\"center\">";
	$out .= "		<a class=\"navlink\" href=\"month.php?date=".mktime(0, 0, 0, $month , 1 , $year )."&".SID."\">".Lang::getLanguageString("gentemp_month_name_".$mymonth)."</a>";
	$out .= "	</td>";
	$out .= "	<td class=\"subnavback\"><a class=\"$header_class\" href=\"$PHP_SELF?action=mforw&date=$date&".SID."\"> <strong>&gt;&gt;&gt;</strong></a>&nbsp;</td>";
	$out .= "	<td  class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	$out .= "</tr>\n";
	$out .= "<tr class=\"stand\" height=\"20\">";
	$out .= "	<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	$out .= "	<td class=\"subnavback\">&nbsp;<a class=\"$header_class\" href=\"$PHP_SELF?action=yback&date=$date&".SID."\"><strong>&lt;&lt;&lt;</strong></a></td>";
	$out .= "	<td class=\"subnavback\" colspan=\"6\" align=\"center\"><strong>$year</strong></td>";
	$out .= "	<td class=\"subnavback\"><a class=\"$header_class\" href=\"$PHP_SELF?action=yforw&date=$date&".SID."\"> <strong>&gt;&gt;&gt;</strong></a>&nbsp;</td>";
	$out .= "	<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	$out .= "</tr>\n";
	$out .= "<tr><td class=\"lines\" width=\"1\" height=\"1\" colspan=\"10\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td></tr>";

	$out .= "<tr class=\"stand\" height=\"20\">";
	$out .= "	<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	$out .= "	<td class=\"category\" align=\"center\">&nbsp;" . Lang::getLanguageString("calweek") . "&nbsp;</td>";

	for($i=$starts_at; $i<$starts_at+7; $i++) // prints names of days
		$out .= "<td class=\"category\" align=\"center\">&nbsp;". Lang::getLanguageString("temp_weekday_abbr_".$i%7) . "&nbsp;</td>";

	$out .="	<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>
	</tr>\n";

	$out .= "<tr><td class=\"lines\" width=\"1\" height=\"1\" colspan=\"10\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td></tr>";

	for($i=0;$i<count($month_days);$i++) {
		// today
		$day_tag = date("Y",$month_days[$i]["timestamp"]).date("m",$month_days[$i]["timestamp"]).date("d",$month_days[$i]["timestamp"]);
		if($day_tag == $today) $klasse = "heute";
		//weekend
		elseif ($month_days[$i]["day_of_week"]==6 || $month_days[$i]["day_of_week"]==0) $klasse = "wochenende";
		//end of last/beginning of next month
		elseif ($i<(abs($days_before)+1) || $i>abs($days_before)+$num_days) $klasse = "tab";
		//holiday
		elseif (get_celebrate_days($month_days[$i]["timestamp"], $_SESSION["MGW"]->settings["calendar_holiday_system"]) != "") $klasse = "feiertag";
		//absolutely ordinary day :))
		else $klasse = "tab";

		if($i%7==0) {
			$out .= "<tr class=\"tab\"  height=20 bgcolor=\"#c8c9d4\">\n";
			$out .= "<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
			$out .= "<td bgcolor=\"#838899\" align=\"center\"><a class=\"subnavlink\" href=\"week.php?date=".$month_days[$i]["timestamp"]."&".SID."\">" . get_weeknumber($month_days[$i]["timestamp"]) . "</a></td>\n";
		}

//		if($trim_month &&)
		//$sqldate = $conn->DBTimeStamp(strtotime($month_days[$i]["sql_tag"]));
		$sqldate = $month_days[$i]["sql_tag"];
		$sqldate_end = $conn->DBTimeStamp(mktime(23,59,59, date("m",$month_days[$i]["timestamp"]), date("d",$month_days[$i]["timestamp"]), date("Y",$month_days[$i]["timestamp"])) );
//		$sql = "SELECT COUNT(*) AS appointment_count FROM mgw_calendar WHERE ".$sql_owner_part." SUBSTRING(date,1,8) = $sqldate GROUP BY date ORDER BY date";
        $sql = "SELECT COUNT(*) AS appointment_count
        		FROM mgw_calendar
				WHERE ".$sql_owner_part." date >= $sqldate AND
        				date <= $sqldate_end
				GROUP BY date
				ORDER BY date";
		if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
		$row = $res->FetchRow();
		if($row["appointment_count"]>0) $markday = " style=\"font-weight:bold;\" title=\"".$row["appointment_count"]."\" alt=\"".$row["appointment_count"]."\"";
		else $markday = "";

		/***************************/
		/* *** OLD :
		if(!$trim_month || ($trim_month && ($i>0 && $i<=$num_days+abs($days_before)))) {
			$out .= "<td class=\"$klasse\" align=\"center\"$markday>";
			$out .= "<a class=\"subnavlink\" href=\"index.php?date=".$month_days[$i]["timestamp"]."&".SID."\">".$month_days[$i]["day_number"]."</a></td>\n";
		} else {
			$out .= "<td class=\"stand\"></td>";
		}
		*** */

		/* *** NEW : */
		//timestamp of 1st day of current month :
		$ts_curr_month = mktime(0, 0, 0, $month , 1 , $year );
		//timestamp of 1st day of next month :
		$next_month = ($month==12) ? 1 : $month+1;
		$next_year = ($month==12) ? $year+1 : $year;
		$ts_next_month = mktime(0, 0, 0, $next_month , 1 , $next_year );

		if(!$trim_month || ($trim_month && ( ($i>0 or $month_days[$i]["timestamp"]==$ts_curr_month+1) && $i<=$num_days+abs($days_before)) && $month_days[$i]["timestamp"]<$ts_next_month )) {
			//the day don't belong to the month -> italic
			if ($month_days[$i]["timestamp"]<$ts_curr_month) {
				$out .= "<td class=\"stand\">";
				$out .= "&nbsp;&nbsp;<a class=\"subnavlink\" href=\"index.php?date=".$month_days[$i]["timestamp"]."&".SID."\"><I>".$month_days[$i]["day_number"]."</I></a></td>\n";
			}
			else {
			$out .= "<td class=\"$klasse\" align=\"center\"$markday>";
			$out .= "<a class=\"subnavlink\" href=\"index.php?date=".$month_days[$i]["timestamp"]."&".SID."\">".$month_days[$i]["day_number"]."</a></td>\n";
			}
		}
		else {
			$out .= "<td class=\"stand\"></td>";
		}

		/***************************/

		if(($i+1)%7==0) {
			$out .= "<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>\n";
			$out .= "</tr>\n";
		}
	}

	//$out .= "<td class=\"lines\" width=\"1\" height=\"1\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td>";
	//$out .= "</tr>\n";
	$out .= "<tr><td class=\"lines\" width=\"1\" height=\"1\" colspan=\"10\"><img src=\"". $appconf["imgpathgeneral"] ."/space.gif\" alt=\"\" width=\"1\" height=\"1\" /></td></tr>";
	$out .= "</table>\n";

	return $out;
}

// ======================================================
// void db_delete_date( Int id, Int rep_id, Int tn_id)
//
// liefert ein Array von Terminen zu einer Kalenderregel
// ======================================================
function db_delete_date_rep($id, $rep_opt, $tn_opt, $userid){
    global $conn;

    $sql  = "SELECT * FROM mgw_calendar WHERE id = $id AND userid = ".$userid;
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row  = $res->FetchRow();
    $group_id = $row["dategroup_id"];
    $sdate  = $row["date"];
    if ($group_id == 0){ $rep_opt=0; }

    // only for user
	if ($rep_opt==0 && $tn_opt==0 && $id > 0 && $userid > 0) $sql2 = "DELETE FROM mgw_calendar WHERE id = $id and userid=$userid";
	// for all users
    elseif ($rep_opt==0 && $tn_opt==1 && $id > 0) $sql2 = "DELETE FROM mgw_calendar WHERE id = $id";
	//all timeseries but only for user
    elseif ($rep_opt==2 && $tn_opt==0 && $group_id > 0 && $userid > 0) $sql2 = "DELETE FROM mgw_calendar WHERE dategroup_id = $group_id and userid=$userid and date >= '$sdate'";
    elseif ($rep_opt==2 && $tn_opt==1 && $group_id > 0) $sql2 = "DELETE FROM mgw_calendar WHERE dategroup_id = $group_id and date >= '$sdate'";
	//all timeseries for all users
    elseif ($rep_opt==3 && $tn_opt==0 && $group_id > 0 && $userid > 0) $sql2 = "DELETE FROM mgw_calendar WHERE dategroup_id = $group_id and userid=$userid";
    elseif ($rep_opt==3 && $tn_opt==1 && $group_id > 0) $sql2 = "DELETE FROM mgw_calendar WHERE dategroup_id = $group_id";
    if($sql2 == "") return; // HACK (or FIX?) for bug 608097
    if(!$res = $conn->Execute($sql2)) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
}

// ======================================================
// void db_delete_date( Int id, Int userid )
//
// loscht alle Terminen zu einer ID in der Table calendar
// ======================================================
function db_delete_date($id, $userid){
    global $conn;
    $sql  = "SELECT * FROM mgw_calendar WHERE id = $id AND userid=".$userid;

    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row  = $res->FetchRow();
    $group_id = $row["dategroup_id"];

    if ($group_id==0 && $id > 0) $sql2 = "DELETE FROM mgw_calendar WHERE id = $id";
    elseif ($group_id > 0) $sql2 = "DELETE FROM mgw_calendar WHERE dategroup_id = $group_id";

    if(!$res = $conn->Execute($sql2)) die(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
}

// ======================================================
// void db_copy_date_from_tmp( Int id)
//
// kopiert alle Terminen zu einer ID aus calendar_tmp in die Table calendar
// ======================================================
function db_copy_date_from_tmp($id){
    global $conn;

    $sql = "INSERT INTO mgw_calendar SELECT DISTINCT b.* FROM mgw_calendar_tmp a, mgw_calendar_tmp b WHERE a.id = $id AND a.userid = b.userid and ((a.id = b.id and a.dategroup_id = 0) OR (a.dategroup_id = b.dategroup_id and a.dategroup_id > 0))";
    if(!$conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
}

// ======================================================
// void db_delete_date_from_tmp
//
// löscht alle Termine zu einer ID aus calendar_tmp
// ======================================================
function db_delete_date_from_tmp($id){
    global $conn;

    $sql  = "SELECT * FROM mgw_calendar_tmp WHERE id = ".$id;

    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row  = $res->FetchRow();

    $group_id = $row["dategroup_id"];

    if ($group_id==0) $sql2 = "DELETE FROM mgw_calendar_tmp WHERE id = $id";
    elseif ($group_id!=0) $sql2 = "DELETE FROM mgw_calendar_tmp WHERE dategroup_id = $group_id";
    if(!$res = $conn->Execute($sql2)) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
}

// ======================================================
// String select_tag($datum, $name)
//
// return HTML <SELECT> object with days...
//
// ======================================================
function select_tag($datum, $name){

	echo "SELECT_TAG : obsolete function ! use mSelectBox class";
	/* /// NATYS ///
	for($d=1; $d<=31; $d++){
	if ($d==1) $dvon = "<select name=\"$name\">";

	if ($d==date("d", $datum))
	    $dvon .= "<option value=\"$d\" Selected>$d&nbsp;</option>";
	else
	    $dvon .= "<option value=\"$d\">$d&nbsp;</option>";

	if ($d==31) $dvon .= "</select>";
    }
    return $dvon;
	*/
}

// ======================================================
// String select_monat($datum,$name)
//
// return HTML <SELECT> object with months...
//
// ======================================================
function select_monat($datum,$name){

   	echo "SELECT_MONAT : obsolete function ! use mSelectBox class";
	/* /// NATYS ///
	for($d=1; $d<=12; $d++){
	if ($d==1) $dvon = "<select name=\"$name\">";

	if ($d==date("m", $datum))
	    $dvon .= "<option value=\"$d\" Selected>$d&nbsp;</option>";
	else
	    $dvon .= "<option value=\"$d\">$d&nbsp;</option>";

	if ($d==12) $dvon .= "</select>";
    }
    return $dvon;
	*/
}

// ======================================================
// String select_jahr($datum, $name)
//
// return HTML <SELECT> object with years...
//
// ======================================================
function select_jahr($datum, $name){

	echo "SELECT_MONAT : obsolete function ! use mSelectBox class";
/*	// NATYS //
	$ende = date("Y", $datum) + 30; // current year + 30
	//////////
    for($d=date("Y", $datum); $d <= $ende; $d++) {
	if ($d==date("Y", $datum)) $dvon = "<select name=\"$name\">";
	$dvon .= "<option value=\"$d\">$d&nbsp;</option>";
	if ($d==$ende)    $dvon .= "</select>";
    }
    return $dvon;
*/
}

// ======================================================
function new_date_notify($id){
    global $conn;
    $concat_c=$conn->Concat("c.firstname", "c.lastname", "'<'", "c.email", "'>'");

    $sql = "SELECT DISTINCT userid, b.lastname, b.firstname, repeat_mode, rep_until, $concat_c AS initu FROM mgw_users b, mgw_calendar a LEFT OUTER JOIN mgw_users c ON a.inituserid = c.id WHERE NOT(b.level=".UDELETED.") AND a.userid = b.id AND a.id = ".$id;

    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    while($row = $res->FetchRow()){
	if ($row["rep_until"] != "00000000000000") $rep_bis = date("d.m.Y", $res->UnixTimeStamp($row["rep_until"]));

	$teiln[]=trim($row["firstname"])." ".trim($row["lastname"]);

	if ($row["repeat_mode"]==0) $rep_text = Lang::getLanguageString("gentemp_repeater_0");
	elseif ($row["repeat_mode"]==1) $rep_text = Lang::getLanguageString("gentemp_repeater_1") . ", " . Lang::getLanguageString("gentemp_from") . " $rep_bis";
	elseif ($row["repeat_mode"]==2) $rep_text = Lang::getLanguageString("gentemp_repeater_2") . ", " . Lang::getLanguageString("gentemp_from") . " $rep_bis";
	elseif ($row["repeat_mode"]==3) $rep_text = Lang::getLanguageString("gentemp_repeater_3") . ", " . Lang::getLanguageString("gentemp_from") . " $rep_bis";

	$init_user = $row["initu"];
    }

    $sql  = "SELECT * FROM mgw_calendar a, mgw_users b WHERE NOT(b.level=".UDELETED.") AND a.userid = b.id AND a.id = ".$id;
    if(!$res = $conn->Execute($sql)) die(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    $teiln_text = "";
    for($i=0; $i<count($teiln);$i++){
	if ($i==0) $teiln_text .= $teiln[$i];
	else $teiln_text .= ", ". $teiln[$i];
    }

    while($row = $res->FetchRow()){
	if($row["userid"] != $_SESSION['MGW']->userid) {
	    $zeit = $res->UnixTimeStamp($row["date"]);

	    $text  = Lang::getLanguageString("hello").' '.$row['firstname'].",\n\n";
	    $text .= Lang::getLanguageString("newappointment4you"). ":\n";
	    $text .= Lang::getLanguageString("date"). " : ". date ( "d.m.Y", $zeit ) . "\n";
	    $text .= Lang::getLanguageString("temp_time"). " : ". date ( "H:i", $zeit ) . "\n";
	    $text .= Lang::getLanguageString("duration")." : ". $row["duration"]. "\n";
	    $text .= Lang::getLanguageString("temp_subject"). " : ". $row["subject"]. "\n";
	    $text .= Lang::getLanguageString("city"). " : ". $row["location"]. "\n";
	    $text .= Lang::getLanguageString("temp_participants"). " : ". $teiln_text. "\n";
	    $text .= Lang::getLanguageString("regulary"). " : ". $rep_text. "\n";

	    if (in_array(NOTIFY_MAIL, $_SESSION['MGW']->settings['calendar_notification']) && strlen($row['email']))
		$GLOBALS['notify']->message($text,NOTIFY_MAIL,':'.$row['email'],Lang::getLanguageString("newappointmentmheader"));
	    if (in_array(NOTIFY_MIM, $_SESSION['MGW']->settings['calendar_notification']))
		$GLOBALS['notify']->message($text,NOTIFY_MIM,'u:'.$row['userid']);
	    if (in_array(NOTIFY_SCREEN, $_SESSION['MGW']->settings['calendar_notification']))
		$GLOBALS['notify']->message(Lang::getLanguageString("newappointment4you"),NOTIFY_SCREEN,'u:'.$row['userid']);
	}
    }
}

// ======================================================
// String get_new_id( name, id)
//
// ermittelt neue Id aus Tabelle Kalender
// id == 0 max_id + 1
// id != 0 $id
// ======================================================
function get_new_id($ridname, $table,  $id, $idname){
    global $conn;

    if ($id == 0){
	$sql = "SELECT MAX($ridname)+1 AS maxid FROM $table";
	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$row = $res->FetchRow();
    } else {
	$sql = "SELECT $ridname AS maxid FROM $table WHERE $idname = ".$id;
	if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
	$row = $res->FetchRow();
    }

    if (!isset($row["maxid"])) return 1;
    else return $row["maxid"];
}

// ======================================================
// Array get_date_list( timestamp date, Integer year, Integer, month)
//
// liefert ein Array von Terminen zu einer Kalenderregel
// ======================================================
function get_appointment_list($art, $von, $bis){ // modified by NATYS
    global $appointment_list;
	/* $art :
		1 : every day
		2 : every week
		3 : every month
		4 : every working day
		5 : every year
	*/
	/*
	* To avoid daylight shifting problems : we must use mktime for each appointment. NO n*3600... !!
	*/
	// 1 -> get d/m/Y hh:mm of the 1st appointment
	$appt_day = date("d",$von);
	$appt_month = date("m",$von);
	$appt_year = date("Y",$von);
	$appt_hour = date("H",$von);
	$appt_min = date("i",$von);

	if ($art == 1)  {
		$t=$von;
		while($t <= $bis){
			$appointment_list[] = $t;
			$appt_day++;
			$t=mktime($appt_hour,$appt_min,0,$appt_month,$appt_day,$appt_year);
		}
	}
    elseif ($art == 2) {
		$t=$von;
		while($t <= $bis){
			$appointment_list[] = $t;
			$appt_day+=7;
			$t=mktime($appt_hour,$appt_min,0,$appt_month,$appt_day,$appt_year);
		}
	}
    elseif ($art == 3){
		$t = $von;
		while($t <= $bis){
			$appointment_list[] = $t;
			$appt_month++;
			$t=mktime($appt_hour,$appt_min,0,$appt_month,$appt_day,$appt_year);
		}
    }
    elseif ($art == 4) {
		$t=$von;
		while($t <= $bis){
			if ( date("w", $t) != 0 && date("w", $t) != 6 && get_celebrate_days($t, $_SESSION["MGW"]->settings["calendar_holiday_system"]) == "") $appointment_list[] = $t;
			$appt_day++;
			$t=mktime($appt_hour,$appt_min,0,$appt_month,$appt_day,$appt_year);
		}
    }
    elseif ($art == 5) {
		$t = $von;
		while($t <= $bis){
			$appointment_list[] = $t;
			$appt_year++;
			$t=mktime($appt_hour,$appt_min,0,$appt_month,$appt_day,$appt_year);
		}
    }


	if (count($appointment_list) == 0) $appointment_list[]=$von; // always at least one
	return $appointment_list;
}

// ======================================================
// Konflikt-Prüfung des aktuellen Termins
//
// andere Termine des Teilnehmers des Tages selektieren
// leyeti : TODO : fix bug with PostGreSQL : substring(....)
// ======================================================
function edit_conflict_list($art, $von, $bis, $userid, $nid){
    global $conflict_list, $conn;

    $sql_tag = date("Ymd", $von);
    $concat_b=$conn->Concat("b.lastname", "', '", "b.firstname");
    $sql = ($art == "update") ?
	"SELECT DISTINCT c.*, $concat_b AS name FROM mgw_calendar a, mgw_calendar c, mgw_users b WHERE NOT(b.level=".UDELETED.") AND a.userid = $userid AND a.userid = c.userid AND SUBSTRING(a.date,1,8) = '$sql_tag' AND SUBSTRING(a.date,1,8) = SUBSTRING(c.date,1,8) AND a.userid = b.id AND ((a.id = $nid AND a.id <> c.id AND a.dategroup_id = 0) OR (a.id = $nid AND a.dategroup_id <> c.dategroup_id AND a.dategroup_id > 0)) ORDER BY DATE"
	:
	"SELECT DISTINCT c.*, $concat_b AS name FROM mgw_calendar a, mgw_calendar c, mgw_users b WHERE NOT(b.level=".UDELETED.") AND a.userid = $userid AND a.userid = c.userid AND SUBSTRING(a.date,1,8) = '$sql_tag' AND SUBSTRING(a.date,1,8) = SUBSTRING(c.date,1,8) AND a.userid = b.id AND ((a.dategroup_id = 0) OR (a.dategroup_id <> c.dategroup_id AND a.dategroup_id > 0)) ORDER BY DATE";

    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    while($row = $res->FetchRow()){
	$term_von = $res->UnixTimeStamp($row["date"] );
	$term_bis = $term_von + 60*$row["duration"];

	// does it overlap?
/// NATYS ///
//	if(($von >= $term_von && $von < $term_bis) || ($bis > $term_von && $bis <= $term_bis) || ($von <= $term_von && $bis >= $term_bis) || ($row["day_ind"] == 1)){
	if(($von >= $term_von && $von < $term_bis) || ($bis > $term_von && $bis <= $term_bis) || ($von <= $term_von && $bis >= $term_bis)){
/////////////
	    if ($row["privat"] == 0)
		$conflict_list["$von"][] = array("name"  => $row["name"],
						 "appointment"  => date($_SESSION["MGW"]->settings["datefmt"], $res->UnixTimeStamp($row["date"])),
						 "time_start"   =>  date("H:i", $term_von),
						 "time_end"     =>  date("H:i", $term_bis),
						 "topic" 	  => $row["subject"],
						 "class"	  => "tab",
						 "id"  	  => $nid);
	    else $conflict_list["$von"][] = array("name"  => $row["name"],
						  "appointment"  => date($_SESSION["MGW"]->settings["datefmt"], $res->UnixTimeStamp($row["date"])),
						  "time_start"   => date("H : i", $term_von),
						  "time_end"  	  => date("H : i", $term_bis),
						  "topic" 	  => Lang::getLanguageString("private"),
						  "class"  	  => "tab",
						  "id"   	  => $nid);
	}
    }
}
?>
