<?php
/**
 * result.php - Controller for survey results
 *
 * @author $Author: dtong $
 * @version $Id: result.php,v 1.5 2011/03/14 12:41:59 dtong Exp $
 * @copyright Copyright (c) 2010, Tiller Software Co., Ltd.
*/

class Result extends CI_Controller {
	const CMS_SURVEY_LOGIN_SESSION = 'SURVEY_LOGIN';
	private $blocks = FALSE;
	//question - question text, weight - weight arrays from template (not used)
	//selections - selection text, selected - sum of selected for each question
	//total - (not used)
	private $result_array = array('question'=>array(), 'weight'=>array(),
									'selections'=>array(), 'selected'=>array(), 'selected_teacher'=>array(),
									'total'=>0);

	function __construct() {
		parent::__construct();
		$this->access_model->checkaccess_any('survey_write');
		$this->load->model('survey/survey_model');
		$this->load->model('survey/survey_result_model');
		osa_load_lang('survey');
	}

	//Lists the result for one survey
	function index($surveyid, $survey_type=FALSE) {
		return $this->_show_result($surveyid, FALSE, $survey_type);
	}

	//Show all aggregated result of all surveys belonging to one goal
	//Have to support module other than goal later
	function showall($goalid, $survey_type=FALSE) {
		return $this->_show_result($goalid, TRUE, $survey_type);
	}

	//Prints the OFC JSON data
	function chart($index, $cachebust=FALSE) {
		//$sessionid = 'surveybarchart_' . $index;
		$json_array = $this->session->userdata(CMS_SESSION_BARCHART_JASON);
		if ( empty($json_array) || !is_array($json_array) || !array_key_exists($index, $json_array) ) {
			echo '{}';
			exit;
		}
		echo $json_array[$index];
		//Don't want to update the session table on every chart
		//Just leave the data in the session?
		//@$this->session->unset_userdata($sessionid);
		exit;
	}

	//Cleans the json data in session
	//Not used due to async since we don't know when data access is done.
	/*
	function chart_reset() {
		$this->session->unset_userdata(CMS_SESSION_BARCHART_JASON);
	}*/

	//Lists all the indexes in a javascript array.
	//This is used by Javascript to reference the charts
	function chartindexes() {
		$indexes = $this->session->flashdata('surveychartindexes');
		if (empty($indexes)) {
			echo '[]';
			exit;
		}
		echo $indexes;
		exit;
	}

	//$id can be surveyid or goalid depending on $all_results
	//$survey_type can be CMS_SURVEY_TEMPLATE_SINGLE_TYPE, CMS_SURVEY_TEMPLATE_TEACHER_TYPE, CMS_SURVEY_TEMPLATE_STUDENT_TYPE
	private function _show_result($id, $all_results=FALSE, $survey_type=FALSE) {
		$surveys = FALSE;
		$header_data = FALSE;
		if ( $all_results ) {
			$survey_ids = array();
			//This is the list of selected survey ids for show combined check boxes
			if ( array_key_exists('combineid', $_REQUEST) ) {
				$selected_ids = $_REQUEST['combineid'];
				if ( is_array($selected_ids) && count($selected_ids) > 0 ) {
					foreach ($selected_ids as $tmp_id) {
						if ( osa_is_int($tmp_id) ) {
							$survey_ids[] = $tmp_id;
						}
					}
				}
			}

			if ( count($survey_ids) <= 0 ) {
				//Didn't select any and show all anyway
				$surveys = $this->survey_model->get_survey_bygoalid($id, TRUE);
			}
			else {
				$surveys = $this->survey_model->get_survey_byids($survey_ids);
			}
			//For combined results, need the external title, goal only for now
			$this->load->model('goal/goal_model');
			$goal = $this->goal_model->get_goal($id);
			if ( $goal ) {
				$header_data = array();
				$header_data['ext_title'] = $goal->title;
			}
		}
		else {
			$surveys = $this->survey_model->get_survey($id, FALSE);
			if ( $surveys ) {
				//Header info on the result page
				$header_data = $this->_survey_header_data($surveys);
				$surveys = array($surveys);
			}
		}
		if ( $survey_type === FALSE ) {
			//Setting this to show all templates
			$survey_type = CMS_SURVEY_TEMPLATE_TYPE_ALL;
		}
		$questions = $this->_get_results($surveys, $survey_type);
		if ( !$questions ) {
			echo osa_ajaxmsg(lang('gen_internalservererror'));
			exit;
		}
		$data = array();
		if ( $header_data ) {
			$data = $header_data;
		}
		$data['questions'] = $questions;
		$this->load->view('survey/survey_result_view', $data);
	}

	private function _survey_header_data($survey) {
		$data = array();
		if ( is_object($survey) ) {
			$data['title'] = $survey->title;
			$data['startdate'] = osa_date_format($survey->startdate);
			$data['enddate'] = osa_date_format($survey->enddate);
			$data['blocks'] = $this->_get_blocks($survey->id);
			$data['courses'] = $this->survey_model->get_course_names($survey->id);
		}
		return $data;
	}

	//Assumes multiple surveys to use the same template(s).
	//If multiple surveys use different surveys then please take out the all survey result feature in the UI
	private function _get_results($surveys, $survey_type) {
		//Get the survey template object so we can get the questions, weights etc.
		if ( ($template_obj = $this->_get_template_obj($surveys, $survey_type)) == FALSE ) {
			return FALSE;
		}
		//Prepares $this->result_array with all the data
		$ret = $this->_prepare_result_array($template_obj, $surveys, $survey_type);
		$this->load->library('cms/osa_barchart');
		//These 3 arrays share the same array indexes
		$questions = &$this->result_array['question'];
		$selections = &$this->result_array['selections'];
		$selected = &$this->result_array['selected'];
		$selected_teacher = &$this->result_array['selected_teacher'];
		//Construct a Javascript format array containing all the indexes
		//Need this for processing all the charts
		$index_list = '';
		$index_sep = '';
		foreach ($selections as $selection_index=>$selections_values) {
			$this->osa_barchart->reset();
			foreach ($selections_values as $index=>$value) {
				$this->osa_barchart->add_bar($value,0,$selected[$selection_index][$index]);
			}
			$this->osa_barchart->set_title(lang('survey_student_results'));
			$this->osa_barchart->prepare($selection_index);
			$this->osa_barchart->reset();
			foreach ($selections_values as $index=>$value) {
				$this->osa_barchart->add_bar($value,0,$selected_teacher[$selection_index][$index]);
			}
			$this->osa_barchart->set_title(lang('survey_teacher_results'));
			//there will be array of 1t,2,t,3t.. in the barchart session json data in additon to the one above without t.
			$this->osa_barchart->prepare($selection_index . 't');
			$index_list .= "{$index_sep}{$selection_index}";
			$index_sep = ',';
		}
		$this->session->set_flashdata('surveychartindexes', "[$index_list]");
		//This is used in the view to construct the questions titles and the OFC bar charts
		return $questions;
	}

	//Prepares the class result array by combining the predefined data from the template and the survey results from the DB
	private function _prepare_result_array($template_obj, $surveys, $survey_type) {
		$tmp = $template_obj->stage;
		//Survey template always contains a single stage
		//So, array_shift gets the first element from the array will always return this single stage
		$stage = array_shift($tmp);
		$return = &$this->result_array;
		$typeid = 0;

		//Collect all the text from the template
		foreach ($stage as $question) {
			if (  array_key_exists('_type', $question) && $question['_type'] == 'unit_radio' &&
					array_key_exists('_index', $question) && array_key_exists('_question_text', $question) &&
					array_key_exists('_radio_text_array', $question) && array_key_exists('_survey_weight', $question) &&
					array_key_exists('_typeid', $question) ) {
				$index = (int) $question['_index'];
				$return['question'][$index] = $question['_question_text'];
				$return['weight'][$index] = $question['_survey_weight'];
				$return['selections'][$index] = $question['_radio_text_array'];
				$return['selected'][$index] = array();
				$return['selected_teacher'][$index] = array();
				//Init all selected as zero
				foreach ($question['_radio_text_array'] as $key=>$value) {
					$return['selected'][$index][$key] = 0;
					$return['selected_teacher'][$index][$key] = 0;
				}
				//Typeid have to be the same in every question
				$typeid = $question['_typeid'];
			}
		}

		//Collect DB results
		$ids = array();
		foreach ($surveys as $survey) {
			$ids[] = $survey->id;
		}
		$result = $this->survey_result_model->get_results_by_surveyid($ids, $survey_type, $typeid);
		if ( $result ) {
			foreach ( $result as $record ) {
				$q_index = $record->question_index;
				$q_selected = $record->radio_select;
				//Separate teacher and student survey results
				$selected_index = 'selected';
				if ( $record->template_type == CMS_SURVEY_TEMPLATE_TEACHER_TYPE ) {
					$selected_index = 'selected_teacher';
				}
				if ( array_key_exists($q_index, $return[$selected_index]) ) {
					if ( isset($return[$selected_index][$q_index][$q_selected]) ) {
						$return[$selected_index][$q_index][$q_selected] = $return[$selected_index][$q_index][$q_selected] + 1;
					}
				}
			}
		}
		return TRUE;
	}

	//Get the survey template object
	private function _get_template_obj($surveys, $survey_type) {
		if ( !is_array($surveys) ) {
			osa_errorlog(__METHOD__ . ' - $surveys contains no surveys.');
			return FALSE;
		}
		//Find the appropiate survey file
		$template_file_part = $this->_get_template_file_part($surveys[0], $survey_type);
		if ( !$template_file_part ) {
			osa_errorlog(__METHOD__ . ' - failed to get template file part.');
			return FALSE;
		}
		//Load the survey template
		$ret = osa_load_template_obj($template_file_part, TRUE, CMS_TEMPLATE_SURVEY_IDENTIFIER, 'survey_config');
		if ( !$ret ) {
			osa_errorlog(__METHOD__ . " - failed to load survey template $template_file_part");
			return FALSE;
		}
		//Please look at osa_load_template_obj() for how the class gets constructed
		$class_name = "survey_config_{$template_file_part}";
		$template_obj = FALSE;
		//$obj = @survey_config_survey_2::get();
		@eval("\$template_obj=@{$class_name}::get();");
		if ( !is_object($template_obj) ) {
			osa_errorlog(__METHOD__ . ' - bad class survey_config_survey_2.');
			return FALSE;
		}
		//Make sure object has the stage array
		if ( !isset($template_obj->stage) || !is_array($template_obj->stage) ) {
			return FALSE;
		}
		return $template_obj;
	}

	//Gets the survey file name (survey_template->template) from the database
	private function _get_template_file_part($survey, $survey_type) {
		if ( is_object($survey) ) {
			//Get all the templates for the survey
			$templates = $this->survey_model->get_templates($survey->id);
			if ( !$templates ) {
				return FALSE;
			}
			$template_student = FALSE;
			$template_teacher = FALSE;
			$template_all = FALSE;
			//Go thru each template and find the one we need
			foreach ($templates as $template) {
				if ( $template->type == $survey_type ) {
					return $template->template;
				}
				switch ($template->type) {
					case CMS_SURVEY_TEMPLATE_SINGLE_TYPE:
						$template_all = $template->template;
						break;
					case CMS_SURVEY_TEMPLATE_TEACHER_TYPE:
						$template_teacher = $template->template;
						break;
					case CMS_SURVEY_TEMPLATE_STUDENT_TYPE:
						$template_student = $template->template;
						break;
				}
			}
			//Didn't find the the right template so lets just return one exisiting one in this predefined order
			//Student should come b4 teacher and you can move all to be the first if required
			if ( $template_student ) {
				return $template_student;
			}
			if ( $template_teacher ) {
				return $template_teacher;
			}
			if ( $template_all ) {
				return $template_all;
			}
		}
		return FALSE;
	}

	//Get the list of block names for a survey
	private function _get_blocks($surveyid) {
		$blocks = $this->survey_model->get_blocks($surveyid);
		$ret = '';
		$sep = '';
		$blocks_list = $this->config->item('cms_survey_blocks');
		if ( $blocks && $blocks_list ) {
			foreach ($blocks as $record) {
				$ret .= $sep . $blocks_list[$record];
				$sep = ', ';
			}
		}
		return $ret;
	}
}