<?php
//$Id: date.theme,v 1.6.4.51 2009/06/09 17:20:31 karens Exp $
/**
 * @file
 * Theme functions.
 */
/**
 * @addtogroup themeable
 * @{
 *
 * Formatter themes
 */
/**
 * Theme from/to date combination in the view.
 *
 * Useful values:
 * 
 *   $node->date_id 
 *     If set, this will show only an individual date on a field with 
 *     multiple dates. The value should be a string that contains
 *     the following values, separated with colons:
 *     - module name of the module adding the item
 *     - node nid
 *     - field name
 *     - delta value of the field to be displayed
 *     - other information the module's custom theme might need
 * 
 *     Used by the calendar module and available for other uses.
 *     example: 'date:217:field_date:3:test'
 * 
 *   $node->date_repeat_show
 *     If true, tells the theme to show all the computed values
 *     of a repeating date. If not true or not set, only the
 *     start date and the repeat rule will be displayed.
 * 
 *   $dates['format'] - the format string used on these dates
 *   $dates['value']['local']['object'] - the local date object for the From date
 *   $dates['value2']['local']['object'] - the local date object for the To date
 *   $dates['value']['local']['datetime'] - the datetime value of the From date database (GMT) value
 *   $dates['value2']['local']['datetime'] - the datetime value of the To date database (GMT) value
 *   $dates['value']['formatted'] = formatted From date, i.e. 'February 15, 2007 2:00 pm';
 *   $dates['value']['formatted_date'] - only the date part of the formatted From date
 *   $dates['value']['formatted_time'] - only the time part of the formatted From date
 *   $dates['value2']['formatted'] = formatted To date, i.e. 'February 15, 2007 6:00 pm';
 *   $dates['value2']['formatted_date'] - only the date part of the formatted To date
 *   $dates['value2']['formatted_time'] - only the time part of the formatted To date
 */
function theme_date_display_combination($element) {
  static $repeating_ids = array();
  
  $node = $element['#node'];
  $field_name = $element['#field_name'];
  $context = !empty($node->content) && !empty($node->content[$field_name]) ? $node->content[$field_name]['#context'] : 'full';
  $type_name = $element['#type_name'];
  $fields = content_fields();
  $field = $fields[$field_name];
  $item = $element['#item'];
    
  // Get the formatter settings, either the default settings for this node
  // type or the View settings stored in $node->date_info.
  $options = date_formatter_get_settings($field_name, $type_name, $context);
  if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
    $options = $node->date_info->formatter_settings;
  }
    
  // If date_id is set for this field and the delta doesn't match, don't display it.
  if (!empty($node->date_id)) {
    foreach ((array) $node->date_id as $key => $id) {
      list($module, $nid, $field_name, $delta, $other) = explode(':', $id);
      if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
        return;
      }
    }
  }

  $output = '';
    
  // Check the formatter settings to see if the repeat rule should be
  // displayed. Show it only with the first multiple value date.
  if (!in_array($node->nid, $repeating_ids) && module_exists('date_repeat') 
  && !empty($item['rrule']) && $options['repeat']['show_repeat_rule'] == 'show') {
    require_once('./'. drupal_get_path('module', 'date') .'/date_repeat.inc');
    $output .= theme('date_repeat_display', $field, $item, $node);
    $repeating_ids[] = $node->nid;
  }
   
  // If this is a full node or a pseudo node created by grouping
  // multiple values, see exactly which values are supposed to be visible.
  if (isset($node->$field_name)) {
    $node = date_prepare_node($node, $field, $type_name, $context, $options);
    // Did the current value get removed by formatter settings?
    if (empty($node->{$field_name}[$item['#delta']])) {
      return $output;
    }
    // Adjust the $element values to match the changes.
    $element['#node'] = $node;
  }
    
  // Call the right theme for this formatter.
  // Update the element with values that might have been altered by 
  // date_prepare_node() and figure out which values to display.
  $dates = date_formatter_process($element);
  switch ($options['fromto']['fromto']) {
    case 'value':
      $date1 = $dates['value']['formatted'];
      $date2 = $date1;
      break;    
    case 'value2':
      $date2 = $dates['value2']['formatted'];
      $date1 = $date2;
      break;
    default:
      $date1 = $dates['value']['formatted'];
      $date2 = $dates['value2']['formatted'];  
      break;
  }
  
  // Pull the timezone, if any, out of the formatted result and tack it
  // back on at the end, if it is in the current formatted date.
  $timezone = $dates['value']['formatted_timezone'];
  if ($timezone) {
    $timezone = ' ' . $timezone;
  }
  $date1 = str_replace($timezone, '', $date1);
  $date2 = str_replace($timezone, '', $date2);
   
  // No date values, display nothing.
  if (empty($date1) && empty($date2)) {
    $output .= '';
  }
  // From and To dates match or there is no To date, display a complete single date.
  elseif ($date1 == $date2 || empty($date2)) {
    $output .= theme('date_display_single', $date1, $timezone);
  }
  // Same day, different times, don't repeat the date but show both From and To times.
  elseif (date_has_time($field['granularity']) && $dates['value']['formatted_date'] == $dates['value2']['formatted_date']) {
    // Replace the original time with the from/to time in the formatted start date.  
    // Make sure that parentheses or brackets wrapping the time will be retained in the
    // final result.
    $time1 = preg_replace('`^([\(\[])`', '', $dates['value']['formatted_time']);
    $time1 = preg_replace('([\)\]]$)', '', $time1);
    $time2 = preg_replace('`^([\(\[])`', '', $dates['value2']['formatted_time']);
    $time2 = preg_replace('([\)\]]$)', '', $time2);
    $time = theme('date_display_range', $time1, $time2);
    $replaced = str_replace($time1, $time, $date1);
    $output .= theme('date_display_single', $replaced, $timezone);
  }
  // Different days, display both in their entirety.
  else {
    $output .= theme('date_display_range', $date1, $date2, $timezone);
  }
  
  return $output;
}

function theme_date_display_single($date, $timezone = NULL) {
  return '<span class="date-display-single">'. $date . $timezone .'</span>';
}

function theme_date_display_range($date1, $date2, $timezone = NULL) {
  return '<span class="date-display-start">'. $date1 .'</span>'.
      '<span class="date-display-separator"> - </span>' .
      '<span class="date-display-end">'. $date2 . $timezone. '</span>';
}

/**
 * Theme a format interval for a date element
 *
 *  @param $field = the field settings
 *  @param $node = node information, this is not always available and not
 *     always the full node, it depends on what value was provided to the formatter.
 *     Only the nid is always guaranteed to be available.
 *  @param $dates - an array of date information, see explanation for date_field_object for details.
 *  @return a formatted display
 *
 */
function theme_date_format_interval($element) {
  $node = $element['#node'];
  $field_name = $element['#field_name'];
  $context = !empty($node->content) ? $node->content[$field_name]['#context'] : 'full';
  $type_name = $element['#type_name'];
  $fields = content_fields();
  $field = $fields[$field_name];
  $item = $element['#item'];
    
  // Get the formatter settings, either the default settings for this node
  // type or the View settings stored in $node->date_info.
  $options = date_formatter_get_settings($field_name, $type_name, $context);
  if (!empty($node->date_info) && !empty($node->date_info->formatter_settings)) {
    $options = $node->date_info->formatter_settings;
  }
  
  // If date_id is set for this field and the delta doesn't match, don't display it.
  if (!empty($node->date_id)) {
    foreach ((array) $node->date_id as $key => $id) {
      list($module, $nid, $field_name, $delta, $other) = explode(':', $id);
      if ($field_name == $field['field_name'] && isset($item['#delta']) && $delta != $item['#delta']) {
        return;
      }
    }
  }
   
  // If this is not coming from Views, it is the full node.
  // If we aren't retrieving a specific value, adjust the node values 
  // to match the formatter settings, removing values we should not see.
  if (!empty($node->content) && empty($node->date_id)) {
    $node = date_prepare_node($node, $field, $type_name, $context, $options);
    
    // Did the current value get removed by formatter settings?
    if (empty($node->{$field_name}[$item['#delta']])) {
      return;
    }
    // Adjust the $element values to match the changes.
    $element['#node'] = $node;
  }
  $dates = date_formatter_process($element);
  return theme('date_time_ago', $dates['value']['local']['object'], $dates['value2']['local']['object']);
}

/**
 * Theme the human-readable description for a Date Repeat rule.
 *
 * TODO -
 * add in ways to store the description in the date so it isn't regenerated
 * over and over and find a way to allow description to be shown or hidden.
 */
function theme_date_repeat_display($field, $item, $node = NULL) {
  $output = '';
  if (!empty($item['rrule'])) {
    $output = date_repeat_rrule_description($item['rrule']);
    $output = '<div>'. $output .'</div>';
  }
  return $output;
}

/**
 * Adjust from/to date format to account for 'all day'.
 *
 * @param array $field, the field definition for this date field.
 * @param string $which, which value to return, 'date1' or 'date2'.
 * @param object $date1, a date/time object for the 'from' date.
 * @param object $date2, a date/time object for the 'to' date.
 * @param string $format
 * @param object $node, the node this date comes from (may be incomplete, always contains nid).
 * @param object $view, the view this node comes from, if applicable.
 * @return formatted date.
 */
function theme_date_all_day($field, $which, $date1, $date2, $format, $node, $view = NULL) {
  if (empty($date1) || !is_object($date1) || $format == 'format_interval') {
    return;
  }
  if (empty($date2)) {
    $date2 = $date1;
  }
  $granularity = array_pop(date_format_order($format));
  if (empty($field['granularity'])) {
    $field['granularity'] = date_format_order($format);
  }
  $increment = $field['widget']['increment'];
  $max_seconds = array_pop(date_seconds('s', TRUE, $increment));
  $max_minutes = array_pop(date_minutes('i', TRUE, $increment));
  
  switch ($granularity) {
    case 'second':
      $min_comp = date_format($date1, 'H:i:s') == '00:00:00';
      $max_comp = date_format($date2, 'H:i:s') == '00:00:00' || date_format($date2, 'H:i:s') == '23:'. $max_minutes .':'. $max_seconds;
      break;
    case 'minute':
      $min_comp = date_format($date1, 'H:i') == '00:00';
      $max_comp = date_format($date2, 'H:i:s') == '00:00:00' || date_format($date2, 'H:i') == '23:'. $max_minutes;
      break;
    case 'hour':
      $min_comp = date_format($date1, 'H') == '00';
      $max_comp = date_format($date2, 'H:i:s') == '00:00:00' || date_format($date2, 'H') == '23';
      break;
    default:
      $min_comp = TRUE;
      $max_comp = FALSE;
  }
  
  // Time runs from midnight to the maximum time -- call it 'All day'.
  if (date_has_time($field['granularity']) && $min_comp && $max_comp) {
    $format = date_limit_format($format, array('year', 'month', 'day'));
    return trim(date_format_date($$which, 'custom', $format) .' '. theme('date_all_day_label'));
  }
  // There is no time, use neither 'All day' nor time.
  elseif (!date_has_time($field['granularity'])) {
    $format = date_limit_format($format, array('year', 'month', 'day'));
    return date_format_date($$which, 'custom', $format);
  }
  // Normal formatting.
  else {
    return date_format_date($$which, 'custom', $format);
  }
}

/**
 * Theme the way an 'all day' label will look.
 */
function theme_date_all_day_label() {
  return '('. date_t('All day', 'datetime') .')';
}
/** @} End of addtogroup themeable */