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


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';

/**
 * @defgroup tripal_core Tripal Core Module
 * @ingroup tripal_modules
 * @{
 * Functionality useful for all other Tripal modules including the Tripal jobs, files,
 * materialized views and custom table functions.
 * @}
 */

/**
 * Implements hook_init().
 * Used to set the search_path, create default content and set default variables.
 *
 * @ingroup tripal_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_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_core
 */
function tripal_core_permission() {
  return array();
}

/**
 * Implements hook_theme().
 * Registers template files/functions used by this module.
 *
 * @ingroup tripal_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_core
 */
function tripal_core_views_api() {
  return array(
    'api' => 3.0,
  );
}

/**
 * Implements hook_node_view_alter().
 *
 * @ingroup tripal_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_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
      );
    }
  }
}