Index: /trunk/calendar/inc/class.bocalendar.inc.php
===================================================================
--- /trunk/calendar/inc/class.bocalendar.inc.php	(revision 363)
+++ /trunk/calendar/inc/class.bocalendar.inc.php	(revision 386)
@@ -142,4 +142,10 @@
 		function bocalendar($session=0)
 		{
+
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
+
 			$this->cat = CreateObject('phpgwapi.categories');
 			$this->grants = $GLOBALS['phpgw']->acl->get_grants('calendar');
@@ -752,5 +758,8 @@
 		function update($params='')
 		{
-			
+			if(!is_object($GLOBALS['phpgw']->datetime))
+			{
+				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
+			}
 			$l_cal = (@isset($params['cal']) && $params['cal']?$params['cal']:$_POST['cal']);
 			$l_participants = (@$params['participants']?$params['participants']:$_POST['participants']);
@@ -915,9 +924,45 @@
 					case MCAL_RECUR_NONE:
 						$this->so->set_recur_none();
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
 						break;
 					case MCAL_RECUR_DAILY:
 						$this->so->set_recur_daily((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
 						break;
 					case MCAL_RECUR_WEEKLY:
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
+
 						foreach(array('rpt_sun','rpt_mon','rpt_tue','rpt_wed','rpt_thu','rpt_fri','rpt_sat') as $rpt_day)
 						{
@@ -929,4 +974,5 @@
 							{
 								$l_cal['recur_data'] |= (int)$mask;
+								$rpt_wdays = $l_cal['recur_data']; // recebe os dias da semana (somatorio) para repetir o alarme;
 							}
 						}
@@ -935,4 +981,20 @@
 					case MCAL_RECUR_MONTHLY_MDAY:
 						$this->so->set_recur_monthly_mday((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
 						break;
 					case MCAL_RECUR_MONTHLY_WDAY:
@@ -941,4 +1003,20 @@
 					case MCAL_RECUR_YEARLY:
 						$this->so->set_recur_yearly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval']);
+
+						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
+
+						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
+						$init_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_init[1]),$tmp_init[0],$tmp_init[2]); // transforma a data inicial + hora + minuto em UNIX timestamp;
+
+						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
+						{
+
+							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
+							$end_rept = mktime($_POST['start']['hour'],$_POST['start']['min'],0,intval($tmp_end[1]),$tmp_end[0],$tmp_end[2]); // transforma a data inicial + hora e minuto de inicio da repeticao em UNIX timestamp;
+
+						}else { // se nao existe data final da repeticao (agendamento infinito):
+
+							$end_rept = 0; // variavel recebe zero e nao sera adicionado nenhum alarme para o agendamento;
+						}
 						break;
 				}
@@ -1050,5 +1128,9 @@
 						'offset'  => $offset,
 						'owner'   => $this->owner,
-						'enabled' => 1
+						'enabled' => 1,
+						'repeat'  => $repetido, // para repetir alarme;
+						'init_rept' => $init_rept, // inicio repeticao;
+						'end_rept' => $end_rept, // fim repeticao;
+						'rpt_wdays' => $rpt_wdays // dias repeticao da semana;
 					);
 				}
@@ -2742,5 +2824,5 @@
 			$mail->IsHTML(true);
 
-			// Aqui é enviado o email
+			// Aqui ï¿œ enviado o email
 			foreach($to_notify as $userid => $statusid) 
 			{
@@ -2996,5 +3078,5 @@
 			}
 
-			//Inicializa variável de retorno.
+			//Inicializa variï¿œvel de retorno.
 			$returncode=true;			
 			if(count($mail->to)) {				
@@ -3095,5 +3177,5 @@
 			$GLOBALS['phpgw_info']['user']['preferences']['common']['dateformat'] = $temp_dateformat;
 			
-			// Notifica por email o criador do compromisso, com as possíveis falhas.						
+			// Notifica por email o criador do compromisso, com as possï¿œveis falhas.						
 			if($errorInfo) {
 				$tmpbody = "<font color='red'>".lang("The following commitment had problems for DELIVERING the NOTIFICATION messages.").".</font><br>";
Index: /trunk/calendar/inc/class.socalendar_sql.inc.php
===================================================================
--- /trunk/calendar/inc/class.socalendar_sql.inc.php	(revision 204)
+++ /trunk/calendar/inc/class.socalendar_sql.inc.php	(revision 386)
@@ -29,4 +29,5 @@
 		var $today = Array('raw','day','month','year','full','dow','dm','bd');
 
+
 		function socalendar_()
 		{
@@ -148,4 +149,6 @@
 		}
 
+/* Funcao save_alarm modificada para gerar alarmes repetidos, caso seja marcado um evento igualmente repetido. A funcao recebe qual o tipo
+de repeticao escolhido pelo usuario (diario, semanal, mensal, anual) e insere alarmes nas respectivas repeticoes do evento. */
 		/*!
 		@function save_alarm
@@ -158,15 +161,349 @@
 		function save_alarm($cal_id,$alarm)
 		{
-			//echo "<p>save_alarm(cal_id=$cal_id, alarm="; print_r($alarm); echo ")</p>\n";
+
 			if (!($id = $alarm['id']))
 			{
+				$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
 				$alarms = $this->read_alarms($cal_id);	// find a free alarm#
-				$n = count($alarms);
-				do
-				{
-					$id = 'cal:'.(int)$cal_id.':'.$n;
-					++$n;
-				}
-				while (@isset($alarms[$id]));
+
+				if($alarm['repeat'] == 1) // repeticao do tipo "Diariamente";
+				{
+					$n = 0;
+
+					while(@isset($alarms[$id]));
+					{
+
+						$init_alarm = $alarm['init_rept'];
+						$end_alarm = $alarm['end_rept'];
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm <= $end_alarm)
+							{
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+								
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] += 86400;
+								$init_alarm += 86400;
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 2) { // repeticao do tipo "Semanalmente";
+
+					$n = 0;
+
+					$init_alarm = $data_atual = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+
+					$rpt_alarm_wdays = $alarm['rpt_wdays'];
+
+					$divisor = 64;
+					$quociente = 0;
+					$resto = 0;
+
+					$dia_semana = date("w",$init_alarm);
+
+					switch($dia_semana)
+					{
+						case 0:
+							$dia = array(
+									0 => 'domingo',
+									1 => 'segunda',
+									2 => 'terca',
+									3 => 'quarta',
+									4 => 'quinta',
+									5 => 'sexta',
+									6 => 'sabado'
+							);
+							break;
+						case 1:
+							$dia = array(
+									0 => 'segunda',
+									1 => 'terca',
+									2 => 'quarta',
+									3 => 'quinta',
+									4 => 'sexta',
+									5 => 'sabado',
+									6 => 'domingo'
+							);
+							break;
+						case 2:
+							$dia = array(
+									0 => 'terca',
+									1 => 'quarta',
+									2 => 'quinta',
+									3 => 'sexta',
+									4 => 'sabado',
+									5 => 'domingo',
+									6 => 'segunda'
+							);
+							break;
+						case 3:
+							$dia = array(
+									0 => 'quarta',
+									1 => 'quinta',
+									2 => 'sexta',
+									3 => 'sabado',
+									4 => 'domingo',
+									5 => 'segunda',
+									6 => 'terca'
+							);
+							break;
+						case 4:
+							$dia = array(
+									0 => 'quinta',
+									1 => 'sexta',
+									2 => 'sabado',
+									3 => 'domingo',
+									4 => 'segunda',
+									5 => 'terca',
+									6 => 'quarta'
+							);
+							break;
+						case 5:
+							$dia = array(
+									0 => 'sexta',
+									1 => 'sabado',
+									2 => 'domingo',
+									3 => 'segunda',
+									4 => 'terca',
+									5 => 'quarta',
+									6 => 'quinta'
+							);
+							break;
+						case 6:
+							$dia = array(
+									0 => 'sabado',
+									1 => 'domingo',
+									2 => 'segunda',
+									3 => 'terca',
+									4 => 'quarta',
+									5 => 'quinta',
+									6 => 'sexta'
+							);
+							break;
+					}
+
+
+					$dias_semana = array(
+								64 => 'sabado',
+								32 => 'sexta',
+								16 => 'quinta',
+								8 => 'quarta',
+								4 => 'terca',
+								2 => 'segunda',
+								1 => 'domingo'
+							);
+
+					do
+					{
+
+						$resto = ($rpt_alarm_wdays % $divisor);
+						$quociente = floor($rpt_alarm_wdays / $divisor);
+
+						if($quociente == 1)
+						{
+							$result[] .= $dias_semana[$divisor];
+
+							$divisor = $divisor / 2;
+							$rpt_alarm_wdays = $resto;
+
+						}else {
+
+							while($rpt_alarm_wdays < $divisor)
+							{
+								$divisor = $divisor / 2;
+							}
+
+							$resto = ($rpt_alarm_wdays % $divisor);
+							$quociente = floor($rpt_alarm_wdays / $divisor);
+
+							if($quociente == 1)
+							{
+
+								$result[] .= $dias_semana[$divisor];
+
+								$divisor = $divisor / 2;
+								$rpt_alarm_wdays = $resto;
+							}
+						}
+
+					}
+					while($resto != 0);
+
+					krsort($result);
+
+					$week_num = 0;
+					$y = 0;
+
+					while(@isset($alarms[$id]));
+					{
+
+						if($end_alarm != 0)
+						{
+
+							while($data_atual <= $end_alarm)
+							{
+
+								foreach($dia as $index => $value)
+								{
+									if(in_array($value,$result))
+									{
+
+										$nova_data = $init_alarm + (86400 * ($index + (7 * $y)));
+
+										if($nova_data == $init_alarm){
+
+											continue;
+										}
+
+										$id = 'cal:'.(int)$cal_id.':'.$n;
+										$n++;
+
+										$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+										unset($alarm['repeat']);
+										unset($alarm['init_rept']);
+										unset($alarm['end_rept']);
+										unset($alarm['rpt_wdays']);
+										
+										$data_atual = $nova_data;
+
+										if($data_atual > $end_alarm){
+											if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+											{
+												return False;
+											}
+											break;
+										}
+
+										if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+										{
+											return False;
+										}
+											$alarm['time'] = $nova_data - $alarm['offset'] - $GLOBALS['phpgw']->datetime->tz_offset; 
+									}
+								}
+								$y++;
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 3) { // repeticao do tipo "Mensalmente (por data)";
+
+					$n = 0;
+
+					$init_alarm = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+					
+					while(@isset($alarms[$id]));
+					{
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm <= $end_alarm)
+							{
+
+								$next_month = date("n",$init_alarm) + 1;
+								$next_alarm = mktime(date("G",$alarm['time']),date("i",$alarm['time']),date("s",$alarm['time']),$next_month,date("j",$alarm['time']),date("Y",$alarm['time']));
+
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] = $next_alarm;
+								$init_alarm = $next_alarm;
+
+							}
+						}
+					}
+
+				}elseif($alarm['repeat'] == 5) { // repeticao do tipo "Anualmente";
+
+					$n = 0;
+
+					$init_alarm = $alarm['init_rept'];
+					$end_alarm = $alarm['end_rept'];
+					
+					while(@isset($alarms[$id]));
+					{
+
+
+						if($end_alarm != 0)
+						{
+							while($init_alarm < $end_alarm)
+							{
+
+								$next_year = date("Y",$init_alarm) + 1;
+								$next_alarm = mktime(date("G",$alarm['time']),date("i",$alarm['time']),date("s",$alarm['time']),date("n",$alarm['time']),date("j",$alarm['time']),$next_year);
+
+								$id = 'cal:'.(int)$cal_id.':'.$n;
+								$n++;
+
+								$alarm['cal_id'] = $cal_id;		// we need the back-reference
+
+								unset($alarm['repeat']);
+								unset($alarm['init_rept']);
+								unset($alarm['end_rept']);
+								unset($alarm['rpt_wdays']);
+
+								if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+								{
+									return False;
+								}
+
+								$alarm['time'] = $next_alarm;
+								$init_alarm = $next_alarm;
+							}
+						}
+					}
+
+				}else {
+					$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
+					$n = count($alarms);
+					while(@isset($alarms[$id]));
+					{
+
+						$id = 'cal:'.(int)$cal_id.':'.$n;
+
+						unset($alarm['repeat']);
+						unset($alarm['init_rept']);
+						unset($alarm['end_rept']);
+						unset($alarm['rpt_wdays']);
+
+						$alarm['cal_id'] = $cal_id;		// we need the back-reference
+						if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
+						{
+							return False;
+						}
+
+						++$n;
+					}
+				}
+
 			}
 			else
@@ -174,11 +511,5 @@
 				$this->async->cancel_timer($id);
 			}
-			$alarm['cal_id'] = $cal_id;		// we need the back-reference
-
-			//$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
-			if (!$this->async->set_timer($alarm['time'],$id,'calendar.bocalendar.send_alarm',$alarm))
-			{
-				return False;
-			}
+			$alarm['time'] -= $GLOBALS['phpgw']->datetime->tz_offset;	// time should be stored in server timezone
 			return $id;
 		}
@@ -566,4 +897,7 @@
 		function save_event(&$event)
 		{
+
+			$GLOBALS['calendar']->bocalendar = CreateObject('calendar.bocalendar');
+
 			$locks = Array(
 				'phpgw_cal',
@@ -685,4 +1019,5 @@
 						. 'WHERE cal_id='.$event['id'],__LINE__,__FILE__);
 				}
+
 			}
 			else
