diff --git a/date_admin.inc b/date_admin.inc
index a3a8cdb..624597e 100644
--- a/date_admin.inc
+++ b/date_admin.inc
@@ -390,8 +390,9 @@ function _date_field_widget_settings_form($field, $instance) {
   }
   if (module_exists('date_repeat') && date_is_repeat_field($field, $instance)) {
     $form['repeat_collapsed'] = array(
+      '#access' => FALSE,
       '#type' => 'radios',
-      '#default_value' => $settings['repeat_collapsed'],
+      '#default_value' => 1,
       '#options' => array(0 => t('Expanded'), 1 => t('Collapsed')),
       '#title' => t('Repeat display'),
       '#description' => t("Should the repeat options form start out expanded or collapsed? Set to 'Collapsed' to make those options less obtrusive."),
diff --git a/date_api/date.css b/date_api/date.css
index d7743b7..a001fea 100644
--- a/date_api/date.css
+++ b/date_api/date.css
@@ -104,6 +104,51 @@ span.date-display-end {
   float: none;
 }
 
+.date-repeat-radios {
+  margin-bottom: 1em;
+}
+
+.date-repeat-radios input[type=radio] {
+  float: left;
+  margin: 0.75em 0.75em 0 0;
+}
+
+.date-repeat-radios .form-wrapper {
+  float: left;
+}
+
+.date-repeat-radios .form-type-checkboxes .form-type-checkbox {
+  width: 15%;
+  float: left;
+  margin: 0;
+}
+
+.date-repeat-radios .date-repeat-radios-item {
+  margin-bottom: 1em;
+}
+
+.weekly .form-type-checkboxes .form-type-checkbox {
+  float: left;
+  margin-right: 10px;
+}
+
+.range-of-repeat > div {
+  margin-top: 0.5em;
+}
+
+.range-of-repeat .count input[type=text] {
+  margin: 0 0.5em;
+}
+
+.range-of-repeat .until .form-wrapper {
+  margin: 0 0.5em;
+}
+
+.range-of-repeat .until .form-type-date-select,
+.range-of-repeat .until .form-type-date-text {
+  border: none;
+}
+
 .date-views-filter-wrapper {
   min-width: 250px;
 }
diff --git a/date_elements.inc b/date_elements.inc
index 08a8b8f..a5f4215 100644
--- a/date_elements.inc
+++ b/date_elements.inc
@@ -91,6 +91,19 @@ function date_field_widget_form(&$form, &$form_state, $field, $instance, $langco
     '#element_validate' => array('date_combo_validate', 'date_widget_validate'),
   );
 
+  $element['#title'] = $instance['label'];
+
+  if (!empty($field['settings']['repeat'])) {
+    $element['show_repeat_settings'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Repeat'),
+      '#weight' => $instance['widget']['weight'] + .3,
+      '#prefix' => '<div class="date-clear">',
+      '#suffix' => '</div>',
+      '#default_value' => isset($items[$delta]['rrule']) && !empty($items[$delta]['rrule']) ? 1 : 0,
+    );
+  }
+
   if ($field['settings']['tz_handling'] == 'date') {
     $element['timezone'] = array(
       '#type' => 'date_timezone',
diff --git a/date_repeat.inc b/date_repeat.inc
index 0a9dd5c..1042d7c 100644
--- a/date_repeat.inc
+++ b/date_repeat.inc
@@ -99,10 +99,17 @@ function _date_repeat_widget_validate($element, &$form_state) {
   // Require the UNTIL date for now.
   // The RRULE has already been created by this point, so go back
   // to the posted values to see if this was filled out.
-  $error_field = implode('][', $element['#parents']) . '][rrule][UNTIL][datetime][date';
-  if (!empty($item['rrule']) && empty($rrule_values['UNTIL']['datetime'])) {
-    form_set_error($error_field, t('The UNTIL value is required for repeating dates.'));
+  $error_field_base = implode('][', $element['#parents']);
+  $error_field_until =  $error_field_base . '][rrule][until_child][datetime][date';
+  if (!empty($item['rrule']) && $rrule_values['range_of_repeat'] === 'UNTIL' && empty($rrule_values['UNTIL']['datetime'])) {
+    form_set_error($error_field_until, t('The UNTIL value is required for repeating dates.'));
   }
+
+  $error_field_count = $error_field_base . '][rrule][count_child';
+  if (!empty($item['rrule']) && $rrule_values['range_of_repeat'] === 'COUNT' && empty($rrule_values['COUNT'])) {
+    form_set_error($error_field_count, t('The COUNT value is required for repeating dates.'));
+  }
+
   if (form_get_errors()) {
     return;
   }
diff --git a/date_repeat/date_repeat.module b/date_repeat/date_repeat.module
index 4af01f0..ae22634 100644
--- a/date_repeat/date_repeat.module
+++ b/date_repeat/date_repeat.module
@@ -23,6 +23,12 @@ function date_repeat_element_info() {
     '#element_validate' => array('date_repeat_rrule_validate'),
     '#theme_wrappers' => array('date_repeat_rrule'),
   );
+  $type['date_repeat_form_element_radios'] = array(
+    '#input' => TRUE,
+    '#process' => array('date_repeat_form_element_radios_process'),
+    '#theme_wrappers' => array('radios'),
+    '#pre_render' => array('form_pre_render_conditional_form_element'),
+  );
   if (module_exists('ctools')) {
     $type['date_repeat_rrule']['#pre_render'] = array('ctools_dependent_pre_render');
   }
@@ -42,21 +48,19 @@ function date_repeat_theme() {
  */
 function FREQ_options() {
   return array(
-    'NONE' => t('-- Period'),
-    'DAILY' => t('Days', array(), array('context' => 'datetime_plural')),
-    'WEEKLY' => t('Weeks', array(), array('context' => 'datetime_plural')),
-    'MONTHLY' => t('Months', array(), array('context' => 'datetime_plural')),
-    'YEARLY' => t('Years', array(), array('context' => 'datetime_plural')),
+    'DAILY' => t('Daily', array(), array('context' => 'datetime_singular')),
+    'WEEKLY' => t('Weekly', array(), array('context' => 'datetime_singular')),
+    'MONTHLY' => t('Monthly', array(), array('context' => 'datetime_singular')),
+    'YEARLY' => t('Yearly', array(), array('context' => 'datetime_singular')),
   );
 }
 
 function INTERVAL_options() {
   $options = array(
-    0 => t('-- Frequency'),
-    1 => t('Every', array(), array('context' => 'date_order')),
+    1 => 1,
   );
   for ($i = 2; $i < 367; $i++) {
-    $options[$i] = t('Every @number', array('@number' => $i));
+    $options[$i] = $i;
   }
   return $options;
 }
@@ -80,6 +84,40 @@ function date_repeat_dow_day_options($translated = TRUE) {
   );
 }
 
+/**
+ * Helper function for FREQ options.
+ *
+ * Translated and untranslated arrays of the iCal abbreviated day of week names.
+ */
+function date_repeat_dow_day_options_abbr($translated = TRUE, $length = 3) {
+  $return = array();
+  switch ($length) {
+    case 1:
+      $context = 'day_abbr1';
+      break;
+    case 2:
+      $context = 'day_abbr2';
+      break;
+    default:
+      $context = '';
+      break;
+  }
+  foreach (date_repeat_dow_day_untranslated() as $key => $day) {
+    $return[$key] = $translated ? t(substr($day, 0, $length), array(), array('context' => $context)) : substr($day, 0, $length);
+  }
+  return $return;
+}
+
+function date_repeat_dow_day_untranslated() {
+  static $date_repeat_weekdays;
+  if (empty($date_repeat_weekdays)) {
+    $date_repeat_weekdays = array('SU' => 'Sunday', 'MO' => 'Monday', 'TU' => 'Tuesday',
+      'WE' => 'Wednesday', 'TH' => 'Thursday', 'FR' => 'Friday',
+      'SA' => 'Saturday');
+  }
+  return $date_repeat_weekdays;
+}
+
 function date_repeat_dow_day_options_ordered($week_start) {
   $unordered = date_repeat_dow_day_options(FALSE);
   if (variable_get('date_first_day', 0) > 0) {
@@ -298,3 +336,78 @@ function date_repeat_rrule_process($element, &$form_state, $form) {
   module_load_include('inc', 'date_repeat', 'date_repeat_form');
   return _date_repeat_rrule_process($element, $form_state, $form);
 }
+
+/**
+ * Process function for 'date_repeat_form_element_radios'.
+ */
+function date_repeat_form_element_radios_process($element) {
+  $childrenkeys = element_children($element);
+
+  if (count($element['#options']) &&
+      count($element['#options']) == count($childrenkeys)) {
+    $weight = 0;
+    $children = array();
+    $classes = isset($element['#div_classes']) ?
+      $element['#div_classes'] : array();
+    foreach ($childrenkeys as $childkey) {
+      $children[$childkey] = $element[$childkey];
+      unset($element[$childkey]);
+    }
+    foreach ($element['#options'] as $key => $choice) {
+      $currentchildkey = array_shift($childrenkeys);
+      $weight += 0.001;
+      $class = array_shift($classes);
+      $element += array($key => array());
+      $parents_for_id = array_merge($element['#parents'], array($key));
+      $element[$key] += array(
+        '#prefix' => '<div' . ($class ? " class=\"{$class}\"" : '') . '>',
+        '#type' => 'radio',
+        '#title' => $choice,
+        '#title_display' => 'invisible',
+        '#return_value' => $key,
+        '#default_value' => isset($element['#default_value']) ?
+          $element['#default_value'] : NULL,
+        '#attributes' => $element['#attributes'],
+        '#parents' => $element['#parents'],
+        '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
+        '#ajax' => isset($element['#ajax']) ? $element['ajax'] : NULL,
+        '#weight' => $weight,
+        '#theme_wrappers' => array(),
+        '#suffix' => ' ',
+      );
+
+      $child = $children[$currentchildkey];
+
+      $weight += 0.001;
+
+      $child['#weight'] = $weight;
+      $child['#title_display'] = 'invisible';
+      $child['#suffix'] = (!empty($child['#suffix']) ? $child['#suffix'] : '') .
+        '</div>';
+      $child['#parents'] = $element['#parents'];
+      array_pop($child['#parents']);
+      array_push($child['#parents'], $currentchildkey);
+
+      $element_prototype = element_info($child['#type']);
+      $old_wrappers = array();
+      if (isset($child['#theme_wrappers'])) {
+        $old_wrappers += $child['#theme_wrappers'];
+      }
+      if (isset($element_prototype['#theme_wrappers'])) {
+        $old_wrappers += $element_prototype['#theme_wrappers'];
+      }
+
+      $child['#theme_wrappers'] = array();
+
+      foreach ($old_wrappers as $wrapper) {
+        if ($wrapper != 'form_element') {
+          $child['#theme_wrappers'][] = $wrapper;
+        }
+      }
+
+      $element[$currentchildkey] = $child;
+    }
+  }
+
+  return $element;
+}
diff --git a/date_repeat/date_repeat_form.inc b/date_repeat/date_repeat_form.inc
index 32734b5..903c01e 100644
--- a/date_repeat/date_repeat_form.inc
+++ b/date_repeat/date_repeat_form.inc
@@ -73,50 +73,401 @@ function _date_repeat_rrule_process($element, &$form_state, $form) {
     $UNTIL = date_format($until_date, DATE_FORMAT_DATETIME);
   }
 
-  $element['INTERVAL'] = array(
+  $COUNT = '';
+  if (!empty($merged_values['COUNT'])) {
+    $COUNT = $merged_values['COUNT'];
+  }
+
+  $element['FREQ'] = array(
     '#type' => 'select',
-    //'#title' => t('Interval'),
-    '#default_value' => (!empty($rrule['INTERVAL']) ? $rrule['INTERVAL'] : 0),
-    '#options' => INTERVAL_options(),
+    '#title' => t('Repeats'),
+    '#default_value' => !empty($rrule['FREQ']) ? $rrule['FREQ'] : 'WEEKLY',
+    '#options' => FREQ_options(),
     '#prefix' => '<div class="date-repeat-input">',
     '#suffix' => '</div>',
   );
 
-  $element['FREQ'] = array(
+  $element['daily'] = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#prefix' => '<div class="date-clear daily">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'DAILY'),
+      ),
+    ),
+  );
+
+  $element['weekly'] = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#prefix' => '<div class="date-clear weekly">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'WEEKLY'),
+      ),
+    ),
+  );
+
+  $element['monthly'] = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#prefix' => '<div class="date-clear monthly">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'MONTHLY'),
+      ),
+    ),
+  );
+
+  $element['yearly'] = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#prefix' => '<div class="date-clear yearly">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'YEARLY'),
+      ),
+    ),
+  );
+
+  $DAILY_INTERVAL = array(
+    '#type' => 'textfield',
+    '#title' => t('Repeats'),
+    '#title_display' => 'invisible',
+    '#default_value' => (!empty($rrule['INTERVAL']) ? $rrule['INTERVAL'] : 1),
+    '#element_validate' => array('element_validate_integer'),
+    '#options' => INTERVAL_options(),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => t('days') . '</div>',
+    '#field_prefix' => t('every'),
+    '#field_suffix' => t('days')
+  );
+
+  $element['weekly']['INTERVAL'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Repeats'),
+    '#default_value' => (!empty($rrule['INTERVAL']) ? $rrule['INTERVAL'] : 1),
+    '#element_validate' => array('element_validate_integer'),
+    '#options' => INTERVAL_options(),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#field_prefix' => t('every'),
+    '#field_suffix' => t('weeks')
+  );
+
+  $element['monthly']['INTERVAL'] = array(
+    '#access' => FALSE,
+    '#type' => 'textfield',
+    '#title' => t('Repeats'),
+    '#default_value' => (!empty($rrule['INTERVAL']) ? $rrule['INTERVAL'] : 1),
+    '#element_validate' => array('element_validate_integer'),
+    '#options' => INTERVAL_options(),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#field_prefix' => t('every'),
+    '#field_suffix' => t('months')
+  );
+
+  $element['yearly']['INTERVAL'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Repeats'),
+    '#default_value' => (!empty($rrule['INTERVAL']) ? $rrule['INTERVAL'] : 1),
+    '#element_validate' => array('element_validate_integer'),
+    '#options' => INTERVAL_options(),
+    '#size' => 3,
+    '#maxlength' => 3,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#field_prefix' => t('every'),
+    '#field_suffix' => t('years')
+  );
+
+  $element['weekly']['BYDAY'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Repeat on'),
+    '#default_value' => !empty($rrule['BYDAY']) && $rrule['FREQ'] === 'WEEKLY' ? $rrule['BYDAY'] : array(),
+    '#options' => date_repeat_dow_day_options_abbr(TRUE, 1),
+    '#attributes' => array('class' => array('container-inline byday')),
+    '#multiple' => TRUE,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+  );
+
+  $DAILY_radios_default = 'INTERVAL';
+  if (isset($rrule['FREQ']) && $rrule['FREQ'] === 'DAILY' && !empty($rrule['BYDAY'])) {
+    switch (count($rrule['BYDAY'])) {
+      case 2:
+        $DAILY_radios_default = 'every_tu_th';
+        break;
+      case 3:
+        $DAILY_radios_default = 'every_mo_we_fr';
+        break;
+      case 5:
+        $DAILY_radios_default = 'every_weekday';
+        break;
+    }
+  }
+
+  $DAILY_every_weekday = array(
+    '#type' => 'item',
+    '#markup' => '<div>' . t('Every weekday') . '</div>',
+  );
+
+  $DAILY_mo_we_fr = array(
+    '#type' => 'item',
+    '#markup' => '<div>' . t('Every Mon, Wed, Fri') . '</div>',
+  );
+
+  $DAILY_tu_th = array(
+    '#type' => 'item',
+    '#markup' => '<div>' . t('Every Tue, Thu') . '</div>',
+  );
+
+  $element['daily']['byday_radios'] = array(
+    '#type' => 'date_repeat_form_element_radios',
+    '#tree' => TRUE,
+    '#title' => t('Repeats every'),
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'DAILY'),
+      ),
+    ),
+    '#default_value' => $DAILY_radios_default,
+    '#options' => array(
+      'INTERVAL' => t('interval'),
+      'every_weekday' => t('every weekday'),
+      'every_mo_we_fr' => t('monday wednesday friday'),
+      'every_tu_th' => t('tuesday thursday'),
+    ),
+    'INTERVAL_child' => $DAILY_INTERVAL,
+    'every_weekday_child' => $DAILY_every_weekday,
+    'mo_we_fr_child' => $DAILY_mo_we_fr,
+    'tu_th_child' => $DAILY_tu_th,
+    '#div_classes' => array(
+      'container-inline interval',
+      'container-inline weekday',
+      'container-inline mo-we-fr',
+      'container-inline tu-th',
+    ),
+  );
+
+  $MONTHLY_day_month_default = 'BYMONTHDAY_BYMONTH';
+  if (isset($rrule['FREQ']) && $rrule['FREQ'] === 'MONTHLY' && !empty($rrule['BYDAY'])) {
+    $MONTHLY_day_month_default = 'BYDAY_BYMONTH';
+  }
+
+  $MONTHLY_on_day_BYMONTHDAY_of_BYMONTH = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+  );
+
+  $MONTHLY_on_day_BYMONTHDAY_of_BYMONTH['BYMONTHDAY'] = array(
     '#type' => 'select',
-    //'#title' => t('Frequency'),
-    '#default_value' => !empty($rrule['FREQ']) ? $rrule['FREQ'] : 'NONE',
-    '#options' => FREQ_options(),
-    '#prefix' => '<div class="date-repeat-input">',
+    '#title' => t('On day'),
+    '#default_value' => !empty($rrule['BYMONTHDAY']) && $rrule['FREQ'] === 'MONTHLY' ? $rrule['BYMONTHDAY'] : '',
+    '#options' => drupal_map_assoc(range(1, 31)) + drupal_map_assoc(range(-1, -31)),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-clear bymonthday">',
+    '#suffix' => '</div>',
+  );
+
+  $MONTHLY_on_day_BYMONTHDAY_of_BYMONTH['BYMONTH'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('of'),
+    '#default_value' => !empty($rrule['BYMONTH']) && $rrule['FREQ'] === 'MONTHLY' && $MONTHLY_day_month_default === 'BYMONTHDAY_BYMONTH' ? $rrule['BYMONTH'] : array(),
+    '#options' => date_month_names_abbr(TRUE),
+    '#attributes' => array('class' => array('container-inline')),
+    '#multiple' => TRUE,
+    '#prefix' => '<div class="date-clear bymonth">',
+    '#suffix' => '</div>',
+  );
+
+  $MONTHLY_on_the_BYDAY_of_BYMONTH = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+  );
+
+  $MONTHLY_BYDAY_COUNT = '';
+  $MONTHLY_BYDAY_DAY = '';
+  if (isset($rrule['BYDAY']) && !empty($rrule['BYDAY']) && $rrule['FREQ'] === 'MONTHLY') {
+    $MONTHLY_BYDAY_COUNT = substr($rrule['BYDAY'][0], 0, -2);
+    $MONTHLY_BYDAY_DAY = substr($rrule['BYDAY'][0], -2);;
+  }
+
+  $MONTHLY_on_the_BYDAY_of_BYMONTH['BYDAY_COUNT'] = array(
+    '#type' => 'select',
+    '#title' => t('On the'),
+    '#default_value' => !empty($MONTHLY_BYDAY_COUNT) ? $MONTHLY_BYDAY_COUNT : '',
+    '#options' => date_order_translated(),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-repeat-input byday-count">',
     '#suffix' => '</div>',
   );
-  $element['UNTIL'] = array(
+
+  $MONTHLY_on_the_BYDAY_of_BYMONTH['BYDAY_DAY'] = array(
+    '#type' => 'select',
+    '#title' => '&nbsp;', // for vertically aligning this select with BYDAY_COUNT (would be much uglier via CSS)
+    '#default_value' => !empty($MONTHLY_BYDAY_DAY) ? $MONTHLY_BYDAY_DAY : '',
+    '#options' => date_repeat_dow_day_options(TRUE),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-repeat-input byday-day">',
+    '#suffix' => '</div>',
+  );
+
+  $MONTHLY_on_the_BYDAY_of_BYMONTH['BYMONTH'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('of'),
+    '#default_value' => !empty($rrule['BYMONTH']) && $rrule['FREQ'] === 'MONTHLY' && $MONTHLY_day_month_default === 'BYDAY_BYMONTH' ? $rrule['BYMONTH'] : array(),
+    '#options' => date_month_names_abbr(TRUE),
+    '#attributes' => array('class' => array('container-inline')),
+    '#multiple' => TRUE,
+    '#prefix' => '<div class="date-clear bymonth">',
+    '#suffix' => '</div>',
+  );
+
+  $element['monthly']['day_month'] = array(
+    '#type' => 'date_repeat_form_element_radios',
     '#tree' => TRUE,
     '#prefix' => '<div class="date-clear">',
     '#suffix' => '</div>',
-    'datetime' => array(
-      '#type' => $element['#date_repeat_widget'],
-      '#title' => t('Until'),
-      '#description' => t('Date to stop repeating this item.'),
-      '#default_value' => $UNTIL,
-      '#date_format' => !empty($element['#date_format']) ? date_limit_format($element['#date_format'], array('year', 'month', 'day')) : 'Y-m-d',
-      '#date_timezone' => $timezone,
-      '#date_text_parts'  => !empty($element['#date_text_parts']) ? $element['#date_text_parts'] : array(),
-      '#date_year_range'  => !empty($element['#date_year_range']) ? $element['#date_year_range'] : '-3:+3',
-      '#date_label_position' => !empty($element['#date_label_position']) ? $element['#date_label_position'] : 'within',
-      '#date_flexible' => 0,
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'MONTHLY'),
       ),
-    'tz' => array('#type' => 'hidden', '#value' => $element['#date_timezone']),
-    'all_day' => array('#type' => 'hidden', '#value' => 1),
-    'granularity' => array('#type' => 'hidden', '#value' => serialize(array('year', 'month', 'day'))),
-    );
+    ),
+    '#attributes' => array('class' => array('date-repeat-radios clearfix')),
+    '#default_value' => $MONTHLY_day_month_default,
+    '#options' => array(
+      'BYMONTHDAY_BYMONTH' => t('On day ... of ...'),
+      'BYDAY_BYMONTH' => t('On the ... of ...'),
+    ),
+    'BYMONTHDAY_BYMONTH_child' => $MONTHLY_on_day_BYMONTHDAY_of_BYMONTH,
+    'BYDAY_BYMONTH_child' => $MONTHLY_on_the_BYDAY_of_BYMONTH,
+    '#div_classes' => array(
+      'date-repeat-radios-item date-clear clearfix bymonthday-bymonth',
+      'date-repeat-radios-item date-clear clearfix byday-bymonth',
+    ),
+  );
+
+  $YEARLY_day_month_default = 'BYMONTHDAY_BYMONTH';
+  if (isset($rrule['FREQ']) && $rrule['FREQ'] === 'YEARLY' && !empty($rrule['BYDAY'])) {
+    $YEARLY_day_month_default = 'BYDAY_BYMONTH';
+  }
+
+  $YEARLY_on_day_BYMONTHDAY_of_BYMONTH = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+  );
+
+  $YEARLY_on_day_BYMONTHDAY_of_BYMONTH['BYMONTHDAY'] = array(
+    '#type' => 'select',
+    '#title' => t('On day'),
+    '#default_value' => !empty($rrule['BYMONTHDAY']) && $rrule['FREQ'] === 'YEARLY' ? $rrule['BYMONTHDAY'] : '',
+    '#options' => drupal_map_assoc(range(1, 31)) + drupal_map_assoc(range(-1, -31)),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-clear bymonthday">',
+    '#suffix' => '</div>',
+  );
+
+  $YEARLY_on_day_BYMONTHDAY_of_BYMONTH['BYMONTH'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('of'),
+    '#default_value' => !empty($rrule['BYMONTH']) && $rrule['FREQ'] === 'YEARLY' && $YEARLY_day_month_default === 'BYMONTHDAY_BYMONTH' ? $rrule['BYMONTH'] : array(),
+    '#options' => date_month_names_abbr(TRUE),
+    '#attributes' => array('class' => array('container-inline')),
+    '#multiple' => TRUE,
+    '#prefix' => '<div class="date-clear bymonth">',
+    '#suffix' => '</div>',
+  );
+
+  $YEARLY_on_the_BYDAY_of_BYMONTH = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+  );
+
+  $YEARLY_BYDAY_COUNT = '';
+  $YEARLY_BYDAY_DAY = '';
+  if (isset($rrule['BYDAY']) && !empty($rrule['BYDAY']) && $rrule['FREQ'] === 'YEARLY') {
+    $YEARLY_BYDAY_COUNT = substr($rrule['BYDAY'][0], 0, -2);
+    $YEARLY_BYDAY_DAY = substr($rrule['BYDAY'][0], -2);;
+  }
+
+  $YEARLY_on_the_BYDAY_of_BYMONTH['BYDAY_COUNT'] = array(
+    '#type' => 'select',
+    '#title' => t('On the'),
+    '#default_value' => !empty($YEARLY_BYDAY_COUNT) ? $YEARLY_BYDAY_COUNT : '',
+    '#options' => date_order_translated(),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-repeat-input byday-count">',
+    '#suffix' => '</div>',
+  );
+
+  $YEARLY_on_the_BYDAY_of_BYMONTH['BYDAY_DAY'] = array(
+    '#type' => 'select',
+    '#title' => '&nbsp;', // for vertically aligning this select with BYDAY_COUNT (would be much uglier via CSS)
+    '#default_value' => !empty($YEARLY_BYDAY_DAY) ? $YEARLY_BYDAY_DAY : '',
+    '#options' => date_repeat_dow_day_options(TRUE),
+    '#multiple' => FALSE,
+    '#prefix' => '<div class="date-repeat-input byday-day">',
+    '#suffix' => '</div>',
+  );
+
+  $YEARLY_on_the_BYDAY_of_BYMONTH['BYMONTH'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('of'),
+    '#default_value' => !empty($rrule['BYMONTH']) && $rrule['FREQ'] === 'YEARLY' && $YEARLY_day_month_default === 'BYDAY_BYMONTH' ? $rrule['BYMONTH'] : array(),
+    '#options' => date_month_names_abbr(TRUE),
+    '#attributes' => array('class' => array('container-inline')),
+    '#multiple' => TRUE,
+    '#prefix' => '<div class="date-clear bymonth">',
+    '#suffix' => '</div>',
+  );
+
+  $element['yearly']['day_month'] = array(
+    '#type' => 'date_repeat_form_element_radios',
+    '#tree' => TRUE,
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'YEARLY'),
+      ),
+    ),
+    '#attributes' => array('class' => array('date-repeat-radios clearfix')),
+    '#default_value' => $YEARLY_day_month_default,
+    '#options' => array(
+      'BYMONTHDAY_BYMONTH' => t('On day ... of ...'),
+      'BYDAY_BYMONTH' => t('On the ... of ...'),
+    ),
+    'BYMONTHDAY_BYMONTH_child' => $YEARLY_on_day_BYMONTHDAY_of_BYMONTH,
+    'BYDAY_BYMONTH_child' => $YEARLY_on_the_BYDAY_of_BYMONTH,
+    '#div_classes' => array(
+      'date-repeat-radios-item date-clear clearfix bymonthday-bymonth',
+      'date-repeat-radios-item date-clear clearfix byday-bymonth',
+    ),
+  );
 
   $collapsed = TRUE;
   if (!empty($merged_values['BYDAY']) || !empty($merged_values['BYMONTH'])) {
     $collapsed = FALSE;
   }
+
   // start the advanced fieldset
   $element['advanced'] = array(
+    '#access' => FALSE,
     '#type' => 'fieldset',
     '#title' => t('Advanced'),
     '#collapsible' => TRUE,
@@ -160,6 +511,76 @@ function _date_repeat_rrule_process($element, &$form_state, $form) {
     '#suffix' => '</div>',
   );
 
+  $count_form_element = array(
+    '#type' => 'textfield',
+    '#title' => t('Count'),
+    '#default_value' => $COUNT,
+    '#element_validate' => array('element_validate_integer'),
+    '#prefix' => t('After'),
+    '#suffix' => t('occurences'),
+    '#size' => 10,
+    '#maxlength' => 10,
+  );
+
+  $until_form_element = array(
+    '#type' => 'container',
+    '#tree' => TRUE,
+    '#prefix' => t('On'),
+    'datetime' => array(
+      '#type' => $element['#date_repeat_widget'],
+      '#title' => t('Until'),
+      '#title_display' => 'invisible',
+      '#default_value' => $UNTIL,
+      '#date_format' => !empty($element['#date_format']) ? date_limit_format($element['#date_format'], array('year', 'month', 'day')) : 'Y-m-d',
+      '#date_timezone' => $timezone,
+      '#date_text_parts'  => !empty($element['#date_text_parts']) ? $element['#date_text_parts'] : array(),
+      '#date_year_range'  => !empty($element['#date_year_range']) ? $element['#date_year_range'] : '-3:+3',
+      '#date_label_position' => !empty($element['#date_label_position']) ? $element['#date_label_position'] : 'within',
+      '#date_flexible' => 0,
+    ),
+    'tz' => array('#type' => 'hidden', '#value' => $element['#date_timezone']),
+    'all_day' => array('#type' => 'hidden', '#value' => 1),
+    'granularity' => array('#type' => 'hidden', '#value' => serialize(array('year', 'month', 'day'))),
+  );
+
+  $range_of_repeat_default = 'NEVER';
+  if (!empty($COUNT)) {
+    $range_of_repeat_default = 'COUNT';
+  }
+  elseif (!empty($UNTIL)) {
+    $range_of_repeat_default = 'UNTIL';
+  }
+  $element['range_of_repeat'] = array(
+    '#type' => 'date_repeat_form_element_radios',
+    '#tree' => TRUE,
+    '#title' => t('Range of repeat'),
+    '#prefix' => '<div class="date-clear">',
+    '#suffix' => '</div>',
+    '#states' => array(
+      'invisible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'NONE'),
+      ),
+    ),
+    '#attributes' => array('class' => array('range-of-repeat')),
+    '#default_value' =>  $range_of_repeat_default,
+    '#options' => array(
+      'NEVER' => t('Never'),
+      'COUNT' => t('Count'),
+      'UNTIL' => t('Until'),
+    ),
+    'never_child' => array(
+      '#type' => 'item',
+      '#markup' => "<div>" . t('Never') . "</div>",
+    ),
+    'count_child' => $count_form_element,
+    'until_child' => $until_form_element,
+    '#div_classes' => array(
+      'container-inline never',
+      'container-inline count',
+      'container-inline until',
+    ),
+  );
+
   $parents = $element['#array_parents'];
   $instance = implode('-', $parents);
 
@@ -174,15 +595,27 @@ function _date_repeat_rrule_process($element, &$form_state, $form) {
     $collapsed = FALSE;
   }
 
+  $element['show_exceptions'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Exclude dates'),
+    '#states' => array(
+      'invisible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'NONE'),
+      ),
+    ),
+    '#default_value' => empty($form_state['num_exceptions'][$instance]) ? 0 : 1,
+  );
+
   $element['exceptions'] = array(
-    '#type' => 'fieldset',
-    '#collapsible' => TRUE,
-    '#collapsed' => $collapsed,
-    '#title' => t('Except'),
-    '#description' => t('Dates to omit from the list of repeating dates.'),
+    '#type' => 'container',
     '#prefix' => '<div id="date-repeat-exceptions-' . $instance . '" class="date-repeat">',
     '#suffix' => '</div>',
-    );
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[show_exceptions]\"]" => array('checked' => TRUE),
+      ),
+    ),
+  );
   for ($i = 0; $i < max($form_state['num_exceptions'][$instance], 1) ; $i++) {
     $EXCEPT = '';
     if (!empty($exceptions[$i]['datetime'])) {
@@ -219,15 +652,29 @@ function _date_repeat_rrule_process($element, &$form_state, $form) {
   else {
     $collapsed = FALSE;
   }
+
+  $element['show_additions'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Include dates'),
+    '#states' => array(
+      'invisible' => array(
+        ":input[name=\"{$element['#name']}[FREQ]\"]" => array('value' => 'NONE'),
+      ),
+    ),
+    '#default_value' => empty($form_state['num_additions'][$instance]) ? 0 : 1,
+  );
+
   $element['additions'] = array(
-    '#type' => 'fieldset',
-    '#collapsible' => TRUE,
-    '#collapsed' => $collapsed,
-    '#title' => t('Additional'),
+    '#type' => 'container',
     '#description' => t('Dates to add to the list of repeating dates.'),
     '#prefix' => '<div id="date-repeat-additions-' . $instance . '" class="date-repeat">',
     '#suffix' => '</div>',
-    );
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$element['#name']}[show_additions]\"]" => array('checked' => TRUE),
+      ),
+    ),
+  );
   for ($i = 0; $i < max($form_state['num_additions'][$instance], 1) ; $i++) {
     $RDATE = '';
     if (!empty($additions[$i]['datetime'])) {
@@ -316,15 +763,118 @@ function date_repeat_merge($form_values, $element) {
   if (empty($form_values) || !is_array($form_values)) {
     return $form_values;
   }
-  if (array_key_exists('advanced', $form_values) || array_key_exists('exceptions', $form_values) || array_key_exists('additions', $form_values)) {
-    if (!array_key_exists('advanced', $form_values)) $form_values['advanced'] = array();
+  if (array_key_exists('exceptions', $form_values) || array_key_exists('additions', $form_values)) {
     if (!array_key_exists('exceptions', $form_values)) $form_values['exceptions'] = array();
     if (!array_key_exists('additions', $form_values)) $form_values['additions'] = array();
-    $form_values = array_merge($form_values, (array) $form_values['advanced'], (array) $form_values['exceptions'], (array) $form_values['additions']);
-    unset($form_values['advanced']);
+    $form_values = array_merge($form_values, (array) $form_values['exceptions'], (array) $form_values['additions']);
     unset($form_values['exceptions']);
     unset($form_values['additions']);
   }
+
+  if (array_key_exists('FREQ', $form_values)) {
+    switch ($form_values['FREQ']) {
+      case 'DAILY':
+        if (array_key_exists('daily', $form_values)) {
+          switch ($form_values['daily']['byday_radios']) {
+            case 'INTERVAL':
+              $form_values['INTERVAL'] = $form_values['daily']['INTERVAL_child'];
+              break;
+            case 'every_weekday':
+              $form_values['BYDAY'] = array('MO', 'TU', 'WE', 'TH', 'FR');
+              break;
+            case 'every_mo_we_fr':
+              $form_values['BYDAY'] = array('MO', 'WE', 'FR');
+              break;
+            case 'every_tu_th':
+              $form_values['BYDAY'] = array('TU', 'TH');
+              break;
+          }
+        }
+        break;
+      case 'WEEKLY':
+        if (array_key_exists('weekly', $form_values)) {
+          $form_values = array_merge($form_values, (array) $form_values['weekly']);
+          if (array_key_exists('BYDAY', $form_values)) {
+            $form_values['BYDAY'] = filter_checkbox_values($form_values['BYDAY']);
+          }
+        }
+        break;
+      case 'MONTHLY':
+        if (array_key_exists('monthly', $form_values)) {
+          switch ($form_values['monthly']['day_month']) {
+            case 'BYMONTHDAY_BYMONTH':
+              $form_values['monthly'] = array_merge($form_values['monthly'], (array) $form_values['monthly']['BYMONTHDAY_BYMONTH_child']);
+              break;
+            case 'BYDAY_BYMONTH':
+              $form_values['monthly']['BYDAY_BYMONTH_child']['BYDAY'] = $form_values['monthly']['BYDAY_BYMONTH_child']['BYDAY_COUNT'] . $form_values['monthly']['BYDAY_BYMONTH_child']['BYDAY_DAY'];
+              $form_values['monthly'] = array_merge($form_values['monthly'], (array) $form_values['monthly']['BYDAY_BYMONTH_child']);
+              break;
+          }
+          unset($form_values['monthly']['BYDAY_BYMONTH_child']);
+          unset($form_values['monthly']['BYMONTHDAY_BYMONTH_child']);
+          $form_values = array_merge($form_values, (array) $form_values['monthly']);
+          if (array_key_exists('BYMONTH', $form_values)) {
+            $form_values['BYMONTH'] = filter_checkbox_values($form_values['BYMONTH']);
+          }
+          if (array_key_exists('BYMONTHDAY', $form_values) && !is_array($form_values['BYMONTHDAY'])) {
+            $form_values['BYMONTHDAY'] = (array) $form_values['BYMONTHDAY'];
+          }
+          if (array_key_exists('BYDAY', $form_values) && !is_array($form_values['BYDAY'])) {
+            $form_values['BYDAY'] = (array) $form_values['BYDAY'];
+          }
+        }
+        break;
+      case 'YEARLY':
+        if (array_key_exists('yearly', $form_values)) {
+          switch ($form_values['yearly']['day_month']) {
+            case 'BYMONTHDAY_BYMONTH':
+              $form_values['yearly'] = array_merge($form_values['yearly'], (array) $form_values['yearly']['BYMONTHDAY_BYMONTH_child']);
+              break;
+            case 'BYDAY_BYMONTH':
+              $form_values['yearly']['BYDAY_BYMONTH_child']['BYDAY'] = $form_values['yearly']['BYDAY_BYMONTH_child']['BYDAY_COUNT'] . $form_values['yearly']['BYDAY_BYMONTH_child']['BYDAY_DAY'];
+              $form_values['yearly'] = array_merge($form_values['yearly'], (array) $form_values['yearly']['BYDAY_BYMONTH_child']);
+              break;
+          }
+          unset($form_values['yearly']['BYDAY_BYMONTH_child']);
+          unset($form_values['yearly']['BYMONTHDAY_BYMONTH_child']);
+          $form_values = array_merge($form_values, (array) $form_values['yearly']);
+          if (array_key_exists('BYMONTH', $form_values)) {
+            $form_values['BYMONTH'] = filter_checkbox_values($form_values['BYMONTH']);
+          }
+          if (array_key_exists('BYMONTHDAY', $form_values) && !is_array($form_values['BYMONTHDAY'])) {
+            $form_values['BYMONTHDAY'] = (array) $form_values['BYMONTHDAY'];
+          }
+          if (array_key_exists('BYDAY', $form_values) && !is_array($form_values['BYDAY'])) {
+            $form_values['BYDAY'] = (array) $form_values['BYDAY'];
+          }
+        }
+        break;
+      default:
+        break;
+    }
+  }
+
+  unset($form_values['daily']);
+  unset($form_values['weekly']);
+  unset($form_values['monthly']);
+  unset($form_values['yearly']);
+
+  if (array_key_exists('range_of_repeat', $form_values)) {
+    switch ($form_values['range_of_repeat']) {
+      case 'COUNT':
+        $form_values['COUNT'] = $form_values['count_child'];
+        break;
+      case 'UNTIL':
+        $form_values['UNTIL'] = $form_values['until_child'];
+        break;
+      case 'NEVER':
+        break;
+    }
+  }
+
+  unset($form_values['count_child']);
+  unset($form_values['until_child']);
+
   if (array_key_exists('BYDAY', $form_values) && is_array($form_values['BYDAY'])) unset($form_values['BYDAY']['']);
   if (array_key_exists('BYMONTH', $form_values) && is_array($form_values['BYMONTH'])) unset($form_values['BYMONTH']['']);
   if (array_key_exists('BYMONTHDAY', $form_values) && is_array($form_values['BYMONTHDAY'])) unset($form_values['BYMONTHDAY']['']);
@@ -336,6 +886,9 @@ function date_repeat_merge($form_values, $element) {
     $date = $function($until_element, $form_values['UNTIL']['datetime']);
     $form_values['UNTIL']['datetime'] = is_object($date) ? $date->format(DATE_FORMAT_DATETIME) : '';
   }
+  if (array_key_exists('show_exceptions', $form_values) && $form_values['show_exceptions'] === 0) {
+    unset($form_values['EXDATE']);
+  }
   if (array_key_exists('EXDATE', $form_values) && is_array($form_values['EXDATE'])) {
     $function = $element['#date_repeat_widget'] . '_input_date';
     $exdate_element = $element;
@@ -347,6 +900,10 @@ function date_repeat_merge($form_values, $element) {
       }
     }
   }
+
+  if (array_key_exists('show_additions', $form_values) && $form_values['show_additions'] === 0) {
+    unset($form_values['RDATE']);
+  }
   if (array_key_exists('RDATE', $form_values) && is_array($form_values['RDATE'])) {
     $function = $element['#date_repeat_widget'] .'_input_date';
     $rdate_element = $element;
@@ -369,6 +926,14 @@ function date_repeat_rrule_validate($element, &$form_state) {
     return;
   }
 
+  $parents = $element['#parents'];
+  array_pop($parents);
+  $field_values = drupal_array_get_nested_value($form_state['values'], $parents);
+  if ($field_values['show_repeat_settings'] === 0 || $field_values['rrule']['FREQ'] === 'NONE') {
+    form_set_value($element, NULL, $form_state);
+    return;
+  }
+
   module_load_include('inc', 'date_api', 'date_api_ical');
 
   $item = drupal_array_get_nested_value($form_state['values'], $element['#parents']);
@@ -415,13 +980,28 @@ function theme_date_repeat_current_additions($rows = array()) {
 function theme_date_repeat_rrule($vars) {
   $element = $vars['element'];
   $class = $element['#date_repeat_collapsed'] ? array('date-no-float', 'collapsible', 'collapsed') : array('date-no-float', 'collapsible');
+  $id = drupal_html_id('repeat-settings-fieldset');
+  $parents = $element['#parents'];
+  $selector = "{$parents[0]}[{$parents[1]}][{$parents[2]}][show_repeat_settings]";
   $fieldset = array(
-    '#title' => t('Repeat'),
-    '#value' => '',
-    '#description' => theme('advanced_help_topic', 'date_api', 'date-repeat-form') . t('Choose a frequency and period to repeat this date. If nothing is selected, the date will not repeat.'),
+    '#type' => 'item',
+    '#title' => t('Repeat settings'),
+    '#title_display' => 'invisible',
     '#attributes' => array('class' => $class),
-    '#children' => $element['#children'],
+    '#markup' => $element['#children'],
+    '#states' => array(
+      'visible' => array(
+        ":input[name=\"{$selector}\"]" => array('checked' => TRUE),
+      ),
+    ),
+    '#id' => $id,
   );
 
-  return theme('fieldset', array('element' => $fieldset));
+  return drupal_render($fieldset);
+}
+
+function filter_checkbox_values($values) {
+  return array_filter($values, function ($i) {
+    return $i !== 0;
+  });
 }
