<?php
/**
 * @file
 * The Tripal Core module
 */

/**
 * @defgroup tripal_legacy_api Tripal Legacy API
 * @{
 * Provides an application programming interface (API) for Tripal v2
 * backwards-compatibilty. These functions are DEPRECATED and may not
 * be available in future version of Tripal.
 * @}
 */

/**
 * @defgroup tripal_legacy_core Legacy Tripal Core Module
 * @ingroup tripal_legacy_modules
 * @{
 * Functionality useful for all other Tripal modules including the Tripal jobs, files,
 * materialized views and custom table functions.
 * @}
 */
require_once 'api/tripal_core.chado_nodes.api.inc';
require_once 'api/tripal_core.chado_nodes.title_and_path.inc';
require_once 'api/tripal_core.chado_nodes.properties.api.inc';
require_once 'api/tripal_core.chado_nodes.dbxrefs.api.inc';
require_once 'api/tripal_core.chado_nodes.relationships.api.inc';
require_once 'api/tripal_core.tripal_variables.api.inc';
require_once 'includes/tripal_core.form_elements.inc';
require_once 'includes/tripal_core.search.inc';



/**
 * Implements hook_init().
 * Used to set the search_path, create default content and set default variables.
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_init() {

  // If we want AHAH elements on the node forms (e.g. chado_pub form) then we need to include
  // the node.pages file. Otherwise this error message is given:
  //
  // warning: call_user_func_array() expects parameter 1 to be a valid callback,
  // function 'node_form' not found or invalid function name
  // in /var/www/includes/form.inc on line 382.
  module_load_include('inc', 'node', 'node.pages');

}

/**
 * Implements hook_menu().
 * Defines all menu items needed by Tripal Core
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_menu() {
  $items = array();

  // Triapl setting groups
  $items['admin/tripal/legacy'] = array(
    'title' => 'Tripal Legacy',
    'description' => t("Legacy functionality from Tripal v2.0."),
    'weight' => -8,
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array('administer tripal'),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );

  // Relationshi API autocomplete callback
  $items['tripal_ajax/relationship_nodeform/%/%/name_to_id'] = array(
    'page callback' => 'chado_add_node_form_relationships_name_to_id_callback',
    'page arguments' => array(2,3),
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK
  );

  // The node's TOC tab
  $items['node/%node/tripal_toc'] = array(
    'title' => 'TOC',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('tripal_core_node_toc_form', 1),
    'access callback' => 'tripal_core_access_node_toc_form',
    'access arguments' => array(1),
    'type' => MENU_LOCAL_TASK,
    'file' => '/includes/tripal_core.toc.inc',
  );

  return $items;
}

/**
 * An access wrapper function for editing the TOC
 *
 * @param $node
 *   A node object
 * @return
 *   Returns TRUE if the node is a Tripal-based node and the user hass
 *   the 'administer tripal' role.
 */
function tripal_core_access_node_toc_form($node) {
  $types = module_invoke_all('node_info');
  if (array_key_exists($node->type, $types) and
      array_key_exists('chado_node_api', $types[$node->type])) {
    return user_access('administer tripal');
  }
  return FALSE;
}

/**
 * Implements hook_permission().
 *
 * Set the permission types that the chado module uses.  Essentially we
 *  want permissionis that protect creation, editing and deleting of chado
 *  data objects
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_permission() {
  return array();
}

/**
 * Implements hook_theme().
 * Registers template files/functions used by this module.
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_theme($existing, $type, $theme, $path) {
  return array(
    'tripal_core_customize' => array(
      'arguments' => array('job_id' => NULL),
      'template' => 'tripal_core_customize',
      'path' => "$path/theme/templates"
    ),
    'theme_file_upload_combo' => array(
      'render element' => 'element',
    ),
    'theme_sequence_combo' => array(
      'render element' => 'element',
    ),
    'tripal_core_jobs_help' => array(
      'template' => 'tripal_core_jobs_help',
      'variables' =>  array(NULL),
      'path' => "$path/theme/templates"
    ),
    'tripal_core_customtables_help' => array(
      'template' => 'tripal_core_customtables_help',
      'variables' =>  array(NULL),
      'path' => "$path/theme/templates"
    ),

    // Chado Node API Themes
    // --------------------------------
    // Properties Node Form
    'chado_node_properties_form_table' => array(
      'function' => 'theme_chado_add_node_form_properties',
      'render element' => 'element',
    ),
    // Additional Dbxrefs Nore Form
    'chado_node_additional_dbxrefs_form_table' => array(
      'function' => 'theme_chado_add_node_form_dbxrefs_table',
      'render element' => 'element',
    ),
    // Relationships Nore Form
    'chado_node_relationships_form_table' => array(
      'function' => 'theme_chado_add_node_form_relationships_table',
      'render element' => 'element',
    ),

    // Form and form element themes.
    // --------------------------------
    'tripal_node_toc_items_table' => array(
      'render element' => 'element',
    ),
    // Theme function for the extension admin page.
    'tripal_core_extensions_form_tables' => array(
      'render element' => 'element',
    ),
    'administer controlled vocabularies' => array(
      'title' => t('Administer controlled vocabularies (CVs).'),
      'description' => t('Allow a user to add, edit and delete controlled vocabularies as well as add and edit terms.')
    ),
  );
}

/**
 * Implements hook_coder_ignore().
 *
 * Defines the path to the file (tripal_core.coder_ignores.txt) where ignore
 * rules for coder are stored.
 *
 */
function tripal_core_coder_ignore() {
  return array(
    'path' => drupal_get_path('module', 'tripal_core'),
    'line prefix' => drupal_get_path('module', 'tripal_core'),
  );
}

/**
 * Implements hook_views_api().
 *
 * Essentially this hook tells drupal that there is views support for
 * for this module which then includes tripal_db.views.inc where all the
 * views integration code is.
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_views_api() {
  return array(
    'api' => 3.0,
  );
}

/**
 * Implements hook_node_view_alter().
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_node_view_alter(&$build) {
  module_load_include('inc', 'tripal_core', 'includes/tripal_core.toc');
  tripal_core_node_view_build_toc($build);
}

/**
 * Implements hook_node_view().
 *
 * @ingroup tripal_legacy_core
 */
function tripal_core_node_view($node, $view_mode, $langcode) {

  // if this node type is a chado-based node (i.e. Tripal node)
  // the we want to add a table of contents to it's content list
  // this table of contents will be an empty
  if (preg_match('/^chado_/', $node->type)) {
    if ($view_mode == 'full') {
      if (!isset($node->content['#tripal_generic_node_template'])) {
        $node->content['#tripal_generic_node_template'] = TRUE;
      }
    }
  }
}

/**
 * Adds support for tokens in the field_resource_links field.
 *
 * The field_resource_links field is a special field that can be manually
 * added by the site admin for providing links on the Tripal TOC sidebar.
 * Using tokens will allow for creation of custom links. This function
 * will add a fieldset contiaining the list of appropriate tokens for the
 * content type.
 *
 * @param unknown $element
 * @param unknown $form_state
 * @param unknown $context
 */
function tripal_core_field_widget_form_alter(&$element, &$form_state, $context) {

  // If the name of the field is 'field_resource_links' then we want to
  // add a fieldset of tokens.
  if (isset($element['#field_name']) AND $element['#field_name'] == 'field_resource_links') {

    // Add the tokens fieldset to the last element.
    $num_elements = count($context['items']);
    if ($num_elements == $element['#delta']) {
      $bundle = $element['#bundle'];
      $base_table = preg_replace('/^chado_(.*)$/', '\1', $bundle);
      $tokens = chado_node_generate_tokens($base_table);
      $token_list = chado_node_format_tokens($tokens);
      $element['tokens'] = array(
        '#type' => 'fieldset',
        '#title' => 'Available tokens',
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
        '#weight' => 100
      );
      $element['tokens']['tokens_table'] = array(
        '#type' => 'item',
        '#markup' => $token_list
      );
    }
  }
}

/**
 * Implements hook_block_info().
 */
function tripal_core_block_info() {

  $blocks['tripal_search'] = array(
    'info' => t('Tripal Search Block'),
    'cache' => DRUPAL_NO_CACHE,
  );

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function tripal_core_block_view($delta = '') {
  $block = array();

  switch ($delta) {
    case 'tripal_search':
      $block['title'] = 'Search';

      $form_render_arr = drupal_get_form('tripal_core_search_block');
      $block['content'] = array(
        '#markup' => drupal_render($form_render_arr),
      );
      break;
  }

  return $block;
}

/**
 * A simple search box form.
 */
function tripal_core_search_block($form, $form_state) {

  $form['wrapper'] = array(
    '#prefix' => '<div id="search-block-form" class="container-inline">',
    '#suffix' => '</div>',
  );

  $form['wrapper']['title'] = array(
    '#markup' => '<h2 class="element-invisible">Search form</h2>',
  );

  $form['wrapper']['search_block_form'] = array(
    '#title' => 'Search',
    '#title_display' => 'invisible',
    '#type' => 'textfield',
    '#size' => 15,
    '#maxlength' => 128,
    '#attributes' =>array('placeholder' => t(variable_get('tripal_search_placeholder', 'Keywords')))
  );

  $form['wrapper']['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Search',
    '#prefix' => '<div class="form-actions form-wrapper" id="edit-actions">',
    '#suffix' => '</div>'
  );

  $form['search_placeholder'] = array(
    '#type' => 'textfield',
    '#title' => 'Placeholder Text',
    '#description' => 'Change the text that shows up within the search box until the user enters any of their own text.',
    '#default_value' => variable_get('tripal_search_placeholder', 'Keywords'),
  );

  return $form;
}

/**
 * Submit for tripal_core_search_block form.
 */
function tripal_core_search_block_submit($form, &$form_state) {

  $form_state['redirect'] = array(
    variable_get('tripal_search_block_url', 'search/data'),
    array(
      'query' => array(
        'keywords' => $form_state['values']['search_block_form']
      ),
    ),
  );

}

/**
 * Implements hook_block_configure().
 */
function tripal_core_block_configure ($delta = '') {
  $form = array();

  $form['search_url'] = array(
    '#type' => 'textfield',
    '#title' => 'Search Page URL',
    '#description' => 'The URL for the page you would like to redirect to when the user
        clicks "Search". It is expected that this page will be a view with an exposed
        filter having a "Filter Identifier" (in "More" fieldset on the edit filter form)
        of "keywords".',
    '#default_value' => variable_get('tripal_search_block_url', 'search/data'),
  );

  return $form;
}

/**
 * Implements hook_block_save().
 */
function tripal_core_block_save($delta = '', $edit = array()) {

  // We simply want to save this information in a Drupal variable for use in the form submit.
  if (!empty($edit['search_url'])) {
    variable_set('tripal_search_block_url', $edit['search_url']);
  }
  if (!empty($edit['search_placeholder'])) {
    variable_set('tripal_search_placeholder', $edit['search_placeholder']);
  }
}