<?php

/**
 * @file
 * Primarily Drupal hooks.
 */

// Functions for tracking the file usage of [[inline tags]].
require_once dirname(__FILE__) . '/includes/media_wysiwyg.file_usage.inc';

// Functions for working with [[inline tags]] and wysiwyg editors.
require_once dirname(__FILE__) . '/includes/media_wysiwyg.filter.inc';

// Functions for UUID support to embedded media.
require_once dirname(__FILE__) . '/includes/media_wysiwyg.uuid.inc';

/**
 * Implements hook_hook_info().
 */
function media_wysiwyg_hook_info() {
  $hooks = array(
    'media_wysiwyg_token_to_markup_alter',
    'media_wysiwyg_allowed_view_modes_alter',
    'media_wysiwyg_format_form_prepare_alter',
  );

  return array_fill_keys($hooks, array('group' => 'media_wysiwyg'));
}

/**
 * Implements hook_menu().
 */
function media_wysiwyg_menu() {
  $items['media/%file/format-form'] = array(
    'title' => 'Style selector',
    'description' => 'Choose a format for a piece of media',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('media_wysiwyg_format_form', 1),
    'access callback' => 'file_entity_access',
    'access arguments' => array('view', 1),
    'file' => 'includes/media_wysiwyg.pages.inc',
    'theme callback' => 'media_dialog_get_theme_name',
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
 * Implements hook_element_info_alter().
 */
function media_wysiwyg_element_info_alter(&$types) {
  $types['text_format']['#pre_render'][] = 'media_wysiwyg_pre_render_text_format';
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function media_wysiwyg_form_wysiwyg_profile_form_alter(&$form, &$form_state) {
  // Add warnings if the media filter is disabled for the WYSIWYG's text format.
  $form['buttons']['drupal']['media']['#element_validate'][] = 'media_wysiwyg_wysiwyg_button_element_validate';
  $form['buttons']['drupal']['media']['#after_build'][] = 'media_wysiwyg_wysiwyg_button_element_validate';
  form_load_include($form_state, 'inc', 'media_wysiwyg', 'wysiwyg_plugins/media');
}

/**
 * Element validate callback for the media WYSIWYG button.
 */
function media_wysiwyg_wysiwyg_button_element_validate($element, &$form_state) {
  if (!empty($element['#value'])) {
    $format = filter_format_load($form_state['build_info']['args'][0]->format);
    $filters = filter_list_format($format->format);
    if (empty($filters['media_filter']->status)) {
      form_error($element, t('The <em>Convert Media tags to markup</em> filter must be enabled for the <a href="@format-link">@format format</a> in order to use the Media browser WYSIWYG button.', array(
        '@format-link' => url('admin/config/content/formats/' . $format->format, array('query' => array('destination' => $_GET['q']))),
        '@format' => $format->name,
      )));
    }
  }

  return $element;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function media_wysiwyg_form_media_admin_config_browser_alter(&$form, &$form_state) {
  $form['wysiwyg'] = array(
    '#type' => 'fieldset',
    '#title' => t('WYSIWYG configuration'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  $form['wysiwyg']['media_wysiwyg_wysiwyg_browser_plugins'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Enabled browser plugins'),
    '#options' => array(),
    '#required' => FALSE,
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_browser_plugins', array()),
    '#description' => t('If no plugins are selected, they will all be available.'),
  );

  $plugins = media_get_browser_plugin_info();

  foreach ($plugins as $key => $plugin) {
    $form['wysiwyg']['media_wysiwyg_wysiwyg_browser_plugins']['#options'][$key] = !empty($plugin['title']) ? $plugin['title'] : $key;
  }

  $form['wysiwyg']['media_wysiwyg_wysiwyg_upload_directory'] = array(
    '#type' => 'textfield',
    '#title' => t("File directory for uploaded media"),
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_upload_directory', ''),
    '#description' => t('Optional subdirectory within the upload destination where files will be stored. Do not include preceding or trailing slashes.'),
  );

  if (module_exists('token')) {
    $form['wysiwyg']['media_wysiwyg_wysiwyg_upload_directory']['#description'] .= t('This field supports tokens.');
    $form['wysiwyg']['tokens'] = array(
      '#theme' => 'token_tree',
      '#dialog' => TRUE,
    );
  }

  $form['wysiwyg']['media_wysiwyg_wysiwyg_allowed_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Allowed types in WYSIWYG'),
    '#options' => file_entity_type_get_names(),
    '#default_value' => variable_get('media_wysiwyg_wysiwyg_allowed_types', array('audio', 'image', 'video', 'document')),
  );

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

/**
 * Manipulate values before form is submitted.
 */
function media_wysiwyg_admin_config_browser_pre_submit(&$form, &$form_state) {
  $wysiwyg_browser_plugins = array_unique(array_values($form_state['values']['media_wysiwyg_wysiwyg_browser_plugins']));
  if (empty($wysiwyg_browser_plugins[0])) {
    variable_del('media_wysiwyg_wysiwyg_browser_plugins');
    unset($form_state['values']['media_wysiwyg_wysiwyg_browser_plugins']);
  }
}

/**
 * Implements hook_filter_info().
 */
function media_wysiwyg_filter_info() {
  $filters['media_filter'] = array(
    'title' => t('Convert Media tags to markup'),
    'description' => t('This filter will convert [[{type:media... ]] tags into markup. This must be enabled for the Media WYSIWYG integration to work with this input format.'),
    'process callback' => 'media_wysiwyg_filter',
    'weight' => 2,
    // @TODO not implemented
    'tips callback' => 'media_filter_tips',
  );

  return $filters;
}

/**
 * Prepares the page to be able to launch the media browser.
 *
 * Defines default variables.
 */
function media_wysiwyg_include_browser_js() {
  static $included;
  if ($included) {
    return;
  }
  $included = TRUE;
  module_load_include('inc', 'media', 'includes/media.browser');
  $javascript = media_browser_js();
  foreach ($javascript as $key => $definitions) {
    foreach ($definitions as $definition) {
      $function = 'drupal_add_' . $key;
      // Since the arguments to pass are variable, use call_user_func_array().
      // This will not handle all potential drupal_add_*() functions directly
      // but covers the js and library needed here, which are unlikely to be
      // expanded since this function is only a workaround for a wysiwyg
      // limitation.
      call_user_func_array($function, $definition);
    }
  }
  // Add wysiwyg-specific settings.
  $settings = array('wysiwyg_allowed_attributes' => variable_get('media_wysiwyg_wysiwyg_allowed_attributes', _media_wysiwyg_wysiwyg_allowed_attributes_default()));
  drupal_add_js(array('media' => $settings), 'setting');
}

/**
 * Implements hook_wysiwyg_include_directory().
 */
function media_wysiwyg_wysiwyg_include_directory($type) {
  switch ($type) {
    case 'plugins':
      return 'wysiwyg_plugins';

      break;
  }
}

/**
 * Returns the default set of allowed attributes for use with WYSIWYG.
 *
 * @return array
 *   An array of whitelisted attributes.
 */
function _media_wysiwyg_wysiwyg_allowed_attributes_default() {
  return array(
    'alt',
    'title',
    'height',
    'width',
    'hspace',
    'vspace',
    'border',
    'align',
    'style',
    'class',
    'id',
    'usemap',
    'data-picture-group',
    'data-picture-align',
    'data-picture-mapping',
  );
}

/**
 * Returns a drupal_render() array for just the file portion of a file entity.
 *
 * Optional custom settings can override how the file is displayed.
 */
function media_wysiwyg_get_file_without_label($file, $view_mode, $settings = array()) {
  $file->override = $settings;

  $element = file_view_file($file, $view_mode);

  // The formatter invoked by file_view_file() can use $file->override to
  // customize the returned render array to match the requested settings. To
  // support simple formatters that don't do this, set the element attributes to
  // what was requested, but not if the formatter applied its own logic for
  // element attributes.
  if (isset($settings['attributes'])) {
    if (empty($element['#attributes'])) {
      $element['#attributes'] = $settings['attributes'];
    }

    // While this function may be called for any file type, images are a common
    // use-case, and image theme functions have their own structure for render
    // arrays.
    if (isset($element['#theme'])) {
      // theme_image() and theme_image_style() require the 'alt' attributes to
      // be passed separately from the 'attributes' array. (see
      // http://drupal.org/node/999338). Until that's fixed, implement this
      // special-case logic. Image formatters using other theme functions are
      // responsible for their own 'alt' attribute handling. See
      // theme_media_formatter_large_icon() for an example.
      if (in_array($element['#theme'], array('image', 'image_style'))) {
        if (empty($element['#alt']) && isset($settings['attributes']['alt'])) {
          $element['#alt'] = $settings['attributes']['alt'];
        }
      }
      // theme_image_formatter() and any potential replacements, such as
      // theme_colorbox_image_formatter(), also require attribute handling.
      elseif (strpos($element['#theme'], 'image_formatter') !== FALSE) {
        // theme_image_formatter() requires the attributes to be
        // set on the item rather than the element itself.
        if (empty($element['#item']['attributes'])) {
          $element['#item']['attributes'] = $settings['attributes'];
        }

        // theme_image_formatter() also requires alt, title, height, and
        // width attributes to be set on the item rather than within its
        // attributes array.
        foreach (array('alt', 'title', 'width', 'height') as $attr) {
          if (isset($settings['attributes'][$attr])) {
            $element['#item'][$attr] = $settings['attributes'][$attr];
          }
        }
      }
    }
  }

  return $element;
}

/**
 * Returns an array containing the names of all fields that perform text filtering.
 */
function media_wysiwyg_filter_fields_with_text_filtering($entity_type, $entity) {
  list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entity);
  $fields = field_info_instances($entity_type, $bundle);

  // Get all of the fields on this entity that allow text filtering.
  $fields_with_text_filtering = array();
  foreach ($fields as $field_name => $field) {
    if (!empty($field['settings']['text_processing'])) {
      $fields_with_text_filtering[] = $field_name;
    }
  }

  return $fields_with_text_filtering;
}
