<?php
// This file is part of
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

// Adds gradeimporter to add new activity page
function tool_devcourse_extend_navigation_course($navigation, $course, $coursecontext) {
  $url = new moodle_url('/admin/tool/devcourse/index.php');
  $devcoursenode = navigation_node::create('Development course', $url, navigation_node::TYPE_CUSTOM, 'Dev course', 'devcourse');
  $navigation->add_node($devcoursenode);
}

function gradeimporter_supports($feature) {
  switch ($feature) {
    case FEATURE_MOD_ARCHETYPE:
      return MOD_ARCHETYPE_RESOURCE;
    case FEATURE_GROUPS:
      return false;
    case FEATURE_GROUPINGS:
      return false;
    case FEATURE_MOD_INTRO:
      return true;
    case FEATURE_COMPLETION_TRACKS_VIEWS:
      return true;
    case FEATURE_GRADE_HAS_GRADE:
      return false;
    case FEATURE_GRADE_OUTCOMES:
      return false;
    case FEATURE_BACKUP_MOODLE2:
      return true;
    case FEATURE_GRADE_HAS_GRADE:
      return true;
    case FEATURE_GRADE_OUTCOMES:
      return true;
    default:
      return null;
  }
}

function gradeimporter_add_instance($data, $mform) {
  /*
    *Given an object containing all the necessary data,
    *(defined by the form in mod_form.php) this function
    *creates a new instance and returns the id of this new
    *instance.
    *
    *@param $data: an object from the form in mod_form.php
    *@return int: the id of the newly inserted gradeimport record
  */
  global $DB;
  $data->timemodified = time();

  $data->id = $DB->insert_record("gradeimporter", $data);

  return $data->id;
}

function gradeimporter_update_instance($data) {
  /*
    *given an object containing all the necessary data,
    *(defined by the form in mod_form.php) this function
    *updates an existing instance with the new data.
    *
    *@param $data: an object from the form mod_form.php
    *@return boolean: if the record update was a success of fail
  */
  global $DB;

  $data->timemodified = time();
  $data->id = $data->instance;

  return $DB->update_record('gradeimporter', $data);
}

function gradeimporter_delete_instance($data) {
  /*
  *Given an id of a gradeimporter instance,
  * this function permanently deletes the instance
  * and any data that depends on it.
  *
  *@param int $id: Id of the gradeimporter instance
  *@return boolean, if the deletion was a success or
  *         a failure.
  */

  global $DB;

  if (!$data = $DB->get_record('gradeimporter', array('id' => $id))) {
    return false;
  }

  $cm = get_coursemodule_from_instance('gradeimporter', $gradeimporter->id);

  $context = context_module::instance($cm->id);
  // Files
  $fs = get_file_storage();
  $fs->delete_area_files($context->id, 'submissionfiles');

  // Delete all files and submissions associated with this instance
  $DB->delete_records('gradeimporter_submission', array('gradeimporterid' => $gradeimporter->id));
  $DB->delete_records('gradeimporter_feedback', array('gradeimporterid' => $gradeimporter->id));
  $DB->delete_records('gradeimporter_submissiontype', array('gradeimporterid' => $gradeimporter->id));

  // Delete the instance itself
  $DB->delete_records('gradeimporter', array('id' => $id));
  return true;
}


/**
 * Implementation of pluginfile function to get file from a pluginfile url
 */
function mod_gradeimporter_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
  // Check the contextlevel is as expected - if your plugin is a block, this becomes CONTEXT_BLOCK, etc.
  if ($context->contextlevel != CONTEXT_MODULE) {
    return false;
  }
  // Make sure the filearea is one of those used by the plugin.
  if ($filearea !== 'submissionfiles') {
    return false;
  }

  // Make sure the user is logged in and has access to the module
  // (plugins that are not course modules should leave out the 'cm' part).
  require_login($course, true, $cm);

  // Check the relevant capabilities - these may vary depending on the filearea being accessed.
  if (!has_capability('mod/gradeimporter:view', $context)) {
    return false;
  }

  // Leave this line out if you set the itemid to null in make_pluginfile_url (set $itemid to 0 instead).
  $itemid = array_shift($args); // The first item in the $args array.

  // Use the itemid to retrieve any relevant data records and perform any security checks to see if the
  // user really does have access to the file in question.

  // Extract the filename / filepath from the $args array.
  $filename = array_pop($args); // The last item in the $args array.
  if (!$args) {
    $filepath = '/'; // If $args is empty => the path is '/'
  } else {
    $filepath = '/'.implode('/', $args).'/'; // If $args contains elements of the filepath
  }

  // Retrieve the file from the Files API.
  $fs = get_file_storage();
  $file = $fs->get_file($context->id, 'mod_gradeimporter', $filearea, $itemid, $filepath, $filename);
  if (!$file) {
    echo "didnt find the file";
    return false; // The file does not exist.
  }

  // We can now send the file back to the browser - in this case with a cache lifetime of 1 day and no filtering.
  send_stored_file($file, 86400, 0, $forcedownload, $options);
}

function gradeimporter_grade_item_update ($submission, $grades = null) {
  global $CFG, $COURSE;

  require_once("{$CFG->libdir}/gradelib.php");

  $params = array('itemname' => $submission->name, 'idnumber' => $submission->cmid);

  if ($submission->gradebook == 0) {
    $params['gradetype'] = GRADE_TYPE_NONE;
  } else {
    $params['gradetype'] = GRADE_TYPE_VALUE;
    $params['grademax'] = $submission->maxgrade;
    $params['grademin'] = 0;
  }

  if ($grades == 'reset') {
    $params['reset'] == true;
    $grades = null;
  }

  return grade_update('mod/gradeimporter', $COURSE->id, 'mod', 'gradeimporter', $submission->gradeimporterid, 0, $grades, $params);
}

function gradeimporter_update_grades ($submission, $userid = 0, $nullifnone = true) {
  global $CFG, $DB, $COURSE;

  require_once("{$CFG->libdir}/gradelib.php");

  if ($submission->gradebook == 0) {
    gradeimporter_grade_item_update($submission);
    return;
  }

  // If submission is gradeable (gradebook==1) then tries to submit the grades
  if ($grades = gradeimporter_get_user_grades($submission, $userid)) {
    // Gets student grade from gradeimporter_feedback table
    gradeimporter_grade_item_update($submission, $grades);
    return;
  }

  if ($userid and $nullifnone) {
    $grade = new stdClass();
    $grade->userid = $userid;
    $grade->rawgrade = null;
    gradeimporter_grade_item_update($submission, $grade);
    return;
  }

  gradeimporter_grade_item_update($submission);

}

function gradeimporter_reset_gradebook ($courseid, $type = '') {
  global $CFG, $DB;
  $tp = $CFG->prefix;
  // Select all grades on gradebook and reset them
  $sql = "SELECT gs.*
          FROM {$tp}gradeimporter_submission as gs
          JOIN {$tp}gradeimporter as g ON g.id = gs.gradeimporterid
          WHERE g.course = $courseid";

  $submissions = $DB->get_records_sql($sql);
  foreach ($submissions as $submission) {
    gradeimporter_grade_item_update($submission, 'reset');
  }
}

function gradeimporter_get_user_grades($submission, $userid) {
  global $DB, $CFG;
  $grade = new stdClass();
  $grade->userid = $userid;

  $tp = $CFG->prefix;
  $sql = "SELECT gf.id, gf.grade as grade
          FROM {$tp}gradeimporter_feedback as gf
          JOIN {$tp}gradeimporter_submission as gs
            ON gs.id = gf.submissionid
          JOIN {$tp}gradeimporter as gi
            ON gi.id = gs.gradeimporterid
          WHERE gf.studentid = $userid
              AND gi.id = $submission->gradeimporterid
              AND gs.gradebook = 1
              AND gs.visibility = 1";
  $feedbacks = $DB->get_records_sql($sql);

  if ($feedbacks) {
    $grade->rawgrade = sum_property($feedbacks, 'grade');
    return $grade;
  }

  return null;
}

function sum_property ($array, $property) {
  $sum = 0;
  foreach ($array as $object) {
    $sum += $object->$property;
  }
  return $sum;
}

function create_grade_item($submission) {
  global $CFG, $COURSE;

  require_once("{$CFG->libdir}/gradelib.php");

  $gradeitem = new grade_item(array('id' => 0, 'courseid' => $COURSE->id));
  $data = new stdClass();
  $data->itemname = $submission->name;
  $data->iteminfo = $submission->intro;
  // Blank [idnumer] for now
  $data->outcomeid = $submission->gradeimporterid;
  $data->cmid = $submission->gradeimporterid;
  $data->id = 0;
  $data->courseid = $COURSE->id;
  $data->aggregationcoef = 0;
  $data->itemtype = 'gradeimporter';

  grade_item::set_properties($gradeitem, $data);

  $gradeitem->itemnumber = $submission->id;

  $outcome = grade_outcome::fetch(array('id' => $submission->gradeimporterid));
  $gradeitem->gradetype = GRADE_TYPE_SCALE;
  $gradeitem->scaleid = $outcome->scaleid;

  $gradeitem->insert();

  if ($item = grade_item::fetch(array('itemtype' => 'gradeimporter', 'itemmodule' => $gradeitem->itemmodule,
                                    'iteminstance' => $gradeitem->iteminstance, 'itemnumber' => 0, 'courseid' => $COURSE->id))) {
      $gradeitem->set_parent($item->categoryid);
      $gradeitem->move_after_sortorder($item->sortorder);
  }
}

function insert_grade_outcome($submission, $userid) {
  global $CFG, $DB, $COURSE;
  if (empty($CFG->enableoutcomes)) {
    return;
  }
  require_once("$CFG->libdir/gradelib.php");

  $data = array();
  $gradinginfo = grade_get_grades($COURSE->id, 'mod', 'gradeimporter', $submission->gradeimporterid, $userid);

  if (!empty($gradinginfo->outcomes)) {
    foreach ($gradinginfo->outcomes as $n => $old) {
      $data[$n] = 2;
    }
  }

  if (count($data) > 0) {
    grade_update_outcomes('mod/gradeimporter', $COURSE->id, 'mod', 'gradeimporter', $submission->gradeimporterid, $userid, $data);
  }
}