<?php
/**
 * unit_base.php - Base class for managing unit resource data and UI
 *
 * @author $Author: wichai $
 * @version $Id: unit_base.php,v 1.16 2011/06/06 10:19:00 wichai Exp $
 * @copyright Copyright (c) 2009, Tiller Software Co., Ltd.
*/
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once ('Unitmain.php');
require_once ('unit_buttons.php');

abstract class unit_base {
	const COURSEID_PATTERN = '_COURSEID_';
	const UNITID_PATTERN = '_UNITID_';
	const RESID_PATTERN = '_RESID_';
	const STAGEDIV_PATTERN = '_STAGEDIV_';
	const STAGENUM_PATTERN = '_STAGENUM_';
	const DEPARTMENT_NAME_PATTERN = '_AREA_NAME_';

	static protected $ismycourse=NULL;
	static protected $color_track=FALSE; //Keeps track white or grey background in a list of items

	protected $CI=NULL;
	protected $html='';
	protected $data=NULL; //The array from the builder template, can be whole or part
	protected $params=NULL; //object containing stagenum, divid, action, unitid, courseid, type (template)

	protected $sort_flag=FALSE;
	protected $multitype_sort=FALSE;
	protected $sort_type=FALSE;
	protected $sort_read_only=FALSE;
	protected $buttonsobj=NULL;

	//The complete unitmain object which is the caller.
	//This allows the module objects to have complete access to the the caller
	//Not using it in any module yet but sure it will be useful later.
	private $unitmain_obj=NULL;

	//This is going to be overrided/implemented in the children classes
	abstract public function render($data, $params);

	function __construct() {
		$this->CI = & get_instance();
		$this->CI->load->library('cms/cms_btnsort');
		$this->buttonsobj = & $this->CI->cms_cache->object_get('unit_buttons');
	}

	public function reset(&$data=NULL, &$params=NULL) {
		$this->html = '';
		$this->data = &$data;
		$this->params = $params;
		$this->check_sort();
	}

	public function set_unitmain(& $obj) {
		$this->unitmain_obj = $obj;
	}

	protected function get_unitmain() {
		return $this->unitmain_obj;
	}

	public function getval($key, $data=FALSE) {
		if ( !$data )
			$data = & $this->data;
		if ( is_null($data) || !$data )
			return FALSE;
		//a key always have a '_' prefix
		if ( strpos($key, '_') !== 0 )
		$key = '_' . $key;
		if ( array_key_exists($key, $data) ) {
			$ret = $data[$key];
			if ( $ret !== FALSE )
				return $ret;
		}
		return FALSE;
	}

	public function stage_div() {
		return $this->params->divid;
	}

	public function stagenum() {
		return $this->params->stagenum;
	}

	public function courseid() {
		return $this->params->courseid;
	}

	public function unitid() {
		return $this->params->unitid;
	}

	public function type() {
		//return $this->params->type;
		return $this->getval('_typeid');
	}

	public function action() {
		return $this->params->action;
	}

	public function template_data() {
		if ( is_null($this->data) || !is_array($this->data) )
			return FALSE;
		return $this->data;
	}

	public function get_params() {
		return $this->params;
	}

	//Gets the template object. This is the big template file obtained from config factory in unitmain.
	public function get_templateobj() {
		if ( is_object($this->unitmain_obj) ) {
			return $this->unitmain_obj->get_template();
		}
		//Very bad error, just exist. The only way we can get here is thru unitmain
		//so the template should always exist.
		osa_log(__METHOD__, 'Failed to get template object. This should never happen.');
		echo osa_buildererror();
		exit;
	}

	//Gets the template file_part like ubd, pyp, myp etc.
	public function get_template_filepart() {
		if ( $this->params && property_exists($this->params, 'unit_template') ) {
			return $this->params->unit_template;
		}
		osa_log(__METHOD__, 'Failed to get template file_part. This should never happen.', $this->params);
		echo osa_buildererror();
		exit;
	}

	public function is_teacher() {
		if ( !($user = $this->CI->login_model->getLogin() ))
			return FALSE;
		if ( is_null($this->params) )
			return FALSE;
		if ( $this->CI->access_model->checkaccess_any('admin_unit_write', $user, FALSE, FALSE) )
			return TRUE;
		if ( is_null(self::$ismycourse) ) { //Run once for all sub-classes
			if ( !property_exists($this->CI, 'cms_template') ) {
				$this->CI->load->library('cms/cms_template/cms_template');
			}
			if ( !property_exists($this->CI, 'resource_model') ) {
				$this->CI->load->model('unit/resource_model');
			}
			if ( $this->params->courseid > 0 ) {
				self::$ismycourse = $this->CI->resource_model->is_teacher($user->id, $this->params->courseid);
			}
			elseif ( $this->params->unitid > 0 &&
						$this->CI->cms_template->type_filename($this->type()) == 'course_desc' ) {
				//This was done for course resources. There is some design issues since the course_description_id gets
				//assigned as $this->params->unitid. But, if courseid is not zero then other parts of the
				//code would not work... course_desc is system template so OK to hardcode.
				//Goal and survey should not have private resources so the logic here is OK.
				$this->CI->load->model('course/course_model');
				$get_coursedesc = $this->CI->course_model->get_descbyid($this->params->unitid);
				if ( !is_object($get_coursedesc) || !property_exists($get_coursedesc, 'courseid') || !osa_is_int_one($get_coursedesc->courseid) ) {
					echo osa_buildererror();
					return FALSE;
				}
				// (issue: 218) to tell teacher or not we must use real course id,
				// so using unit id to identify course id from course description model
				//self::$ismycourse = $this->CI->resource_model->is_teacher($user->id, $this->params->unitid);
				self::$ismycourse = $this->CI->resource_model->is_teacher($user->id, $get_coursedesc->courseid);
			}
		}
		return self::$ismycourse;
	}

	public static function color_track($color1, $color2) {
		self::$color_track = !self::$color_track;
		return (self::$color_track ? $color1 : $color2);
	}

	public static function color_track_reset() {
		self::$color_track = FALSE;
	}

	protected function error($msg, $var=NULL) {
		osa_errorlog($msg, $var);
		$this->html .= osa_buildererror();
	}

	protected function copy_values($obj) {
		foreach (array_keys($this->data) as $key) {
			//eval('$obj->' . $key . '=$this->data[$key];');
			$obj->$key = $this->data[$key];
		}
	}

	//Not using this because we just copy everything using copy_values
	protected function assign_obj_values($obj, $fields) {
		foreach ($fields as $field) {
			if ( !array_key_exists($field, $this->data) )
				log_message('error', __METHOD__ . " - Invalid field '{$field}'");
			eval('$obj->' . $field . '=$this->getval($field);');
		}
	}

	//Get sorting params from template. This applies to all modules.
	protected function check_sort() {
		$this->sort_flag = FALSE;
		$this->multitype_sort = FALSE;
		$this->sort_type=FALSE;
		$this->sort_read_only=FALSE;

		if ( !is_array($this->data) ) {
			return;
		}
		//Defaults is to do sort if flag is not set. So, you have to put '_sort_flag'=>FALSE to turn off sort
		if ( !array_key_exists('_sort_flag', $this->data) ) {
			$this->sort_flag = TRUE;
		}
		else {
			$this->sort_flag = $this->getval('_sort_flag');
		}
		if ( !$this->sort_flag ) {
			return;
		}

		$tmp = $this->getval('_typeid');
		$this->multitype_sort = is_array($tmp);
		if ( $this->multitype_sort ) {
			//Defaults to the first array element, should always use _sort_typeid in template to override
			$this->sort_type = reset($tmp);
		}
		else {
			$this->sort_type = $tmp;
		}
		if ( ($tmp = $this->getval('_sort_typeid')) !== FALSE && osa_is_int_one($tmp) ) {
			$this->sort_type = $tmp;
		}

		if ( $this->action() != CMS_ACTION_EDIT ) {
			$this->sort_read_only = TRUE;
}
	}

	//Gets  sort buttons html
	protected function render_sort_buttons($record, $type) {
		if ( !$this->sort_flag ) {
			return '';
		}
		$buttons = $this->CI->cms_btnsort->get_button_array($record, $type);
		if ( !$buttons ) {
			return '';
		}
		$tmpparams = $this->params;
		$tmpparams->resid = $record->id; //assign the resource id
		$html = $this->buttonsobj->render($buttons, $tmpparams);
		if ( $html ) {
			return '<td valign="middle" align="right" class="itembuttons">' . $html . '</td>';
		}
		return '';
	}

}
