Index: trunk/expressoCalendar/setup/tables_current.inc.php
===================================================================
--- trunk/expressoCalendar/setup/tables_current.inc.php	(revision 5994)
+++ trunk/expressoCalendar/setup/tables_current.inc.php	(revision 6111)
@@ -152,7 +152,5 @@
                 'id' => array( 'type' => 'auto', 'nullable' => False),
                 'action_id' => array( 'type' => 'int', 'precision' => '8', 'nullable' => False),
-                'range_end' => array( 'type' => 'bigint', 'precision' => '16', 'nullable' => True),
-                'range_start' => array( 'type' => 'bigint', 'precision' => '16', 'nullable' => True),
-                'unit' => array('type' => 'varchar','precision' => '20','nullable' => True),
+		'alarm_offset' => array( 'type' => 'bigint', 'precision' => '16', 'nullable' => False),
                 'time' => array('type' => 'varchar','precision' => '50','nullable' => True),
                 'participant_id' => array('type' => 'int', 'precision' => '8','nullable' => True),
Index: trunk/expressoCalendar/setup/tables_update.inc.php
===================================================================
--- trunk/expressoCalendar/setup/tables_update.inc.php	(revision 5994)
+++ trunk/expressoCalendar/setup/tables_update.inc.php	(revision 6111)
@@ -107,5 +107,14 @@
 	};
         
-        
+        $test[] = '1.005';
+	function expressoCalendar_upgrade1_005() {
+            $oProc = $GLOBALS['phpgw_setup']->oProc;
+            $oProc->query("ALTER TABLE calendar_alarm ADD COLUMN alarm_offset bigint;");
+	    $oProc->query("UPDATE calendar_alarm SET alarm_offset = obj.range_start - calendar_alarm.range_start FROM calendar_object as obj WHERE obj.id = object_id;");
+	    $oProc->query("ALTER TABLE calendar_alarm DROP COLUMN range_start;");
+	    $oProc->query("ALTER TABLE calendar_alarm DROP COLUMN range_end;");
+            $GLOBALS['setup_info']['expressoCalendar']['currentver'] = '1.006';
+            return $GLOBALS['setup_info']['expressoCalendar']['currentver'];
+	};
         
 ?>
Index: trunk/expressoCalendar/setup/setup.inc.php
===================================================================
--- trunk/expressoCalendar/setup/setup.inc.php	(revision 5953)
+++ trunk/expressoCalendar/setup/setup.inc.php	(revision 6111)
@@ -13,5 +13,5 @@
 	$setup_info['expressoCalendar']['title']     	= 'Expresso Calendar';
 	/* Ao incrementar versão, não esquecer de declarar função do tables_update.inc.php*/
-	$setup_info['expressoCalendar']['version']   	= '1.005';
+	$setup_info['expressoCalendar']['version']   	= '1.006';
 	$setup_info['expressoCalendar']['app_order']	= 10;
 
Index: trunk/prototype/Sync.php
===================================================================
--- trunk/prototype/Sync.php	(revision 5905)
+++ trunk/prototype/Sync.php	(revision 6111)
@@ -36,4 +36,21 @@
 
                false;
+    }
+}
+
+///Conversor Para utf8 ante de codificar para json pois o json so funciona com utf8
+if(!function_exists('toUtf8'))
+{
+    function toUtf8($data)
+    {
+	if(!is_array($data))
+	  return mb_convert_encoding( $data , 'UTF-8' , 'UTF-8 , ISO-8859-1' );
+
+	$return = array();
+
+	foreach ($data as $i => $v)
+	  $return[toUtf8($i)] = toUtf8($v);
+
+	return $return;
     }
 }
@@ -128,5 +145,5 @@
 	  }
 	  catch( Exception $e ){
-	      $return[ $uri ] = $e->getMessage();
+	      $return[ $uri ] = toUtf8( $e->getMessage() );
 	      unset( $data[$uri] );
 	      continue;
Index: trunk/prototype/config/participant.ini
===================================================================
--- trunk/prototype/config/participant.ini	(revision 5514)
+++ trunk/prototype/config/participant.ini	(revision 6111)
@@ -13,4 +13,10 @@
 schedulable = schedulable.participants
 
+[after.find]
+deepnessFindParticipant = modules/calendar/interceptors/DBMapping.php
+
+[after.read]
+deepnessReadParticipant = modules/calendar/interceptors/DBMapping.php
+
 [after.commit]
 commitParticipant = modules/calendar/interceptors/Notifications.php
Index: trunk/prototype/config/alarm.ini
===================================================================
--- trunk/prototype/config/alarm.ini	(revision 5514)
+++ trunk/prototype/config/alarm.ini	(revision 6111)
@@ -22,7 +22,8 @@
 time = "time"
 sent = "sent"
-rangeStart = "range_start"
-rangeEnd = "range_end"
+; rangeStart = "range_start"
+; rangeEnd = "range_end"
 unit = "unit"
 participant = "participant_id"
 schedulable = "object_id"   
+offset = "alarm_offset"
Index: trunk/prototype/modules/calendar/interceptors/DBMapping.php
===================================================================
--- trunk/prototype/modules/calendar/interceptors/DBMapping.php	(revision 6096)
+++ trunk/prototype/modules/calendar/interceptors/DBMapping.php	(revision 6111)
@@ -117,5 +117,6 @@
 		}
 
-	    $sql = ' SELECT calendar_object.id as id ,calendar_object.cal_uid as "uid", calendar_object.type_id as "type", calendar_object.dtstart as "startTime", calendar_object.summary as "summary", calendar_object.description as "description", calendar_object.dtend as "endTime" , calendar_object.location as "location", calendar_object.allday as "allDay", calendar_object.transp as "transparent", calendar_object.class_id as "class", calendar_object.repeat as "repeat", calendar_object.range_start as "rangeStart",calendar_object.range_end as "rangeEnd", calendar_object.last_update as "lastUpdate", calendar_object.dtstamp as "dtstamp", calendar_object.sequence as "sequence",  calendar_object.tzid as "timezone" ,calendar_to_calendar_object.calendar_id as calendar FROM calendar_to_calendar_object , calendar_object WHERE (range_start >= \'' . $start . '\' AND range_end <= \'' . $end . '\' AND calendar_to_calendar_object.calendar_id IN (\'' . implode('\',\'', $criteria['filter'][3][2]) . '\')) AND calendar_to_calendar_object.calendar_object_id = calendar_object.id' . (!empty($ids) ? ' AND calendar_object.id NOT IN (\'' . implode('\',\'', $ids) . '\')' : '');
+	    $sql = ' SELECT calendar_object.id as id ,calendar_object.cal_uid as "uid", calendar_object.type_id as "type", calendar_object.dtstart as "startTime", calendar_object.summary as "summary", calendar_object.description as "description", calendar_object.dtend as "endTime" , calendar_object.location as "location", calendar_object.allday as "allDay", calendar_object.transp as "transparent", calendar_object.class_id as "class", calendar_object.repeat as "repeat", calendar_object.range_start as "rangeStart",calendar_object.range_end as "rangeEnd", calendar_object.last_update as "lastUpdate", calendar_object.dtstamp as "dtstamp", calendar_object.sequence as "sequence",  calendar_object.tzid as "timezone" ,calendar_to_calendar_object.calendar_id as calendar FROM calendar_to_calendar_object , calendar_object WHERE (range_start >= \'' . $start . '\' AND range_end <= \'' . $end . '\' AND calendar_to_calendar_object.calendar_id IN (\'' . implode('\',\'', $criteria['filter'][3][2]) . '\')) AND calendar_to_calendar_
+object.calendar_object_id = calendar_object.id' . (!empty($ids) ? ' AND calendar_object.id NOT IN (\'' . implode('\',\'', $ids) . '\')' : '');
 
 	    $params = Controller::service('PostgreSQL')->execResultSql($sql);
@@ -504,19 +505,5 @@
 
 		if (isset($v['id'])) {
-		    $participants = Controller::find(array('concept' => 'participant'), false, array('filter' => array('=', 'schedulable', $v['id'])));
-
-		    if (is_array($participants) && count($participants) > 0)
-			foreach ($participants as $ii => $vv) {
-			    if ($vv['isExternal'] == 1)
-				$participants[$ii]['user'] = Controller::read(array('concept' => 'user', 'id' => $vv['user'], 'service' => 'PostgreSQL'));
-			    else
-				$participants[$ii]['user'] = Controller::read(array('concept' => 'user', 'id' => $vv['user']));
-
-			    if ($participants[$ii]['user']['id'] == Config::me('uidNumber'))
-				$participants[$ii]['alarms'] = Controller::find(array('concept' => 'alarm'), null, array('filter' => array('AND', array('=', 'participant', $vv['id']), array('=', 'schedulable', $v['id']))));
-			}
-		    $result[$i]['participants'] = $participants;
-
-
+		    $result[$i]['participants'] = Controller::find( array( 'concept' => 'participant' ) , false ,array( 'filter' => array('=', 'schedulable'  ,  $v['id']), 'criteria' => array( 'deepness' => $original['criteria']['deepness'] - 1 ))); 
 
 		    $attachmentRelation = Controller::find(array('concept' => 'schedulableToAttachment'), false, array('filter' => array('=', 'schedulable', $v['id'])));
@@ -568,31 +555,33 @@
     }
 
-    //TODO: Remover apos suporte a deepness na api
-    public function deepnessReadParticipant(&$uri, &$result, &$criteria, $original) {
-
-	if (isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) {
-	    if (isset($result['id'])) {
-		if ($result['isExternal'] == 1)
-		    $result['user'] = Controller::read(array('concept' => 'user', 'id' => $result['user'], 'service' => 'PostgreSQL'));
-		else
-		    $result['user'] = Controller::read(array('concept' => 'user', 'id' => $result['user']));
-	    }
-	}
-    }
-
     //TODO: Remover apos suporte a deepness na api 
-    public function deepnessFindParticipant(&$uri, &$result, &$criteria, $original) {
-
-	if (isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0) {
-	    foreach ($result as $i => $v) {
-		if (isset($v['id'])) {
-		    if ($result[$i]['isExternal'] == 1)
-			$result[$i]['user'] = Controller::read(array('concept' => 'user', 'id' => $result[$i]['user'], 'service' => 'PostgreSQL'));
-		    else
-			$result[$i]['user'] = Controller::read(array('concept' => 'user', 'id' => $result[$i]['user']));
-		}
-	    }
-	}
-    }
+    public function deepnessReadEvent( &$uri , &$result , &$criteria , $original ){		
+       
+       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0)
+       {
+            if(isset($result['id']))
+            {
+                $result['participants'] = Controller::find( array( 'concept' => 'participant' ) , false ,array( 'filter' => array('=' ,  'schedulable' ,  $result['id']), 'criteria' => array('deepness' => $original['criteria']['deepness'] - 1) )); 
+
+		$repeat =  Controller::find( array( 'concept' => 'repeat' ), false, array( 'filter' => array( '=', 'schedulable', $result['id'] ) ) );
+
+                if(is_array($repeat))
+		    $result['repeat'] = $repeat[0];
+	    }
+       }
+   } 
+   
+    //TODO: Remover apos suporte a deepness na api 
+    public function deepnessFindParticipant( &$uri , &$result , &$criteria , $original ){		
+       
+       if(isset($original['criteria']['deepness']) && $original['criteria']['deepness'] != 0)
+       {
+           foreach ($result as $i => &$v)
+           {
+		self::deepnessReadParticipant( $uri, $v, $criteria, $original );
+           }
+       }
+       
+   } 
 
     //TODO: Remover apos suporte a deepness na api 
@@ -673,37 +662,34 @@
 /////////////////////////////////////////////////////////////////////////
 
-    static function dayAlarm(&$uri, &$params, &$criteria, $original) {
-	if (isset($criteria['filter'][1]) && $criteria['filter'][1] == 'date') {
-	    $filter = array('AND',
-		array('=', 'sent', '0'),
-		array('=', 'type', ALARM_ALERT),
-		array('>=', 'rangeStart', $criteria['filter'][2]),
-		array('<=', 'rangeEnd', $criteria['filter'][2] + 86400000));
-
-	    //Busca os Alarmes no Range
-	    $al = Controller::find(array('concept' => 'alarm'), false, array('filter' => $filter));
-
-	    if (is_array($al))
-		foreach ($al as $i => $v) {
-		    $ev = Controller::read(array('concept' => 'schedulable', 'id' => $v['schedulable']));
-
-		    $unit = 0;
-		    switch (strtolower($v['unit'])) {
-			case 'm': $unit = 60;
-			    break;
-			case 'H': $unit = 3600;
-			    break;
-			case 'd': $unit = 216000;
-			    break;
-		    }
-
-		    $al[$i]['sendTime'] = (((int) ( $ev['startTime'] / 1000 )) - ( $v['time'] * $unit ));
-		    $al[$i]['schedulable'] = $ev;
-		}
-
-	    $params = $al;
-	    return false;
-	}
-    }
+    static function dayAlarm( &$uri , &$params , &$criteria , $original ) {     
+        if(isset($criteria['filter'][1]) && $criteria['filter'][1] == 'date')
+        {
+	    $target = $criteria['filter'][2];
+
+	    $params = array();
+            
+	    $al = Controller::service('PostgreSQL')->execSql("SELECT co.id as id, co.cal_uid as uid, co.type_id as type, co.dtstart as startTime, co.summary as summary, co.description as description, co.dtend as endTime, co.location as location, co.allday as allDay, co.transp as transparent, co.class_id as class, ".
+							      "co.range_start as rangeStart, co.range_end as rangeEnd, co.last_update as lastUpdate, co.dtstamp as dtstamp, co.sequence as sequence, co.tzid as timezone, CASE WHEN rep.object_id = co.id THEN occ.occurrence - al.alarm_offset ELSE co.dtstart - al.alarm_offset END as sendTime ".
+							      "FROM calendar_alarm as al, calendar_object as co, calendar_repeat as rep, calendar_repeat_occurrence as occ, calendar_participant as part WHERE ".
+							      "al.action_id = '".ALARM_ALERT."' AND al.sent = '0' AND al.participant_id = part.id AND part.object_id = co.id AND ".
+							      "CASE WHEN rep.object_id = co.id ".
+							      "THEN rep.id = occ.repeat_id AND occ.occurrence - al.alarm_offset >= '$target' AND occ.occurrence - al.alarm_offset <= '".( $target + 86400000)."' ".
+							      "ELSE co.range_start - al.alarm_offset >= '$target' AND co.range_start - al.alarm_offset <= '".( $target + 86400000)."' END");
+
+	    if(is_array($al))
+	      foreach( $al as $v )
+	      {
+		    $params['sendTime'] = $al['sendTime'];
+
+		    unset( $al['sendTime'] );
+
+		    $params['schedulable'] = $al;
+	      }
+	    else
+	      $params = false;
+
+            return false;
+        }
+    } 
 
     public function deleteSchedulable(&$uri, &$params, &$criteria, $original) {
Index: trunk/prototype/modules/calendar/alarms.php
===================================================================
--- trunk/prototype/modules/calendar/alarms.php	(revision 5724)
+++ trunk/prototype/modules/calendar/alarms.php	(revision 6111)
@@ -2,111 +2,70 @@
 
 if(!defined('ROOTPATH'))
-	define('ROOTPATH', dirname(__FILE__).'/../..');
+    define('ROOTPATH', dirname(__FILE__).'/../..');
 
 require_once ROOTPATH.'/api/controller.php';
 require_once ROOTPATH.'/modules/calendar/constants.php';
+require_once ROOTPATH.'/api/parseTPL.php';
 
-$filter = array( 'AND', 
-          array( '='  , 'sent' , '0') ,
-          array( '='  , 'type' , ALARM_MAIL) ,  
-          array( '>=' , 'rangeStart' ,(gmdate('U') - 300 ).'000') ,
-          array( '<=' , 'rangeEnd' , (gmdate('U') + 86400).'000')
-          ); 
+$target = (gmdate('U') - 300 ).'000';
 
-//Busca os Alarmes no Range
-$al = Controller::find( array('concept' => 'alarm'), false ,array( 'filter' => $filter));
+$parts = Controller::service('PostgreSQL')->execSql("SELECT calendar_participant.user_info_id as user, co.id as schedulable, co.dtend as endTime, co.dtstart as startTime, co.summary as summary, co.tzid as timezone, co.location as location, al.id as id ".
+						      "FROM calendar_participant, calendar_alarm as al, calendar_object as co, calendar_repeat as rep WHERE ".
+						      "al.participant_id = calendar_participant.id AND ".
+						      "calendar_participant.object_id = co.id AND ".
+						      "al.action_id = '".ALARM_MAIL."' AND ".
+						      "al.sent = '0' AND ".
+						      "CASE WHEN rep.object_id = co.id ".
+						      "THEN  ( select count(occurrence) FROM calendar_repeat_occurrence WHERE rep.object_id = co.id AND rep.id = calendar_repeat_occurrence.repeat_id AND occurrence - al.alarm_offset >= '$target' ) > 0 ".
+						      "ELSE co.range_start - al.alarm_offset >= '$target' END");
 
-if(is_array($al))
-foreach ($al as $i => $v)
+if(!is_array($parts))
+  return;
+
+$ids = array();
+
+foreach ($parts as $i => $part)
 {
-	$ev =  Controller::read( array( 'concept' => 'schedulable' , 'id' => $v['schedulable']) ) ;
-		
-	$unit = 0;
-	switch ($v['unit']) {
-		case 'm': $unit = 60; break;
-		case 'H': $unit = 3600; break;
-		case 'd': $unit = 86400; break; }
-	
+	///Montando lista de participantes
 
-	if( strtotime($v['rangeEnd']) >= time() ) // Evento Recursivo ?
+	$users = Controller::find( array( 'concept' => 'participant' ) , array( 'user', 'id', 'isExternal' ) ,array('filter' => array ('=', 'schedulable' , $part['schedulable'] ), 'deepness' => 1 ) );
+
+	$attList = array();
+
+	foreach( $users as $user )
 	{
-		//TODO: Fazer Acontecer
-	}	
-	else
-	{		               
-		if((((int)( $ev['startTime'] / 1000 )) - ( $v['time'] * $unit )) < gmmktime() ) //ja esta na hora de mandar o alarme ?
-		{           
-                        require_once (ROOTPATH.'/api/parseTPL.php' );
-           
-			switch ($v['type']) {
-				case 'mail':
-                    
-			$part =  Controller::read( array( 'concept' => 'participant' , 'id' => $v['participant']) );
-                        $participants = Controller::find( array( 'concept' => 'participant' ) , false ,array('filter' => array ('=', 'schedulable' , $part['schedulable'] )) ); 
-                    
-                        if($part['isExternal'] == 1)
-                                $user =  Controller::read( array( 'concept' => 'user' , 'id' => $part['user'] , 'service' => 'PostgreSQL' ) );
-                        else
-                                $user =  Controller::read( array( 'concept' => 'user' , 'id' => $part['user'] ) );
-						
-                        ///Montando lista de participantes
-                            $attList = '<UL> ';
-                            $organizer = array();
-                            foreach ($participants as $ii => $participant)
-                            {
-                                if($participant['isExternal'] == 1)
-                                    $att[$ii] = Controller::read( array( 'concept' => 'user' , 'id' => $participant['user'] , 'service' => 'PostgreSQL' ) );
-                                else
-                                    $att[$ii] = Controller::read( array( 'concept' => 'user' , 'id' => $participant['user'] ));
+	    if( $part['user'] === $user['user']['id'] )
+		$part['mail'] = $user['user']['mail'];
 
-                                $attList .= '<LI> '.$att[$ii]['name'] .'</LI> ';
+	    $attList[] = $user['user']['name'];
+	}
 
-                            }
-                            $attList .= '</UL>';
-                        /////////////////////////
-                        
-                         $timezone = new DateTimeZone('UTC');
-                         $sTime = new DateTime( '@'.(int)($ev['startTime'] / 1000) , $timezone );
-                         $eTime =  new DateTime( '@'.(int)($ev['endTime'] / 1000) , $timezone ); 
-                         if($ev['timezone'])                             
-                         {
-                             $sTime->setTimezone(new DateTimeZone($ev['timezone']));
-                             $eTime->setTimezone(new DateTimeZone($ev['timezone']));
-                         }
-                            
-                         
-                         $data = array('startDate' =>  date_format( $sTime , 'd/m/Y') ,
-                                                                  'startTime' =>  date_format( $sTime , 'H:i') ,
-                                                                  'endDate' =>  date_format( $eTime , 'd/m/Y') ,
-                                                                  'endTime' =>  date_format( $eTime , 'H:i') ,
-                                                                  'eventTitle' =>  $ev['summary'],
-                                                                  'eventLocation' =>  $ev['location'],
-                                                                  'timezone' =>  ($ev['timezone']) ? $ev['timezone'] : 'UTC' ,
-                                                                  'participants' =>  $attList
-                                                                );
-                         
-						 $mail['isHtml'] = true;                         
-						 $mail['body'] = parseTPL::load_tpl($data,ROOTPATH.'/modules/calendar/templates/notify_alarm_body.tpl');
-                         
-						 $mail['subject'] = 'Alarme de Calendario';
-						 $mail['from'] = $user['mail'];
-						 $mail['to'] = $user['mail'];
-					
-   
-                            Controller::create( array( 'service' => 'SMTP' ), $mail );
-                            Config::regSet('noAlarm', TRUE); //Evita o envio de notificação
-                            Controller::update( array( 'concept' => 'alarm' , 'id' => $v['id']) , array('sent' => '1'));
-					break;
+      /////////////////////////
 
-				case 'sms':
-					//Sem suporte atualmente
-					break;
+	$timezone = ($part['timezone']) ? $part['timezone'] : 'UTC';
+	$sTime = new DateTime( '@'.(int)($part['startTime'] / 1000) , new DateTimeZone($timezone) );
+	$eTime =  new DateTime( '@'.(int)($part['endTime'] / 1000) , new DateTimeZone($timezone) );
 
-			}
-		}
-	}
-	
+	$data = array('startDate' =>  date_format( $sTime , 'd/m/Y') ,
+		      'startTime' =>  date_format( $sTime , 'H:i') ,
+		      'endDate' =>  date_format( $eTime , 'd/m/Y') ,
+		      'endTime' =>  date_format( $eTime , 'H:i') ,
+		      'eventTitle' =>  $part['summary'],
+		      'eventLocation' =>  $part['location'],
+		      'timezone' => $timezone,
+		      'participants' =>  '<UL> <LI> '.implode( '<LI></LI> ', $attList ).'</LI> </UL>');
+
+	Controller::create( array( 'service' => 'SMTP' ), array( 'body' => parseTPL::load_tpl( $data, ROOTPATH.'/modules/calendar/templates/notify_alarm_body.tpl' ),
+								  'isHtml' => true,
+								  'subject' => 'Alarme de Calendario',
+								  'from' => $part['mail'],
+								  'to' => $part['mail'] ) );
+
+	Config::regSet('noAlarm', TRUE); //Evita o envio de notificaÃ§Ã£o ?????
+	$ids[] = $part['id'];
 }
 
+if( !empty( $ids ) )
+    Controller::update( array( 'concept' => 'alarm' ) , array('sent' => '1'), array( 'IN', 'id', $ids ) );
 
 ?>
Index: trunk/prototype/request.php
===================================================================
--- trunk/prototype/request.php	(revision 5399)
+++ trunk/prototype/request.php	(revision 6111)
@@ -29,21 +29,15 @@
 
 ///Conversor Para utf8 ante de codificar para json pois o json so funciona com utf8
-function srtToUtf8($data)
-{
-    return mb_convert_encoding( $data , 'UTF-8' , 'UTF-8 , ISO-8859-1' );
-}
-
 function toUtf8($data)
 {
-    if(is_array($data))
-    {   
-        $return = array();
-        foreach ($data as $i => $v)
-           $return[srtToUtf8($i)] = (is_array($v)) ? toUtf8($v) : srtToUtf8($v);
-        
-        return $return;
-    }
-    else
-       return srtToUtf8($data);
+    if(!is_array($data))
+      return mb_convert_encoding( $data , 'UTF-8' , 'UTF-8 , ISO-8859-1' );
+
+    $return = array();
+
+    foreach ($data as $i => $v)
+      $return[toUtf8($i)] = toUtf8($v);
+
+    return $return;
 }
 ////////////////////////////////////////////////////////////////////////////////////////
