require_once $CFG->dirroot . '/mod/offlinequiz/locallib.php';
require_once $CFG->dirroot . '/question/editlib.php';
list($thispageurl, $contexts, $cmid, $cm, $offlinequiz, $pagevars) = question_edit_setup('editq', '/mod/offlinequiz/edit.php', true);
// Get the course object and related bits.
$course = $DB->get_record('course', array('id' => $offlinequiz->course), '*', MUST_EXIST);
require_capability('mod/offlinequiz:manage', $contexts->lowest());
// Determine groupid.
$groupnumber = optional_param('groupnumber', 1, PARAM_INT);
if ($groupnumber === -1 and !empty($SESSION->question_pagevars['groupnumber'])) {
    $groupnumber = $SESSION->question_pagevars['groupnumber'];
}
if ($groupnumber === -1) {
    $groupnumber = 1;
}
$offlinequiz->groupnumber = $groupnumber;
$thispageurl->param('groupnumber', $offlinequiz->groupnumber);
// Load the offlinequiz group and set the groupid in the offlinequiz object.
if ($offlinequizgroup = offlinequiz_get_group($offlinequiz, $groupnumber)) {
    $offlinequiz->groupid = $offlinequizgroup->id;
    $groupquestions = offlinequiz_get_group_question_ids($offlinequiz);
    $offlinequiz->questions = $groupquestions;
} else {
    print_error('invalidgroupnumber', 'offlinequiz');
}
// Create offlinequiz question bank view.
$questionbank = new mod_offlinequiz\question\bank\custom_view($contexts, $thispageurl, $course, $cm, $offlinequiz);
$questionbank->set_offlinequiz_has_scanned_pages(offlinequiz_has_scanned_pages($offlinequiz->id));
// Output.
$output = $PAGE->get_renderer('mod_offlinequiz', 'edit');
$contents = $output->question_bank_contents($questionbank, $pagevars);
echo json_encode(array('status' => 'OK', 'contents' => $contents));
/**
 * Retrieves a template question usage for an offline group. Creates a new template if there is none.
 * While creating question usage it shuffles the group questions if shuffleanswers is created.
 *
 * @param object $offlinequiz
 * @param object $group
 * @param object $context
 * @return question_usage_by_activity
 */
function offlinequiz_get_group_template_usage($offlinequiz, $group, $context)
{
    global $CFG, $DB;
    if (!empty($group->templateusageid) && $group->templateusageid > 0) {
        $templateusage = question_engine::load_questions_usage_by_activity($group->templateusageid);
    } else {
        $questionids = offlinequiz_get_group_question_ids($offlinequiz, $group->id);
        if ($offlinequiz->shufflequestions) {
            $offlinequiz->groupid = $group->id;
            $questionids = offlinequiz_shuffle_questions($questionids);
        }
        // We have to use our own class s.t. we can use the clone function to create results.
        $templateusage = offlinequiz_make_questions_usage_by_activity('mod_offlinequiz', $context);
        $templateusage->set_preferred_behaviour('immediatefeedback');
        if (!$questionids) {
            print_error(get_string('noquestionsfound', 'offlinequiz'), 'view.php?q=' . $offlinequiz->id);
        }
        // Gets database raw data for the questions.
        $questiondata = question_load_questions($questionids);
        // Get the question instances for initial markmarks.
        $sql = "SELECT questionid, maxmark\n                  FROM {offlinequiz_group_questions}\n                 WHERE offlinequizid = :offlinequizid\n                   AND offlinegroupid = :offlinegroupid ";
        $groupquestions = $DB->get_records_sql($sql, array('offlinequizid' => $offlinequiz->id, 'offlinegroupid' => $group->id));
        foreach ($questionids as $questionid) {
            if ($questionid) {
                // Convert the raw data of multichoice questions to a real question definition object.
                if (!$offlinequiz->shuffleanswers) {
                    $questiondata[$questionid]->options->shuffleanswers = false;
                }
                $question = question_bank::make_question($questiondata[$questionid]);
                // We only add multichoice questions which are needed for grading.
                if ($question->get_type_name() == 'multichoice' || $question->get_type_name() == 'multichoiceset') {
                    $templateusage->add_question($question, $groupquestions[$question->id]->maxmark);
                }
            }
        }
        // Create attempts for all questions (fixes order of the answers if shuffleanswers is active).
        $templateusage->start_all_questions();
        // Save the template question usage to the DB.
        question_engine::save_questions_usage_by_activity($templateusage);
        // Save the templateusage-ID in the offlinequiz_groups table.
        $group->templateusageid = $templateusage->get_id();
        $DB->set_field('offlinequiz_groups', 'templateusageid', $group->templateusageid, array('id' => $group->id));
    }
    // End else.
    return $templateusage;
}
    foreach ($choices as $choice) {
        if (!isset($choicesdata[$choice->slotnumber]) || !is_array($choicesdata[$choice->slotnumber])) {
            $choicesdata[$choice->slotnumber] = array();
        }
        $choicesdata[$choice->slotnumber][$choice->choicenumber] = $choice;
    }
}
if ($sheetloaded) {
    // Print image of the form sheet.
    $fs = get_file_storage();
    $imagefile = $fs->get_file($context->id, 'mod_offlinequiz', 'imagefiles', 0, '/', $scannedpage->filename);
    // E.g. http://131.130.103.117/mod_offlinequiz/pluginfile.php/65/mod_offlinequiz/imagefiles/0/zimmer.png_1.
    echo '<img name="formimage" src="' . $CFG->wwwroot . "/pluginfile.php/{$context->id}/mod_offlinequiz/imagefiles/0/" . $imagefile->get_filename() . '" border="1" width="' . OQ_IMAGE_WIDTH . '" style="position:absolute; top:0px; left:0px; display: block;">';
    $answerspots = $scanner->export_hotspots_answer(OQ_IMAGE_WIDTH);
    if ($options->gradedsheetfeedback) {
        $questionids = offlinequiz_get_group_question_ids($offlinequiz, $group->id);
        list($qsql, $params) = $DB->get_in_or_equal($questionids, SQL_PARAMS_NAMED, 'qid');
        $params['offlinequizid'] = $offlinequiz->id;
        $params['offlinegroupid'] = $group->id;
        $sql = "SELECT q.*, ogq.maxmark\n                  FROM {question} q,\n                       {offlinequiz_group_questions} ogq\n                 WHERE ogq.offlinequizid = :offlinequizid\n                   AND ogq.offlinegroupid = :offlinegroupid\n                   AND q.id = ogq.questionid\n                   AND q.id {$qsql}";
        // Load the questions.
        if (!($questions = $DB->get_records_sql($sql, $params))) {
            $viewurl = new moodle_url($CFG->wwwroot . '/mod/offlinequiz/view.php', array('q' => $offlinequiz->id));
            print_error('noquestionsfound', 'offlinequiz', $viewurl);
        }
        // Load the question type specific information.
        if (!get_question_options($questions)) {
            print_error('Could not load question options');
        }
        $questioncounter = 0;
        for ($slotindex = $startindex; $slotindex < $endindex; $slotindex++) {
 /**
  * Checks whether the different offlinequiz groups have different sets of questions (order is irrelevant).
  *
  * @param unknown_type $offlinequiz
  * @param unknown_type $groups
  * @return boolean
  */
 private function groups_have_different_questions($offlinequiz, $groups)
 {
     $agroup = array_pop($groups);
     $aquestions = offlinequiz_get_group_question_ids($offlinequiz, $agroup->id);
     // Compare all other groups to the first one.
     foreach ($groups as $bgroup) {
         $bquestions = offlinequiz_get_group_question_ids($offlinequiz, $bgroup->id);
         // Check which questions are in group A but not in group B.
         $diff1 = array_diff($aquestions, $bquestions);
         // Check which questions are in group B but not in group A.
         $diff2 = array_diff($bquestions, $aquestions);
         // Return true if there are any differences.
         if (!empty($diff1) || !empty($diff2)) {
             return true;
         }
     }
     return false;
 }