<?php

/**
 * The main file for cloze question type.
 */

/**
 * Implementation of hook_help().
 */
function cloze_help($path, $args) {
  if ($path == 'admin/help#cloze') {
    return t('This module provides a cloze question type for Quiz.');
  }
}

/**
 * Implementation of hook_quiz_question_info().
 */
function cloze_quiz_question_info() {
  return array(
    'cloze' => array(
      'name' => t('Cloze question'),
      'description' => t('Quiz questions that allow a user to fill-in the missing words.'),
      'question provider' => 'ClozeQuestion',
      'response provider' => 'ClozeResponse',
      'module' => 'quiz_question', // All wrapper functions are in that module.
    ),
  );
}

/**
 * Implementation of the quiz_question hook_config.
 */
function cloze_config() {
  return FALSE; // No config options available for this question type
}


/**
 * Implementation of hook_autoload_info().
 */
function cloze_autoload_info() {
  return array(
    'ClozeQuestion' => array('file' => 'cloze.classes.inc'),
    'ClozeResponse' => array('file' => 'cloze.classes.inc'),
  );
}

/**
 * Implementation of hook_form_alter()
 */
function cloze_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'cloze_node_form') {
    $form['#after_build'][] = 'cloze_node_form_after_build';
  }
}

function cloze_node_form_after_build($form) {
  // To prevent wysiwyg editor messing with question syntax
  $form['body'][LANGUAGE_NONE]['0']['format']['#access'] = FALSE;
  return $form;
}

/**
 * Implementation of hook_theme().
 */
function cloze_theme() {
  $path = drupal_get_path('module', 'cloze') . '/theme';
  return array(
    'cloze_response_form' => array(
      'render element' => 'form',
      'path' => $path,
      'file' => 'cloze.theme.inc',
    ),
    'cloze_user_answer' => array(
      'arguments' => array('answer' => NULL, 'correct' => NULL),
      'path' => $path,
      'file' => 'cloze.theme.inc',
    ),
    'cloze_answering_form' => array(
      'render element' => 'form',
      'path' => $path,
      'file' => 'cloze.theme.inc',
    ),
  );
}

function _cloze_shuffle_choices($choices) {
  $new_array = array();
  $new_array[''] = '';
  while (count($choices)) {
    $element = array_rand($choices);
    $new_array[$element] = $choices[$element];
    unset($choices[$element]);
  }
  return $new_array;
}

function _cloze_get_question_chunks($question) {
  $chunks = array();
  while (strlen($question) > 0) {
    $match = FALSE;
    $pos = strpos($question, '[');
    if ($pos) {
      $substring = substr($question, 0, $pos);
      $question = preg_replace('/'. preg_quote($substring) .'/', '', $question, 1);
      $chunks[] = $substring;
      $match = TRUE;
    }
    $pos = strpos($question, ']');
    if ($pos !== FALSE) {
      $substring = substr($question, 0, $pos + 1);
      $question = preg_replace('/'. preg_quote($substring) .'/', '', $question, 1);
      $chunks[] = $substring;
      $match = TRUE;
    }
    if (!$match) {
      $chunks[] = $question;
      $question = '';
    }
  }
  return $chunks;
}

function _cloze_get_correct_answer_chunks($question) {
  $correct_answer = array();
  $chunks = _cloze_get_question_chunks($question);
  foreach ($chunks as $key => $value) {
    if (strpos($value, '[') === FALSE) {
      continue;
    }
    else {
      $answer_chunk = str_replace(array('[', ']'), '', $value);
      $choice = explode(',', $answer_chunk);
      if (count($choice) == 1) {
        $correct_answer[$key] = $answer_chunk;
      }
      else {
        $correct_answer[$key] = $choice[0];
      }
    }
  }
  return $correct_answer;
}

function _cloze_get_correct_answer($question) {
  $output = '';
  $chunks = _cloze_get_question_chunks($question);
  $answer = _cloze_get_correct_answer_chunks($question);
  $correct_answer = array();
  foreach ($chunks as $key => $chunk) {
    if (isset($answer[$key])) {
      $correct_answer[] =  '<span class="answer correct correct-answer">' . $answer[$key] . '</span>';
    }
    else {
      $correct_answer[] =  $chunk;
    }
  }
  $output = implode(' ', $correct_answer);
  return str_replace("\n", "<br/>", $output);
}

function _cloze_get_user_answer($question, $answer) {
  $output = '';
  $user_answer = $chunks = _cloze_get_question_chunks($question);
  $correct_answer_chunks = _cloze_get_correct_answer_chunks($question);
  foreach ($chunks as $key => $value) {
    if (isset($answer[$key]) && !empty($answer[$key])) {
      $class = (_cloze_get_clean_text($correct_answer_chunks[$key]) == _cloze_get_clean_text($answer[$key])) ? 'correct' : 'incorrect';
      $class .= ' answer user-answer';
      $user_answer[$key] = '<span class="'. $class .'">' . $answer[$key] . '</span>';
    }
    elseif (isset($answer[$key])) {
      $user_answer[$key] = '<span class="incorrect answer user-answer">'. str_repeat('_', strlen($correct_answer_chunks[$key])) .'</span>';
    }
  }
  $output = implode(' ', $user_answer);
  return str_replace("\n", "<br/>", $output);
}

/**
 * Makes the given text consistent for comparison
 */
function _cloze_get_clean_text($text) {
  $text = trim($text);
  $text = drupal_strtolower($text);
  return $text;
}
