<?php
/**
 * @file
 * Integrates Aloha Editor in a Drupal site.
 */

/**
 * Include additional files.
 */
foreach (module_list() as $module) {
  if (file_exists($file = dirname(__FILE__) . "/includes/{$module}.inc")) {
    require_once $file;
  }
}

/**
 * Implements hook_permission().
 */
function aloha_permission() {
  return array(
    'use aloha' => array(
      'title' => t('Use the Aloha Editor'),
      'description' => t('Use the Aloha Editor to edit node content.'),
    ),
    'administer aloha' => array(
      'title' => t('Administer Aloha Editor settings'),
      'description' => t('Administer Aloha Editor module settings.'),
    ),
  );
}

/**
 * Implements hook_theme().
 *
 * @see drupal_common_theme()
 * @see template_preprocess_page()
 */
function aloha_theme() {
  return array(
    'aloha_plugins_settings' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Implements hook_menu().
 *
 * Admin menu item and ajax callbacks to save the data being edited
 */
function aloha_menu() {
  $items = array();

  $items['admin/config/user-interface/aloha'] = array(
    'title' => 'Aloha Editor',
    'description' => 'Front-end HTML5 wysiwyg editor for Drupal.',
    'access arguments' => array('administer aloha'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('aloha_admin'),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'aloha.admin.inc',
  );

  $items['aloha/%/save'] = array(
    'page callback' => 'aloha_invoke_callback',
    'page arguments' => array('save', 1),
    'access callback' => 'aloha_invoke_callback',
    'access arguments' => array('access', 1),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

/**
 * Implements hook_help().
 */
function aloha_help($path, $arg) {
  switch ($path) {
    case 'admin/help#aloha':
      $output = file_get_contents(drupal_get_path('module', 'aloha') . '/README.txt');
      return module_exists('markdown') ? filter_xss_admin(module_invoke('markdown', 'filter', 'process', 0, -1, $output)) : '<pre>' . check_plain($output) . '</pre>';
  }
}

/**
 * Page and access callback for saving content
 *
 * @param <type> $callback
 *   Callback
 * @param <type> $type
 *   Callback type
 */
function aloha_invoke_callback($callback, $type) {
  $info = _aloha_get_type_info($type);
  if (!empty($info) && isset($info["{$callback} callback"]) && function_exists($function = $info["{$callback} callback"])) {
    return $function();
  }
  return FALSE;
}

/**
 * Helper function for aloha_invoke_callback
 *
 * @param <type> $type
 *   Type to get
 * @param <type> $reset
 *   Reset value
 */
function _aloha_get_type_info($type = NULL, $reset = FALSE) {
  $info = &drupal_static(__FUNCTION__);

  if (!isset($info) || $reset) {
    $info = module_invoke_all('aloha_type_info');
  }

  if (!is_null($type)) {
    return isset($info[$type]) ? $info[$type] : FALSE;
  }
  return $info;
}

/**
 * Helper function to add JS files and setings
 */
function _aloha_include_files() {
  $included = &drupal_static(__FUNCTION__);
  if (!$included) {
    if (!in_array('aloha', array_keys(libraries_get_libraries()))) {
      // Display a message when aloha is not found.
      drupal_set_message(check_plain(t('You need to download the !aloha and extract the entire contents of the archive into the %path folder of your server.', array('!aloha' => l(t('Aloha Editor'), 'http://www.aloha-editor.org/'), '%path' => 'sites/all/libraries/aloha'))), 'error', FALSE);
      return FALSE;
    }
    // Because Drupal doesn't allow to setup custom attributes for js or css
    // includes we have to use drupal_add_html_head().
    $plugins_list = variable_get('aloha_plugins', array());
    $plugins_activated = 'data-aloha-plugins="';
    if ($plugins_list) {
      foreach ($plugins_list['list'] as $key => $plugin) {
        if ($plugin == $key && !$plugin == '0') {
          $plugins_activated .= $plugin . ',';
        }
      }
    }
    if (substr($plugins_activated, -1) == ',') {
      $plugins_activated = substr($plugins_activated, 0, -1);
    }
    $plugins_activated .= '"';

    // Create the markup to be added.
    // @TODO: This can probably be done with the Render API with the 'html_tag'
    // element.
    $aloha_to_html_head = array(
      '#type' => 'markup',
      '#markup' => '<script type="text/javascript" src="' . base_path() . libraries_get_path('aloha') . '/aloha/lib/aloha.js" ' . $plugins_activated . '></script>' . PHP_EOL . '<link rel="stylesheet" href="' . base_path() . libraries_get_path('aloha') . '/aloha/css/aloha.css" id="aloha-style-include" type="text/css">' . PHP_EOL,
    );

    drupal_add_html_head($aloha_to_html_head, 'aloha');

    // Add jQuery UI effects.core
    drupal_add_library('system', 'effects');
    
    // Module files
    drupal_add_js(drupal_get_path('module', 'aloha') . '/aloha.js');
    drupal_add_css(drupal_get_path('module', 'aloha') . '/aloha.css');

    // Aloha Settings to be transferred to Aloha library via drupal_ad_js()
    $settings = variable_get('aloha_js_settings', array());
    $settings = _aloha_replace_tokens($settings);
    drupal_add_js(array('aloha' => array('alohaSettings' => $settings, 'saveBase' => url('', array('absolute' => TRUE)))), 'setting');
    $included = TRUE;
  }
  return TRUE;
}

/**
 * Add data about an aloha enabled region to the inline js for a page.
 *
 * @param <type> $key
 *   Region key
 * @param <type> $data
 *   Region data
 */
function _aloha_add_region_to_js($key, $data) {
  $setting = array('aloha' => array('regions' => array($key => $data)));
  drupal_add_js($setting, 'setting');
}

/**
 * Add a target span to a content region which should be editable.
 *
 * @param <type> $content
 *   Content
 * @param <type> $key
 *   Region key
 */
function _aloha_add_target_to_region(&$content, $key) {
  $content .= '<span class="aloha-target aloha-target-' . $key . '"></span>';
}

/**
 * Replace Aloha custom tokens.
 *
 * @param <type> $array
 *   Settings array
 */
function _aloha_replace_tokens($array) {
  global $base_url;
  $new_array = array();
  if (!empty($array)) {
    foreach ($array as $key => $value) {
      $new_array[$key] = (is_array($value) ? _aloha_replace_tokens($value) : str_replace('[base_url]', $base_url, $value));
    }
  }
  return $new_array;
}
