<?php
/**
 * @file
 * Defines a formatter for text fields that displays an icon which triggers
 * a tooltip.
 */

/**
 * Implements hook_field_formatter_info().
 */
function tooltipformatter_field_formatter_info() {
  return array(
    'tooltipformatter_formatter' => array(
      'label' => t('Tooltip'),
      'field types' => array('text', 'text_long'),
      'settings'  => array(
        'icon' => 'misc/message-SIZE-info.png',
        'icon_size' => '24',
        'event' => 'hover',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function tooltipformatter_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  
  $options = array();
  $custom_icons = _tooltipformatter_get_custom_icons();
  $default_icons = _tooltipformatter_get_default_icons();
  if (count($custom_icons)) {
    $options[t('custom')] = $custom_icons;
    $options[t('default')] = $default_icons;
  }
  else {
    $options = $default_icons;
  }
  
  $element = array();
  $element['icon'] = array(
    '#type'          => 'select',
    '#title'         => t('Icon'),
    '#description'   => t('Choose the icon that triggers the tooltip.'),
    '#default_value' => $settings['icon'],
    '#options'       => $options,
  );
  $element['icon']['#attributes']['class'][] = 'tooltip-icon-select';
  
  $element['icon_size'] = array(
    '#type'          => 'select',
    '#title'         => t('Icon size'),
    '#description'   => t('The default icons come in two sizes. Select the icon size.'),
    '#default_value' => $settings['icon_size'],
    '#options'       => array(
      '16' => t('16 px'),
      '24' => t('24 px'),
    ),
  );
  foreach (_tooltipformatter_get_default_icons() as $key => $name) {
    $element['icon_size']['#states']['visible'][] = array(
      '.tooltip-icon-select' => array('value' => $key),
    );
  }

  $element['event'] = array(
    '#type'          => 'select',
    '#title'         => t('Event'),
    '#description'   => t('Select the event that will trigger the tooltip.'),
    '#default_value' => $settings['event'],
    '#options'       => array(
      'hover' => t('Hover'),
      'click' => t('Click'),
    ),
  );

  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function tooltipformatter_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];
  $icon_path = _tooltipformatter_get_icon_path($settings);

  drupal_add_css(drupal_get_path('module', 'tooltipformatter') . '/css/tooltipformatter.admin.css');

  $summary = t('Display the !icon icon and show the tooltip on !event.', array(
    '!icon'  => theme('image', array('path' => $icon_path, 'attributes' => array('class' => 'tooltipformatter-summary-icon'))),
    '!event' => $settings['event'],
  ));
  return $summary;
}

/**
 * Implements hook_field_formatter_view().
 */
function tooltipformatter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];
  $icon = $settings['icon'];
  $event = $settings['event'];

  $icon_path = _tooltipformatter_get_icon_path($settings);

  foreach ($items as $delta => $item) {
    $element[$delta] = array(
      '#theme'      => 'image',
      '#path'       => $icon_path,
      '#title'      => $item['safe_value'],
      '#alt'        => $icon,
      '#attributes' => array(
        'class' => 'tooltipformatter',
      ),
    );
  }

  $options['tooltipformatter'] = array(
    'cssSelect' => 'img.tooltipformatter',
    'trigger'   => array($event, $event),
  );
  beautytips_add_beautytips($options);

  return $element;
}

/**
 * Builds a list of icons in the theme folder and the files folder.
 */
function _tooltipformatter_get_custom_icons() {
  // Detect icons in the tooltipformatter-icons directory in the default theme.
  $theme_path = drupal_get_path('theme', variable_get('theme_default', 'bartik')) .'/tooltipformatter-icons';
  $theme_files = file_scan_directory($theme_path, '/\.(png|jpg|gif)$/');
  // Detect icons in the tooltipformatter-icons directory in the files folder.
  $upload_path = variable_get('file_public_path', conf_path() .'/files') .'/tooltipformatter-icons';
  $uploaded_files = file_scan_directory($upload_path, '/\.(png|jpg|gif)$/');

  $icons = array();
  foreach(array_merge($theme_files, $uploaded_files) as $icon) {
    $icons[$icon->uri] = $icon->name;
  }
  return $icons;
}

/**
 * Returns a fixed list of selected icons included in Drupal.
 */
function _tooltipformatter_get_default_icons() {
  return array(
    'misc/message-SIZE-info.png'    => t('Info'),
    'misc/message-SIZE-help.png'    => t('Help'),
    'misc/message-SIZE-warning.png' => t('Warning'),
    'misc/message-SIZE-ok.png'      => t('OK'),
    'misc/message-SIZE-error.png'   => t('Error'),
  );
}

/**
 * Builds the icon file path based on formatter settings.
 */
function _tooltipformatter_get_icon_path($settings) {
  // If the icon is one of the 5 default icons, merge in the chosen size.
  if (array_key_exists($settings['icon'], _tooltipformatter_get_default_icons())) {
    return str_replace('SIZE', $settings['icon_size'], $settings['icon']);
  }
  return $settings['icon'];
}
