<?php

/**
 * @file
 * Implement a slideshow formatter for fields.
 */

/**
 * Implements hook_field_formatter_info().
 */
function field_slideshow_field_formatter_info() {
  $formatters = array(
    'slideshow' => array(
      'label'       => t('Slideshow'),
      'field types' => array('image', 'imagefield_crop', 'media', 'field_collection'),
      'settings'    => array(
        'slideshow_image_style'               => '',
        'slideshow_link'                      => '',
        'slideshow_colorbox_image_style'      => '',
        'slideshow_colorbox_slideshow'        => '',
        'slideshow_colorbox_slideshow_speed'  => '4000',
        'slideshow_colorbox_transition'       => 'elastic',
        'slideshow_colorbox_speed'            => '350',
        'slideshow_caption'                   => '',
        'slideshow_caption_link'              => '',
        'slideshow_fx'                        => 'fade',
        'slideshow_speed'                     => '1000',
        'slideshow_timeout'                   => '4000',
        'slideshow_order'                     => '',
        'slideshow_controls'                  => 0,
        'slideshow_controls_pause'            => 0,
        'slideshow_controls_position'         => 'after',
        'slideshow_pause'                     => 0,
        'slideshow_start_on_hover'            => 0,
        'slideshow_pager'                     => '',
        'slideshow_pager_position'            => 'after',
        'slideshow_pager_image_style'         => '',
        'slideshow_carousel_image_style'      => '',
        'slideshow_carousel_visible'          => '3',
        'slideshow_carousel_scroll'           => '1',
        'slideshow_carousel_speed'            => '500',
        'slideshow_carousel_vertical'         => 0,
        'slideshow_carousel_circular'         => 0,
        'slideshow_carousel_follow'           => 0,
        'slideshow_field_collection_image'    => '',
        'slideshow_carousel_skin'             => '',
      ),
    ),
  );
  return $formatters;
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function field_slideshow_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];

  if ($field['type'] == 'field_collection') {
    $element['slideshow_field_collection_image'] = array(
      '#title'          => t('Image field'),
      '#type'           => 'select',
      '#default_value'  => $settings['slideshow_field_collection_image'],
      '#empty_option'   => t('None'),
      '#options'        => _field_slideshow_get_fields(array('image', 'imagefield_crop'), $field['type'], $field['field_name']),
      '#required'       => TRUE,
    );
  }

  $element['slideshow_image_style'] = array(
    '#title'          => t('Image style'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_image_style'],
    '#empty_option'   => t('None (original image)'),
    '#options'        => image_style_options(FALSE),
  );

  $links = array(
    'content' => t('Content'),
    'file'    => t('File'),
  );
  if ($field['type'] == 'media' || $field['type'] == 'field_collection')
    $links += _field_slideshow_get_fields(array('link_field', 'node_reference', 'entityreference'), $field['type'], $field['field_name']);
  $element['slideshow_link'] = array(
    '#title'          => t('Link image to'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_link'],
    '#empty_option'   => t('Nothing'),
    '#options'        => $links,
  );
  if (module_exists('colorbox')) {
    $element['slideshow_link']['#options']['colorbox'] = 'Colorbox';
    $element['slideshow_colorbox_image_style'] = array(
      '#title'          => t('Colorbox image style'),
      '#type'           => 'select',
      '#default_value'  => $settings['slideshow_colorbox_image_style'],
      '#empty_option'   => t('None (original image)'),
      '#options'        => image_style_options(FALSE),
      '#states' => array(
        'visible' => array(
          ':input[name$="[settings_edit_form][settings][slideshow_link]"]' => array('value' => 'colorbox'),
        ),
      ),
    );
    $colorbox_slideshow = array(
      'automatic' => t('Automatic'),
      'manual'    => t('Manual'),
    );
    $element['slideshow_colorbox_slideshow'] = array(
      '#title'          => t('Colorbox slideshow'),
      '#type'           => 'select',
      '#default_value'  => $settings['slideshow_colorbox_slideshow'],
      '#empty_option'   => t('No slideshow'),
      '#options'        => $colorbox_slideshow,
      '#states' => array(
        'visible' => array(
          ':input[name$="[settings_edit_form][settings][slideshow_link]"]' => array('value' => 'colorbox'),
        ),
      ),
    );
    $element['slideshow_colorbox_slideshow_speed'] = array(
      '#title'          => t('Colorbox slideshow speed'),
      '#type'           => 'textfield',
      '#size'           => 5,
      '#default_value'  => $settings['slideshow_colorbox_slideshow_speed'],
      '#description'    => t('Time between transitions (ms).'),
      '#states' => array(
        'invisible' => array(
          ':input[name$="[settings_edit_form][settings][slideshow_colorbox_slideshow]"]' => array('value' => ''),
        ),
      ),
    );
    $colorbox_transitions = array(
      'none'    => t('None'),
      'elastic' => t('Elastic'),
      'fade'    => t('Fade'),
    );
    $element['slideshow_colorbox_transition'] = array(
      '#title'          => t('Colorbox transition'),
      '#type'           => 'select',
      '#default_value'  => $settings['slideshow_colorbox_transition'],
      '#options'        => $colorbox_transitions,
      '#states' => array(
        'visible' => array(
          ':input[name$="[settings_edit_form][settings][slideshow_link]"]' => array('value' => 'colorbox'),
        ),
      ),
    );
    $element['slideshow_colorbox_speed'] = array(
      '#title'          => t('Colorbox transition speed'),
      '#type'           => 'textfield',
      '#size'           => 5,
      '#default_value'  => $settings['slideshow_colorbox_speed'],
      '#description'    => t('Duration of transition (ms).'),
      '#states' => array(
        'visible' => array(
          ':input[name$="[settings_edit_form][settings][slideshow_link]"]' => array('value' => 'colorbox'),
        ),
      ),
    );
  }

  if ($field['type'] == 'media' || $field['type'] == 'field_collection')
    $captions = _field_slideshow_get_fields(array('text'), $field['type'], $field['field_name']);
  else $captions = array(
    'title'   => t('Title text'),
    'alt'     => t('Alt text'),
  );
  $element['slideshow_caption'] = array(
    '#title'          => t('Caption'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_caption'],
    '#empty_option'   => t('Nothing'),
    '#options'        => $captions,
  );

  $element['slideshow_caption_link'] = array(
    '#title'          => t('Caption link'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_caption_link'],
    '#empty_option'   => t('Nothing'),
    '#options'        => $links,
    '#states' => array(
      'invisible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_caption]"]' => array('value' => ''),
      ),
    ),
  );
  if (module_exists('colorbox')) $element['slideshow_caption_link']['#options']['colorbox'] = 'Colorbox';

  $element['slideshow_fx'] = array(
    '#title'          => t('Transition effect'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_fx'],
    '#options'        => array(
      'blindX'      => t('blindX'),
      'blindY'      => t('blindY'),
      'blindZ'      => t('blindZ'),
      'cover'       => t('cover'),
      'curtainX'    => t('curtainX'),
      'curtainY'    => t('curtainY'),
      'fade'        => t('fade'),
      'fadeZoom'    => t('fadeZoom'),
      'growX'       => t('growX'),
      'growY'       => t('growY'),
      'scrollUp'    => t('scrollUp'),
      'scrollDown'  => t('scrollDown'),
      'scrollLeft'  => t('scrollLeft'),
      'scrollRight' => t('scrollRight'),
      'scrollHorz'  => t('scrollHorz'),
      'scrollVert'  => t('scrollVert'),
      'shuffle'     => t('shuffle'),
      'slideX'      => t('slideX'),
      'slideY'      => t('slideY'),
      'toss'        => t('toss'),
      'turnUp'      => t('turnUp'),
      'turnDown'    => t('turnDown'),
      'turnLeft'    => t('turnLeft'),
      'turnRight'   => t('turnRight'),
      'uncover'     => t('uncover'),
      'wipe'        => t('wipe'),
      'zoom'        => t('zoom'),
    ),
  );

  $element['slideshow_speed'] = array(
    '#title'          => t('Transition speed'),
    '#type'           => 'textfield',
    '#size'           => 5,
    '#default_value'  => $settings['slideshow_speed'],
    '#description'    => t('Duration of transition (ms).'),
    '#required'       => TRUE,
  );

  $element['slideshow_timeout'] = array(
    '#title'          => t('Timeout'),
    '#type'           => 'textfield',
    '#size'           => 5,
    '#default_value'  => $settings['slideshow_timeout'],
    '#description'    => t('Time between transitions (ms). Enter 0 to disable automatic transitions (then, enable pager and/or controls).'),
    '#required'       => TRUE,
  );

  $element['slideshow_order'] = array(
    '#title'          => t('Order'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_order'],
    '#empty_option'   => t('Normal'),
    '#options'        => array(
      'reverse' => t('Reverse'),
      'random'  => t('Random'),
    ),
  );

  $element['slideshow_controls'] = array(
    '#title'          => t('Create prev/next controls'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_controls'],
  );

  $element['slideshow_controls_pause'] = array(
    '#title'          => t('Create play/pause button'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_controls_pause'],
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_controls]"]' => array('checked' => TRUE),
      ),
    ),
  );

  $element['slideshow_controls_position'] = array(
    '#title'          => t('Prev/next controls position'),
    '#type'           => 'select',
    '#options'        => array('before' => 'Before', 'after' => 'After'),
    '#default_value'  => $settings['slideshow_controls_position'],
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_controls]"]' => array('checked' => TRUE),
      ),
    ),
  );

  $element['slideshow_pause'] = array(
    '#title'          => t('Pause on hover'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_pause'],
  );

  $element['slideshow_start_on_hover'] = array(
    '#title'          => t('Activate on hover'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_start_on_hover'],
  );

  $element['slideshow_pager'] = array(
    '#title'          => t('Pager'),
    '#type'           => 'select',
    '#options'        => array('number' => 'Slide number', 'image' => 'Image', 'carousel' => 'Carousel'),
    '#empty_option'   => t('None'),
    '#default_value'  => $settings['slideshow_pager'],
  );

  $element['slideshow_pager_position'] = array(
    '#title'          => t('Pager position'),
    '#type'           => 'select',
    '#options'        => array('before' => 'Before', 'after' => 'After'),
    '#default_value'  => $settings['slideshow_pager_position'],
    '#states' => array(
      'invisible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => ''),
      ),
    ),
  );

  $element['slideshow_pager_image_style'] = array(
    '#title'          => t('Pager image style'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_pager_image_style'],
    '#empty_option'   => t('None (original image)'),
    '#options'        => image_style_options(FALSE),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'image'),
      ),
    ),
  );

  $element['slideshow_carousel_image_style'] = array(
    '#title'          => t('Carousel: Image style'),
    '#type'           => 'select',
    '#default_value'  => $settings['slideshow_carousel_image_style'],
    '#empty_option'   => t('None (original image)'),
    '#options'        => image_style_options(FALSE),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_visible'] = array(
    '#title'          => t('Carousel: Number of visible images'),
    '#type'           => 'textfield',
    '#size'           => 2,
    '#default_value'  => $settings['slideshow_carousel_visible'],
    '#description'    => t('The number of images that are visible in the pager. Defaults to 3.'),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_scroll'] = array(
    '#title'          => t('Carousel: Number of images to scroll by'),
    '#type'           => 'textfield',
    '#size'           => 2,
    '#default_value'  => $settings['slideshow_carousel_scroll'],
    '#description'    => t('The number of images scrolled with each click. Defaults to 1.'),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_speed'] = array(
    '#title'          => t('Carousel: Transition speed'),
    '#type'           => 'textfield',
    '#size'           => 5,
    '#default_value'  => $settings['slideshow_carousel_speed'],
    '#description'    => t('Speed of the Carousel scroll. Defaults to 500.'),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $skin_options = array();
  $path = libraries_get_path('jquery.jcarousel') . '/skins';
  $dirnames = scandir($path);
  foreach ($dirnames as $dirname) {
    $dirname = check_plain($dirname);
    if (is_dir($path . '/' . $dirname) && file_exists($path . '/' . $dirname . '/skin.css')) {
      $skin_options[$dirname] = $dirname;
    }
  }
  $element['slideshow_carousel_skin'] = array(
    '#title'         => t('Carousel Skin'),
    '#type'          => 'select',
    '#default_value' => $settings['slideshow_carousel_skin'],
    '#options'       => $skin_options,
    '#empty_option'  => t('None'),
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_follow'] = array(
    '#title'          => t('Follow active slide'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_carousel_follow'],
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_vertical'] = array(
    '#title'          => t('Vertical Carousel'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_carousel_vertical'],
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  $element['slideshow_carousel_circular'] = array(
    '#title'          => t('Circular Carousel'),
    '#type'           => 'checkbox',
    '#default_value'  => $settings['slideshow_carousel_circular'],
    '#states' => array(
      'visible' => array(
        ':input[name$="[settings_edit_form][settings][slideshow_pager]"]' => array('value' => 'carousel'),
      ),
    ),
  );

  return $element;
}

/**
 * Implements hook_form_alter().
 */
function field_slideshow_form_alter(&$form, &$form_state, $form_id) {
  // If Colorbox slideshow is needed, enable required variable
  if ($form_id == 'field_ui_display_overview_form' && !empty($form_state['triggering_element'])) {
    if (!empty($form_state['formatter_settings']) && isset($form_state['triggering_element']['#field_name'])) {
      $field = $form_state['triggering_element']['#field_name'];
      if (isset($form_state['formatter_settings'][$field]['slideshow_colorbox_slideshow']) && $form_state['formatter_settings'][$field]['slideshow_colorbox_slideshow'] != '')
        variable_set('colorbox_load', 1);
    }
  }
}

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

  $summary = array();

  $image_styles = image_style_options(FALSE);
  // Unset possible 'No defined styles' option.
  unset($image_styles['']);
  // Styles could be lost because of enabled/disabled modules that defines
  // their styles in code.
  if (isset($image_styles[$settings['slideshow_image_style']])) {
    $summary[] = t('Image style: @style', array('@style' => $image_styles[$settings['slideshow_image_style']]));
  }
  else $summary[] = t('Original image');

  $link_types = array(
    'content'   => t('content'),
    'file'      => t('file'),
    'colorbox'  => t('Colorbox'),
  );
  if ($field['type'] == 'media' || $field['type'] == 'field_collection')
    $link_types += _field_slideshow_get_fields(array('link_field', 'node_reference'), $field['type'], $field['field_name']);
  // Display this setting only if image is linked.
  if (isset($link_types[$settings['slideshow_link']])) {
    $link_type_message = t('Link to: @link', array('@link' => $link_types[$settings['slideshow_link']]));
    if ($settings['slideshow_link'] == 'colorbox') {
      $link_type_message .= ' (';
      if (isset($image_styles[$settings['slideshow_colorbox_image_style']])) {
        $link_type_message .= t('Image style: @style', array('@style' => $image_styles[$settings['slideshow_colorbox_image_style']]));
      }
      else $link_type_message .=  t('Original image');
      if (isset($settings['slideshow_colorbox_slideshow']) && $settings['slideshow_colorbox_slideshow']) {
        $colorbox_slideshow = array(
          'automatic' => t('Automatic'),
          'manual'    => t('Manual'),
        );
        $link_type_message .= ', with Slideshow (' . $colorbox_slideshow[$settings['slideshow_colorbox_slideshow']] . ' - Speed: ' . $settings['slideshow_colorbox_slideshow_speed'] . ')';
      }
      $link_type_message .= ')';
    }
    $summary[] = $link_type_message;
  }

  if ($field['type'] == 'media' || $field['type'] == 'field_collection')
    $caption_types = _field_slideshow_get_fields(array('text'), $field['type'], $field['field_name']);
  else $caption_types = array(
    'title' => t('Title text'),
    'alt'   => t('Alt text'),
  );
  // Display this setting only if there's a caption.
  if (isset($caption_types[$settings['slideshow_caption']])) {
    $caption_message = t('Caption: @caption', array('@caption' => $caption_types[$settings['slideshow_caption']]));
    if (isset($link_types[$settings['slideshow_caption_link']])) $caption_message .= ' (' . t('Link to: @link', array('@link' => $link_types[$settings['slideshow_caption_link']])) . ')';
    $summary[] = $caption_message;
  }

  $summary[] = t('Transition effect: @effect', array('@effect' => $settings['slideshow_fx']));
  $summary[] = t('Speed: @speed', array('@speed' => $settings['slideshow_speed']));
  $summary[] = t('Timeout: @timeout', array('@timeout' => $settings['slideshow_timeout']));
  $orders = array(
    'reverse' => t('Reverse order'),
    'random'  => t('Random order'),
  );
  if (isset($orders[$settings['slideshow_order']])) {
    $summary[] = $orders[$settings['slideshow_order']];
  }
  $pause_button_text = "";
  if (isset($settings['slideshow_controls_pause']) && $settings['slideshow_controls_pause']) $pause_button_text = " " . t("(with play/pause)");
  if (isset($settings['slideshow_controls']) && $settings['slideshow_controls']) $summary[] = t('Create prev/next controls') . $pause_button_text;
  if (isset($settings['slideshow_pause']) && $settings['slideshow_pause']) $summary[] = t('Pause on hover');
  if (isset($settings['slideshow_start_on_hover']) && $settings['slideshow_start_on_hover']) $summary[] = t('Activate on hover');

  switch ($settings['slideshow_pager']) {
    case 'number':
      $summary[] = t('Pager') . ': ' . t('Slide number');
    break;
    case 'image':
      $pager_image_message = t('Pager') . ': ' . t('Image') . ' (';
      if (isset($image_styles[$settings['slideshow_pager_image_style']])) {
        $pager_image_message .= t('Image style: @style', array('@style' => $image_styles[$settings['slideshow_pager_image_style']]));
      }
      else $pager_image_message .= t('Original image');
      $pager_image_message .= ')';
      $summary[] = $pager_image_message;
    break;
    case 'carousel':
      $pager_image_message = t('Pager') . ': ' . t('Carousel') . ' (';
      if (isset($image_styles[$settings['slideshow_carousel_image_style']])) {
        $pager_image_message .= t('Image style: @style', array('@style' => $image_styles[$settings['slideshow_carousel_image_style']]));
      }
      else $pager_image_message .= t('Original image');
      $pager_image_message .= ', ' . t('Number of visible images: @visible', array('@visible' => $settings['slideshow_carousel_visible']));
      $pager_image_message .= ', ' . t('Number of images to scroll by: @scroll', array('@scroll' => $settings['slideshow_carousel_scroll']));
      $pager_image_message .= ', ' . t('Transition speed: @speed', array('@speed' => $settings['slideshow_carousel_speed']));
      if ($settings['slideshow_carousel_skin']) $pager_image_message .= ', ' . t('Skin: @skin', array('@skin' => $settings['slideshow_carousel_skin']));
      if ($settings['slideshow_carousel_vertical']) $pager_image_message .= ', ' . t('Vertical');
      if ($settings['slideshow_carousel_circular']) $pager_image_message .= ', ' . t('Circular');
      if ($settings['slideshow_carousel_follow']) $pager_image_message .= ', ' . t('Follow slide');
      $pager_image_message .= ')';
      $summary[] = $pager_image_message;
    break;
  }

  return implode('<br />', $summary);
}

/**
 * Implements hook_field_formatter_view().
 */
function field_slideshow_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $settings = $display['settings'];
  static $slideshow_count;
  $slideshow_count = (is_int($slideshow_count)) ? $slideshow_count + 1 : 1;

  // Needed when upgrading to 1.1
  if (!isset($settings['slideshow_order'])) $settings['slideshow_order'] = '';
  if (!isset($settings['slideshow_carousel_image_style'])) $settings['slideshow_carousel_image_style'] = '';
  if (!isset($settings['slideshow_carousel_visible'])) $settings['slideshow_carousel_visible'] = '3';
  if (!isset($settings['slideshow_carousel_scroll'])) $settings['slideshow_carousel_scroll'] = '1';
  if (!isset($settings['slideshow_carousel_speed'])) $settings['slideshow_carousel_speed'] = '500';
  if (!isset($settings['slideshow_carousel_vertical'])) $settings['slideshow_carousel_vertical'] = 0;
  // Needed when upgrading to 1.2
  if (!isset($settings['slideshow_colorbox_transition'])) $settings['slideshow_colorbox_transition'] = 'elastic';
  if (!isset($settings['slideshow_colorbox_speed'])) $settings['slideshow_colorbox_speed'] = '350';
  // Needed when upgrading to 1.3
  if (!isset($settings['slideshow_field_collection_image'])) $settings['slideshow_field_collection_image'] = '';
  if (!isset($settings['slideshow_carousel_circular'])) $settings['slideshow_carousel_circular'] = 0;

  if (!isset($settings['slideshow_carousel_follow'])) $settings['slideshow_carousel_follow'] = 0;
  if (!isset($settings['slideshow_pager_position'])) $settings['slideshow_pager_position'] = 'after';
  if (!isset($settings['slideshow_controls_position'])) $settings['slideshow_controls_position'] = 'after';
  if (!isset($settings['slideshow_start_on_hover'])) $settings['slideshow_start_on_hover'] = 0;

  if (!isset($settings['slideshow_carousel_skin'])) $settings['slideshow_carousel_skin'] = '';

  // Check plugins
  if (module_exists('libraries')) {
    $path = libraries_get_path('jquery.cycle');
    if (!file_exists($path . '/jquery.cycle.all.min.js') && !file_exists($path . '/jquery.cycle.all.js')) {
      drupal_set_message(t('JQuery Cycle must be installed in order to run the slideshow. Please go to !page for instructions.', array('!page' => l(t('Status Report'), 'admin/reports/status'))), 'warning', FALSE);
    }
    if ($settings['slideshow_pager'] == 'carousel') {
      $path = libraries_get_path('jquery.jcarousel');
      if (!file_exists($path . '/lib/jquery.jcarousel.min.js') && !file_exists($path . '/lib/jquery.jcarousel.js')) {
        drupal_set_message(t('JCarousel must be installed in order to run the slideshow. Please go to !page for instructions.', array('!page' => l(t('Status Report'), 'admin/reports/status'))), 'warning', FALSE);
      }
    }
  }
  else {
    drupal_set_message(t('Please install the !module module in order to use Field Slideshow.', array('!module' => l('Libraries API', 'http://drupal.org/project/libraries'))), 'warning', FALSE);
  }

  $element = array();

  // Media field support
  if ($field['type'] == 'media') {
    foreach ($items as $delta => $item) {
      $items[$delta] = (array) $item;
      $items[$delta]['uri'] = $item['file']->uri;
    }
  }
  // Field Collection support
  elseif ($field['type'] == 'field_collection') {
    foreach ($items as $delta => $item) {
      $items[$delta] = (array) field_collection_field_get_entity($item);
      $items[$delta]['uri'] = $items[$delta][$settings['slideshow_field_collection_image']][$langcode][0]['uri'];
      $items[$delta]['title'] = $items[$delta][$settings['slideshow_field_collection_image']][$langcode][0]['title'];
      $items[$delta]['alt'] = $items[$delta][$settings['slideshow_field_collection_image']][$langcode][0]['alt'];
    }
  }

  // Get correct caption
  if ($settings['slideshow_caption'] != '') {
    foreach ($items as $delta => $item) {
      if ($field['type'] == 'media' || $field['type'] == 'field_collection') {
        if ($field['type'] == 'media') $items[$delta]['caption'] = $items[$delta]['file']->$settings['slideshow_caption'];
        elseif ($field['type'] == 'field_collection') $items[$delta]['caption'] = $items[$delta][$settings['slideshow_caption']];
        if (!empty($items[$delta]['caption']) && isset($items[$delta]['caption'][$langcode]))
          $items[$delta]['caption'] = $items[$delta]['caption'][$langcode][0]['value'];
        else $items[$delta]['caption'] = '';
      }
      else $items[$delta]['caption'] = $item[$settings['slideshow_caption']];
    }
  }

  $links = array(
    'slideshow_link'          => 'path',
    'slideshow_caption_link'  => 'caption_path',
  );

  $content_uri = entity_uri($entity_type, $entity);
  // Get the correct field for identifying entity (used to get correct links)
  $entity_info = entity_get_info($entity_type);
  $entity_id_field = $entity_info['entity keys']['id'];

  // Loop through required links (because image and caption can have different links).
  foreach ($links as $setting => $path) {
    // Check if the formatter involves a link.
    $link_type = '';
    switch ($settings[$setting]) {
      case 'content':
        $link_type = 'content';
      break;
      case 'file':
      case 'colorbox':
        $link_type = 'file';
      break;
      default:
        if (($field['type'] == 'media' || $field['type'] == 'field_collection') && drupal_substr($settings[$setting], 0, 6) == 'field_') {
          $infos = field_info_field($settings[$setting]);
          $link_type = $infos['type'];
        }
      break;
    }

    // Generate special links (other than node)
    foreach ($items as $delta => $item) {
      $uri = array();
      switch ($link_type) {
        case 'content':
          $uri = $content_uri;
        break;
        case 'file':
          $uri = array(
            'path'    => file_create_url($item['uri']),
            'options' => array(),
          );
          if ($settings[$setting] == 'colorbox') {
            // check if we need a thumbnaill and change the link
            if ($settings['slideshow_colorbox_image_style'] != '') {
              $uri['path'] = image_style_url($settings['slideshow_colorbox_image_style'], $item['uri']);
            }
            // add correct attributes
            $uri['options']['attributes'] = array(
              'class' => array('colorbox'),
              'rel'   => 'field-slideshow[' . $entity_id_field . '-' . $entity->$entity_id_field . $field["id"] . ']',
            );
            if ($settings['slideshow_caption'] != '') $uri['options']['attributes']['title'] = $item['caption'];
            if (isset($settings['slideshow_colorbox_slideshow']) && $settings['slideshow_colorbox_slideshow'] != '') {
              $uri['options']['attributes']['class'] = array('colorbox-load');
              $uri['path'] .= (strpos($uri['path'], '?') === FALSE) ? '?' : '&';
              $uri['path'] .= 'slideshow=true&slideshowAuto=' . (($settings['slideshow_colorbox_slideshow'] == 'automatic') ? 'true':'false') . '&slideshowSpeed=' . $settings['slideshow_colorbox_slideshow_speed'] . '&speed=' . $settings['slideshow_colorbox_speed'] . '&transition=' . $settings['slideshow_colorbox_transition'];
            }
          }
        break;
        case 'link_field':
          if ($field['type'] == 'media') $pathfield = $item['file']->$settings[$setting];
          elseif ($field['type'] == 'field_collection') $pathfield = $item[$settings[$setting]];
          if (isset($pathfield[$langcode])) {
            $uri = array(
              'path'    => $pathfield[$langcode][0]['url'],
              'options' => array(),
            );
          }
        break;
        case 'node_reference':
          if ($field['type'] == 'media') $pathfield = $item['file']->$settings[$setting];
          elseif ($field['type'] == 'field_collection') $pathfield = $item[$settings[$setting]];
          if (isset($pathfield[$langcode])) {
            $uri = array(
              'path'    => drupal_get_path_alias('node/' . $pathfield[$langcode][0]['nid'], $langcode),
              'options' => array(),
            );
          }
        break;
        case 'entityreference':
          if ($field['type'] == 'media') $pathfield = $item['file']->$settings[$setting];
          elseif ($field['type'] == 'field_collection') $pathfield = $item[$settings[$setting]];
          if (isset($pathfield[$langcode])) {
            $uri = array(
              'path'    => drupal_get_path_alias('node/' . $pathfield[$langcode][0]['target_id'], $langcode),
              'options' => array(),
            );
          }
        break;
      }
      $items[$delta][$path] = !empty($uri) ? $uri : '';
    }
  }

  if (count($items)) {
    $pager = array(
      '#theme'                => 'field_slideshow_pager',
      '#items'                => $items,
      '#pager'                => $settings['slideshow_pager'],
      '#pager_image_style'    => $settings['slideshow_pager_image_style'],
      '#carousel_image_style' => $settings['slideshow_carousel_image_style'],
      '#slideshow_id'         => $slideshow_count,
      '#carousel_skin'        => $settings['slideshow_carousel_skin'],
    );
    $controls = array(
      '#theme'                => 'field_slideshow_controls',
      '#slideshow_id'         => $slideshow_count,
      '#controls_pause'       => $settings['slideshow_controls_pause'],
    );
    $element[] = array(
      '#theme'                => 'field_slideshow',
      '#items'                => $items,
      '#image_style'          => $settings['slideshow_image_style'],
      '#order'                => $settings['slideshow_order'],
      '#controls'             => ($settings['slideshow_controls'] === 1 ? $controls : array()),
      '#controls_position'    => $settings['slideshow_controls_position'],
      '#pager'                => ($settings['slideshow_pager'] !== "" ? $pager : array()),
      '#pager_position'       => $settings['slideshow_pager_position'],
      '#entity'               => $entity,
      '#slideshow_id'         => $slideshow_count,
      '#js_variables'         => array(
        'fx'                   => $settings['slideshow_fx'],
        'speed'                => $settings['slideshow_speed'],
        'timeout'              => $settings['slideshow_timeout'],
        'pause'                => $settings['slideshow_pause'],
        'start_on_hover'       => $settings['slideshow_start_on_hover'],
        'carousel_visible'     => $settings['slideshow_carousel_visible'],
        'carousel_scroll'      => $settings['slideshow_carousel_scroll'],
        'carousel_speed'       => $settings['slideshow_carousel_speed'],
        'carousel_vertical'    => $settings['slideshow_carousel_vertical'],
        'carousel_circular'    => $settings['slideshow_carousel_circular'],
        'carousel_follow'      => $settings['slideshow_carousel_follow'],
        'carousel_skin'        => $settings['slideshow_carousel_skin'],
        // Need to access the following variables in js too
        'pager'                => $settings['slideshow_pager'],
        'controls'             => ($settings['slideshow_controls'] === 1 ? $controls : array()),
      ),
    );
  }

  return $element;
}

/**
 * Implements hook_theme().
 */
function field_slideshow_theme() {
  return array(
    'field_slideshow' => array(
      'variables'     => array(
        'items'                 => NULL,
        'image_style'           => NULL,
        'order'                 => NULL,
        'controls'              => NULL,
        'controls_pause'        => NULL,
        'controls_position'     => NULL,
        'pager'                 => NULL,
        'pager_position'        => NULL,
        'pager_image_style'     => NULL,
        'carousel_image_style'  => NULL,
        'entity'                => NULL,
        'breakpoints'           => NULL,
        'slideshow_id'          => NULL,
        'js_variables'          => array(),
      ),
      'template'     => 'field_slideshow',
    ),
    'field_slideshow_controls' => array(
      'variables'    => array(
        'slideshow_id'          => NULL,
        'controls_pause'        => NULL,
      ),
      'template'     => 'field_slideshow_controls',
    ),
    'field_slideshow_pager' => array(
      'variables'    => array(
        'items'                 => NULL,
        'pager'                 => NULL,
        'pager_image_style'     => NULL,
        'carousel_image_style'  => NULL,
        'slideshow_id'          => NULL,
        'carousel_skin'         => NULL,
      ),
      'template'     => 'field_slideshow_pager',
    ),
  );
}

/**
 * Implements template_preprocess().
 */
function template_preprocess_field_slideshow(&$variables) {
  // Add js variables
  $js_variables = $variables["js_variables"];

  drupal_add_js(array('field_slideshow' => array('field-slideshow-' . $variables['slideshow_id'] => $js_variables)), 'setting');

  // Add the JQuery plugins and the JS code
  if (module_exists('libraries')) {
    $path = libraries_get_path('jquery.cycle');
    if (file_exists($path . '/jquery.cycle.all.min.js')) drupal_add_js($path . '/jquery.cycle.all.min.js');
    elseif (file_exists($path . '/jquery.cycle.all.js')) drupal_add_js($path . '/jquery.cycle.all.js');

    if (isset($js_variables['pager']) && $js_variables['pager'] == 'carousel') {
      $path = libraries_get_path('jquery.jcarousel');
      if (file_exists($path . '/lib/jquery.jcarousel.min.js')) drupal_add_js($path . '/lib/jquery.jcarousel.min.js');
      elseif (file_exists($path . '/lib/jquery.jcarousel.js')) drupal_add_js($path . '/lib/jquery.jcarousel.js');
    }

    $path = libraries_get_path('jquery.imagesloaded');
    if (file_exists($path . '/jquery.imagesloaded.min.js')) drupal_add_js($path . '/jquery.imagesloaded.min.js');
    elseif (file_exists($path . '/jquery.imagesloaded.js')) drupal_add_js($path . '/jquery.imagesloaded.js');

    drupal_add_js(drupal_get_path('module', 'field_slideshow') . '/field_slideshow.js');
  }

  // Add css
  drupal_add_css(drupal_get_path('module', 'field_slideshow') . '/field_slideshow.css');

  // Generate classes
  $variables['classes_array'][] = 'field-slideshow-' . $variables['slideshow_id'];
  $variables['classes_array'][] = 'effect-' . $variables['js_variables']['fx'];
  $variables['classes_array'][] = 'timeout-' . $variables['js_variables']['timeout'];
  if (isset($variables['pager']) && $variables['pager'] != '') $variables['classes_array'][] = 'with-pager';
  if (isset($variables['controls'])) $variables['classes_array'][] = 'with-controls';

  // Change order if needed
  if (isset($variables['order'])) {
    if ($variables['order'] == 'reverse') $variables['items'] = array_reverse($variables['items']);
    elseif ($variables['order'] == 'random') shuffle($variables['items']);
  }

  // Generate slides
  $field_slideshow_zebra = 'odd';
  $variables['slides_max_width'] = 0;
  $variables['slides_max_height'] = 0;
  $slide_theme = (isset($variables['breakpoints']) && isset($variables['breakpoints']['mapping']) && !empty($variables['breakpoints']['mapping'])) ? 'picture' : 'image_style';
  foreach ($variables['items'] as $num => $item) {
    // Generate classes
    $classes = array('field-slideshow-slide', 'field-slideshow-slide-' . (1+$num));
    $field_slideshow_zebra = ($field_slideshow_zebra == 'odd') ? 'even' : 'odd';
    $classes[] = $field_slideshow_zebra;
    if ($num == 0) $classes[] = 'first';
    elseif ($num == count($variables['items']) - 1) $classes[] = 'last';
    $variables['items'][$num]['classes'] = implode(' ', $classes);

    // Generate the image html
    $image = array();
    $image['path'] = $item['uri'];
    $image['attributes']['class'] = array('field-slideshow-image', 'field-slideshow-image-' . (1+$num));
    $image['alt'] = isset($item['alt']) ? $item['alt'] : '';
    if (isset($item['width']) && isset($item['height'])) {
      $image['width'] = $item['width'];
      $image['height'] = $item['height'];
    }
    else {
      $image_dims = getimagesize($image['path']);
      $image['width'] = $image_dims[0];
      $image['height'] = $image_dims[1];
    }
    if (isset($item['title']) && drupal_strlen($item['title']) > 0) $image['title'] = $item['title'];
    if (isset($variables['image_style']) && $variables['image_style'] != '') {
      $image['style_name'] = $variables['image_style'];
      $image['breakpoints'] = $variables['breakpoints'];
      $variables['items'][$num]['image'] = theme($slide_theme, $image);
    }
    else {
      $variables['items'][$num]['image'] = theme('image', $image);
    }

    // Get image sizes and keeps the bigger ones, so height is correctly calculated by Cycle
    $dimensions = array(
      'width' => $image['width'],
      'height' => $image['height'],
    );
    if (isset($variables['image_style']) && $variables['image_style'] != '') {
      if (function_exists('image_style_transform_dimensions')) {
        image_style_transform_dimensions($image['style_name'], $dimensions);
      }
      // manual calculation if Drupal < 7.9 or image_style_transform_dimensions doesn't work
      if (!function_exists('image_style_transform_dimensions') || !is_numeric($dimensions['width'])) {
        $thumbnail_path = image_style_path($variables['image_style'], $image['path']);
        // if thumbnail is not generated, do it, so we can get the dimensions
        if (!file_exists($thumbnail_path)) {
          image_style_create_derivative(image_style_load($variables['image_style']), $image['path'], $thumbnail_path);
        }
        $thumbnail_dims = getimagesize($thumbnail_path);
        $dimensions = array(
          'width' => $thumbnail_dims[0],
          'height' => $thumbnail_dims[1],
        );
      }
    }

  // If the theme function hasn't added width and height attributes to the image, add them
  if (strpos($variables['items'][$num]['image'], 'width=') === FALSE) {
    $variables['items'][$num]['image'] = drupal_substr($variables['items'][$num]['image'], 0, -2) . "width=\"$dimensions[width]\" height=\"$dimensions[height]\" />";
  }

  // Keeps biggest dimensions
  if ($dimensions['width'] > $variables['slides_max_width']) $variables['slides_max_width'] = $dimensions['width'];
  if ($dimensions['height'] > $variables['slides_max_height']) $variables['slides_max_height'] = $dimensions['height'];

    // Add links if needed
    $links = array('path' => 'image');
    if (isset($item['caption']) && $item['caption'] != '') $links['caption_path'] = 'caption';
    // Loop thru required links (because image and caption can have different links)
    foreach ($links as $link => $out) {
      if (!empty($item[$link])) {
        $path = $item[$link]['path'];
        $options = $item[$link]['options'];
        // When displaying an image inside a link, the html option must be TRUE.
        $options['html'] = TRUE;
        // Generate differnet rel attribute for image and caption, so colorbox doesn't double the image list
        if (isset($options['attributes']['rel'])) $options['attributes']['rel'] .= $out;
        $options = array_merge($options, drupal_parse_url($path));
        $variables['items'][$num][$out] = l($variables['items'][$num][$out], $options['path'], $options);
      }
    }
  }

  // Don't add controls if there's only one image
  if (count($variables['items']) == 1) {
    $variables['controls'] = '';
    $variables['pager'] = '';
  }
}

/**
 * Implements template_preprocess().
 */
function template_preprocess_field_slideshow_pager(&$variables) {
  // Add thumbnails pager/carousel if needed
  if (isset($variables['pager']) && ($variables['pager'] == 'image' || $variables['pager'] == 'carousel')) {

      if ($variables['pager'] == 'carousel') {
        $thumbnail_style = $variables['carousel_image_style'];
        $path = libraries_get_path('jquery.jcarousel');
        if (isset($variables['carousel_skin']) && $variables['carousel_skin']) {
          drupal_add_css($path . '/skins/' . $variables['carousel_skin'] . '/skin.css');
        }
      }
      else {
        $thumbnail_style = $variables['pager_image_style'];
      }

      $thumbnails = array();
      foreach ($variables['items'] as $num => $item) {
        $thumbnail = array();
        $thumbnail['path'] = $item['uri'];
        $thumbnail['attributes']['class'] = array('field-slideshow-thumbnail', 'field-slideshow-thumbnail-' . (1+$num));
        $thumbnail['alt'] = isset($item['alt']) ? $item['alt'] : '';
        if (isset($item['width']) && isset($item['height'])) {
          $thumbnail['width'] = $item['width'];
          $thumbnail['height'] = $item['height'];
        }
        else {
          $thumbnail_dims = getimagesize($thumbnail['path']);
          $thumbnail['width'] = $thumbnail_dims[0];
          $thumbnail['height'] = $thumbnail_dims[1];
        }
        if (isset($item['title']) && drupal_strlen($item['title']) > 0) $thumbnail['title'] = $item['title'];
        if ($thumbnail_style) {
          $thumbnail['style_name'] = $thumbnail_style;
          $thumbnail_output = theme('image_style', $thumbnail);
        }
        else {
          $thumbnail_output = theme('image', $thumbnail);
        }
        $thumbnails[] = '<a href="#">' . $thumbnail_output . '</a>';
      }

    $variables['thumbnails'] = theme('item_list', array(
      'items'       => $thumbnails,
      'attributes'  => array(
        'id'    => 'field-slideshow-' . $variables['slideshow_id'] . '-pager',
        'class' => 'field-slideshow-pager slides-' . count($variables['items']),
      ),
    ));
  }
}

/*
 * Helper functions.
 */
function _field_slideshow_get_fields($field_types, $entity_type, $field_name = '') {
  $links = array();
  $fields = field_info_fields();

  switch ($entity_type) {
    case 'media':
      $bundle = 'file';
      $bundle_instance = 'image';
      $entity_label = t('Media field:');
    break;
    case 'field_collection':
      $bundle = 'field_collection_item';
      $bundle_instance = $field_name;
      $entity_label = t('Field Collection field:');
    break;
  }

  foreach ($fields as $name => $field) {
    if (in_array($bundle, array_keys($field['bundles'])) && in_array($bundle_instance, $field['bundles'][$bundle]) && in_array($field['type'], $field_types)) {
      $infos = field_info_instance($bundle, $name, $bundle_instance);
      $links[$name] = $entity_label . ' ' . $infos['label'];
    }
  }

  return $links;
}
