Index: /branches/2.2/calendar/inc/class.bocalendar.inc.php
===================================================================
--- /branches/2.2/calendar/inc/class.bocalendar.inc.php	(revision 3429)
+++ /branches/2.2/calendar/inc/class.bocalendar.inc.php	(revision 3728)
@@ -97,5 +97,7 @@
 		);
 
-		var $debug = False;
+                var $wdays;
+
+                var $debug = False;
 //		var $debug = True;
 
@@ -378,4 +380,6 @@
 			}
 			$this->xmlrpc = is_object($GLOBALS['server']) && $GLOBALS['server']->last_method;
+                        $this->wdays = Array(MCAL_M_SUNDAY,MCAL_M_MONDAY,MCAL_M_TUESDAY,MCAL_M_WEDNESDAY,
+                            MCAL_M_THURSDAY,MCAL_M_FRIDAY,MCAL_M_SATURDAY);
 		}
 
@@ -784,4 +788,207 @@
 		}
 
+                function getNextDow($start){
+                    if ($start == 6)
+                    {
+                        return 0;
+                    }
+                    else
+                    {
+                        return $start + 1;
+                    }
+                }
+
+                // TODO: Levar em consideração no cálculo das ocorrências o parâmetro
+                // $event['recur_interval']
+                function expand_repetition($event){
+                    $return = Array();
+
+                    $event['recur_enddate']['hour'] = 24;
+                    $enddate = $this->maketime($event['recur_enddate']);
+
+                    $owner = $event['owner'];
+                    $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']) {
+                        case MCAL_RECUR_DAILY:
+                            // add 1 day = 86400 sec
+                            $starttime = $this->maketime($event['start']);
+                            $endtime = $this->maketime($event['end']);
+
+                            $offset = 86400;
+                            for (; $starttime <= $enddate;
+                                $starttime = $starttime+$offset,
+                                $endtime = $endtime+$offset)
+                            {
+                                $new_event = Array();
+                                $new_event['owner'] = $owner;
+                                $new_event['participants'] = $participants;
+                                $new_event['start'] = $starttime;
+                                $new_event['end'] = $endtime;
+                                $return[] = $new_event;
+                            }
+
+                            break;
+                        case MCAL_RECUR_WEEKLY:
+
+                            $setDow = (int)date('w',$this->maketime($event['start']));
+                            $dowOffsets = Array();
+                            $firstDow;
+                            $firstDowOffset = 0;
+
+                            // Initializing do
+                            $mask = $this->wdays[$setDow];
+                            $firstDayMismatch = False;
+                            if (((int)$event['recur_data'] & $mask) == 0){
+                                $firstDayMismatch = True;
+                            }
+
+                            $dow = $setDow;
+
+                            for ($nextDow = $setDow; array_sum($dowOffsets) < 7;)
+                            {
+
+                                $nextDow = $this->getNextDow($nextDow);
+                                $mask = $this->wdays[$nextDow];
+
+                                if (((int)$event['recur_data'] & $mask) != 0)
+                                {
+                                    if ($firstDayMismatch and $firstDowOffset == 0)
+                                    {
+                                        if ($dow < $nextDow)
+                                        {
+                                            $firstDowOffset = $nextDow - $dow;
+                                        }
+                                        else if ($dow > $nextDow)
+                                        {
+                                            $firstDowOffset = (7 - $dow) + $nextDow;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        if ($dow < $nextDow)
+                                        {
+                                            $dowOffsets[] = $nextDow - $dow;
+                                        }
+                                        else if ($dow > $nextDow)
+                                        {
+                                            $dowOffsets[] = (7 - $dow) + $nextDow;
+                                        }
+                                        else
+                                        {
+                                            $dowOffsets[] = 7;
+                                        }
+
+                                    }
+
+                                    $dow = $nextDow;
+                                    if (!isset($firstDow))
+                                    {
+                                        $firstDow = $dow;
+                                    }
+
+                                }
+
+            //                    $nextDow = $this->getNextDow($nextDow);
+            //                    $mask = $this->wdays[$nextDow];
+
+                            }
+
+                            if ($firstDayMismatch)
+                            {
+                                if ($dow < $firstDow)
+                                {
+                                    $dowOffsets[] = $firstDow - $dow;
+                                }
+                                else if ($dow > $firstDow)
+                                {
+                                    $dowOffsets[] = (7 - $dow) + $firstDow;
+                                }
+                            }
+
+                            // Gera os eventos
+                            $starttime = $this->maketime($event['start']);
+                            $endtime = $this->maketime($event['end']);
+                            $offset = 86400;
+
+                            $new_event = Array();
+                            $new_event['owner'] = $owner;
+                            $new_event['participants'] = $participants;
+                            $new_event['start'] = $starttime;
+                            $new_event['end'] = $endtime;
+                            $return[] = $new_event;
+
+                            if ($firstDayMismatch && $firstDowOffset != 0)
+                            {
+                                $multi = $firstDowOffset;
+
+                                $new_event = Array();
+                                $new_event['owner'] = $owner;
+                                $new_event['participants'] = $participants;
+                                $new_event['start'] = $starttime += $offset*$multi;
+                                $new_event['end'] = $endtime += $offset*$multi;
+                                $return[] = $new_event;
+                            }
+
+                            for ($i = 0, $multi = $dowOffsets[$i],
+                                $starttime += $offset*$multi,
+                                $endtime += $offset*$multi;
+                                $starttime <= $enddate;
+                                $i++,
+                                $i = ($i < count($dowOffsets))?$i:0,
+                                $multi = $dowOffsets[$i],
+                                $starttime += $offset*$multi,
+                                $endtime += $offset*$multi)
+                            {
+                                //error_log('loop infinito?');
+                                $new_event = Array();
+                                $new_event['owner'] = $owner;
+                                $new_event['participants'] = $participants;
+                                $new_event['start'] = $starttime; // + $offset*$multi;
+                                $new_event['end'] = $endtime; // + $offset*$multi;
+                                $return[] = $new_event;
+                            }
+
+
+                            break;
+                        case MCAL_RECUR_MONTHLY_WDAY:
+                            // Not working!!!
+                            break;
+                        case MCAL_RECUR_MONTHLY_MDAY:
+                        case MCAL_RECUR_YEARLY:
+
+                            for ($key = ($event['recur_type'] == MCAL_RECUR_YEARLY)?'year':'month',
+                                $starttime = $event['start'], $endtime = $event['end'];
+                                $this->maketime($starttime) <= $enddate;
+                                $starttime['year'] = ($key == 'month' && $starttime['month'] == 12)?$starttime['year']+1:$starttime['year'],
+                                $endtime['year'] = ($key == 'month' && $endtime['month'] == 12)?$endtime['year']+1:$endtime['year'],
+                                $starttime[$key] = ($key == 'year')?$starttime[$key]+1:($key == 'month' && $starttime[$key] < 12)?$starttime[$key]+1:1,
+                                $endtime[$key] = ($key == 'year')?$endtime[$key]+1:($key == 'month' && $endtime[$key] < 12)?$endtime[$key]+1:1)
+                            {
+                                $new_event = Array();
+                                $new_event['owner'] = $owner;
+                                $new_event['participants'] = $participants;
+                                $new_event['start'] = $this->maketime($starttime);
+                                $new_event['end'] = $this->maketime($endtime);
+                                $return[] = $new_event;
+                            }
+
+                            break;
+            //            default:
+            //                return Array();
+
+                    }
+
+                    return $return;
+                }
+
 		function update($params='')
 		{
@@ -1222,11 +1429,33 @@
 				}
 
-				$overlapping_events = $this->overlap(
-					$this->maketime($event['start']),
-					$this->maketime($event['end']),
-					$event['participants'],
-					$event['owner'],
-					$event_ids
-				);
+				if (isset($repetido) and $repetido > 0){
+                                    $events = $this->expand_repetition($event);
+                                    $overlapping_events = False;
+                                    foreach($events as $evt){
+                                        $overlap = $this->overlap(
+                                            $evt['start'],
+                                            $evt['end'],
+                                            $evt['participants'],
+                                            $evt['owner'],
+                                            $event_ids);
+                                        if ($overlap)
+                                        {
+                                            if (!$overlapping_events)
+                                            {
+                                                $overlapping_events = Array();
+                                            }
+                                            array_push($overlapping_events, $overlap);
+                                        }
+                                    }
+                                }
+                                else {
+                                    $overlapping_events = $this->overlap(
+                                        $this->maketime($event['start']),
+                                        $this->maketime($event['end']),
+                                        $event['participants'],
+                                        $event['owner'],
+                                        $event_ids
+                                    );
+                                }
 			}
 			if(!$this->ex_participants)
