<?php

/**
 * @file
 * Picture formatter with flexslider support.
 */

/**
 * Implements hook_theme_registry_alter().
 */
function flexslider_picture_theme_registry_alter(&$registry) {
  $registry['flexslider_list']['file'] = 'flexslider_picture.theme.inc';
  $registry['flexslider_list']['theme_path'] = drupal_get_path('module', 'flexslider_picture') . '/theme';
  $registry['flexslider_list']['function'] = 'theme_flexslider_picture_list';
  $default_processor = array_search('template_preprocess_flexslider_list', $registry['flexslider_list']['preprocess functions']);
  $registry['flexslider_list']['preprocess functions'][(int) $default_processor] = 'template_preprocess_flexslider_picture_list';
  $registry['flexslider_list']['includes'][] = $registry['flexslider_list']['theme_path'] . '/' . $registry['flexslider_list']['file'];

  $registry['flexslider_list_item']['file'] = 'flexslider_picture.theme.inc';
  $registry['flexslider_list_item']['theme_path'] = drupal_get_path('module', 'flexslider_picture') . '/theme';
  $default_processor = array_search('template_process_flexslider_list_item', $registry['flexslider_list_item']['process functions']);
  $registry['flexslider_list_item']['process functions'][(int) $default_processor] = 'template_process_flexslider_picture_list_item';
  $registry['flexslider_list_item']['includes'][] = $registry['flexslider_list_item']['theme_path'] . '/' . $registry['flexslider_list_item']['file'];
}

/**
 * Implements hook_field_formatter_info().
 *
 * Redefine the formatter from flexslider so that our formatter function will
 * be used.
 */
function flexslider_picture_field_formatter_info() {
  return array(
    'flexslider' => array(
      'label' => t('flexslider'),
      'field types' => array('image', 'media'),
      'settings' => array(
        'optionset' => 'default',
        'image_style' => '',
        'caption' => FALSE,
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_settings_form().
 *
 * Provides display settings form within the manage display page of
 * an image field with formatter flexslider.
 */
function flexslider_picture_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  return flexslider_fields_field_formatter_settings_form($field, $instance, $view_mode, $form, $form_state);
}

/**
 * Implements hook_field_formatter_settings_summary().
 *
 * Displays the summary of the options of a flexslider formatted image field.
 */
function flexslider_picture_field_formatter_settings_summary($field, $instance, $view_mode) {
  return flexslider_fields_field_formatter_settings_summary($field, $instance, $view_mode);
}

/**
 * Implements hook_field_formatter_view().
 *
 * Prepares a renderable array of images and adds the neccessary JS and CSS.
 */
function flexslider_picture_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = flexslider_fields_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
  $optionsets = array();
  foreach (element_children($element) as $child) {
    if (!isset($optionsets[$element[$child]['#settings']['optionset']])) {
      $optionsets[$element[$child]['#settings']['optionset']] = flexslider_optionset_load($element[$child]['#settings']['optionset']);
    }
    $optionset = $optionsets[$element[$child]['#settings']['optionset']];
    if ($optionset && isset($optionset->imagestyle_type) && !empty($optionset->imagestyle_type) && $optionset->imagestyle_type == 'picture_mapping') {
      $element[$child]['#attached'] = array(
        'library' => array(
          array('picture', 'matchmedia'),
          array('picture', 'picturefill'),
          array('picture', 'picture.ajax'),
        ),
      );
    }
  }
  return $element;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function flexslider_picture_form_ctools_export_ui_edit_item_form_alter(&$form, &$form_state) {
  if ($form_state['plugin']['schema'] == 'flexslider_optionset') {
    $form['image_style']['#tree'] = TRUE;
    $form['image_style']['#weight'] = 0;
    $form['title']['#weight'] = -1;
    $form['image_style']['imagestyle_type'] = array(
      '#type' => 'radios',
      '#title' => t('Image type'),
      '#description' => t(
          'Choosing picture mapping will give you a truly responsive slider.
          Flexslider is responsive because it will resize the images for smaller screens, but it will still load the large image.
          With picture mappings, a smaller image will be loaded for smaller screens (and thus less data transfer).'),
      '#options' => array(
        'image_style' => t('Image Style'),
        'picture_mapping' => t('Picture Mapping'),
      ),
      '#weight' => -2,
      '#default_value' => (isset($form_state['item']->imagestyle_type) && !empty($form_state['item']->imagestyle_type)) ? $form_state['item']->imagestyle_type : 'image_style',
    );

    $options = picture_get_mapping_options();
    $form['image_style']['mapping'] = array(
      '#title' => t('Normal picuture mapping'),
      '#states' => array(
        'visible' => array(
          ':input[name="image_style[imagestyle_type]"]' => array('value' => 'picture_mapping'),
        ),
      ),
      '#weight' => -1,
    );
    if (!empty($options)) {
      $form['image_style']['mapping'] += array(
        '#type' => 'select',
        '#description' => t('Picture mapping for the main stage images.'),
        '#options' => $options,
        '#default_value' => (!empty($form_state['item']->mapping)) ? $form_state['item']->mapping : '',
      );
    }
    else {
      $form['image_style']['mapping'] += array(
        '#type' => 'item',
        '#markup' => t("There're no picture mappings defined, you'll have to !create them first.", array('!create' => l(t('create'), 'admin/config/media/picture'))),
      );
    }
    $image_styles = image_style_options(FALSE);
    $form['image_style']['fallback'] = array(
      '#title' => t('Fallback image style'),
      '#description' => t('The fallback image style to use'),
      '#type' => 'select',
      '#empty_option' => t('Automatic'),
      '#options' => $image_styles + array(
        PICTURE_EMPTY_IMAGE => t('Empty image'),
        PICTURE_ORIGINAL_IMAGE => t('Original image'),
      ),
      '#states' => array(
        'visible' => array(
          ':input[name="image_style[imagestyle_type]"]' => array('value' => 'picture_mapping'),
        ),
      ),
      '#default_value' => (!empty($form_state['item']->fallback)) ? $form_state['item']->fallback : '',
    );

    // Colorbox support.
    $form['image_style']['colorboxEnabled'] = array(
      '#title' => t('Enable colorbox'),
      '#type' => 'checkbox',
      '#default_value' => (!empty($form_state['item']->options['colorboxEnabled'])) ? $form_state['item']->options['colorboxEnabled'] : '',
    );
    $form['image_style']['colorboxImageStyle'] = array(
      '#title' => t('Colorbox group'),
      '#type' => 'select',
      '#default_value' => (!empty($form_state['item']->options['colorboxImageStyle'])) ? $form_state['item']->options['colorboxImageStyle'] : '',
      '#required' => FALSE,
      '#options' => $options,
      '#states' => array(
        'visible' => array(
          ':input[name$="image_style[colorboxEnabled]"]' => array('checked' => TRUE),
        ),
      ),
    );

    $form['image_style']['colorboxFallbackImageStyle'] = array(
      '#title' => t('Colorbox fallback image style'),
      '#type' => 'select',
      '#default_value' => (!empty($form_state['item']->options['colorboxFallbackImageStyle'])) ? $form_state['item']->options['colorboxFallbackImageStyle'] : '',
      '#required' => FALSE,
      '#empty_option' => t('Automatic'),
      '#options' => $image_styles + array(
        PICTURE_EMPTY_IMAGE => t('Empty image'),
        PICTURE_ORIGINAL_IMAGE => t('Original image'),
      ),
      '#states' => array(
        'visible' => array(
          ':input[name$="image_style[colorboxEnabled]"]' => array('checked' => TRUE),
        ),
      ),
    );

    $form['#submit'][] = '_flexslider_picture_ctools_export_ui_edit_item_form_submit';
  }
}

/**
 * Submit callback.
 */
function _flexslider_picture_ctools_export_ui_edit_item_form_submit($form, &$form_state) {
  $fields = array_intersect_key($form_state['values']['image_style'], drupal_map_assoc(array(
    'imagestyle_type',
    'mapping',
    'fallback',
  )));
  $fields['flexslider_optionset'] = $form_state['values']['name'];
  db_merge('flexslider_picture_optionset')
    ->key(array('flexslider_optionset' => $form_state['values']['name']))
    ->fields($fields)
    ->execute();

  // Add the colorbox options into the generic options field.
  // @todo Should we move it into our own table or how likely is it that
  // flexslider itself will add colorbox support and thus add "similar" options?
  $optionset = &$form_state['optionset'];
  $optionset->options['colorboxEnabled'] = !empty($form_state['values']['image_style']['colorboxEnabled']);
  $optionset->options['colorboxImageStyle'] = !empty($form_state['values']['image_style']['colorboxImageStyle']) ? $form_state['values']['image_style']['colorboxImageStyle'] : '';
  $optionset->options['colorboxFallbackImageStyle'] = !empty($form_state['values']['image_style']['colorboxFallbackImageStyle']) ? $form_state['values']['image_style']['colorboxFallbackImageStyle'] : '';
}

/**
 * Join callback.
 *
 * @see flexslider_picture_schema_alter()
 */
function flexslider_picture_join_callback(&$query, $schema, $join_schema) {
  $tables = &$query->getTables();
  foreach ($tables as &$table) {
    if ($table['table'] == 'flexslider_picture_optionset') {
      $table['join type'] = 'LEFT OUTER';
      break;
    }
  }
}

/**
 * Implements hook_flexslider_default_presets_alter().
 *
 * Mashed up the default presets of flexslider and picture.
 */
function flexslider_picture_flexslider_default_presets_alter(&$defaults) {
  foreach ($defaults as $name => &$settings) {
    $default_preset = ctools_get_default_object('flexslider_picture_optionset', $name);
    if (!empty($default_preset)) {
      $settings->imagestyle_type = $default_preset->imagestyle_type;
      $settings->mapping = $default_preset->mapping;
      $settings->fallback = $default_preset->fallback;
    }
  }
}
