/**
  * @param $EventId int Id of event.
  * @return array
  *	- rdates
  *	- rrules
  *	- exdates
  *	- exrules
  * @todo Optional date limits
  */
 function SelectRecurByEvent($EventId)
 {
     static $date_fields = array('event_date_start			AS start', 'event_date_time_associated	AS time_associated', 'event_date_duration		AS duration', 'event_date_exclude			AS exclude');
     // Get dates
     $this->db->select(implode(',', $date_fields));
     $this->db->from('event_dates');
     $this->db->where(array('event_date_event_id' => $EventId));
     /// @todo Limit by time using range of selection (min <= date <= max)
     $dates_query = $this->db->get();
     $dates = $dates_query->result_array();
     $include_ranges = array();
     $exclude_ranges = array();
     foreach ($dates as $date) {
         $start_parts = explode(' ', $date['start']);
         $start_date = str_replace('-', '', $start_parts[0]);
         // YYYYMMDD
         if ($date['time_associated']) {
             $start_time = str_replace(':', '', $start_parts[1]);
             // HHMMSS
         } else {
             $start_time = NULL;
         }
         if (NULL === $date['duration']) {
             $duration = NULL;
         } else {
             $duration = (int) $date['duration'];
         }
         if (!$date['exclude']) {
             // include
             if (!array_key_exists($start_date, $include_ranges)) {
                 $include_ranges[$start_date] = array();
             }
             $include_ranges[$start_date][$start_time] = $duration;
         } else {
             // exclude (never a range)
             if (!array_key_exists($start_date, $exclude_ranges)) {
                 $exclude_ranges[$start_date] = array();
             }
             $exclude_ranges[$start_date][$start_time] = NULL;
         }
     }
     static $rule_fields = array('event_recur_rule_id			AS rule_id', 'event_recur_rule_event_id		AS event_id', 'event_recur_rule_exclude		AS exclude', 'event_recur_rule_frequency		AS frequency', 'UNIX_TIMESTAMP(event_recur_rule_until)	AS until', 'event_recur_rule_count			AS count', 'event_recur_rule_interval		AS recur_interval', 'event_recur_rule_week_start	AS week_start', 'event_recur_rule_by_by			AS by_by', 'event_recur_rule_by_primary	AS by_primary', 'event_recur_rule_by_secondary	AS by_secondary');
     /// @todo Limit by time using range of selection (until > min)
     // Get recurrence rules
     $this->db->select(implode(',', $rule_fields));
     $this->db->from('event_recur_rules');
     $this->db->join('event_recur_rule_by', 'event_recur_rule_by_event_recur_rule_id = event_recur_rule_id', 'left');
     $this->db->where(array('event_recur_rule_event_id' => $EventId));
     $rules_query = $this->db->get();
     // Turn each rule into an object
     $rrules = array();
     $exrules = array();
     $results = $rules_query->result_array();
     foreach ($results as $rule_data) {
         $category_name = $rule_data['exclude'] ? 'exrules' : 'rrules';
         // If not already created, do so now
         $recur_id = (int) $rule_data['rule_id'];
         if (!array_key_exists($recur_id, ${$category_name})) {
             $rule = new CalendarRecurRule();
             $rule->SetFrequency($rule_data['frequency']);
             if (NULL !== $rule_data['until']) {
                 $rule->SetUntil((int) $rule_data['until']);
             } elseif (NULL !== $rule_data['count']) {
                 $rule->SetCount((int) $rule_data['count']);
             }
             if (NULL !== $rule_data['recur_interval']) {
                 $rule->SetInterval((int) $rule_data['recur_interval']);
             }
             if (NULL !== $rule_data['week_start']) {
                 $rule->SetWkSt(CalendarRecurRule::$sWeekdays[strtoupper($rule_data['week_start'])]);
             }
             if ($rule_data['exclude']) {
                 $exrules[$recur_id] = $rule;
             } else {
                 $rrules[$recur_id] = $rule;
             }
         }
         // If by data included, add it
         if (NULL !== $rule_data['by_by']) {
             $primary = (int) $rule_data['by_primary'];
             $optional = $rule_data['by_secondary'];
             if (NULL !== $optional) {
                 if ($optional != 0) {
                     $optional = (int) $optional;
                 } else {
                     $optional = NULL;
                 }
             }
             if ($rule_data['exclude']) {
                 $rule =& $exrules[$recur_id];
             } else {
                 $rule =& $rrules[$recur_id];
             }
             switch ($rule_data['by_by']) {
                 case 'second':
                     $rule->SetBySecond($primary);
                     break;
                 case 'minute':
                     $rule->SetByMinute($primary);
                     break;
                 case 'hour':
                     $rule->SetByHour($primary);
                     break;
                 case 'day':
                     $rule->SetByDay($primary, $optional);
                     break;
                 case 'monthday':
                     $rule->SetByMonthDay($primary);
                     break;
                 case 'yearday':
                     $rule->SetByYearDay($primary);
                     break;
                 case 'weekno':
                     $rule->SetByWeekNo($primary);
                     break;
                 case 'month':
                     $rule->SetByMonth($primary);
                     break;
                 case 'setpos':
                     $rule->SetBySetPos($primary);
                     break;
                 case 'term':
                     $rule->SetByTerm($primary);
                     break;
                 case 'termday':
                     $rule->SetByTermDay($primary);
                     break;
                 case 'termweek':
                     $rule->SetByTermWeek($primary);
                     break;
                 case 'easter':
                     $rule->SetByEaster($primary);
                     break;
             }
         }
     }
     return array($include_ranges, $rrules, $exclude_ranges, $exrules);
 }