<?php
/**
 * OSA_Menutree.php - Serverside library for handling the menu trees using jstree Treeview
 *
 * @author $Author: wichai $
 * @version $Id: Osa_menutree.php,v 1.91 2011/05/30 10:11:18 wichai Exp $
 * @copyright Copyright (c) 2009, Tiller Software Co., Ltd.
*/

if ( ! defined('BASEPATH')) exit('No direct script access allowed');
require_once('jstree_html_element.php');

Class Osa_menutree {
   private $CI = NULL;
   private $userobj = NULL; //The user session object
   private $mycourses = NULL; //All course objects belong to the user
   private $mycourses_hash = NULL; //Associate array of all the course id in $mycourses above
   private $isAdminUnitWrite = FALSE;
   private $unit_types = FALSE;

   const FOLDER_COURSE = 'folder_opened.gif';
   const FOLDER_COURSE_HIDE = 'folder_course_hide.gif';
   const FOLDER_IMAGE = 'folder_close.gif';
   const PAGE_IMAGE = 'page_cyan.gif';
   const GLOBE_IMAGE = 'globe.gif';
   const EDIT_IMAGE = 'edit.gif';
   const COPY_IMAGE = 'copy.gif';

   private $COURSE_DESC_HTML;
   private $TARGET_HTML;
   private $UNIT_HTML;
   private $EDITUNITREAD_HTML;
   // private $ADDUNIT_HTML;
   private $COPYUNIT_HTML;
   private $IMAGE_FOLDER;
   private $STYLE_FOLDER;

   //Constructor
	function __construct($params) {
		if ( !isset($params) || $params == '' )
         return FALSE;
      if ( !isset($params['user']) )
         return FALSE;

      //$this->courseid = $params['courseid'];
      $this->userobj = $params['user'];

		$this->CI =& get_instance();
		$this->CI->load->model('menu/menu_model');
		$this->CI->load->model('unit/unit_model');
		//$this->CI->load->model('auth/login_model');
		$this->isAdminUnitWrite = $this->CI->access_model->checkaccess_any('admin_unit_write',$this->userobj,FALSE,FALSE);
		//Get the courses for this user
		$this->mycourses = $this->CI->menu_model->mycourses($this->userobj->id);
		osa_array_natsort($this->mycourses, 'name');
		//Set the courses in an array for faster seraches later
		$this->set_mycourses_hash($this->mycourses);

		//Load the language file menu_lang.php
		osa_load_lang('menu');

      $this->COURSE_DESC_HTML = '<a id="course_desc_html" href="' . base_url() . 'course/desc/index/%s' .
            '" onClick=\'get_current_id(); ajaxGetpage("page_content","' . base_url(). 'course/desc/index/%s' .
            '"); return false;\'>' . lang('menu_coursedescription') . '</a>';
      $this->COURSE_SUM_HTML = '<a href="' . base_url() . 'course/desc/coursesum/%s' .
            '" onClick=\'ajaxGetpage("page_content","' . base_url(). 'course/desc/coursesum/%s' .
            '");return false;\'>' . lang('menu_coursesummary') . '</a>';
      if ( ($target_linktext = $this->CI->config->item('cms_menu_target_name')) == FALSE )
      	$target_linktext = lang('menu_learingtargets');
      if ( ($target_readlink = $this->CI->config->item('cms_menu_target_readlink')) == FALSE )
      	$target_readlink = 'course/target/index/';
      if ( ($target_editlink = $this->CI->config->item('cms_menu_target_editlink')) == FALSE )
      	$target_editlink = 'course/target/edit/';
      $target_readlink .= '%s';
      $target_editlink .= '%s';
      $this->TARGET_HTML = '<a href="' . base_url() . $target_readlink .
            '" onClick=\'ajaxGetpage("page_content","' . base_url() . $target_readlink .
            '"); return false;\'>' . $target_linktext . '</a>';
      $this->TARGET_EDIT_HTML = '<a href="' . base_url() . $target_editlink .
            '" onClick=\'ajaxGetpage("page_content","' . base_url() . $target_editlink .
            '"); return false;\'>' . $target_linktext . '</a>';
      /*
      $this->ADDUNIT_HTML = '<a href="' . base_url() . 'unit/unit/add/%s/'.CMS_UBD_TEMPLATE .
            '" onClick=\'LoadUnitPage("' . base_url() . 'unit/unit/add/%s/'.CMS_UBD_TEMPLATE .
            '","page_content"); return false;\'>' .
      		lang('menu_addunit') . '</a>'; */
      $this->ADDUNIT_TEMPLATE_HTML = '<a id="addunit_html" href="' . base_url() . 'unit/unit/add/%s/%s' .
            '" onClick=\'get_unit_id(); LoadUnitPage("' . base_url() . 'unit/unit/add/%s/%s' .
            '","page_content"); return false;\'>' .
      		'%s' . '</a>';
      $this->COPYUNIT_HTML = '<a id="copyunit_html" href="' . base_url() . 'unit/unit/copy_index/%s' .
            '" onClick=\'get_unit_id(); LoadUnitPage("' . base_url() . 'unit/unit/copy_index/%s' .
            '","page_content"); return false;\'>' .
      		lang('menu_copyunit') . '</a>';
      		 //hidden  UNIT_HTML_HIDE
      $this->UNIT_HTML_HIDE = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/index/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/index/%s"); return false;\'><span class="hidecourse_unit">%s</span></a>';
      $this->UNIT_HTML = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/index/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/index/%s"); return false;\'>%s</a>';
      $this->UNITEDITVIEW_HTML = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/editview/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/editview/%s"); return false;\'>%s</a>';
      		//hidden  UNITEDIT_HTML_HIDE
      $this->UNITEDIT_HTML_HIDE = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/edit/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/edit/%s"); return false;\'><span class="hidecourse_unit">%s</span></a>';
      $this->UNITEDIT_HTML = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/edit/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/edit/%s"); return false;\'><span class="editunitnode">%s</span></a>';
      $this->UNITEDIT_HTML_LOCKED = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/edit/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/edit/%s"); return false;\'><span class="editunitnode_lock">%s</span></a>';
      $this->UNITEDIT_HTML_MY = '<a id="otherunitnode" href="' . base_url() .
            'unit/unit/edit/%s" onClick=\'get_unit_id(); ajaxGetpage("page_content","' . base_url() .
            'unit/unit/edit/%s"); return false;\'><span class="editunitnode_my">%s</span></a>';

      $flashparams = 'false';
      $swfurl = osa_include_path() . 'flashchart.swf';
		$j_divid = 'unit_calendar'; //_chart_divid 'flashchart_assessment';
		$j_width = 1000;
		$bustcache = time();
		//Encode in jscript so don't need it here, unencoded version needed in jscript also
		//$dataurl = urlencode(base_url() . "chart/chart/get/$j_divid/$bustcache");
		$url_unitcalendar = base_url() . "course/unitcalendar/process/%s";
		$url_flash = base_url() . "chart/chart/get/unit_calendar";
		//Future enhancement, make the following a multi-dimension jscript array to support more than one chart
		//%s is height
		$flashparams = "['$swfurl','$j_divid',$j_width,'%s','$url_flash']";
		$url_unittotal = base_url() . 'course/unitcalendar/unittotal/%s';
		$title = lang('menu_unit_calendar');
		$divid = 'unit_calendar';
		$this->UNITCALENDAR_HTML = "<a href='$url_unitcalendar' onclick=\"unitcalendar('$url_unitcalendar','$title',1150," .
											"'$divid','$divid',$flashparams,'$url_unittotal');return false;\" >$title</a>";

      /*
      $this->EDITUNITREAD_HTML = '<a href="' . base_url() .
            'unit/unit/index/%s" onClick=\'ajaxGetpage("page_content","' . base_url() .
            'unit/unit/index/%s"); return false;\'><span class="editunitnode">%s</span></a>';
      $this->UNIT_NOTSAVED_HTML = '<a href="' . base_url() .
            'unit/unit/index/%s" onClick=\'ajaxGetpage("page_content","' . base_url() .
            'unit/unit/index/%s"); return false;\'><span class="editunitnode">%s</span></a>';
     */
      //newDhtmlWindow('http://nb2/cms/unit/itstd/addo/8/12/9','IT Standards',900,800,'itstandards')
      $url = base_url() . "unit/itstd/sample/" . CMS_ITSTANDARDS_TYPE .
      		'/' . CMS_ITSTANDARDS_RESOURCE_TYPE . '/%s';
      $this->ITSTANDARDS_UPLOAD_HTML = '<a href="' . $url .  '" onClick="newDhtmlWindow(\'' . $url .
      			'\',\'' . lang('menu_ict_upload') . '\',900,800,\'itstandards\'); return false;" \><span class="editunitnode">%s</span></a>';

      $this->CI->load->library('cms/cms_template/cms_template');
      $this->unit_types = $this->CI->cms_template->templateid_filenames(CMS_TEMPLATE_UNIT_IDENTIFIER);
      $this->CI->load->helper('html');
}

	//Put the mycourse ids into an associate array for faster searches
	private function set_mycourses_hash(&$courses) {
      if ( is_null($this->mycourses_hash) ) {
      	$this->mycourses_hash = array();
      	foreach($courses as $course) {
      		//PHP won't create associate arrays even if you cast an integrer to string
      		//so, add prefix string 'id'
      		$id = 'id' . $course['id'];
            $this->mycourses_hash[$id] = $course;
      	}
      }
	}

	private function is_my_course($courseid) {
		return array_key_exists('id' . $courseid, $this->mycourses_hash);
	}

	//My courses and can edit
	private function is_my_editcourse($courseid) {
		if (array_key_exists('id' . $courseid, $this->mycourses_hash)) {
			$course = $this->mycourses_hash['id' . $courseid];
			return $course['iseditor'];
		}
		return false;
	}

	// Course Node - Add a single course node, all tress have to use this call for generating a course node
  	function course_node(&$mycourse, $unique_prefix, $link, $hideDisbledCourse = FALSE) {
		$enabled = $mycourse['enabled'];
  		if ( !$enabled ) {
      	//$coursename = "<font class='disable_course'>$coursename</font>";
      	//Disabled course, just return nothing;
      	return '';
      }
      $course_idname = $unique_prefix . 'course' . $mycourse['id'];
      $unitname = $unique_prefix . 'courseunit' . $mycourse['id'];
      $course_detail = $mycourse['name'];
      $courseid = $mycourse['id'];
      $data_course = '';
      $hidden = $mycourse['hidden'];
 		if ( $hidden == CMS_HIDDEN_YES ){
 			$course_htmltext = "<span id='{$course_idname}' class='hidecourse_unit'>{$course_detail}</span>";
			$data_course = $this->add_jstreenode($course_idname, $course_htmltext, $link, NULL, FALSE, TRUE);
      }
      else {
      	$course_htmltext = "<span id='{$course_idname}' class='course_unit'>{$course_detail}</span>";
			$data_course = $this->add_jstreenode($course_idname, $course_htmltext, $link, NULL, FALSE, TRUE);
      }
     	return $data_course;
   }

	/* Create course details eg.
	 * # Course Description
	 * # Course Summary
	 * # Learning Targets
	 * # Unit Calendar
	 * [+] Units
	 */
	function course_node_detail($courseid, $unique_prefix) {
		if ( !is_numeric($courseid) ) {
			return FALSE;
		}
   	$data_coursedetail = '';
		//$courseid = $mycourse['id'];
		$unitname = $unique_prefix . 'courseunit' . $courseid;
   	//Course Description
      $course_desc_htmltext = sprintf($this->COURSE_DESC_HTML,$courseid, $courseid);
      $course_desc_id = "{$unique_prefix}desc_". $courseid ;
	   $data_coursedetail .= $this->add_jstreenode($course_desc_id, $course_desc_htmltext, NULL, NULL, FALSE, FALSE);
		//Course Summary
      $course_sum_htmltext = sprintf($this->COURSE_SUM_HTML, $courseid, $courseid);
      $course_sum_id = "{$unique_prefix}sum_". $courseid ;
		$data_coursedetail .= $this->add_jstreenode($course_sum_id, $course_sum_htmltext, NULL, NULL, FALSE, FALSE);
		//Learning target
		$course_target_id = "{$unique_prefix}target_". $courseid;
		if ( $this->is_my_editcourse($courseid) || $this->isAdminUnitWrite ){
			$course_learningtarget_htmltext = sprintf($this->TARGET_EDIT_HTML, $courseid, $courseid);
		}
		else {
			$course_learningtarget_htmltext = sprintf($this->TARGET_HTML, $courseid, $courseid);
		}
      $data_coursedetail .= $this->add_jstreenode($course_target_id, $course_learningtarget_htmltext, NULL, NULL, FALSE, FALSE);
      //Unit Calendar
      $menu_units = lang('menu_units');
      if ( $this->CI->config->item('cms_no_unit_calendar') === FALSE ){
	      //$units = $this->CI->course_model->get_unit_calendar($courseid);
	      $swf_hight = 75;
	      //$window_hight = 170;
	      /* Setting the height in the Javascript and get the unit total each time a calendar is created.
	       * Just assign dummy value 75
	      if ( count($units) > 1 ){
	      	$swf_hight = $swf_hight + (count($units)*35);
	      	$window_hight = $window_hight + (count($units)*35);
	      }
	      */
	      $unit_calendar_htmltext = sprintf($this->UNITCALENDAR_HTML, $courseid, $courseid, $swf_hight, $courseid);
	      $data_coursedetail .= $this->add_jstreenode("{$unique_prefix}unitcal_$courseid", $unit_calendar_htmltext, NULL, NULL, FALSE, FALSE);
       }
       $units_htmltext = "<a href='' name='menu/menu/unit/{$courseid}/{$unique_prefix}/'>{$menu_units}</a>";
		 $data_coursedetail .= $this->add_jstreenode($unitname, $units_htmltext, NULL, NULL, FALSE, TRUE);
		 return $data_coursedetail;
   }

   function show_units($courseid, $unique_prefix) {
   	if ( !is_numeric($courseid) ){
			return FALSE;
		}
   	$showunits_html = '';
		$mycourse = $this->CI->menu_model->get_one_course($courseid);
   	$enabled = $mycourse['enabled'];
   	if (!$enabled ) {
   		//A disabled course should not get here so just return nothing
   		return FALSE;
   	}

   	$canedit = ( $this->is_my_editcourse($mycourse['id']) || $this->isAdminUnitWrite );
   	if (  $canedit || $this->is_my_course($courseid) ) {
   		//Gets all unit including hidden ones
			$units = $this->CI->unit_model->getunits_bystartdate($mycourse['id'],CMS_ADMIN_ALL);
   	}
		else{
			//Only get non-hidden units
			$units = $this->CI->unit_model->getunits_bystartdate($mycourse['id'],CMS_DB_BOOLEAN_FALSE);
		}
		//$nodename = $unique_prefix . 'course' . $mycourse['id'];
      //$unitname = "root";

      //$i tells do we have units or not
	    $i=0;
	    $editline_htmltext = '<span class="menueditline">- ' . lang('menu_publishedunits') .':</span>';
		 $publishline_id = "{$unique_prefix}pub_$courseid";
		 $showunits_html .= $this->add_jstreenode($publishline_id, $editline_htmltext, NULL, NULL, FALSE, FALSE);
  		 if ( $units ) {
  		 	$editing_units = array();
  		 	//Add published units
  		 	//$loop_published = 0; //create loop for array
			foreach ($units as $unit) {
	         //hidden UNIT_HTML_HIDE
		      $hidden=$unit->hidden;
		      if ( $canedit || $this->is_my_course($courseid) ) {
		      	if ($hidden==CMS_HIDDEN_YES){
		      		$UNIT_HTML=$this->UNIT_HTML_HIDE;
		      	}
		      	else {
		      		$UNIT_HTML=$this->UNIT_HTML;
		      	}
		      }
		      else {
		      	$UNIT_HTML=$this->UNIT_HTML;
		      }
				// for meta, integrated and unified
				$utype = $this->_get_unittype_shortlang($unit->type);
				$html = '';
				//create an array with all the editing units so we can print them after the published units
				if ( $unit->status == $this->CI->unit_model->STATUS_EDIT ) {
					if ( $canedit || $this->is_my_course($courseid) )
						$editing_units[] = $unit;
						continue;
				}

				if ( $canedit && ( $unit->type == $this->CI->unit_model->TYPE_INT_PARENT ||
					  $unit->type == $this->CI->unit_model->TYPE_UNI_PARENT ||
					  $unit->type == $this->CI->unit_model->TYPE_UNI ||
					  $unit->type == $this->CI->unit_model->TYPE_INT )){
					$html = sprintf($UNIT_HTML,$unit->id,$unit->id,$unit->title.$utype);
				}
				else {
					$html = sprintf($UNIT_HTML,$unit->id,$unit->id,$unit->title);
				}
				if ( $html != '' ) {
					$unitindex_id = "{$unique_prefix}unitindex_" . $unit->id;
					$unitindex_htmltext = $html;
					//loop pubished
					$showunits_html .= $this->add_jstreenode($unitindex_id, $unitindex_htmltext, NULL, NULL, FALSE, FALSE);
					//$loop_published++;
					$i=1;
				}
			} //end foreach ($units as $unit)

			//Add editing units
  		 	if ( count($editing_units) > 0 ) {
  		 		$menu_editingunits = lang('menu_editingunits');
				$editline_id = "{$unique_prefix}editline" . $courseid;
				$editline_htmltext = '<span class="menueditline">- ' . $menu_editingunits .':</span>';
				//add menu editing
				$showunits_html .= $this->add_jstreenode($editline_id, $editline_htmltext, NULL, NULL, FALSE, FALSE);

				foreach ($editing_units as $unit) {
					// fix bug error when unit lost editorid
					if (!isset($unit->editorid))
						$unit->editorid = null;
					$utype = $this->_get_unittype_shortlang($unit->type);
					$html = '';
					if ( $canedit ) {
						//hidden UNITEDIT_HTML_HIDE
						$hidden=$unit->hidden;
						if ($hidden==CMS_HIDDEN_YES){
							$UNITEDIT_HTML=$this->UNITEDIT_HTML_HIDE;
		      		}
		      		elseif ( !is_null($unit->editorid) && $unit->editorid != $this->userobj->id ) {
							$UNITEDIT_HTML=$this->UNITEDIT_HTML_LOCKED;
						}
						elseif ( !is_null($unit->editorid) && $unit->editorid == $this->userobj->id ) {
							$UNITEDIT_HTML=$this->UNITEDIT_HTML_MY;
						}
		      		else {
		      		 	$UNITEDIT_HTML=$this->UNITEDIT_HTML;
		      		}
						if ($unit->type != $this->CI->unit_model->TYPE_INT_PARENT &&
							 $unit->type != $this->CI->unit_model->TYPE_UNI_PARENT &&
							 $unit->type != $this->CI->unit_model->TYPE_UNI &&
							 $unit->type != $this->CI->unit_model->TYPE_INT )
							 $utype ='';
						$html = sprintf($UNITEDIT_HTML,$unit->id,$unit->id,$unit->title.$utype);
					}
					else {
						$html = sprintf($this->UNITEDITVIEW_HTML,$unit->id,$unit->id,$unit->title);
					}
					if ( $html != '' ) {
						$unitindex_id = "{$unique_prefix}editunit_" . $unit->id;
						$unitindex_htmltext = $html;
						// loop add edit
						$showunits_html .= $this->add_jstreenode($unitindex_id, $unitindex_htmltext, NULL, NULL, FALSE, FALSE);
						$i=1;
					}
				} //end foreach ($editing_units as $unit)
			} //end if ( count($editing_units) > 0 )
		}

		//Add the add unit links in the course tree
		if ( !isset($editing_units) || count($editing_units) == 0 ) {
			$menu_editingunits = lang('menu_editingunits');
			$editline_id = "{$unique_prefix}editline" . $courseid;
			$editline_htmltext = '<span class="menueditline">- ' . $menu_editingunits .':</span>';
			// edit line
			$showunits_html .= $this->add_jstreenode($editline_id, $editline_htmltext, NULL, NULL, FALSE, FALSE);
		}

		if ( $canedit && $enabled ) {
			$unit_template = $this->CI->config->item('cms_unit_templates');
			$displaygrade = $this->CI->course_model->get_displaygrades($courseid,true);

		    if (!is_array($displaygrade)){
			    $course = $this->CI->course_model->get_course($courseid);
			    $gmin = $course->gmin;
			    $gmax = $course->gmax;
			    if ( $course->gmin > $course->gmax){
			    	$gmin = $course->gmax;
			    	$gmax = $course->gmin;
			    }
			    $displaygrade  = $this->CI->course_model->get_gradebyin($gmin,$gmax,FALSE);
		    }

		    if ( is_array($unit_template) && count($unit_template) > 0 ){
		    //Config ['cms_unit_templates'] is defined so use the layout for add unit links
				if ( is_array($displaygrade) ){
					//Loop 's $displaygrade
					$displaygrade_unit_template = array();
					$link_unit_template = array();
					foreach ($displaygrade as $grade){
						//Start of (issue: 133)
						if ( !array_key_exists($grade->gradeid, $unit_template) ) {
							//Once we found a grade that is not defined in config then we just use all template types
							//This is will overwrite any previous assignment since we are going to assign all any way
							$link_unit_template = $this->unit_types;
							break;
						}
						//End of (issue: 133)
						$displaygrade_unit_template[$grade->gradeid] = $unit_template[$grade->gradeid];
						foreach ($displaygrade_unit_template as $displaygrade_unit){
							foreach ($displaygrade_unit as $template){
								if (!in_array($template,$link_unit_template)) {
									$link_unit_template[] = $template;
								}
							}
						}
					}
				}
		    } // end if ( is_array($unit_template) && count($unit_template) > 0 )
		    else {
		    	//Use the unit types generated from the cms_templates
		    	//This is what makes it plug and play :)
		    	$link_unit_template = $this->unit_types;
		    }
   		//Loop 's $link_unit_template
   		//$loop_linkunit = 4000; // create loop for array. Using 4000 to avoid same name of array
   		$template_index = 1;
			foreach ( $link_unit_template as $template ) {
				$add_template_unit_atag = $this->format_addunit_link($template,$mycourse['id']);
				$unitadd_id = "{$unique_prefix}unitadd{$template_index}_" . $mycourse['id'];
				$unitadd_htmltext = $add_template_unit_atag;
				$showunits_html .= $this->add_jstreenode($unitadd_id, $unitadd_htmltext, NULL, NULL, FALSE, FALSE, 'editicon_type');
			   $i = 1;
			   $template_index++;
			}
   	} // if ( $canedit && $enabled )

   	//Copy unit link at the bottom
	   $iscoyunit= $this->CI->config->item('cms_unit_copyunit');
	 	if ( $iscoyunit!=FALSE ){
	 	  	if ( $canedit && $enabled ) {
			 	$html = sprintf($this->COPYUNIT_HTML,$mycourse['id'],$mycourse['id'],$mycourse['id'],$unique_prefix);
			 	$unitadd_id = "{$unique_prefix}unitcopy_" . $mycourse['id'];
			 	$unitadd_htmltext = $html;
			 	// copy unit add
			 	$showunits_html .= $this->add_jstreenode($unitadd_id, $unitadd_htmltext, NULL, NULL, FALSE, FALSE, 'copyicon_type');
		     	$i = 1;
	    	}
	 	}

   	if ( $i <= 0 ) {
   		$nounit_id = "{$unique_prefix}nounit_" . $mycourse['id'];
   		$nounit_htmltext = lang('menu_nounits');
   		// no unit
   		$showunits_html .= $this->add_jstreenode($nounit_id, $nounit_htmltext, NULL, NULL, FALSE, FALSE);
		}
		//Slow down response
		//sleep(0.5);
		return $showunits_html;
   }

	/* Create mycourse tree by using array result from  mycourses model
	 * @return string $mycourse_tree List html of owner course node
	 */
	function get_mycoursetree() {
		$mycourses_array = $this->mycourses;
		$menu_mycourses = lang('menu_mycourses');
		$menu_mycourses = "<a>{$menu_mycourses}</a>";
		$link = base_url() . "menu/menu/mycourses_detail/";
		$course_idname = "myu";
		//$pointer = 0;
		// create root
		$root_obj = new jstree_html_element('li');
		$root_obj->set_id('root');
		$root_obj->set_innertext($menu_mycourses);
		$root_obj->set('rel','mytree_icon_type');
		// create child
		$child_obj = new jstree_html_element('ul');

		$have_course = FALSE;
	   if ( !empty($mycourses_array) ) {
			$childlist = '';
			foreach ( $mycourses_array as $result ) {
				$canedit = ( $result['iseditor'] || $this->isAdminUnitWrite );
				if ( $canedit || $result['hidden'] == CMS_DB_BOOLEAN_FALSE ) {
					$nodeid = $course_idname.$result['id'];
					$list_obj = new jstree_html_element('li');
					$list_obj->set_id($nodeid);
					$list_obj->set_class_jstreeclosed();
					//use pointer to identify detail
					$get_link = $link . $result['id'];
					$link_obj = new jstree_html_element('a');
					$link_obj->set_title($get_link);
					$link_obj->set_href_novalue();
					// (issue: 120) course name must has span class to using in change_course() in app.js
					$course_name = "<span class=\"course_unit\">{$result['name']}</span>";
					if ( $result['hidden'] == CMS_DB_BOOLEAN_TRUE ) {
						$course_name = "<span class=\"hidecourse_unit\">{$result['name']}</span>";
					}
					$link_obj->set_innertext($course_name);
					$list_obj->append_html($link_obj);
					$childlist .= $list_obj->render();
					$have_course = TRUE;
				}
			}
			if ( $have_course ) {
				$child_obj->set_innertext($childlist);
			}
	   }

	   // if array is empty then show no course
		if ( !$have_course ) {
			$childlist_obj = new jstree_html_element('li');
			$childlist_obj->set_id('nomycourse');
			$nocources_text = '<span class=\'menutree_nomycourse\'>' . lang('menu_nomycourses') . '</span>';
			$childlist_obj->set_innertext($nocources_text);
			$child_obj->append_html($childlist_obj);
	   }

	   //insert child into root
	   $root_obj->append_html($child_obj);
	   $mycourse_tree = $root_obj->render();
	   return $mycourse_tree;
	}

	/* Get course deatil such as description, summary, learning targets and unit
	 * @return string $mycourse_details List of html owner course node details
	 */
	function get_mycourse_details($courseid) {
		return $this->course_node_detail($courseid, 'myu');
	}

	/* Create department tree by using array result from getalldepartment() model
	 * @return string $department_tree List html of all deapartment
	 */
	function get_depttree() {
		// create root
		$root_obj = new jstree_html_element('li');
		$root_obj->set_id('root');
		$department_courselist = lang('menu_courselist');
		$root_obj->set_innertext($department_courselist);

		if ( $this->CI->config->item('cms_menutree_use_category') == FALSE ) {
			$dept_result_array = $this->CI->menu_model->getalldepartment();
			osa_array_natsort($dept_result_array, 'name');
			$link =  base_url() . "menu/menu/listdept/%s";
			$course_idname = "dept";
			// create child
			$childlist = $this->add_jstreenode($course_idname, NULL, $link, $dept_result_array, FALSE, TRUE);
			$child_obj = new jstree_html_element('ul');
			$child_obj->set_innertext($childlist);
			// insert child into root
			$root_obj->append_html($child_obj);
		}
		else {
			$categorys = $this->CI->menu_model->getallcategory();
			if ( $categorys ) {
				foreach ($categorys as $record) {
					$cat_obj = new jstree_html_element('li');
					$cat_obj->set_id("cat_{$record->id}");
					/* TODO: (issue: 90) <a> tag is a hack to show folder icon for categories.
					Please find better solution and take the hack out. */
					$cat_obj->set_innertext("<a>{$record->name}</a>");
					$cat_obj->set_class_jstreeclosed();
					$ul_container = new jstree_html_element('ul');

					$link = base_url() . "menu/menu/listdept/%s/{$record->id}";
					$departments = $this->CI->menu_model->getdepartment_bycategory($record->id);
					$dept_nodes_html = $this->add_jstreenode("dept_{$record->id}_", NULL, $link, $departments, FALSE, TRUE);

					$ul_container->set_innertext($dept_nodes_html);
					$cat_obj->append_html($ul_container);
					$ul_container = new jstree_html_element('ul');
					$ul_container->set_class_jstreeclosed();
					$ul_container->set_innertext($cat_obj->render());
					$root_obj->append_html($ul_container);
				}
			}
		}

		$department_tree = $root_obj->render();
		return $department_tree;
	}

	/* Get all courses for the supplied department
	 * @return string $department_course List of html department course node
	 */
	function get_coursesbydept($id, $catid=FALSE) {
		if ( !is_numeric($id) ){
			return FALSE;
		}
		if ( $this->CI->config->item('cms_menutree_use_category') == FALSE ) {
			$courses_dept = $this->CI->menu_model->getcourse($id);
		}
		else {
			$courses_dept = $this->CI->menu_model->getcourse_usecategory($id, $catid);
		}
		osa_array_natsort($courses_dept, array('tree_sort', 'name'));
		$menu_nocourses = lang('menu_nocourses');
		$type = "dept";

		$department_course = '';
		if ( !$courses_dept ) {
			$courses_dept = array();
		}
		$have_course = FALSE;
		foreach( $courses_dept as $record ) {
			$canedit = ( $this->is_my_editcourse($record['id']) || $this->isAdminUnitWrite );
			if ( $canedit || $record['hidden'] == CMS_DB_BOOLEAN_FALSE ) {
				$link = base_url() . "menu/menu/deptcourses_detail/{$record['id']}";
				$department_course .= $this->course_node($record, 'deptu' , $link);
				$have_course = TRUE;
			}
		 }
		 if ( !$have_course ) {
			$department_course = $this->add_jstreenode('gradenocourse'. $id , $menu_nocourses, NULL, NULL, TRUE, TRUE);
		 }
		return  $department_course;
	}

	/* Get course deatil such as description, summary, learning targets and unit
	 * @return string $department_coursedetail List of html department course node details
	 */
	function get_coursesbydept_details($courseid) {
	   return $this->course_node_detail($courseid, 'deptu');
	}

	/* Create grade tree by using array result from getgrade() model
	 * @return string $grade_tree List html of all grade
	 */
	function get_gradetree() {
		$grade_result_array = $this->CI->menu_model->getgrade();
		$gradelist = lang('menu_gradelist');
		$link = base_url() . "menu/menu/listgrade/%s";
		$course_idname = "grade";
		// create root
		$root_obj = new jstree_html_element('li');
		$root_obj->set_id('root');
		$root_obj->set_innertext($gradelist);
		// create child
		$childlist = $this->add_jstreenode($course_idname, NULL, $link, $grade_result_array, FALSE, TRUE);
		$child_obj = new jstree_html_element('ul');
		$child_obj->set_innertext($childlist);
		// insert child into root list
		$root_obj->append_html($child_obj);
		$grade_tree = $root_obj->render();

		return $grade_tree;
	}

	/* Get all courses for the supplied grade
	 * @return string $grade_course List of html grade course node
	 */
	function get_coursesbygrade($id) {
		if ( !is_numeric($id) ){
			return FALSE;
		}
		$courses_grade = $this->CI->menu_model->get_coursesbygrade($id);
		osa_array_natsort($courses_grade, array('tree_sort', 'name'));
		$menu_nocourses = lang('menu_nocourses');
		//$type = "grad";
		$grade_course = '';
		if ( !$courses_grade ) {
			$courses_grade = array();
		}
		$have_course = FALSE;
		foreach( $courses_grade as $record ) {
			$canedit = ( $this->is_my_editcourse($record['id']) || $this->isAdminUnitWrite );
			if ( $canedit || $record['hidden'] == CMS_DB_BOOLEAN_FALSE ) {
				$link = base_url() . "menu/menu/gradecourses_detail/{$record['id']}";
				$grade_course .= $this->course_node($record, 'gradeu' , $link);
				$have_course = TRUE;
			}
	   }
		if ( !$have_course ) {
			$grade_course = $this->add_jstreenode('gradenocourse'. $id , $menu_nocourses, NULL, NULL, TRUE, TRUE);
	   }
	   return  $grade_course;
	}

	/* Get course deatil such as description, summary, learning targets and unit
	 * @return string $grade_coursedetail List of html grade course node details
	 */
	function get_coursesbygrade_details($courseid) {
		return $this->course_node_detail($courseid, 'gradeu');
	}

	function add_jstreenode($id_name, $innertext, $link, $data_array, $no_result, $expand, $override_type=FALSE){
		$tree_generate = new jstree_generate();
		$jstree_node = $tree_generate->render($id_name, $innertext, $link, $data_array, $no_result, $expand, $override_type);
		return $jstree_node;
	}

	/*
	 * Case Unit Type to Unit Language
	 */
	private function _get_unittype_shortlang($type) {
		$shortname = '';
		switch ($type) {
			case $this->CI->unit_model->TYPE_NORMAL:
				break;
			case $this->CI->unit_model->TYPE_META:
				//$shortname = " (".substr(lang('unit_metaunit'),0,1).")";
				$shortname = " (". lang('unit_metasymbol') . ")";
				break;
			case $this->CI->unit_model->TYPE_INT_PARENT:
				//$shortname = " (".substr(lang('unit_integratedunit'),0,1).")";
				$shortname = " (". lang('unit_intsymbol') . ")";
				break;
			case $this->CI->unit_model->TYPE_INT:
				//$shortname = " (".substr(lang('unit_integratedunit'),0,1).")";
				$shortname = " (". lang('unit_intsymbol') . ")";
				break;
			case $this->CI->unit_model->TYPE_UNI_PARENT:
				//$shortname = " (".substr(lang('unit_unifiedunit'),0,1).")";
				$shortname = " (". lang('unit_unisymbol') . ")";
				break;
			case $this->CI->unit_model->TYPE_UNI:
				//$shortname = " (".substr(lang('unit_unifiedunit'),0,1).")";
				$shortname = " (". lang('unit_unisymbol') . ")";
				break;
      	}
      	return $shortname;
	}

	function get_unit($status) {
		return $this->CI->unit_model->get_countunit($status);
		/*
		$unit = $this->CI->unit_model->get_countunit($status);
		if (isset($unit) && $unit != FALSE)
			return count($unit);
		else
			return 0;
			*/
	}

	// Formats the a anchor link for all the add unit links
	private function format_addunit_link($template, $courseid) {
		$link_title = lang('menu_unit_add') . osa_unittype_translate($template, 1);
		$add_template_unit = sprintf($this->ADDUNIT_TEMPLATE_HTML,$courseid,$template,
									$courseid,$template,$link_title);
		return $add_template_unit;
	}

	/* moved to osautil_helper
	//Returns an array containg arrays for the 3 trees on the left menu
	//[0] - the tree name, [1] - the actual jstree html, [2] name for the other 2 trees (for hightlight deselect)
	function get_all_tree_data() {
		$tree_init_params = array();
		$tmp = array("'course_tree'", $this->_escape_jscript_str($this->get_mycoursetree()), "'#dept_tree,#grade_tree'");
		$tree_init_params['course_tree'] = $tmp;
		$tmp = array("'dept_tree'", $this->_escape_jscript_str($this->get_depttree()), "'#course_tree,#grade_tree'");
		$tree_init_params['dept_tree'] = $tmp;
		$tmp = array("'grade_tree'", $this->_escape_jscript_str($this->get_gradetree()), "'#course_tree,#dept_tree'");
		$tree_init_params['grade_tree'] = $tmp;
		return $tree_init_params;
	}

	//Generate and escapes a string for jscript string format.
	private function _escape_jscript_str($str) {
	 	$str = str_replace("\\", "\\\\", $str);
		$str = str_replace("'","\'",$str);
		return "'{$str}'";
	}
	*/
}
?>