<?php
define('EOL_QUERY_URL', 'http://services.eol.org/lifedesk/service.php?function=search&search=');
define('EOL_REQUEST_URL', 'http://services.eol.org/lifedesk/service.php?function=details_tcs&id=');

/**
 * Implementation of hook_tcsdc_form
 */
function eol_tcsdc_form($form, $form_state){
  // Request for Phthiraptera or Pediculus!
  $request = drupal_http_request(EOL_REQUEST_URL . '34238633', array(
    'timeout' => 10
  ));
  $eol_service_status = FALSE;
  if($request->code == 200){
    try{
      $eol_service_status = new SimpleXMLElement($request->data);
    }
    catch(Exception $e){
      ;
    }
  }
  return array(
    'eol' => array(
      '#type' => 'fieldset',
      '#title' => 'EOL',
      '#description' => 'Import a classification directly from EOL',
      '#collapsed' => TRUE,
      '#collapsible' => TRUE,
      'eol-status' => array(
        '#weight' => -10,
        '#type' => 'markup',
        '#markup' => $eol_service_status ? '<div class="messages status"><h2 class="element-invisible">Status message</h2>The EOL classification service appears to be running.</div>' : '<div class="messages error"><h2 class="element-invisible">Status message</h2>The EOL classification service (<a href="' . EOL_REQUEST_URL . '">' . (strpos(EOL_REQUEST_URL, '?') ? substr(EOL_REQUEST_URL, 0, strpos(EOL_REQUEST_URL, '?')) : EOL_REQUEST_URL) . '</a>) does not appear to be running.  Please try again later.</div>'
      ),
      'eol-name' => array(
        '#weight' => -5,
        '#type' => 'textfield',
        '#title' => t('Enter the root term of your classification, e.g. Phthiraptera, Insecta, Aves'),
        '#attributes' => array(
          'onkeypress' => 'if(event.keyCode == 13){return false;}else{return true}'
        )
      ),
      'eol-search' => array(
        '#weight' => 0,
        '#type' => 'button',
        '#value' => 'Search EOL',
        '#title' => 'Search EOL',
        '#disabled' => $eol_service_status ? FALSE : TRUE,
        '#ajax' => array(
          'callback' => 'eol_classifications_js',
          'event' => 'click',
          'wrapper' => 'eol-import-full'
        ),
        '#validate' => array(
          'eol_validate'
        )
      ),
      'import-full' => array(
        '#weight' => 5,
        '#markup' => '<div id="eol-import-full" style="clear:both"><input name="eol-import-id" style="display:none"/></div>'
      ),
      'submit-eol' => array(
        '#weight' => 10,
        '#disabled' => $eol_service_status ? FALSE : TRUE,
        '#type' => 'submit',
        '#title' => t('Import from EOL'),
        '#value' => t('Import from EOL'),
        '#submit' => array(
          'eol_submit'
        ),
        '#validate' => array(
          'eol_validate'
        ),
        '#states' => array(
          'invisible' => array(
            ':input[name="eol-import-id"]' => array(
              'value' => ''
            )
          )
        )
      )
    )
  );
}

/**
 * Callback for the ajax
 */
function eol_classifications_js($form, $form_state){
  // We rebuild the form here, and output only the bit that we need (the eol
  // options).
  // sleep(30);
  $request = drupal_http_request(EOL_QUERY_URL . urlencode($_POST['eol-name']), array(
    'timeout' => 5
  ));
  if($request->code == 200){
    $eol_xml = new SimpleXMLElement($request->data);
    $num_results = count($eol_xml->value);
    $options = array();
    for($i = 0; $i < $num_results; $i++){
      $options[check_plain($eol_xml->value[$i]->id) . '|' . check_plain($eol_xml->value[$i]->number_of_children + $eol_xml->value[$i]->number_of_children_synonyms)] = str_replace('|', ' &#187; ', check_plain($eol_xml->value[$i]->ancestry . '|' . $eol_xml->value[$i]->name)) . " <br/>(" . (strlen(trim($eol_xml->value[$i]->metadata->url)) > 5 ? l($eol_xml->value[$i]->metadata->title, $eol_xml->value[$i]->metadata->url, array(
        'abosulte' => 1
      )) : $eol_xml->value[$i]->metadata->title) . ') [approx. ' . check_plain($eol_xml->value[$i]->number_of_children + $eol_xml->value[$i]->number_of_children_synonyms) . ' taxa]';
    }
  }
  $form['eol']['eol-import-id'] = array(
    '#weight' => 5,
    '#name' => 'eol-import-id',
    '#type' => 'radios',
    '#title' => t('Import from Classification'),
    '#default_value' => '',
    '#options' => $options,
    '#parents' => array(
      'eol-import-id'
    ),
    '#prefix' => '<div id="eol-import-full" style="clear:both">',
    '#suffix' => '</div>'
  );
  form_set_cache($form['#build_id'], $form, $form_state);
  // The following few lines of code are clearly not right. I shouldn't have
  // to manually set the '#name' for each 'radio' element within the radios
  // element. Ah well, it works!
  $form_to_return = form_process_radios($form['eol']['eol-import-id']);
  $children = element_children($form_to_return);
  foreach($children as $key){
    $form_to_return[$key]['#name'] = 'eol-import-id';
  }
  $output = drupal_render($form_to_return);
  if(count($options) == 1){
    // Odd bug with #states that seems to stop what I've written above from
    // working.
    // It may well be the case that what I've written shouldn't work, but this
    // is a work around.
    $output .= '<input id="edit-eol-import-id-randomgibberish" class="form-radio" type="radio" value="randomgibberish" name="eol-import-id" style="display:none;">';
  }
  drupal_get_messages();
  return $output;
}

/**
 * Validate the form
 */
function eol_validate($form, &$form_state){
  // Lets just check that the eol-import-id is set in #post, and that it is
  // numeric (is this likely to change Patrick?).
  if(!isset($form_state['values']['taxonomy_vid']) || !$form_state['values']['taxonomy_vid']){
    form_set_error('taxonomy_vid', t('Please select a vocabulary first.'));
  }
  if(!(isset($form_state['values']['eol-import-id']) && count(explode("|", $form_state['values']['eol-import-id'])) == 2)){
    form_set_error('eol-import-id', t('Please ensure you select a classification to import.'));
  }
}

/**
 * Callback function when pressing "Import from EOL"
 */
function eol_submit($form, $form_state){
  // Validation doesn't appear to work, so we instead piss people off and
  // do it here.
  if((!isset($form_state['values']['taxonomy_vid']) || !$form_state['values']['taxonomy_vid']) || (!(isset($form_state['values']['eol-import-id']) && count(explode("|", $form_state['values']['eol-import-id'])) == 2))){
    drupal_set_message('Please ensure you select a source and destination vocabulary.', 'error');
    drupal_goto('admin/import');
  }
  // Added for D7 to prevent errors on submission/testing.
  $parts = explode("|", $form_state['values']['eol-import-id']);
  $batch = array(
    'operations' => array(
      array(
        'tcsdc_batch_downloader',
        array(
          array(
            EOL_REQUEST_URL . $parts[0]
          ),
          $parts[1],
          $form_state['values']['taxonomy_vid']
        )
      ),
      array(
        'tcsdc_import_terms',
        array(
          $form_state['values']['taxonomy_vid']
        )
      )
    ),
    'finished' => 'tcsdc_finished_batch',
    'title' => t('Importing'),
    // We use a single multi-pass operation, so the default
    // 'Remaining x of y operations' message will be confusing here.
    'error_message' => t('The import has encountered an error.')
  );
  // Update the vocabulary to state that we've downloaded from EOL.
  $vocabulary = taxonomy_vocabulary_load($form_state['values']['taxonomy_vid']);
  $vocabulary->description = trim($vocabulary->description . ' ' . t('(Imported from EOL)'));
  taxonomy_vocabulary_save($vocabulary);
  batch_set($batch);
}