<?php

/**
 * @file
 * Adds autocomplete capabilities for Search API searches.
 */

// Include the files with the module-specific implementations.
require_once('search_api_autocomplete.search_api_page.inc');
require_once('search_api_autocomplete.search_api_views.inc');

/**
 * Implements hook_search_api_autocomplete_types().
 *
 * Adds search types for search pages and views. The actual implementations lie
 * in the above include files.
 */
function search_api_autocomplete_search_api_autocomplete_types() {
  $types = array();
  if (module_exists('search_api_page')) {
    $types['search_api_page'] = array(
      'name' => t('Search pages'),
      'description' => t('Searches provided by the <em>Search pages</em> module.'),
      'list searches' => 'search_api_autocomplete_pages_searches',
      'create query' => 'search_api_autocomplete_pages_query',
    );
  }
  if (module_exists('search_api_views')) {
    $types['search_api_views'] = array(
      'name' => t('Search views'),
      'description' => t('Searches provided by the <em>Search views</em> module.'),
      'list searches' => 'search_api_autocomplete_views_searches',
      'create query' => 'search_api_autocomplete_views_query',
    );
  }

  return $types;
}

/**
 * Implements hook_menu().
 */
function search_api_autocomplete_menu() {
  // Autocompletion path
  $items['search_api_autocomplete/%search_api_autocomplete_search'] = array(
    'title' => 'Search API autocomplete',
    'page callback' => 'search_api_autocomplete_autocomplete',
    'page arguments' => array(1),
    'access arguments' => array('use search_api_autocomplete'),
    'type' => MENU_CALLBACK,
    'file' => 'search_api_autocomplete.pages.inc',
  );

  // Admin UI
  $items['admin/config/search/search_api/index/%search_api_index/autocomplete'] = array(
    'title' => 'Autocomplete',
    'description' => 'Add autocompletion to searches for this index.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('search_api_autocomplete_admin_overview', 5),
    'access arguments' => array('administer search_api'),
    'weight' => -1,
    'type' => MENU_LOCAL_TASK,
    'context' => MENU_CONTEXT_INLINE | MENU_CONTEXT_PAGE,
    'file' => 'search_api_autocomplete.admin.inc',
  );
  $items['admin/config/search/search_api/index/%/autocomplete/%search_api_autocomplete_search/edit'] = array(
    'title' => 'Edit autocompletion settings',
    'description' => 'Edit the autocompletion settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('search_api_autocomplete_admin_search_edit', 7),
    'access arguments' => array('administer search_api'),
    'file' => 'search_api_autocomplete.admin.inc',
  );
  $items['admin/config/search/search_api/index/%/autocomplete/%search_api_autocomplete_search/delete'] = array(
    'title' => 'Delete autocompletion settings',
    'description' => 'Delete the autocompletion settings of a search.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('search_api_autocomplete_admin_search_delete', 7),
    'access arguments' => array('administer search_api'),
    'file' => 'search_api_autocomplete.admin.inc',
  );

  return $items;
}

/**
 * Implements hook_theme().
 */
function search_api_autocomplete_theme() {
  $themes['search_api_autocomplete_suggestion'] = array(
    'variables' => array(
      'prefix' => NULL,
      'suggestion_prefix' => '',
      'user_input' => '',
      'suggestion_suffix' => '',
      'results' => NULL,
    ),
    'file' => 'search_api_autocomplete.pages.inc',
  );

  return $themes;
}

/**
 * Implements hook_entity_info().
 */
function search_api_autocomplete_entity_info() {
  $info['search_api_autocomplete_search'] = array(
    'label' => t('Autocomplete search'),
    'controller class' => 'EntityAPIControllerExportable',
    'entity class' => 'SearchApiAutocompleteSearch',
    'base table' => 'search_api_autocomplete_search',
    'uri callback' => 'search_api_autocomplete_search_url',
    'module' => 'search_api_autocomplete',
    'exportable' => TRUE,
    'entity keys' => array(
      'id' => 'id',
      'name' => 'machine_name',
      'label' => 'name',
    ),
  );

  return $info;
}

/**
 * Implements hook_permission().
 */
function search_api_autocomplete_permission() {
  return array(
    'use search_api_autocomplete' => array(
      'title' => t('Use search autocomplete'),
    ),
  );
}

/**
 * Implements hook_search_api_index_delete().
 */
function search_api_autocomplete_search_api_index_delete(SearchApiIndex $index) {
  if (!$index->hasStatus(ENTITY_IN_CODE)) {
    $ids = db_query('SELECT id FROM {search_api_autocomplete_search} WHERE index_id = :id',
        array(':id' => $index->machine_name))->fetchCol();
    if ($ids) {
      entity_delete_multiple('search_api_autocomplete_search', $ids);
    }
  }
}

/**
 * Get information about all search types, or a specific one.
 *
 * @param $type
 *   (optional) The name of a type.
 *
 * @return
 *   If $type was not given, an array containing information about all search
 *   types. Otherwise, either information about the specified type, or NULL if
 *   the type is not known.
 *
 * @see hook_search_api_autocomplete_types()
 */
function search_api_autocomplete_get_types($type = NULL) {
  $types = &drupal_static(__FUNCTION__);
  if (!isset($types)) {
    $types = module_invoke_all('search_api_autocomplete_types');
  }
  if (isset($type)) {
    return isset($types[$type]) ? $types[$type] : NULL;
  }
  return $types;
}

/**
 * Loads an autocomplete search entity.
 *
 * @param $id
 *   Either the ID or machine name of an autocomplete search.
 * @param $reset
 *   Whether to reset the internal cache.
 *
 * @return SearchApiAutocompleteSearch
 *   The specified autocomplete search entity, or FALSE if it doesn't exist.
 */
function search_api_autocomplete_search_load($id, $reset = FALSE) {
  $ret = search_api_autocomplete_search_load_multiple(array($id), array(), $reset);
  return $ret ? reset($ret) : FALSE;
}

/**
 * Loads autocomplete search entities.
 *
 * @param $ids
 *   An array of IDs or machine names, or FALSE to load all searches.
 * @param $conditions
 *   An associative array of conditions on the {search_api_autocomplete_search}
 *   table.
 * @param $reset
 *   Whether to reset the internal cache.
 *
 * @return array
 *   An array of all autocomplete search entities that meet the criteria.
 *
 * @see entity_load()
 */
function search_api_autocomplete_search_load_multiple($ids = FALSE, array $conditions = array(), $reset = FALSE) {
  return entity_load_multiple_by_name('search_api_autocomplete_search', $ids, $conditions, $reset);
}
