diff --git a/theme/theme.inc b/theme/theme.inc
index 4a45469..c8fcd63 100644
--- a/theme/theme.inc
+++ b/theme/theme.inc
@@ -137,16 +137,48 @@ function fullcalendar_prepare_events($view, $rows, $options) {
     // Collect all fields for the customize options.
     $fields = array();
     // Collect only date fields.
-    $date_fields = array();
+    $date_fields = $r_events = array();
     foreach ($view->field as $field_name => $field) {
       $fields[$field_name] = $view->style_plugin->get_field($delta, $field_name);
       if (fullcalendar_field_is_date($field)) {
+        $view->row_index = $delta;
+        $value = $field->get_items($row);
         $date_fields[$field_name] = array(
-          'value' => $field->get_items($row),
+          'value' => $value,
           'field_alias' => $field->field_alias,
           'field_name' => $field->field_info['field_name'],
           'field_info' => $field->field_info,
         );
+
+        // Special handling for date_repeat
+        if (isset($value[0]['raw']['rrule'])) {
+          $rrule = $value[0]['raw']['rrule'];
+          $rule = date_repeat_split_rrule($rrule);
+
+          $start = $value[0]['raw']['value'];
+          if (isset($rule[0]['UNTIL'])) {
+            $end = $rule[0]['UNTIL']['datetime'];
+          }
+          else{
+            // We can limit this to +1 month because full calendar only displays up to month.
+            $end = $value[0]['raw']['value'] + strtotime('+1 month');
+          }
+
+          // Get all repeat events.
+          $repeating_dates = date_repeat_calc($rrule, $start, $end);
+          // Remove the current date.
+          array_shift($repeating_dates);
+          foreach ($repeating_dates as $r_date){
+            $r_value = $value;
+            $r_value[0]['raw']['value'] = strtotime($r_date);
+            $r_events[][$field_name] = array(
+              'value' => $r_value,
+              'field_alias' => $field->field_alias,
+              'field_name' => $field->field_info['field_name'],
+              'field_info' => $field->field_info,
+            );
+          }
+        }
       }
     }
 
@@ -165,121 +197,130 @@ function fullcalendar_prepare_events($view, $rows, $options) {
       return $events;
     }
 
+    // Merge Repeating Events.
+    foreach ($date_fields as $field_key => $date_field) {
+      $r_events[][$field_key] = $date_field;
+    }
+
     $entities = array();
     $event = array();
-    foreach ($date_fields as $field) {
-      // If this row doesn't contain this entity, or if this entity has already
-      // been processed, skip it.
-      if (!isset($row->_field_data[$field['field_alias']])) {
-        continue;
-      }
+    foreach ($r_events as $date_fields) {
+      foreach ($date_fields as $field) {
 
-      if (!isset($entities[$field['field_alias']])) {
-        // Find the field's alias that refers to it's entity.
-        $alias = $field['field_alias'];
-        $entity = $row->_field_data[$alias]['entity'];
-        $entity->entity_type = $row->_field_data[$alias]['entity_type'];
-
-        list(, , $bundle) = entity_extract_ids($entity->entity_type, $entity);
-        $entity->bundle = $bundle;
-        $entity->eid = $row->{$alias};
-        $entity->options = $view->style_options;
-
-        // If the view disallows editing, that's it.
-        if (!empty($view->fullcalendar_disallow_editable)) {
-          $entity->editable = FALSE;
-        }
-        // Otherwise, see what other modules think.
-        else {
-          // Allow resize/drag/drop of an event if user has proper permissions.
-          $editable = module_invoke_all('fullcalendar_editable', $entity, $view);
-          // If one value is FALSE, return FALSE. The identical operator is needed
-          // because of the return value of array_search().
-          $editable = array_search(FALSE, $editable, TRUE) === FALSE;
-          drupal_alter('fullcalendar_editable', $editable, $entity, $view);
-          $entity->editable = $editable;
+        // If this row doesn't contain this entity, or if this entity has already
+        // been processed, skip it.
+        if (!isset($row->_field_data[$field['field_alias']])) {
+          continue;
         }
 
-        // Store the current date field name for later.
-        $entity->fullcalendar_date_field = $field['field_name'];
-
-        // Create a string of valid HTML class names and add them to the entity.
-        $classes = module_invoke_all('fullcalendar_classes', $entity);
-        drupal_alter('fullcalendar_classes', $classes, $entity);
-        $classes = array_map('drupal_html_class', $classes);
-        $entity->class = implode(' ', array_unique($classes));
-
-        // Default URL.
-        $uri = entity_uri($entity->entity_type, $entity);
-        $entity->url = isset($uri['path']) ? $uri['path'] : '';
-        // Fetch custom URL if needed.
-        if (!empty($options['url'])) {
-          $field_name = $options['url_field'];
-          if (!empty($fields[$field_name])) {
-            $entity->url = ltrim($fields[$field_name], '/');
+        if (!isset($entities[$field['field_alias']])) {
+          // Find the field's alias that refers to it's entity.
+          $alias = $field['field_alias'];
+          $entity = $row->_field_data[$alias]['entity'];
+          $entity->entity_type = $row->_field_data[$alias]['entity_type'];
+          $entity_info = entity_get_info($entity->entity_type);
+
+          list(, , $bundle) = entity_extract_ids($entity->entity_type, $entity);
+          $entity->bundle = $bundle;
+          $entity->eid = $entity->{$entity_info['entity keys']['id']};
+          $entity->options = $view->style_options;
+
+          // If the view disallows editing, that's it.
+          if (!empty($view->fullcalendar_disallow_editable)) {
+            $entity->editable = FALSE;
           }
-        }
-
-        // Fetch custom title if needed.
-        if (!isset($entity->title)) {
-          $entity->title = '';
-        }
-        if (!empty($options['title'])) {
-          $field_name = $options['title_field'];
-          if (!empty($fields[$field_name])) {
-            $entity->title = $fields[$field_name];
+          // Otherwise, see what other modules think.
+          else {
+            // Allow resize/drag/drop of an event if user has proper permissions.
+            $editable = module_invoke_all('fullcalendar_editable', $entity, $view);
+            // If one value is FALSE, return FALSE. The identical operator is needed
+            // because of the return value of array_search().
+            $editable = array_search(FALSE, $editable, TRUE) === FALSE;
+            drupal_alter('fullcalendar_editable', $editable, $entity, $view);
+            $entity->editable = $editable;
           }
-        }
-
-        $entities[$alias] = $entity;
-      }
 
-      $entity = $entities[$field['field_alias']];
-      // Filter fields without value.
-      if (!empty($field['value'])) {
-        $instance = field_info_instance($entity->entity_type, $field['field_name'], $bundle);
-        foreach ($field['value'] as $index => $item) {
-          $dates = _fullcalendar_process_dates($instance, $entity, $field['field_info'], $item['raw']);
-          if (empty($dates)) {
-            continue;
+          // Store the current date field name for later.
+          $entity->fullcalendar_date_field = $field['field_name'];
+
+          // Create a string of valid HTML class names and add them to the entity.
+          $classes = module_invoke_all('fullcalendar_classes', $entity);
+          drupal_alter('fullcalendar_classes', $classes, $entity);
+          $classes = array_map('drupal_html_class', $classes);
+          $entity->class = implode(' ', array_unique($classes));
+
+          // Default URL.
+          $uri = entity_uri($entity->entity_type, $entity);
+          $entity->url = isset($uri['path']) ? $uri['path'] : '';
+          // Fetch custom URL if needed.
+          if (!empty($options['url'])) {
+            $field_name = $options['url_field'];
+            if (!empty($fields[$field_name])) {
+              $entity->url = ltrim($fields[$field_name], '/');
+            }
           }
 
-          list($start, $end, $all_day) = $dates;
-
-          // Add a class if the event was in the past or is in the future, based
-          // on the end time. We can't do this in hook_fullcalendar_classes()
-          // because the date hasn't been processed yet.
-          if (($all_day && strtotime($start) < strtotime('today')) || (!$all_day && strtotime($end) < REQUEST_TIME)) {
-            $time_class = 'fc-event-past';
-          }
-          elseif (strtotime($start) > REQUEST_TIME) {
-            $time_class = 'fc-event-future';
+          // Fetch custom title if needed.
+          if (!isset($entity->title)) {
+            $entity->title = '';
           }
-          else {
-            $time_class = 'fc-event-now';
+          if (!empty($options['title'])) {
+            $field_name = $options['title_field'];
+            if (!empty($fields[$field_name])) {
+              $entity->title = $fields[$field_name];
+            }
           }
 
-          $event[] = array(
-            '#theme' => 'link',
-            '#text' => $item['rendered']['#markup'],
-            '#path' => $entity->url,
-            '#options' => array(
-              'attributes' => array(
-                'data-all-day' => $all_day,
-                'data-start' => $start,
-                'data-end' => $end,
-                'data-editable' => $entity->editable,
-                'data-field' => $field['field_name'],
-                'data-index' => $index,
-                'data-eid' => $entity->eid,
-                'data-entity-type' => $entity->entity_type,
-                'data-cn' => $entity->class . ' ' . $time_class,
-                'title' => strip_tags(htmlspecialchars_decode($entity->title, ENT_QUOTES)),
-                'class' => array('fullcalendar-event-details'),
+          $entities[$alias] = $entity;
+        }
+
+        $entity = $entities[$field['field_alias']];
+        // Filter fields without value.
+        if (!empty($field['value'])) {
+          $instance = field_info_instance($entity->entity_type, $field['field_name'], $bundle);
+          foreach ($field['value'] as $index => $item) {
+            $dates = _fullcalendar_process_dates($instance, $entity, $field['field_info'], $item['raw']);
+            if (empty($dates)) {
+              continue;
+            }
+
+            list($start, $end, $all_day) = $dates;
+
+            // Add a class if the event was in the past or is in the future, based
+            // on the end time. We can't do this in hook_fullcalendar_classes()
+            // because the date hasn't been processed yet.
+            if (($all_day && strtotime($start) < strtotime('today')) || (!$all_day && strtotime($end) < REQUEST_TIME)) {
+              $time_class = 'fc-event-past';
+            }
+            elseif (strtotime($start) > REQUEST_TIME) {
+              $time_class = 'fc-event-future';
+            }
+            else {
+              $time_class = 'fc-event-now';
+            }
+
+            $event[] = array(
+              '#theme' => 'link',
+              '#text' => $item['rendered']['#markup'],
+              '#path' => $entity->url,
+              '#options' => array(
+                'attributes' => array(
+                  'data-all-day' => $all_day,
+                  'data-start' => $start,
+                  'data-end' => $end,
+                  'data-editable' => $entity->editable,
+                  'data-field' => $field['field_name'],
+                  'data-index' => $index,
+                  'data-eid' => $entity->eid,
+                  'data-entity-type' => $entity->entity_type,
+                  'data-cn' => $entity->class . ' ' . $time_class,
+                  'title' => strip_tags(htmlspecialchars_decode($entity->title, ENT_QUOTES)),
+                  'class' => array('fullcalendar-event-details'),
+                ),
+                'html' => TRUE,
               ),
-              'html' => TRUE,
-            ),
-          );
+            );
+          }
         }
       }
     }
