Index: trunk/calendar/inc/class.bocalendar.inc.php
===================================================================
--- trunk/calendar/inc/class.bocalendar.inc.php	(revision 4935)
+++ trunk/calendar/inc/class.bocalendar.inc.php	(revision 5132)
@@ -97,6 +97,4 @@
 		);
 
-                var $wdays;
-
                 var $debug = False;
 //		var $debug = True;
@@ -111,9 +109,9 @@
 		var $year;
 		var $prefs;
-
+                var $wdays; 
 		var $owner;
 		var $holiday_color;
 		var $printer_friendly = False;
-
+                var $repetido;
 		var $cached_holidays;
 
@@ -142,4 +140,10 @@
        	var $async = false;
 
+                var $alreadyNotifieds;
+                var $alreadyExtNotifieds = array();
+                
+                var $extAdded;
+                var $extDeleted;
+                
 		function bocalendar($session=0)
 		{
@@ -300,5 +304,5 @@
 				MCAL_RECUR_DAILY	=> 'Daily',
 				MCAL_RECUR_WEEKLY	=> 'Weekly',
-            //MCAL_RECUR_MONTHLY_WDAY	=> 'Monthly (by day)',
+				MCAL_RECUR_MONTHLY_WDAY	=> 'Monthly (by day)',
 				MCAL_RECUR_MONTHLY_MDAY	=> 'Monthly (by date)',
 				MCAL_RECUR_YEARLY	=> 'Yearly'
@@ -382,37 +386,4 @@
                         $this->wdays = Array(MCAL_M_SUNDAY,MCAL_M_MONDAY,MCAL_M_TUESDAY,MCAL_M_WEDNESDAY,
                             MCAL_M_THURSDAY,MCAL_M_FRIDAY,MCAL_M_SATURDAY);
-		}
-
-		function delegar($idDelegador,$idDelegado,$idEvento) {
-
-			$this->so->cal->stream->lock(array("phpgw_cal_user"));
-			
-			if(substr($idDelegado,-1) == 'U') {
-			    $idDelegado = substr($idDelegado,0,-1);
-			}
-
-			$sql = "SELECT * FROM phpgw_cal_user where cal_id=$idEvento and cal_login=$idDelegado";
-
-			if($idDelegado != '')
-			{
-				$this->so->cal->stream->query($sql,__LINE__,__FILE__);
-				if($this->so->cal->stream->next_record())
-				{
-					throw new Exception("The selected User is already included in this event");
-				}else{
-					$sql = "update phpgw_cal_user set cal_login = $idDelegado,cal_status='U' where cal_id=$idEvento 
-						and cal_login=$idDelegador";
-
-					$this->so->cal->stream->query($sql,__LINE__,__FILE__,0,-1,true);
-				
-					$event = $this->so->read_entry($idEvento);
-
-					$this->send_update(MSG_ADDED,array($idDelegado => 'U'),$event,$event);
-				}
-			}else {
-				throw new Exception('999');
-			}
-
-			$this->so->cal->stream->unlock();
 		}
 
@@ -656,5 +627,5 @@
 //				print_debug('exception time',$event['recur_exception'][count($event['recur_exception']) -1]);
 //				print_debug('count event exceptions',count($event['recur_exception']));
-				$this->so->add_entry($event);
+				$this->so->add_entry($event,true,$event['owner']);
 				$cd = 16;
 
@@ -756,5 +727,5 @@
 				if($this->check_perms(PHPGW_ACL_DELETE,$event))
 				{
-					$this->send_update(MSG_DELETED,$event['participants'],$event);
+					$this->send_update(MSG_DELETED,$event['participants'],$event,false,$event['owner']);
 				}
 				else
@@ -815,11 +786,4 @@
                     $participants = $event['participants'];
 
-            //        $new_event = Array();
-            //        $new_event['owner'] = $owner;
-            //        $new_event['participants'] = $participants;
-            //        $new_event['start'] = $event['start'];
-            //        $new_event['end'] = $event['end'];
-            //
-            //        $return[] = $new_event;
 
                     switch($event['recur_type']) {
@@ -998,15 +962,8 @@
 		function update($params='')
 		{
+			$prefix = ( $params['from_mobile'] ? "mobile.ui_mobile" : "calendar.ui" ) . "calendar";
 			
-			if($params['from_mobile']) {
-				$ui_return = "mobile.ui_mobilecalendar.edit";
-				$ui_index = "mobile.ui_mobilecalendar.index";
-				$ui_overlap = "mobile.ui_mobilecalendar.overlap";
-			}
-			else {
-				$ui_return = "calendar.uicalendar.edit";
-				$ui_index = "calendar.uicalendar.index";		
-				$ui_overlap = "calendar.uicalendar.overlap";
-			}
+			$ui_return = "$prefix.edit";
+			$ui_index = "$prefix.index";
 			
 			if(!is_object($GLOBALS['phpgw']->datetime))
@@ -1014,41 +971,14 @@
 				$GLOBALS['phpgw']->datetime = createobject('phpgwapi.date_time');
 			}
-
 			$l_cal = (@isset($params['cal']) && $params['cal']?$params['cal']:$_POST['cal']);
-
-                        $post_max_size = ini_get('post_max_size');
-                        $mul = substr($post_max_size, -1);
-                        $mul = ($mul == 'M' ? 1048576 : ($mul == 'K' ? 1024 : ($mul == 'G' ? 1073741824 : 1)));
-                        if ($_SERVER['CONTENT_LENGTH'] > $mul*(int)$post_max_size && $post_max_size)
-                             $l_cal['attachment'] = 'ERROR';
-
-                        if(count($_FILES['cal']) > 0){
-
-                            if($l_cal['attachment'] != '')
-                               $attachments = unserialize($l_cal['attachment']);
-                            else
-                               $attachments = Array();
-
-                            foreach ($_FILES['cal']['error']['attachment'] as $key => $error) {
-
-                                if ($error == UPLOAD_ERR_OK) {
-
-                                    $new_file= $GLOBALS['phpgw_info']['server']['temp_dir'].'/'.$_SESSION[ 'phpgw_session' ][ 'session_id' ].md5($attachment['name'].microtime());
-                                    move_uploaded_file($_FILES['cal']['tmp_name']['attachment'][$key], $new_file);
-                                    $attach = Array('tmp_name' => $new_file, 'name' => $_FILES['cal']['name']['attachment'][$key], 'type' =>  $_FILES['cal']['type']['attachment'][$key]);
-
-                                    $attachments[] = $attach;
-
-                                }elseif($error == UPLOAD_ERR_INI_SIZE){
-                                    $attachments = 'ERROR';
-                                    break;
-
-                                }
-                            }
-                            $l_cal['attachment'] = $attachments;
-
-                        }
 			$l_participants = (@$params['participants']?$params['participants']:$_POST['participants']);
-			$this->ex_participants = (@$params['ex_participants']?$params['ex_participants']:$_POST['ex_participants']);
+
+                        require_once($_SESSION['rootPath'].'/calendar/inc/class.ex_participants.inc.php');
+                        $this->ex_participants = new exParticipants();
+                        $this->ex_participants->setParticipantsByString(@$params['ex_participants']?$params['ex_participants']:$_POST['ex_participants']);
+
+                        if(@$params['h_exParticipants']?$params['h_exParticipants']:$_POST['h_exParticipants'])
+                             $this->ex_participants->updateAttribBySerializable(@$params['h_exParticipants']?$params['h_exParticipants']:$_POST['h_exParticipants']);
+
 			$l_categories = (@$params['categories']?$params['categories']:$_POST['categories']);
 			$l_start = (@isset($params['start']) && $params['start']?$params['start']:$_POST['start']);
@@ -1083,5 +1013,5 @@
 					}
 				}
-				unset($l_cal['participants']);
+
 
 				if (!is_object($GLOBALS['phpgw']->categories))
@@ -1120,5 +1050,4 @@
 				$event['title'] = stripslashes($event['title']);
 				$event['description'] = stripslashes($event['description']);
-				$event['observations'] = stripslashes($event['observations']);
 				$event['ex_participants'] = stripslashes($event['ex_participants']);
 				$datetime_check = $this->validate_update($event);
@@ -1136,5 +1065,5 @@
 						return;
 				}
-				$overlapping_events = False;
+				//$overlapping_events = False;
 			}
 			else
@@ -1163,5 +1092,5 @@
 				if(!isset($l_cal['ex_participants']))
 				{
-					$l_cal['ex_participants'] = $this->ex_participants;
+					$l_cal['ex_participants'] = $this->ex_participants->getParticipantsSerializable();
 				}
 
@@ -1173,5 +1102,11 @@
 				$is_public = ($l_cal['type'] != 'private' && $l_cal['type'] != 'privateHiddenFields');
 				$this->so->event_init();
+
+                                if($l_cal['uid'])
 				$this->add_attribute('uid',$l_cal['uid']);
+                                else
+                                $this->add_attribute('uid',time().'@Expresso');
+                                
+
 				$this->add_attribute('type',$l_cal['type']);
 				if($l_cal['ex_participants']) {
@@ -1188,7 +1123,4 @@
 				$this->so->set_title($l_cal['title']);
 				$this->so->set_description($l_cal['description']);
-				$this->so->set_observations($l_cal['observations']);
-				$this->so->set_notifications_owner($l_cal['notifications_owner']);
-				$this->so->set_attachment($l_cal['attachment']);
 				$this->so->set_ex_participants($l_cal['ex_participants']);
 				$this->so->set_start($l_start['year'],$l_start['month'],$l_start['mday'],$l_start['hour'],$l_start['min'],0);
@@ -1197,8 +1129,4 @@
 				$this->so->add_attribute('reference',(@isset($l_cal['reference']) && $l_cal['reference']?$l_cal['reference']:0));
 				$this->so->add_attribute('location',(@isset($l_cal['location']) && $l_cal['location']?$l_cal['location']:''));
-				$this->so->add_attribute('repeat',(@isset($l_cal['recur_type']) && $l_cal['recur_type']?$l_cal['recur_type']:''));
-				$this->so->add_attribute('alarmd',(@isset($l_cal['alarmdays'])?$l_cal['alarmdays']:0));
-				$this->so->add_attribute('alarmh',(@isset($l_cal['alarmhours'])?$l_cal['alarmhours']:0));
-				$this->so->add_attribute('alarmm',(@isset($l_cal['alarmminutes'])?$l_cal['alarmminutes']:0));
 				if($l_cal['id'])
 				{
@@ -1222,7 +1150,5 @@
 						$this->so->set_recur_none();
 
-						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
-						$this->so->add_attribute('recur_type',(@isset($repetido) && $repetido?$repetido:0));
-						$this->so->add_attribute('rpt_end_use',(@isset($l_cal['rpt_use_end']) && $l_cal['rpt_use_end']?$l_cal['rpt_use_end']:''));
+						$this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
 
 						break;
@@ -1230,6 +1156,5 @@
 						$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;
-						$this->so->add_attribute('recur_type',(@isset($repetido) && $repetido?$repetido:0));
+						$this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
 
 						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
@@ -1238,5 +1163,4 @@
 						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
 						{
-							$this->so->add_attribute('rpt_end_use',(@isset($l_cal['rpt_use_end']) && $l_cal['rpt_use_end']?$l_cal['rpt_use_end']:''));
 							
 							$tmp_end = explode("/",$_POST['recur_enddate']['str']); // recebe data final da repeticao;
@@ -1250,6 +1174,5 @@
 					case MCAL_RECUR_WEEKLY:
 
-						$repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
-						$this->so->add_attribute('recur_type',(@isset($repetido) && $repetido?$repetido:0));
+						$this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
 
 						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
@@ -1259,5 +1182,4 @@
 						{
 
-							$this->so->add_attribute('rpt_end_use',(@isset($l_cal['rpt_use_end']) && $l_cal['rpt_use_end']?$l_cal['rpt_use_end']:''));
 							$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;
@@ -1280,5 +1202,4 @@
 							}
 						}
-						$this->so->add_attribute('rpt_wdays',(@isset($rpt_wdays) && $rpt_wdays?$rpt_wdays:''));
 						$this->so->set_recur_weekly((int)$l_recur_enddate['year'],(int)$l_recur_enddate['month'],(int)$l_recur_enddate['mday'],(int)$l_cal['recur_interval'],$l_cal['recur_data']);
 						break;
@@ -1286,6 +1207,5 @@
 						$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;
-						$this->so->add_attribute('recur_type',(@isset($repetido) && $repetido?$repetido:0));
+						$this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
 
 						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
@@ -1294,5 +1214,5 @@
 						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
 						{
-							$this->so->add_attribute('rpt_end_use',(@isset($l_cal['rpt_use_end']) && $l_cal['rpt_use_end']?$l_cal['rpt_use_end']:''));
+
 							$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;
@@ -1309,6 +1229,5 @@
 						$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;
-						$this->so->add_attribute('recur_type',(@isset($repetido) && $repetido?$repetido:0));
+						$this->repetido = (int)$l_cal['recur_type']; // recebe o tipo de repeticao;
 
 						$tmp_init = explode("/",$_POST['start']['str']); // recebe a data inicial da repeticao;
@@ -1317,5 +1236,5 @@
 						if($l_cal['rpt_use_end'] == 'y') // verifica se foi indicada data final da repeticao, se sim:
 						{
-							$this->so->add_attribute('rpt_end_use',(@isset($l_cal['rpt_use_end']) && $l_cal['rpt_use_end']?$l_cal['rpt_use_end']:''));
+
 							$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;
@@ -1340,5 +1259,5 @@
 						}
 						$acct_type = $GLOBALS['phpgw']->accounts->get_type((int)$parts[$i]);
-						if($acct_type == 'u')
+						if($acct_type == 'u' || $acct_type == 's')
 						{
 							$part[(int)$parts[$i]] = $accept_type;
@@ -1422,6 +1341,5 @@
 				$event = $this->get_cached_event();
 
-				if ($l_cal['alarmdays'] > 0 || $l_cal['alarmhours'] > 0 ||
-						$l_cal['alarmminutes'] > 0)
+				if ($l_cal['alarmdays'] > 0 || $l_cal['alarmhours'] > 0 ||$l_cal['alarmminutes'] > 0)
 				{
 					$offset = ($l_cal['alarmdays'] * 24 * 3600) +
@@ -1435,5 +1353,5 @@
 						'owner'   => $this->owner,
 						'enabled' => 1,
-						'repeat'  => $repetido, // para repetir alarme;
+						'repeat'  => $this->repetido, // para repetir alarme;
 						'init_rept' => $init_rept, // inicio repeticao;
 						'end_rept' => $end_rept, // fim repeticao;
@@ -1463,4 +1381,96 @@
 				}
 
+			    $overlapping_events = $this->event_overlap( $event, $send_to_ui, $prefix );
+
+			    if( $overlapping_events )
+				return( $overlapping_events );
+			}
+
+				$event['ex_participants'] = $this->ex_participants->getParticipantsSerializable();
+			
+                        if($event['owner'] != $GLOBALS['phpgw_info']['user']['account_id']) $userSend = $event['owner'];
+                        else $userSend = false;
+       
+			if(!$event['id'])
+			{
+                                /** Whenever a recurrent event is edit in a way that a new  
+                                 * exception is created, an exception must be added to 
+                                 * the old event. This is necessary to keep consistency 
+                                 * with synchornization solutions in accordancy to 
+                                 * the iCalendar RFC. 
+                                 */ 
+                                $old_event = $this->so->read_entry($_POST['cal']['reference']); 
+
+                                $date = $_POST['cal']['date']; 
+                                $year  = substr($date,0,4); 
+                                $month = substr($date,4,2); 
+                                $day   = substr($date,6,2); 
+
+                                $exception_time = mktime($old_event['start']['hour'],$old_event['start']['min'],0,$month,$day,$year) - $GLOBALS['phpgw']->datetime->tz_offset; 
+                                $old_event['recur_exception'][] = (int)$exception_time; 
+                                $this->so->add_entry($old_event,false); 
+                            
+                            
+                                $this->so->add_entry($event,false);
+				print_debug('New Event ID',$event['id']);
+                                $send_type = MSG_ADDED;
+			}
+			else
+			{
+				print_debug('Updating Event ID',$event['id']);
+				$new_event = $event;
+				$old_event = $this->read_entry($event['id']);
+				// if old event has alarm and the start-time changed => update them
+				//echo "<p>checking ".count($old_event['alarm'])." alarms of event #$event[id] start moved from ".print_r($old_event['start'],True)." to ".print_r($event['start'],True)."</p>\n";
+				if ($old_event['alarm'] &&
+					$this->maketime($old_event['start']) != $this->maketime($event['start']))
+				{
+					$this->so->delete_alarms($old_event['id']);
+					foreach($old_event['alarm'] as $id => $alarm)
+					{
+						$alarm['time'] = $this->maketime($event['start']) - $alarm['offset'];
+						$event['alarm'][] = $alarm;
+					}
+					//echo "updated alarms<pre>".print_r($event['alarm'],True)."</pre>\n";
+				}
+				$this->so->cal->event = $event;
+				$this->so->add_entry($event,false);
+				$this->prepare_recipients($new_event,$old_event,$userSend);
+                                $send_type = MSG_MODIFIED;
+			}
+                     
+                        //Retira da lista usuarios ja notificados
+                        $to_notify = $event['participants'];
+                        foreach ($this->alreadyNotifieds as $key => $value) 
+                            if(array_key_exists($value,$to_notify))
+                                unset ($to_notify[$value]);
+                        //------------------------------------------------//
+                           
+                        if(count($to_notify) > 0 && $userSend !== -2)    
+                            $this->send_update( $send_type,$to_notify,'',$this->get_cached_event(),$userSend);
+
+			$date = sprintf("%04d%02d%02d",$event['start']['year'],$event['start']['month'],$event['start']['mday']);
+			if($send_to_ui)
+			{
+				$this->read_sessiondata();
+				if ($this->return_to)
+				{
+					$GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.$this->return_to);
+					$GLOBALS['phpgw']->common->phpgw_exit();
+				}
+				Execmethod($ui_index);
+			}
+			else
+			{
+				return (int)$event['id'];
+			}
+
+			return True;
+		}
+
+		function event_overlap( $event, $send_to_ui = false, $prefix = "calendar.uicalendar" ,$user = false)
+		{
+		    $event_ids = array();
+
 				if($event['id'])
 				{
@@ -1472,5 +1482,6 @@
 				}
 
-				if (isset($repetido) and $repetido > 0){
+                    if (isset($this->repetido) and $this->repetido > 0)
+                    { 
                                     $events = $this->expand_repetition($event);
                                     $overlapping_events = False;
@@ -1492,5 +1503,6 @@
                                     }
                                 }
-                                else {
+                    else 
+                    { 
                                     $overlapping_events = $this->overlap(
                                         $this->maketime($event['start']),
@@ -1501,78 +1513,28 @@
                                     );
                                 }
-			}
-			if(!$this->ex_participants)
-				$this->ex_participants = $event['ex_participants'];			
+                                      
 			if($overlapping_events)
 			{
+                            $this->store_to_appsession( $event );
 				if($send_to_ui)
 				{
-					$event['ex_participants'] = $this->ex_participants;
 					unset($GLOBALS['phpgw_info']['flags']['noheader']);
 					unset($GLOBALS['phpgw_info']['flags']['nonavbar']);
-					ExecMethod($ui_overlap,
+				    ExecMethod("$prefix.overlap",
 						Array(
 							'o_events'	=> $overlapping_events,
-							'this_event'	=> $event
+						    'this_event'	=> $event,
+                                                    'this_account' => $user
 						)
 					);
-					if(!$params['from_mobile'])
+
+				    if( $prefix === "calendar.uicalendar" )
 						$GLOBALS['phpgw']->common->phpgw_exit(True);
-					else
-						return;
-				}
-				else
-				{
-					return $overlapping_events;
-				}
-			}
-			else
-			{
-				if(!$event['id'])
-				{
-					$this->so->add_entry($event);
-					$this->send_update(MSG_ADDED,$event['participants'],'',$this->get_cached_event());
-					print_debug('New Event ID',$event['id']);
-				}
-				else
-				{
-					print_debug('Updating Event ID',$event['id']);
-					$new_event = $event;
-					$old_event = $this->read_entry($event['id']);
-					// if old event has alarm and the start-time changed => update them
-					//echo "<p>checking ".count($old_event['alarm'])." alarms of event #$event[id] start moved from ".print_r($old_event['start'],True)." to ".print_r($event['start'],True)."</p>\n";
-					if ($old_event['alarm'] &&
-						$this->maketime($old_event['start']) != $this->maketime($event['start']))
-					{
-						$this->so->delete_alarms($old_event['id']);
-						foreach($old_event['alarm'] as $id => $alarm)
-						{
-							$alarm['time'] = $this->maketime($event['start']) - $alarm['offset'];
-							$event['alarm'][] = $alarm;
-						}
-						//echo "updated alarms<pre>".print_r($event['alarm'],True)."</pre>\n";
-					}
-					$this->so->cal->event = $event;
-					$this->so->add_entry($event);
-					$this->prepare_recipients($new_event,$old_event);
-				}
-
-				$date = sprintf("%04d%02d%02d",$event['start']['year'],$event['start']['month'],$event['start']['mday']);
-				if($send_to_ui)
-				{
-					$this->read_sessiondata();
-					if ($this->return_to)
-					{
-						$GLOBALS['phpgw']->redirect_link('/index.php','menuaction='.$this->return_to);
-						$GLOBALS['phpgw']->common->phpgw_exit();
-					}
-					Execmethod($ui_index);
-				}
-				else
-				{
-					return (int)$event['id'];
-				}
-			}
-			return True;
+				}
+
+			    return( $overlapping_events );
+			}
+
+		    return( false );
 		}
 
@@ -1700,57 +1662,13 @@
 				$error = 43;
 			}
-			elseif ($event['type'] != 'hourAppointment' && $event['title'] == '')
+			elseif ($event['title'] == '')
 			{
 				$error = 40;
 			}
-			elseif ($event['repeat'] != 0)
-			{
-				if( $event['rpt_end_use'] != 'y')
-				{
-					$error = 46;
-				}
-			//}
-			  if ($event['repeat'] == 2)
-			  {
-    				if($event['rpt_wdays'] == '') {
-        				$error = 44;
-            			}
-				if( $event['rpt_end_use'] != 'y')
-				{
-					$error = 46;
-				}
-
-                    		if (  ( isset($event['alarmd'])  && ($event['alarmd'] != 0) ) || ( isset($event['alarmh'])  && ($event['alarmh'] != 0) ) || ( isset($event['alarmm'])  && ($event['alarmm'] != 0) ) )
-                    		{
-		                    	if( isset($event['recur_type']) && ($event['recur_type'] != 0) )
-                    			{
-		                    		if( $event['rpt_end_use'] != 'y')
-	                    			{
-		                    			$error = 45;
-                		    		}
-                    			}
-                    		}
-			   }
-
-			//}
-		  if (  ( isset($event['alarmd'])  && ($event['alarmd'] != 0) ) || ( isset($event['alarmh'])  && ($event['alarmh'] != 0) ) || ( isset($event['alarmm'])  && ($event['alarmm'] != 0) ) )
-                  {
-                	if( isset($event['recur_type']) && ($event['recur_type'] != 0) )
-                	{
-                		if( $event['rpt_end_use'] != 'y')
-                		{
-                			$error = 45;
-                		}
-                	}
-                  }
-		}
 			elseif (($GLOBALS['phpgw']->datetime->time_valid($event['start']['hour'],$event['start']['min'],0) == False) || ($GLOBALS['phpgw']->datetime->time_valid($event['end']['hour'],$event['end']['min'],0) == False))
 			{
 				$error = 41;
 			}
-			elseif (($GLOBALS['phpgw']->datetime->date_valid($event['start']['year'],$event['start']['month'],$event['start']['mday']) == False) 
-				|| ($GLOBALS['phpgw']->datetime->date_valid($event['end']['year'],$event['end']['month'],$event['end']['mday']) == False)
-				|| ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 1)
-				|| $event['start']['year'] > 2037 || $event['end']['year'] > 2037)
+			elseif (($GLOBALS['phpgw']->datetime->date_valid($event['start']['year'],$event['start']['month'],$event['start']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_valid($event['end']['year'],$event['end']['month'],$event['end']['mday']) == False) || ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 1))
 			{
 				$error = 42;
@@ -1758,12 +1676,9 @@
 			elseif ($GLOBALS['phpgw']->datetime->date_compare($event['start']['year'],$event['start']['month'],$event['start']['mday'],$event['end']['year'],$event['end']['month'],$event['end']['mday']) == 0)
 			{
-				if ( ($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 1)
-                                   ||($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 0) )
-				{
-					$error = 47;
-				}
-			}
-                        if($event['attachment'] == 'ERROR')
-                            $error = 99;
+				if ($GLOBALS['phpgw']->datetime->time_compare($event['start']['hour'],$event['start']['min'],0,$event['end']['hour'],$event['end']['min'],0) == 1)
+				{
+					$error = 42;
+				}
+			}
                         
 			return $error;
@@ -1789,16 +1704,4 @@
 		}
 		
-		function participants_unanswered($participants,$event)
-		{
-			foreach($participants as $uid => $status)
-			{				
-				if (isset($event['participants'][$uid]) && $event['participants'][$uid] == 'U' && $status == 'U')
-				{
-					return False;
-				}
-			}
-			return True;
-		}
-
 		function overlap($starttime,$endtime,$participants,$owner=0,$id=0,$restore_cache=False)
 		{
@@ -1909,5 +1812,5 @@
 								$temp_start_time >= $temp_event_start &&
 								$temp_end_time <= $temp_event_end) &&
-								$this->participants_not_rejected($participants,$event) && $this->participants_unanswered($participants,$event))
+								$this->participants_not_rejected($participants,$event))
 							{
 								if($this->debug)
@@ -2080,5 +1983,9 @@
 		function get_short_field($event,$is_private=True,$field='')
 		{
-			if($is_private)
+			if($is_private && $event['type'] == 'E')
+			{
+				return lang('Restrict');
+			}
+			else if($is_private && $event['type'] == 'P')
 			{
 				return lang('private');
@@ -2342,5 +2249,5 @@
 			$search_date_day = date('d',$datetime);
 			$search_date_dow = date('w',$datetime);
-			$search_beg_day = mktime(12,0,0,$search_date_month,$search_date_day,$search_date_year);
+			$search_beg_day = mktime(0,0,0,$search_date_month,$search_date_day,$search_date_year);
 			if($this->debug)
 			{
@@ -2409,5 +2316,5 @@
 							break;
 						case MCAL_RECUR_WEEKLY:
-							if (floor(($search_beg_day - $event_beg_day)/604800)  % ($freq ? $freq : 1))
+							if ((floor($search_beg_day / 604800) - floor($event_beg_day / 604800)) % $freq)
 							{
 								continue;
@@ -2934,5 +2841,5 @@
 		@abstract set the participant response $status for event $cal_id and notifies the owner of the event
 		*/
-		function set_status($cal_id,$status)
+		function set_status($cal_id,$status,$user = false)
 		{
 			$status2msg = array(
@@ -2946,13 +2853,24 @@
 			}
 			$event = $this->so->read_entry($cal_id);
-			$account_id = $GLOBALS['phpgw_info']['user']['account_id'];
+                        if($user) $account_id = $user;
+                        else $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
 			if(($status2msg[$status] == "5" && $event['participants'][$account_id] == "A") ||
 			 ($status2msg[$status] == "3" && $event['participants'][$account_id] == "R")) {
 				return True;
 			}
-			$this->so->set_status($cal_id,$status);
+			$this->so->set_status($cal_id,$status,$account_id);
 			$event = $this->so->read_entry($cal_id);
-			$this->send_update($status2msg[$status],$event['participants'],$event);
-
+			$this->send_update($status2msg[$status],$event['participants'],$event,false,$account_id);
+
+			$sts = array_values( $event['participants'] );
+
+			//verifica se todos os participantes rejeitaram o evento
+			while( $sts[0] && $sts[0] === 'R' ) array_pop( $sts );
+
+			if( empty( $sts ) )
+			{
+				$this->so->delete_entry( $cal_id );
+				$this->so->expunge();
+			}
 		}
 
@@ -3015,79 +2933,388 @@
 		}
 
-		function create_vcard($event_arrays)
-		{
+
+		function create_vcard($event_arrays , $metodo = 'PUBLISH', $externo = false,$importAccount = false)
+		{
+                    if(!$importAccount)
+                        $importAccount['mail'] = $GLOBALS['phpgw_info']['user']['email'];
+
             if(!is_array($event_arrays))
 				return null;
 
-                        $sender = $GLOBALS['phpgw_info']['user']['email'];
-                        $uid_dono = $GLOBALS['phpgw_info']['user']['account_lid'];
-			$tmpattach="BEGIN:VCALENDAR\n"
-			."PRODID:-//Expresso Livre//Calendar//EN\n"
-			."VERSION:1.0\n";
-            foreach ($event_arrays as $event)
-            {
-				// It translates int to string
-				if (!is_object($event) && !is_array($event) || !array_key_exists  ('end', $event))
-					$event = $event_arrays;
-
-				//set to GMT
-				//Aqui estou pegando o horário do evento e setando para GMT de acordo com o fuso horário estabelecido nas configurações do expresso.
-				$start_time = mktime($event['start']['hour'],$event['start']['min'],$event['start']['sec'],$event['start']['month'],$event['start']['mday'],$event['start']['year']) - $GLOBALS['phpgw']->datetime->tz_offset;
-				$end_time = mktime($event['end']['hour'],$event['end']['min'],$event['end']['sec'],$event['end']['month'],$event['end']['mday'],$event['end']['year']) - $GLOBALS['phpgw']->datetime->tz_offset;
-				
-				$start_time = date("Ymd\THis\Z", $start_time);
-				$end_time = date("Ymd\THis\Z", $end_time);
+                    $tmpattach="BEGIN:VCALENDAR\r\n"
+                        ."PRODID:-//Expresso Livre//Calendar//EN\r\n"
+                        ."VERSION:2.0\r\n"
+                        ."CALSCALE:GREGORIAN\r\n"
+                        ."METHOD:".$metodo."\r\n";
+
+		    //$offset = ((int)substr(date('O',$GLOBALS['phpgw']->datetime->users_localtime), 0, 3));
+		    $offset = (($GLOBALS['phpgw']->datetime->tz_offset)/60)/60;
 	
-				// Necessário espaços após quebra-de-linha, na descrição, caso contrário 
-				// ocorrerá erro ao importar o agendamento no Outlook (erro lunar).
-				$description = str_replace("\n","\n ", $event['description']);
-				
-				$tmpattach.="BEGIN:VEVENT\r\n"
-				."DTSTART:".$start_time."\r\n"
-				."DTEND:".$end_time."\r\n"
+                        foreach ($event_arrays as $event_array)
+                        {
+                            $sy = $event_array['start']['year'];
+                            $sm = $event_array['start']['month'];
+                            $sd = $event_array['start']['mday'];
+                            $sh = $event_array['start']['hour'] -= $offset;
+                            $sn = $event_array['start']['min'];
+                            $dtstart = sprintf("%04d%02d%02dT%02d%02d00Z", $sy, $sm, $sd, $sh, $sn);
+
+                            $ey = $event_array['end']['year'];
+                            $em = $event_array['end']['month'];
+                            $ed = $event_array['end']['mday'];
+                            $eh = $event_array['end']['hour'] -= $offset;
+                            $en = $event_array['end']['min'];
+                            $dtend = sprintf("%04d%02d%02dT%02d%02d00Z", $ey, $em, $ed, $eh, $en);
+
+                            // NecessÃ¡rio espaÃ§os apÃ³s quebra-de-linha, na descriÃ§Ã£o, caso contrÃ¡rio
+                            // ocorrerÃ¡ erro ao importar o agendamento no Outlook (erro lunar).
+                            $description = str_replace("\n","\n ",$event_array['description']);
+                            $tmpattach.="BEGIN:VEVENT\r\n";
+							
+							if(isset($event_array['organizer']) && $event_array['owner'] != -2)
+							{
+                                $ldap = $this->getLdap();  
+                                $justthese = array("mail","cn");
+                                $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$event_array['owner']."))";
+                                $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
+                                $entry = ldap_get_entries($ldap, $search);                                        
+								$organizer = 'ORGANIZER;CN='.$entry[0]['cn'][0].':mailto:'.$entry[0]['mail'][0]."\r\n";
+							}   
+							else{   
+								$email = explode('&lt;', $event_array['organizer']);
+								$email2 = explode('&gt;', $email[1]);
+                                $organizer = 'ORGANIZER;CN='.rtrim($email[0]).':mailto:'.$email2[0]."\r\n";
+							}
+								 
+                            if(!$externo)
+                            {
+							    $tmpattach.=
+                                "DTSTART:".$dtstart."\r\n"
+                                ."DTEND:".$dtend."\r\n"
 				."LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
-				//."UID:Expresso-".$event['id'].$event['uid']."\r\n"
-                                ."UID:Expresso-".$event[id]."@".$uid_dono."\n"
+								.$organizer
+                                ."UID:".$event_array['uid']."\r\n"
+								.$this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
+								.$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
 				."DESCRIPTION:".$description."\r\n"
-				."SUMMARY:".$event['title']."\r\n"
-				."LOCATION:".$event['location']."\r\n"
-				."ORGANIZER:mailto:".$sender."\n";
-                                $expart=preg_split('/,/', $event['ex_participants']);
-
-                                foreach ($expart as $mail)
+                                ."SUMMARY:".$event_array['title']."\r\n"
+                                ."LOCATION:".$event_array['location']."\r\n"
+                                ."END:VEVENT\r\n";
+                            }
+                             else
+                            {
+								$tmpattach.=
+                                "DTSTART:".$dtstart."\r\n"
+                                ."DTEND:".$dtend."\r\n"
+                                ."DTSTAMP:".gmdate("Ymd\THis\Z")."\r\n" //Hora no formato UTC
+                                .$organizer
+                                .$this->mb_wordwrap("UID:".$event_array['uid']."\r\n",74,"\r\n ");
+
+                                switch ($metodo) {
+                                    case 'PUBLISH':
+                                          $tmpattach.=
+                                             $this->mb_wordwrap($this->getvCalendarParticipants($event_array['participants'],$event_array['id']),74,"\r\n ")
+											.$this->mb_wordwrap($this->getvCalendarExternalParticipants($event_array['id']),74,"\r\n ")
+                                            .$this->mb_wordwrap("DESCRIPTION:".$description."\r\n",74,"\r\n ")
+                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
+                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ");
+                                        break;
+                                    case 'REPLY':
+                                            $tmpattach.=
+                                             $this->mb_wordwrap("ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;X-NUM-GUESTS=0:mailto:".$importAccount['mail']."\r\n",74,"\r\n ")
+                                            .'DESCRIPTION:\n'."\r\n"
+                                            .$this->mb_wordwrap("LAST-MODIFIED:".gmdate("Ymd\THis\Z")."\r\n",74,"\r\n ") //Hora no formato UTC
+                                            .$this->mb_wordwrap("LOCATION:".$event_array['location']."\r\n",74,"\r\n ")
+                                            ."SEQUENCE:0\r\n"
+                                            ."STATUS:CONFIRMED\r\n"
+                                            .$this->mb_wordwrap("SUMMARY:".$event_array['title']."\r\n",74,"\r\n ")
+                                            ."TRANSP:OPAQUE\r\n";
+                                        break;
+                                    default:
+                                           $tmpattach.=
+                                             "DESCRIPTION:".$description."\r\n"
+                                            ."SUMMARY:".$event_array['title']."\r\n"
+                                            ."LOCATION:".$event_array['location']."\r\n";
+                                        break;
+                                }
+                                  $tmpattach.= "END:VEVENT\r\n";
+                            }
+                            
+                        }
+                    $tmpattach.="END:VCALENDAR\r\n\r\n\r\n";
+                    return $tmpattach;
+		}
+
+                function mb_wordwrap($str, $width=74, $break="\r\n")
+                {
+                    // Return short or empty strings untouched
+                    if(empty($str) || mb_strlen($str, 'ISSO-8859-1') <= $width)
+                        return $str;
+
+                    $br_width  = mb_strlen($break, 'ISSO-8859-1');
+                    $str_width = mb_strlen($str, 'ISSO-8859-1');
+                    $return = '';
+                    $last_space = false;
+
+                    for($i=0, $count=0; $i < $str_width; $i++, $count++)
+                    {
+                        // If we're at a break
+                        if (mb_substr($str, $i, $br_width, 'ISSO-8859-1') == $break)
+                        {
+                            $count = 0;
+                            $return .= mb_substr($str, $i, $br_width, 'ISSO-8859-1');
+                            $i += $br_width - 1;
+                            continue;
+                        }
+
+                        // Keep a track of the most recent possible break point
+                        if(mb_substr($str, $i, 1, 'ISSO-8859-1') == " ")
+                        {
+                            $last_space = $i;
+                        }
+
+                        // It's time to wrap
+                        if ($count > $width)
                                 {
-                                    if($mail != "")
+                            // There are no spaces to break on!  Going to truncate :(
+                            if(!$last_space)
                                     {
-                                        $tmpattach.="ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:".$mail."\n";
+                                $return .= $break;
+                                $count = 0;
+                            }
+                            else
+                            {
+                                // Work out how far back the last space was
+                                $drop = $i - $last_space;
+
+                                // Cutting zero chars results in an empty string, so don't do that
+                                if($drop > 0)
+                                {
+                                    $return = mb_substr($return, 0, -$drop);
+                                }
+
+                                // Add a break
+                                $return .= $break;
+
+                                // Update pointers
+                                $i = $last_space + ($br_width - 1);
+                                $last_space = false;
+                                $count = 0;
                                     }
                                 }
                                 
-                                while (list($id,$status) = each($event['participants']))
+                        // Add character from the input string to the output
+                        $return .= mb_substr($str, $i, 1, 'ISSO-8859-1');
+                    }
+                    return $return;
+                }
+
+                function getvCalendarParticipants($pExtParticipants,$pCalId)
                                 {
-
-                                      $preferences = CreateObject('phpgwapi.preferences',$id);
-                                      $mail = $preferences->email_address($id);
-                                      if ( $sender != $mail)
+                    $participants = explode(',', $pExtParticipants);
+                    $return = '';
+
+                    foreach ($participants as $participant)
                                       {
-                                         if($status == 'U' ){
-                                                  $tmpattach.="ATTENDEE;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;ROLE=REQ-PARTICIPANT:mailto:".$mail."\n";
+                        $array = explode('"', $participant);
+                        $mail = str_replace('<','', str_replace('>','',$array['2']));
+                        if($mail && $array['1'])
+                             $return .= 'ATTENDEE;CN='.$array['1'].';RSVP=TRUE:mailto:'.$mail."\r\n";
+                    }
+                    $db = $this->getDb();
+                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
+                    $parts = array();
+                    while($db->next_record())
+                        array_push($parts, $db->row());
+
+                    $ldap = $this->getLdap();
+                    foreach ($parts as $part)
+                    {
+                        $justthese = array('mail','cn');
+                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
+                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
+                        $entry = ldap_get_entries($ldap, $search);
+                        $return .= 'ATTENDEE;CN='.$entry[0]['cn'][0].';RSVP=TRUE:mailto:'.$entry[0]['mail'][0]."\r\n";
                                                         }
-                                         elseif($status == 'A' ){
-                                                 $tmpattach.="ATTENDEE;RSVP=TRUE;PARTSTAT=ACCEPTED;ROLE=REQ-PARTICIPANT:mailto:".$mail."\n";
+
+                    return $return;
                                                         }
-                                         elseif($status == 'T' ){
-                                                 $tmpattach.="ATTENDEE;RSVP=TRUE;PARTSTAT=TENTATIVE;ROLE=REQ-PARTICIPANT:mailto:".$mail."\n";
+				
+                function getCalendarParticipantsArray($pCalId)
+                {
+                    $db = $this->getDb();
+                    $db->query('SELECT cal_login FROM phpgw_cal_user WHERE cal_id = '.$pCalId);
+                    $parts = array();
+                    while($db->next_record())
+                        array_push($parts, $db->row());
+
+                    $ldap = $this->getLdap();
+                    foreach ($parts as $part)
+                    {
+                        $justthese = array('mail','cn');
+                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l))(uidNumber=".$part['cal_login']."))";
+                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
+                        $entry = ldap_get_entries($ldap, $search);
+                        $return [$entry[0]['mail'][0]] = array( 'CN'=> $entry[0]['cn'][0],'RSVP'=> 'TRUE' ,'ROLE' => 'REQ-PARTICIPANT');
+                    }
+                    return $return;
+                }
+
+                function getvCalendarExternalParticipants($pCalId)
+                {
+
+                    $db = $this->getDb();
+                    $sql = "SELECT ex_participants FROM phpgw_cal WHERE cal_id = '$pCalId'";
+                                $db->query($sql);
+                                
+                    $parts = array();
+                    while($db->next_record())
+                        array_push($parts, $db->row());
+
+					$participants = explode(',', $parts[0]['ex_participants']);
+                    $return = '';
+					
+					$participants = unserialize(base64_decode($parts[0]['ex_participants']));
+
+                    foreach ($participants as $participant)
+                    {	
+                           $part = array();
+
+                           if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $participant['mail']))
+                           {
+                              $cn = null;
+                              $mail = null;
+                              preg_match ("(\"([^\"]*)\")", $participant['mail'], $cn);
+                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
+
+                              if($mail[1])
+                              $part['mail'] =  $mail[1];
+
+                              if($cn[1])
+                                $part['cn'] =  $cn[1];
+
                                                          }
                                          else
+                           if(preg_match("(<[^>]*@[^>]*>)", $participant['mail']))
                                                   {
-                                                     $tmpattach.="ATTENDEE;RSVP=TRUE;PARTSTAT=DECLINED;ROLE=REQ-PARTICIPANT:mailto:".$mail."\n";
+                              $mail = null;
+                              preg_match ('(<([^>]*@[^>]*)>)', $participant['mail'], $mail);
+                              if($mail[1])
+                                $part['mail'] =  $mail[1];
+
                                                    }
+                           else
+                           if(preg_match("([^ ]*@[^ ]*)", $participant['mail']))
+                           {
+                              $mail = null;
+                              preg_match ('([^ ]*@[^ ]*)', $participant['mail'], $mail);
+                              if($mail[0])
+                                $part['mail'] =  $mail[0];
+
+                           }
+
+                          if(count($part) > 0)
+                          {
+                              if($part['cn']) 
+								$return .= 'ATTENDEE;CN='.$part['cn'].';RSVP=TRUE:mailto:'.$part['mail']."\r\n";
+                              else 
+								$return .= 'ATTENDEE;RSVP=TRUE:mailto:'.$part['mail']."\r\n";  
+                             
                                       }
                                 }
-                                $tmpattach.="END:VEVENT"."\n";
-                                //."END:VEVENT\r\n";
-			}
-                    $tmpattach.="END:VCALENDAR\r\n";
-                    return $tmpattach;
+
+                    return $return;
+			}
+
+
+                function getDb()
+                {
+                    include_once('../phpgwapi/inc/class.db.inc.php');
+                    // Conecta ao banco de dados
+                    if (is_array($_SESSION['phpgw_info']['expresso']['server']))
+                        $GLOBALS['phpgw_info']['server'] = $_SESSION['phpgw_info']['expresso']['server'];
+                    else
+                        $_SESSION['phpgw_info']['expresso']['server'] = $GLOBALS['phpgw_info']['server'];
+
+                    $db = new db();
+                    $db->Halt_On_Error = 'no';
+                    $db->connect(
+                                $_SESSION['phpgw_info']['expresso']['server']['db_name'],
+                                $_SESSION['phpgw_info']['expresso']['server']['db_host'],
+                                $_SESSION['phpgw_info']['expresso']['server']['db_port'],
+                                $_SESSION['phpgw_info']['expresso']['server']['db_user'],
+                                $_SESSION['phpgw_info']['expresso']['server']['db_pass'],
+                                $_SESSION['phpgw_info']['expresso']['server']['db_type']
+                                );
+                                // Fim Conecta Banco de dados
+                    return $db;
+                }
+
+                function getLdap()
+                {
+                    require_once($_SESSION['rootPath'].'/header.inc.php');
+                    require_once($_SESSION['rootPath'].'/phpgwapi/inc/class.common.inc.php');
+   
+                    $common = new common();
+                                
+                    if ( (!empty($GLOBALS['phpgw_info']['server']['ldap_master_host'])) &&
+                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_dn'])) &&
+                        (!empty($GLOBALS['phpgw_info']['server']['ldap_master_root_pw'])) )
+                        {
+                            $ldap = $common->ldapConnect($GLOBALS['phpgw_info']['server']['ldap_master_host'],
+                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_dn'],
+                                                         $GLOBALS['phpgw_info']['server']['ldap_master_root_pw']);
+                        }
+                        else
+                        {
+                            $ldap = $common->ldapConnect();
+                        }
+                       
+                    return $ldap;
+                }
+
+                function getvCalendarOrganizer($pOrganizer)
+                {
+
+                    
+                       $organizer = array();
+       
+                       if(preg_match("(\"[^\"]*\"[ ]*<[^>]*@[^>]*>)", $pOrganizer))
+                       {
+                          $cn = null;
+                          $mail = null;
+                          preg_match ("(\"([^\"]*)\")", $pOrganizer, $cn);
+                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
+
+                          if($mail[1])
+                          $organizer['mail'] =  $mail[1];
+
+                          if($cn[1])
+                            $organizer['cn'] =  $cn[1];
+
+                       }
+                       else
+                       if(preg_match("(<[^>]*@[^>]*>)", $pOrganizer))
+                       {
+                          $mail = null;
+                          preg_match ('(<([^>]*@[^>]*)>)', $pOrganizer, $mail);
+                          if($mail[1])
+                            $organizer['mail'] =  $mail[1];
+
+                       }
+                       else
+                       if(preg_match("([^ ]*@[^ ]*)", $pOrganizer))
+                       {
+                          $mail = null;
+                          preg_match ('([^ ]*@[^ ]*)', $pOrganizer, $mail);
+                          if($mail[0])
+                            $organizer['mail'] =  $mail[0];
+
+                       }
+                       
+                       if($organizer['cn']) $return = 'ORGANIZER;CN="'.$organizer['cn'].'":MAILTO:'.$organizer['mail']."\r\n";
+                       else $return = 'ORGANIZER;MAILTO:'.$organizer['mail']."\r\n";
+                       
+                    return $return;
 		}
 
@@ -3101,35 +3328,41 @@
 		@param $new_event Event after the change
 		*/
-		function send_update($msg_type,$to_notify,$old_event,$new_event=False,$user=False)
-		{			
-			if (!is_array($to_notify))
-			{
-				$to_notify = array();
-			}
+		function send_update($msg_type,$to_notify,$old_event,$new_event = False, $user = False)
+			{
+          
+                        if (!is_array($to_notify)) $to_notify = array();
 			$owner = $old_event ? $old_event['owner'] : $new_event['owner'];
-			if ($owner && !isset($to_notify[$owner]) && $msg_type != MSG_ALARM)
-			{
-				$to_notify[$owner] = 'owner';	// always include the event-owner
-			}
+
+                        if($owner === -2)
+                            $to_notify[-2] = 'A'; 
+
 			$version = $GLOBALS['phpgw_info']['apps']['calendar']['version'];
-
 			$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences();
-
-		    $preferences = CreateObject('phpgwapi.preferences',(int)$this->owner); 
- 		    $GLOBALS['phpgw']->accounts->get_account_name((int)$owner,$lid,$fname,$lname); 
  		 
-			if($new_event['notifications_owner'] == '1'){ 
- 		        $sender = $preferences->email_address((int)$owner); 
- 		        $sender_name = $fname.' '.$lname; 
- 		    }else{ 
- 		        $sender = $GLOBALS['phpgw_info']['user']['email']; 
- 		        $sender_name = $GLOBALS['phpgw_info']['user']['fullname']; 
+                        /*
+                         * Caso o evento seja de uma conta compartilha busca obusca o cn e o email da conta
+                         */ 
+                        if($user)
+                        {
+                            $ldap = $this->getLdap();  
+                            $justthese = array("mail","cn");
+                            $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
+                            $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
+                            $entry = ldap_get_entries($ldap, $search);
+                            $sMail = $entry[0]['mail'][0];
+                            $sCN = $entry[0]['cn'][0];
+                            $sUN = $user;
  		        } 
+                        else
+                        {
+                            $sMail = $GLOBALS['phpgw_info']['user']['email'];
+                            $sCN = $GLOBALS['phpgw_info']['user']['fullname'];
+                            $sUN = $GLOBALS['phpgw_info']['user']['account_id'];
+                        }
+                        //------------------------------------------------------------------------------------//
  		 
  		    $temp_tz_offset = $this->prefs['common']['tz_offset'];
-			
 			$temp_timeformat = $this->prefs['common']['timeformat'];
 			$temp_dateformat = $this->prefs['common']['dateformat'];
-
 			$tz_offset = ((60 * 60) * (int)$temp_tz_offset);
 
@@ -3138,16 +3371,11 @@
 				$t_old_start_time = $this->maketime($old_event['start']);
 				if($t_old_start_time < (time() - 86400))
-				{
 					return False;
 				}
-			}
 
 			$temp_user = $GLOBALS['phpgw_info']['user'];
-
-			if (!$user)
-			{
-				$user = $this->owner;
-			}
+			if (!$user) $user = $this->owner;
 			$GLOBALS['phpgw_info']['user']['preferences'] = $GLOBALS['phpgw']->preferences->create_email_preferences($user);
+                        $this->prefs = $GLOBALS['phpgw_info']['user']['preferences'];
 
 			$event = $msg_type == MSG_ADDED || $msg_type == MSG_MODIFIED ? $new_event : $old_event;
@@ -3216,7 +3444,6 @@
 			$notify_msg = $this->prefs['calendar']['notify'.$msg];
 			if (empty($notify_msg))
-			{
 				$notify_msg = $this->prefs['calendar']['notifyAdded'];	// use a default
-			}
+			
 			$details = array(			// event-details for the notify-msg
 				'id'          => $msg_type == MSG_ADDED ? $new_event['id'] : $old_event['id'],
@@ -3252,9 +3479,9 @@
 			$mail->Host = $emailadmin['smtpServer'];
 			$mail->Port = $emailadmin['smtpPort'];
-			$mail->From = $GLOBALS['phpgw']->preferences->values['email'];
-			$mail->FromName = $GLOBALS['phpgw_info']['user']['fullname'];
-			//$mail->IsHTML(true);
-                        $mail->IsCalendar(true);
-
+			$mail->From = $sMail;
+			$mail->FromName = $sCN;
+			$mail->IsHTML(true);
+                        //Inicializa vari?vel de retorno.
+                        $returncode=true;		
 			// Aqui e enviado o email
 			foreach($to_notify as $userid => $statusid) 
@@ -3264,12 +3491,11 @@
 				$userid = (int)$userid;
 
-				if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g')
-				{
-					continue;	// dont notify rejected participants
-				}
-				if($userid != $GLOBALS['phpgw_info']['user']['account_id'] || ($msg_type == MSG_ADDED && $userid != $owner) || $msg_type == MSG_ALARM || isset($new_event['attachment']))
-				//if($userid != $owner ||  $msg_type == MSG_ALARM || isset($new_event['attachment']))
+				if ($statusid == 'R' || $GLOBALS['phpgw']->accounts->get_type($userid) == 'g' || ($sUN == $userid &&  $msg_type != MSG_ALARM))
+                                    continue;	// dont notify rejected participants or to == send
+				
+				if($userid != $sUN  ||  $msg_type == MSG_ALARM)
 				{
 					print_debug('Msg Type',$msg_type);
+                                        
 					print_debug('UserID',$userid);
 
@@ -3285,4 +3511,10 @@
 
 					$to = $preferences->email_address($userid);
+					
+                                        
+					if( $userid === -2 )
+					{
+						$to = htmlspecialchars_decode( $event['organizer'] );
+					}
 					
 					if (empty($to) || $to[0] == '@' || $to[0] == '$')	// we have no valid email-address
@@ -3403,10 +3635,6 @@
 											if( trim($tmpmail) == trim($to) & trim($tmpuid) == trim($NewKey))
 											{
-													if( ( $typesend == 3 ) || ( $typesend == 2 ) )
+													if($typesend == 3)
 													{
-														$question = "";
-														
-														if( $typesend == 2 )
-															$question = lang("Do you wish to change your participation in this event?");
 
 														$lang1 = lang("To See Commitment");
@@ -3415,8 +3643,12 @@
 																		  		   </form>";
 														$lang2 = lang("To accept");
-														$varbuttom1 ="<input type='submit' value='$lang2' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=3&response=1&user_id=$userid\",\"frontpage\",\"height=200,width=450,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+														$varbuttom1 ="<input type='submit' value='$lang2' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=3&response=1&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+                                                                                                                
+                                                                                                                $lang6 = lang("Tentative");
+														$varbuttom5 ="<input type='submit' value='$lang6' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=2&response=3&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+														
 
 														$lang3 = lang("To reject");
-														$varbuttom2 ="<input type='submit' value='$lang3' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=0&response=0\",\"frontpage\",\"height=100,width=400,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
+														$varbuttom2 ="<input type='submit' value='$lang3' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=0&response=2&user=".$tmpuid."\",\"frontpage\",\"height=100,width=500,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";
 														
 														$lang4 = lang("Alarm");
@@ -3426,11 +3658,8 @@
 																		  		   </form>";
 																				   
-														$lang5 = lang("Delegate");
-														$varbuttom4 = "<form action='".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.screen_delegate_event&id_event=$event[id]&date=$newall3&delegator=$tmpuid' method='POST'>
+														$lang5 = lang("Suggest new hour"); 
+														$varbuttom4 = "<form action=".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.view&cal_id=$event[id]&date=$newall3&type=1' method='POST'>
 																		  		  <input type='submit' value='$lang5'>
 																		  		   </form>";
-														
-														$lang6 = lang("Tentative");
-														$varbuttom5 ="<input type='submit' value='$lang6' onClick='javascript:window.open(\"".$GLOBALS['phpgw_info']['server']['webserver_url']."/index.php?menuaction=calendar.uicalendar.set_action&cal_id=$event[id]&action=2&response=1&user_id=$userid\",\"frontpage\",\"height=200,width=450,statusbar=no,toolbar=no,scrollbars=no,menubar=no,left=300,top=200\")'>";														
 													}
 													else
@@ -3466,7 +3695,8 @@
 							
 							// A constante PHPGW_APP_TPL nao existe para envio de alarmes (cront, asyncservice).
-							define ("PHPGW_APP_TPL",PHPGW_API_INC . "/../../calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_dir']."");
+							if(!PHPGW_APP_TPL)
+                                                         define ("PHPGW_APP_TPL",PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
 							
-							$body = CreateObject('phpgwapi.Template',PHPGW_APP_TPL);
+								$body = CreateObject('phpgwapi.Template',PHPGW_INCLUDE_ROOT . "/calendar/templates/".$GLOBALS['phpgw_info']['user']['preferences']['common']['template_set']."");
 							$body->set_file(Array('calendar' => 'body_email.tpl'));
 							$body->set_block('calendar','list');
@@ -3486,5 +3716,4 @@
 								'var8'				=> $var8,
 								'vardata8'			=> $vardata8,
-								'question'			=> $question,															
 								'varbuttom'			=> $varbuttom,
 								'varbuttom1'		=> $varbuttom1,
@@ -3516,18 +3745,9 @@
 							break;
 					}
+                                       
 					$mail->AddAddress($to);
-					//$mail->Body = $tmpbody;
-                                        $tmpattach_n = $this->create_vcard($GLOBALS['bocalendar']->so->cal->event);
-                                        $tmpattach = str_replace("Expresso-","",$tmpattach_n);
-                                        $mail->Body = "This is a multi-part message in MIME format.";
-                                        $mail->Body .= "\n--01BD3665.3AF0D360\n";
-                                        $mail->Body .= "Content-Type: text/html; charset=\"iso-8859-1\"\nContent-Transfer-Encoding: 8bit\n";
-                                        $mail->Body .= $tmpbody;
-                                        $mail->Body .= "\n--01BD3665.3AF0D360\n";
-                                        $mail->Body .="Content-Type:text/calendar; method=REQUEST; charset=US-ASCII\nContent-Transfer-Encoding:7bit\n\n";
-                                        $mail->Body .= $tmpattach;
-                                        $mail->Body .= "\n--01BD3665.3AF0D360--\n";
-                                        $mail->From = $sender;
-					$mail->FromName = $sender_name;
+					$mail->Body = $tmpbody;      
+					$mail->From = $sMail;
+					$mail->FromName = $sCN;
 					$mail->Sender = $mail->From;
 					$mail->SenderName = $mail->FromName;
@@ -3535,29 +3755,36 @@
 					unset($vardata5);
 					unset($vardata6);
-				}
-			}
-
-			//Inicializa variï¿œvel de retorno.
-			$returncode=true;			
-			if(count($mail->to)) {
-
-                            if(isset($new_event['attachment'])){
-                                foreach($new_event['attachment'] as $attach){
-                                    $mail->AddAttachment($attach['tmp_name'], $attach['name'], "base64", $attach['type']);
+                                        
+                                        // Envia aviso ao participante.
+                                        if(!$mail->Send()) {				
+                                                $returncode = false;
+                                                $errorInfo['participants'] = $mail->ErrorInfo;
+			}
+
+                                        $mail->ClearAddresses();    
+
                                 }
                             }
-				// Envia aviso a todos os participantes.
-				if(!$mail->Send()) {				
-					$returncode = false;
-					$errorInfo['participants'] = $mail->ErrorInfo;
+
+                        if(!is_object($this->ex_participants))
+                        {
+                            include_once($_SESSION['rootPath'].'/calendar/inc/class.ex_participants.inc.php');
+                            $objexP = new exParticipants();
+                            $objexP->setParticipantsBySerializable($this->ex_participants);
 				}
 				else
-					$returncode =  true;
-			}
+                            $objexP = $this->ex_participants;
+
 			
-			if(count($to_notify) && $this->ex_participants){
+                        if($msg_type === MSG_ADDED && count($this->extAdded) > 0)
+                               $extMails = $this->extAdded;  
+                        else if($msg_type === MSG_DELETED && count($this->extDeleted) > 0)
+                                $extMails = $this->extDeleted;  
+                        else 
+                            $extMails = array_diff($objexP->getParticipantsMailsArray(), $this->alreadyExtNotifieds);
+                               
+			if(count($extMails) > 0){
 				$mail->ClearAllRecipients();
-				$var = explode(",",trim($this->ex_participants));
-                                $mail->IsHTML(true);
+                              
 				$to = array();
 				if(!$subject) {
@@ -3567,5 +3794,5 @@
 				}
 				
-				foreach($var as $index => $ex_participant){
+				foreach($extMails as $index => $ex_participant){
 					$ex_participant = trim($ex_participant);
 					$ex_participant = preg_replace('#"(.*)" <(.*)\@(.*)\.(.*)>#','\\2@\\3.\\4',$ex_participant);
@@ -3579,6 +3806,6 @@
 				$_body = explode("<hr size='1' width='100%'>",$tmpbody);
 				$tmpbody = $_body[0] ? $_body[0] : $subject ;
-				$tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($this->ex_participants);
-				$tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[title]."<br>";
+				$tmpbody.= "<br><b>".lang("external participants").":: </b> ".htmlentities($objexP->getParticipantsMailsString());
+				$tmpbody.= "<br>".lang("Summary").": ".$this->so->cal->event[description]."<br>";
 				$tmpbody.= "<br>".lang("Start time").": ".$GLOBALS['phpgw']->common->show_date($starttime)."<br>".lang("End date").": ".$GLOBALS['phpgw']->common->show_date($endtime)."<br>";
 				$tmpbody.= "<br><br><hr size='1' width='100%'><font color='red'>"
@@ -3592,16 +3819,57 @@
 				//attach extern vcalendar/icalendar (ics)			
 				// define('context','$GLOBALS.bocalendar.so.cal.event');
-				$tmpattach = $this->create_vcard($GLOBALS['bocalendar']->so->cal->event);
+				
+				$evt = $GLOBALS['bocalendar']->so->cal->event;
+                                                                 
+                                /*
+                                 * Cria Arqvuio ICS
+                                 */
+                                require_once $_SESSION['rootPath'].'/API/class.servicelocator.php';
+                                $icalService = ServiceLocator::getService('ical');
+
+                                if($msg_type == MSG_DELETED)
+                                {
+                                        $icalService->createICal(strtoupper($method));
+                                        $icalService->addEvent(
+                                            $old_event['start']['year'].'-'.$old_event['start']['month'].'-'.$old_event['start']['mday'].' '.$old_event['start']['hour'].':'.$old_event['start']['min'].':00',
+                                            $old_event['end']['year'].'-'.$old_event['end']['month'].'-'.$old_event['end']['mday'].' '.$old_event['end']['hour'].':'.$old_event['end']['min'].':00',
+                                            array($sMail => array('CN'=> $sCN)),
+                                            $old_event['title'],
+                                            $old_event['description'],
+                                            $old_event['location'],
+                                            false,
+                                            false,
+                                            false,
+                                            $old_event['uid']
+                                            );
+                                }
+                                else
+                                {
+                                        $attendee = array();
+                                        foreach($to as $value)
+                                            $attendee[$value] = array('RSVP' => 'TRUE','ROLE' => 'REQ-PARTICIPANT');
+
+                                        $attendee =  array_merge($attendee,$this->getCalendarParticipantsArray($evt['id']));
+                                        $icalService->createICal(strtoupper($method));
+                                        $icalService->addEvent(
+                                            $evt['start']['year'].'-'.$evt['start']['month'].'-'.$evt['start']['mday'].' '.$evt['start']['hour'].':'.$evt['start']['min'].':00',
+                                            $evt['end']['year'].'-'.$evt['end']['month'].'-'.$evt['end']['mday'].' '.$evt['end']['hour'].':'.$evt['end']['min'].':00',
+                                            array($sMail => array('CN'=> $sCN)),
+                                            $evt['title'],
+                                            $evt['description'],
+                                            $evt['location'],
+                                            $attendee,
+                                            false,
+                                            false,
+                                            $evt['uid']
+                                            );
+
+                                }
+
+
+				$tmpattach = $icalService->getICal();
+                                //-------------------------------------------------//
+                                
 				if($tmpattach){					
-					$tmpbody .="<a href='../index.php?menuaction=calendar.uicalendar.add&date="
-					.$GLOBALS['bocalendar']->so->cal->event[start][year]
-				.$event_month
-				.$GLOBALS['bocalendar']->so->cal->event[start][mday]
-					."&hour=".$GLOBALS['bocalendar']->so->cal->event[start][hour]
-					."&minute=".$GLOBALS['bocalendar']->so->cal->event[start][min]
-					."&title=".$GLOBALS['bocalendar']->so->cal->event['title']
-					."&description=".$GLOBALS['bocalendar']->so->cal->event['description']
-					."&location=".$GLOBALS['bocalendar']->so->cal->event['location']."'>"
-					."<h2>".lang("Add to my expresso")."</h2>";
 					$tempdir = $GLOBALS['phpgw_info']['server']['temp_dir'] . SEP;
 					srand((double)microtime()*1000000);
@@ -3614,13 +3882,6 @@
 					fclose($attach_fd);
 				}
-
-                                if(isset($new_event['attachment'])){
-                                    foreach($new_event['attachment'] as $attach){
-                                        $mail->AddAttachment($attach['tmp_name'], $attach['name'], "base64", $attach['type']);
-                                    }
-                                }
-                                
-				$mail->From = $sender;
-				$mail->FromName = $sender_name;
+				$mail->From = $sMail;
+				$mail->FromName = $sCN;
 				$mail->Sender = $mail->From;
 				$mail->SenderName = $mail->FromName;
@@ -3651,5 +3912,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>";
@@ -3678,6 +3939,6 @@
 				$mail->Host = $emailadmin['smtpServer'];
 				$mail->Port = $emailadmin['smtpPort'];
-				$mail->From = $sender;
-				$mail->FromName = $sender_name;
+				$mail->From = $sMail;
+				$mail->FromName = $sCN;
 				$mail->Sender = $mail->From;
 				$mail->SenderName = $mail->FromName;
@@ -3685,5 +3946,5 @@
 				$mail->Subject = lang("calendar event")." - ".lang("email notification");							
 				$mail->Body = $tmpbody;					
-				$mail->AddAddress($sender);
+				$mail->AddAddress($sMail);
 				if(!$mail->Send())			
 					$returncode = false;
@@ -3693,4 +3954,106 @@
 			return $returncode;
 		}
+		
+		
+		
+		/**
+		 * @license http://www.gnu.org/copyleft/gpl.html GPL
+		 * @author Prognus Software Livre (http://www.prognus.com.br)
+		 */
+		function send_suggestion_external_owner($cal_id, $uid, $to, $time_suggest, $array_data_inicio, $array_data_final, $title, $description, $location, $ex_participants,$user = false)
+                {
+
+                    if($cal_id)
+                        $event =  $this->so->read_entry($cal_id);
+                    else
+                    {
+                        $event = $this->restore_from_appsession();
+                        $this->so->add_entry( $event , false);
+                    }
+                    
+                    $this->so->cal->set_status($event['id'],$user,2);
+
+
+                    if($user && $user != $GLOBALS['phpgw_info']['user']['account_id'])
+                    {
+                        $ldap = $this->getLdap();
+                        $justthese = array("mail","cn");
+                        $filter="(&(|(phpgwAccountType=u)(phpgwAccountType=l)(phpgwAccountType=s)(phpgwAccountType=i))(uidNumber=".$user."))";
+                        $search = ldap_search($ldap, $GLOBALS['phpgw_info']['server']['ldap_context'], $filter, $justthese);
+                        $entry = ldap_get_entries($ldap, $search);
+                        $ownerMail = $entry[0]['mail'][0];
+                        $ownerCN = $entry[0]['cn'][0];
+                     }
+                     else
+                     {
+                        $ownerMail = $GLOBALS['phpgw_info']['user']['email'];
+                        $ownerCN = $GLOBALS['phpgw_info']['user']['fullname'];
+                     }
+                     
+                    require_once $_SESSION['rootPath'] . '/API/class.servicelocator.php';
+                    $icalService = ServiceLocator::getService('ical');
+                    $dia_inicio = $array_data_inicio[0];
+                    $mes_inicio = $array_data_inicio[1];
+                    $ano_inicio = $array_data_inicio[2];
+                    $hora_inicio = $time_suggest['hora_inicio'];
+                    $minuto_inicio = $time_suggest['minuto_inicio'];
+                    $dia_final = $array_data_final[0];
+                    $mes_final = $array_data_final[1];
+                    $ano_final = $array_data_final[2];
+                    $hora_final = $time_suggest['hora_final'];
+                    $minuto_final = $time_suggest['minuto_final'];
+
+                    $dtStart = $array_data_inicio[2] . '/' .
+                               $array_data_inicio[1] . '/' .
+                               $array_data_inicio[0] . ' ' .
+                               $time_suggest['hora_inicio'] . ':' .
+                               $time_suggest['minuto_inicio'] . ':00';
+
+                    $dtEnd = $array_data_final[2] . '/' .
+                             $array_data_final[1] . '/' .
+                             $array_data_final[0] . ' ' .
+                             $time_suggest['hora_final'] . ':' .
+                             $time_suggest['minuto_final'] . ':00';
+
+                    $icalService->createICal('REPLY');
+
+                    $other = array( 'X-MICROSOFT-CDO-IMPORTANCE' => '1',
+                                    'X-EXPRESSO-SUGGESTION-HOUR' => '1',
+                                    'CLASS' => 'PUBLIC',
+                                    'PRIORITY' => '5',
+                                    'SEQIENCE' => '0',
+                                    'TRANSP' => 'OPAQUE');
+
+                    /* Corpo do email */
+                    $tmpbody2 = lang("The sender suggested a new hours for the appointment");
+                    $tmpbody2.= " <br /> <b>" . lang("Title") . ":</b> $title";
+                    $tmpbody2.= " <br /> <b>" . lang("Details") . ":</b> <br /> <br /> <b>" . lang("Start") . "  </b>" . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
+                    $tmpbody2.= " <br /> <b>" . lang("End") . " </b>" . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "<br><br><br><br>";
+                    $tmpbody = lang("The sender suggested a new hours for the appointment");
+                    $tmpbody.= " \r\n " . lang("Title") . ": $title";
+                    $tmpbody.= " \r\n " . lang("Suggestion") . ": \r\n \r\n " . lang("Start") . "  " . $dia_inicio . "/" . $mes_inicio . "/" . $ano_inicio . " - " . $hora_inicio . ":" . $minuto_inicio;
+                    $tmpbody.= " \r\n " . lang("End") . " " . $dia_final . "/" . $mes_final . "/" . $ano_final . " - " . $hora_final . ":" . $minuto_final . "";
+
+                    $icalService->addEvent($dtStart,
+                            $dtEnd,
+                            $to,
+                            $title,
+                            utf8_encode($tmpbody),
+                            $location,
+                            array($ownerMail => array('CN' => $ownerCN, 'PARTSTAT' => 'TENTATIVE')),
+                            $other,
+                            false,
+                            $uid
+                    );
+                   
+                    $tmpattach =  $icalService->getICal();                   
+                    
+                    $mailService = ServiceLocator::getService('mail');
+                    $mailService->addStringAttachment($tmpattach, 'suggestion.ics', 'application/ics');
+                    $mailService->addStringAttachment($tmpattach, 'vcalendar.ics', 'text/calendar; charset=utf-8; method=REPLY;', '7bit', 'inline');
+                    $mailService->sendMail($to, $ownerMail, $title, $tmpbody2);
+                     
+                    return $event['id'];                    
+                }		
 		
 		function send_alarm($alarm)
@@ -3764,49 +4127,63 @@
 		}
 
-		function prepare_recipients(&$new_event,$old_event)
-		{
-						
-			// Find modified and deleted users.....
-			while(list($old_userid,$old_status) = each($old_event['participants']))
-			{
-				if(isset($new_event['participants'][$old_userid]))
-				{
-					print_debug('Modifying event for user',$old_userid);
-					$this->modified[(int)$old_userid] = $new_status;
-				}
-				else
-				{
-					print_debug('Deleting user from the event',$old_userid);
-					$this->deleted[(int)$old_userid] = $old_status;
-				}
-			}
-			// Find new users.....
-			while(list($new_userid,$new_status) = each($new_event['participants']))
-			{
-				if(!isset($old_event['participants'][$new_userid]))
-				{
-					print_debug('Adding event for user',$new_userid);
-					$this->added[$new_userid] = 'U';
-					$new_event['participants'][$new_userid] = 'U';
-				}
+		function prepare_recipients(&$new_event,$old_event,$userSend)
+		{
+                        //Verifica se ouve alguem deletado
+                        foreach($old_event['participants'] as $key => $value)
+                           if(!array_key_exists($key, $new_event['participants']))
+				{
+                               $this->deleted[$key] = $value;
+                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
+				}
+                        //Verifica se ouve alguem adicionado
+                        foreach($new_event['participants'] as $key => $value)
+                           if(!array_key_exists($key, $old_event['participants']))
+				{
+                               $this->added[$key] = $value;
+                               $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
 			}
 			
-			if(count($this->added) > 0 || count($this->modified) > 0 || count($this->deleted) > 0)
-			{
-				if(count($this->added) > 0)
-				{
-					$this->ex_participants = '';
-					$this->send_update(MSG_ADDED,$this->added,'',$new_event);
-				}
-				if(count($this->modified) > 0)
-				{
-					$this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event);
-				}
-				if(count($this->deleted) > 0)
-				{
-					$this->ex_participants = '';
-					$this->send_update(MSG_DELETED,$this->deleted,$old_event);
-				}
-			}
+                        //Verifica se ouve alguem modificado
+                        foreach($new_event['participants'] as $key => $value)
+			{
+                            if(array_key_exists($key, $old_event['participants']))                       
+				{
+                                if($old_event['participants'][$key] != $value)
+				{
+                                    $this->modified[$key] = $value;  
+                                    $this->alreadyNotifieds[] = $key; //Adiciona a variavel de ja notificados para não serem notificados 2 vezes;
+				}
+				}
+			}
+                         //Verificando alterações em usuarios externos
+                         include_once($_SESSION['rootPath'].'/calendar/inc/class.ex_participants.inc.php');
+                         $extOld = new exParticipants();
+                         $extNew = new exParticipants();
+                         
+                         $extOld->setParticipantsBySerializable($old_event['ex_participants']);
+                         $extNew->setParticipantsBySerializable($new_event['ex_participants']);
+                        
+                         $oldArray = $extOld->getParticipantsMailsArray();
+                         $newArray = $extNew->getParticipantsMailsArray();
+                         
+                        //Verifica se ouve alguem deletado
+                        $this->extDeleted = array_diff($oldArray, $newArray);
+                        
+                        //Verifica se ouve alguem adicionado
+                        $this->extAdded = array_diff($newArray, $oldArray);
+                        
+                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extDeleted);
+                        $this->alreadyExtNotifieds = array_merge($this->alreadyExtNotifieds, $this->extAdded);
+                        //---------------------------------------------------------------------------------//
+                        
+                        if(count($this->added) > 0 || count($this->extAdded))
+                                $this->send_update(MSG_ADDED,$this->added,'',$new_event,$userSend);
+                        
+                        if(count($this->modified) > 0)
+                                $this->send_update(MSG_MODIFIED,$this->modified,$old_event,$new_event,$userSend);
+                        
+                        if(count($this->deleted) > 0 || count($this->extDeleted))
+                                $this->send_update(MSG_DELETED,$this->deleted,$old_event,false,$userSend);
+                        			
 		}
 
@@ -4021,7 +4398,11 @@
 			);
 
+			$owner = $event['owner'];
+
+			$owner_name = ( $owner === -2 )? $event['organizer'] : $GLOBALS['phpgw']->common->grab_owner_name( $owner );
+
 			$var['owner'] = Array(
 				'field'	=> lang('Created By'),
-				'data'	=> $GLOBALS['phpgw']->common->grab_owner_name($event['owner'])
+				'data'  => $owner_name
 			);
 
@@ -4031,22 +4412,15 @@
 			);
 
-			$var['observations'] = Array(
-				'field'	=> $this->translate('Observations'),
-				'data'	=> $event['observations']
-			);
-			
-                        $var['attachment'] = Array(
-                                'field'	=> $this->translate('Attachment'),
-                                'data'	=> $event['attachment']
-                        );
-
-			$var['alter_by'] = Array(
-                                'field'	=> $this->translate('Alter by'),
-                                'data'	=> $event['alter_by']
-                        );
+			if($event['public']){
+				$type = lang('Public');
+			}else if (!$event['public'] && $event['type'] == 'E'){
+				$type = lang('Restrict');
+			}else{
+				$type = lang('Private');
+			}
 
 			$var['access'] = Array(
 				'field'	=> lang('Access'),
-				'data'	=> $event['public'] ? lang('Public') : lang('Private')
+				'data'	=> $type
 			);
 
