Juan Carlos Raña 14 jaren geleden
bovenliggende
commit
c1ad4a3073

+ 13 - 24
main/coursecopy/classes/CourseBuilder.class.php

@@ -74,9 +74,7 @@ class CourseBuilder {
 			$this->build_links($session_id,$course_code);
 			$this->build_course_descriptions($session_id,$course_code);
 			$this->build_wiki($session_id,$course_code);
-
 		} else {
-
 			$table_link = Database :: get_course_table(TABLE_LINKED_RESOURCES);
 			$table_properties = Database :: get_course_table(TABLE_ITEM_PROPERTY);
 
@@ -106,13 +104,11 @@ class CourseBuilder {
 			}
 		}
 
-		foreach ($this->course->resources as $type => $resources)
-		{
+		foreach ($this->course->resources as $type => $resources) {
 			foreach ($resources as $id => $resource)
 			{
 				$tool = $resource->get_tool();
-				if ($tool != null)
-				{
+				if ($tool != null) {
 					$sql = "SELECT * FROM $table_properties WHERE TOOL = '".$tool."' AND ref='".$resource->get_id()."'";
 					$res = Database::query($sql);
 					$all_properties = array ();
@@ -124,15 +120,13 @@ class CourseBuilder {
 				}
 			}
 		}
-		
-		
 		return $this->course;
 	}
+	   
 	/**
 	 * Build the documents
 	 */
-	function build_documents($session_id = 0,$course_code = '')
-	{
+	function build_documents($session_id = 0,$course_code = '') {
 
 		if (!empty($course_code) && !empty($session_id)) {
 			$course_info = api_get_course_info($course_code);
@@ -176,8 +170,7 @@ class CourseBuilder {
 	/**
 	 * Build the forums
 	 */
-	function build_forums()
-	{
+	function build_forums() {
 		$table = Database :: get_course_table(TABLE_FORUM);
 		$sql = 'SELECT * FROM '.$table;
 		$db_result = Database::query($sql);
@@ -193,22 +186,20 @@ class CourseBuilder {
 	/**
 	 * Build a forum-category
 	 */
-	function build_forum_category($id)
-	{
+	function build_forum_category($id) {
 		$table = Database :: get_course_table(TABLE_FORUM_CATEGORY);
 		$sql = 'SELECT * FROM '.$table.' WHERE cat_id = '.$id;
 		$db_result = Database::query($sql);
-		while ($obj = Database::fetch_object($db_result))
-		{
+		while ($obj = Database::fetch_object($db_result)) {
 			$forum_category = new ForumCategory($obj->cat_id, $obj->cat_title, $obj->cat_comment, $obj->cat_order, $obj->locked, $obj->session_id);
 			$this->course->add_resource($forum_category);
 		}
 	}
+    
 	/**
 	 * Build the forum-topics
 	 */
-	function build_forum_topics()
-	{
+	function build_forum_topics() {
 		$table = Database :: get_course_table(TABLE_FORUM_THREAD);
 		$sql = 'SELECT * FROM '.$table;
 		$db_result = Database::query($sql);
@@ -218,6 +209,7 @@ class CourseBuilder {
 			$this->course->add_resource($forum_topic);
 		}
 	}
+    
 	/**
 	 * Build the forum-posts
 	 * TODO: All tree structure of posts should be built, attachments for example.
@@ -325,18 +317,15 @@ class CourseBuilder {
 		}
 
 		$db_result = Database::query($sql);
-		while ($obj = Database::fetch_object($db_result))
-		{
-			if (strlen($obj->sound) > 0)
-			{
+		while ($obj = Database::fetch_object($db_result)) {
+			if (strlen($obj->sound) > 0) {
 				$doc = Database::fetch_object(Database::query("SELECT id FROM ".$table_doc." WHERE path = '/audio/".$obj->sound."'"));
 				$obj->sound = $doc->id;
 			}
 			$quiz = new Quiz($obj->id, $obj->title, $obj->description, $obj->random, $obj->type, $obj->active, $obj->sound, $obj->max_attempt, $obj->results_disabled, $obj->access_condition, $obj->start_time, $obj->end_time, $obj->feedback_type, $obj->random_answers, $obj->expired_time);
 			$sql = 'SELECT * FROM '.$table_rel.' WHERE exercice_id = '.$obj->id;
 			$db_result2 = Database::query($sql);
-			while ($obj2 = Database::fetch_object($db_result2))
-			{
+			while ($obj2 = Database::fetch_object($db_result2)) {
 				$quiz->add_question($obj2->question_id, $obj2->question_order);
 			}
 			$this->course->add_resource($quiz);

+ 2 - 1
main/coursecopy/classes/CourseRestorer.class.php

@@ -71,6 +71,7 @@ class CourseRestorer
 			$this->course->destination_path = $course_info['path'];
 		} else {
 			$course_info = Database :: get_course_info($destination_course_code);
+            
 			$this->course->destination_db = $course_info['database'];
 			$this->course->destination_path = $course_info['directory'];
 		}
@@ -969,7 +970,7 @@ class CourseRestorer
                     $question_option_id = Database::insert($table_options, $item);
                     $old_option_ids[$old_id] = $question_option_id;
                 }               
-                $new_answers = Database::find($table_ans,'id, correct', array('question_id = ?'=>$new_id));
+                $new_answers = Database::select('id, correct', $table_ans, array('where'=>array('question_id = ?'=>$new_id)));
                 foreach ($new_answers as $answer_item) {                	
                     $params['correct'] = $old_option_ids[$answer_item['correct']];
                     $question_option_id = Database::update_query($table_ans, $params, array('id = ?'=>$answer_item['id']));

+ 73 - 23
main/exercice/answer.class.php

@@ -38,6 +38,7 @@ class Answer
 	public $nbrAnswers;
 	public $new_nbrAnswers;
 	public $new_destination; // id of the next question if feedback option is set to Directfeedback
+    public $course;
 
 /**
 	 * constructor of the class
@@ -45,7 +46,7 @@ class Answer
 	 * @author 	Olivier Brouckaert
 	 * @param 	integer	Question ID that answers belong to
 	 */
-	function Answer($questionId) {
+	function Answer($questionId, $course_id = null) {
 		//$this->questionType=$questionType;
 		$this->questionId			= intval($questionId);
 		$this->answer				= array();
@@ -58,11 +59,20 @@ class Answer
 		$this->destination  		= array();
 		// clears $new_* arrays
 		$this->cancel();
+        
+        if (!empty($course_id)) {
+            $this->course_id        = intval($course_id);
+            $course_info            =  api_get_course_info_by_id($this->course_id);
+        } else {            
+            $course_info = api_get_course_info();
+        }
+        $this->course   = $course_info; 
+        
 
 		// fills arrays
-		$objExercise = new Exercise();
+		$objExercise = new Exercise($this->course['real_id']);
 		$objExercise->read($_REQUEST['exerciseId']);		
-		if($objExercise->random_answers=='1') {
+		if ($objExercise->random_answers=='1') {
 			$this->readOrderedBy('rand()', '');// randomize answers
 		} else {
 			$this->read(); // natural order
@@ -91,9 +101,8 @@ class Answer
 	 *
 	 * @author - Olivier Brouckaert
 	 */
-	function read() {
-		global $_course;
-		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
+	function read() {		
+		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 
 		$questionId=$this->questionId;
 		//$answerType=$this->selectType();
@@ -127,8 +136,7 @@ class Answer
 	 * @param	string	DESC or ASC
 	 * @author 	Frederic Vauthier
 	 */
-	function readOrderedBy($field,$order='ASC') {
-		global $_course;
+	function readOrderedBy($field,$order='ASC') {		
 		$field = Database::escape_string($field);
 		if (empty($field)) {
 			$field = 'position';
@@ -137,7 +145,7 @@ class Answer
 		if ($order != 'ASC' && $order!='DESC') {
 			$order = 'ASC';
 		}
-		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
+		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 		$questionId=$this->questionId;
 		$sql="SELECT answer,correct,comment,ponderation,position, hotspot_coordinates, hotspot_type, destination, id_auto " .
 				"FROM $TBL_ANSWER WHERE question_id='".$questionId."' " .
@@ -223,7 +231,7 @@ class Answer
 	 * return array answer by id else return a bool
 	 */
 	function selectAnswerByAutoId($auto_id) {
-		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER);
+		$TBL_ANSWER = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 		$auto_id = intval($auto_id);
 		$sql="SELECT id, answer FROM $TBL_ANSWER WHERE id_auto='$auto_id'";
 		$rs = Database::query($sql);
@@ -304,7 +312,7 @@ class Answer
 	  */
 	 function getQuestionType()
 	 {
-	 	$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION);
+	 	$TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $this->course['db_name']);
 	 	$sql = "SELECT type FROM $TBL_QUESTIONS WHERE id = '".$this->questionId."'";
 	 	$res = Database::query($sql);
 	 	if(Database::num_rows($res)<=0){
@@ -424,7 +432,7 @@ class Answer
 	 */
 	function updateAnswers($answer,$comment,$weighting,$position,$destination)
 	{
-		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER);
+		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 
 		$questionId=$this->questionId;
 		$sql = "UPDATE $TBL_REPONSES SET " .
@@ -446,7 +454,7 @@ class Answer
 	 */
 	function save()
 	{
-		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER);
+		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 
 		$questionId=$this->questionId;
 
@@ -494,23 +502,65 @@ class Answer
 	/**
 	 * Duplicates answers by copying them into another question
 	 *
-	 * @author - Olivier Brouckaert
-	 * @param - integer $newQuestionId - ID of the new question
+	 * @author Olivier Brouckaert
+	 * @param  int $newQuestionId - ID of the new question
 	 */
-	function duplicate($newQuestionId)
-	{
-		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER);
+	function duplicate($newQuestionId, $course_info = null) {
+        require_once api_get_path(LIBRARY_PATH).'document.lib.php';
+        
+        if (empty($course_info)) {
+            $course_info = $this->course;
+        } else {
+            $course_info = $course_info;
+        }
+        
+		$TBL_REPONSES = Database :: get_course_table(TABLE_QUIZ_ANSWER, $course_info['db_name']);
+        
+        if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
+                
+              var_dump($this->selectQuestionId(), $newQuestionId);
+              
+            //Selecting origin options 
+            
+            $origin_options = Question::readQuestionOption($this->selectQuestionId(),$this->course['db_name']);
+            var_dump($origin_options);
+            if (!empty($origin_options)) {
+                foreach($origin_options as $item) {
+            	   $new_option_list[]=$item['id'];
+                }
+            }
+            
+            
+            $destination_options = Question::readQuestionOption($newQuestionId,$course_info['db_name']);
+            $i=0;
+            $fixed_list = array();
+            if (!empty($destination_options)) {
+                foreach($destination_options as $item) {                 
+                    $fixed_list[$new_option_list[$i]] = $item['id'];
+                    $i++;
+                }
+            }
+            var_dump($fixed_list);
+        }
 
 		// if at least one answer
-		if($this->nbrAnswers) {
+		if ($this->nbrAnswers) {
 			// inserts new answers into data base
-			$sql="INSERT INTO $TBL_REPONSES" .
-					"(id,question_id,answer,correct,comment," .
-					"ponderation,position,hotspot_coordinates,hotspot_type,destination) VALUES";
-
+			$sql="INSERT INTO $TBL_REPONSES (id,question_id,answer,correct,comment, ponderation,position,hotspot_coordinates,hotspot_type,destination) VALUES";
 			for($i=1;$i <= $this->nbrAnswers;$i++) {
+                if ($course_info['db_name'] != $this->course['db_name']) {                    
+                	$this->answer[$i]  = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->answer[$i],$this->course['id'], $course_info['id']) ;
+                    $this->comment[$i] = DocumentManager::replace_urls_inside_content_html_from_copy_course($this->comment[$i],$this->course['id'], $course_info['id']) ;                    
+                }
+                
 				$answer					= Database::escape_string($this->answer[$i]);
 				$correct				= Database::escape_string($this->correct[$i]);
+                
+                if (self::getQuestionType() == MULTIPLE_ANSWER_TRUE_FALSE) {
+                    var_dump($correct);
+                    $correct = $fixed_list[intval($correct)];
+                }
+                
 				$comment				= Database::escape_string($this->comment[$i]);
 				$weighting				= Database::escape_string($this->weighting[$i]);
 				$position				= Database::escape_string($this->position[$i]);

+ 12 - 8
main/exercice/exercice.php

@@ -435,11 +435,8 @@ event_access_tool(TOOL_QUIZ);
 // Tool introduction
 Display :: display_introduction_section(TOOL_QUIZ);
 
-// selects $limitExPage exercises at the same time
-$from = $page * $limitExPage;
-$sql = "SELECT count(id) FROM $TBL_EXERCICES";
-$res = Database::query($sql);
-list ($nbrexerc) = Database :: fetch_array($res);
+
+
 
 HotPotGCt($documentPath, 1, $_user['user_id']);
 $tbl_grade_link = Database :: get_main_table(TABLE_MAIN_GRADEBOOK_LINK);
@@ -550,11 +547,12 @@ if ($is_allowedToEdit) {
 echo '<div class="actions">';
 
 // display the next and previous link if needed
+// selects $limitExPage exercises at the same time
 $from = $page * $limitExPage;
 $sql = "SELECT count(id) FROM $TBL_EXERCICES";
 $res = Database::query($sql);
 list ($nbrexerc) = Database :: fetch_array($res);
-HotPotGCt($documentPath, 1, $_user['user_id']);
+HotPotGCt($documentPath, 1, api_get_user_id());
 
 //condition for the session
 $session_id = api_get_session_id();
@@ -778,7 +776,13 @@ if ($show == 'test') {
                                     
                     //Showing exercise title
                     $row['title']=text_filter($row['title']);
-                    echo Display::tag('h1',$row['title']);                    
+                    echo Display::tag('h1',$row['title']);        
+                     
+                    if ($session_id == $row['session_id']) {
+                        //Settings                                                                
+                        //echo Display::url(Display::return_icon('settings.png',get_lang('Edit'), array('width'=>'22px'))." ".get_lang('Edit'), 'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$row['id']);
+                    }
+                                  
                     echo '<p>';
                     echo $session_img;
                     $exid = $row['id'];
@@ -800,7 +804,7 @@ if ($show == 'test') {
                     
                     if ($session_id == $row['session_id']) {
                         //Settings                                                                
-                        echo Display::url(Display::return_icon('settings.png',get_lang('Edit'), array('width'=>'22px'))." ".get_lang('Edit'), 'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$row['id']);
+                        echo Display::url(Display::return_icon('edit.gif',get_lang('Edit'), array('width'=>'20px')), 'exercise_admin.php?'.api_get_cidreq().'&modifyExercise=yes&exerciseId='.$row['id']);
                         
                         //Export
                         echo Display::url(Display::return_icon('cd.gif',          get_lang('CopyExercise')),       '', array('onclick'=>"javascript:if(!confirm('".addslashes(api_htmlentities(get_lang('AreYouSureToCopy'),ENT_QUOTES,$charset))." ".addslashes($row['title'])."?"."')) return false;",'href'=>'exercice.php?'.api_get_cidreq().'&choice=copy_exercise&sec_token='.$token.'&exerciseId='.$row['id']));

+ 22 - 11
main/exercice/exercise.class.php

@@ -37,14 +37,16 @@ class Exercise {
   	public $start_time;
 	public $questionList;  // array with the list of this exercise's questions
 	public $results_disabled;
-  	public $expired_time;
+  	public $expired_time;    
+    public $course;
+    
   	
 	/**
 	 * Constructor of the class
 	 *
 	 * @author - Olivier Brouckaert
 	 */
-	function Exercise() {
+	function Exercise($course_id = null) {
 		$this->id				= 0;
 		$this->exercise			= '';
 		$this->description		= '';
@@ -59,6 +61,15 @@ class Exercise {
 		$this->start_time 		= '0000-00-00 00:00:00';
 		$this->results_disabled = 1;
 		$this->expired_time 	= '0000-00-00 00:00:00';
+        
+        if (!empty($course_id)) {
+            $this->course_id        =  intval($course_id);
+            $course_info            =  api_get_course_info_by_id($this->course_id);
+        } else {            
+        	$course_info = api_get_course_info();
+        }
+        $this->course   = $course_info; 
+        
 	}
 
 	/**
@@ -69,9 +80,9 @@ class Exercise {
 	 * @return - boolean - true if exercise exists, otherwise false
 	 */
 	function read($id) {
-	    $TBL_EXERCICE_QUESTION  = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-    	$TBL_EXERCICES          = Database::get_course_table(TABLE_QUIZ_TEST);
-	    $TBL_QUESTIONS          = Database::get_course_table(TABLE_QUIZ_QUESTION);
+	    $TBL_EXERCICE_QUESTION  = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION,$this->course['db_name']);
+    	$TBL_EXERCICES          = Database::get_course_table(TABLE_QUIZ_TEST,$this->course['db_name']);
+	    $TBL_QUESTIONS          = Database::get_course_table(TABLE_QUIZ_QUESTION,$this->course['db_name']);
     	#$TBL_REPONSES           = Database::get_course_table(TABLE_QUIZ_ANSWER);
 
 		$sql="SELECT title,description,sound,type,random, random_answers, active, results_disabled, max_attempt,start_time,end_time,feedback_type,expired_time FROM $TBL_EXERCICES WHERE id='".Database::escape_string($id)."'";
@@ -377,9 +388,9 @@ class Exercise {
 	 * @param - string $delete - ask to delete the file
 	 */
 	function updateSound($sound,$delete) {
-		global $audioPath, $documentPath,$_course, $_user;
-        $TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT);
-        $TBL_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY);
+		global $audioPath, $documentPath;
+        $TBL_DOCUMENT = Database::get_course_table(TABLE_DOCUMENT, $this->course['db_name']);
+        $TBL_ITEM_PROPERTY = Database::get_course_table(TABLE_ITEM_PROPERTY,$this->course['db_name']);
 
 		if ($sound['size'] && (strstr($sound['type'],'audio') || strstr($sound['type'],'video'))) {
 			$this->sound=$sound['name'];
@@ -393,7 +404,7 @@ class Exercise {
 			        /*$query="INSERT INTO $TBL_DOCUMENT(path,filetype) VALUES "
 			            ." ('".str_replace($documentPath,'',$audioPath).'/'.$this->sound."','file')";
 			        Database::query($query);*/
-			        $id = add_document($_course,str_replace($documentPath,'',$audioPath).'/'.$this->sound,'file',$sound['size'],$sound['name']);
+			        $id = add_document($this->course,str_replace($documentPath,'',$audioPath).'/'.$this->sound,'file',$sound['size'],$sound['name']);
 			
 			        //$id = Database::insert_id();
 			        //$time = time();
@@ -404,8 +415,8 @@ class Exercise {
 			                ." VALUES "
 			                ."('".TOOL_DOCUMENT."', $id, $_user['user_id'], 0, '$time', '$time', 'DocumentAdded' )";
 			        Database::query($query);*/
-			        api_item_property_update($_course, TOOL_DOCUMENT, $id, 'DocumentAdded',$_user['user_id']);
-			        item_property_update_on_folder($_course,str_replace($documentPath,'',$audioPath),$_user['user_id']);
+			        api_item_property_update($this->course, TOOL_DOCUMENT, $id, 'DocumentAdded',api_get_user_id());
+			        item_property_update_on_folder($this->course,str_replace($documentPath,'',$audioPath),api_get_user_id());
 				}
 			}
 		} elseif($delete && is_file($audioPath.'/'.$this->sound)) {

+ 39 - 5
main/exercice/exercise.lib.php

@@ -92,6 +92,7 @@ function showQuestion($questionId, $onlyAnswers = false, $origin = false, $curre
 		$nbrAnswers=$objAnswerTmp->selectNbrAnswers();
         
         $quiz_question_options = Question::readQuestionOption($questionId);
+        
 
 		// For "matching" type here, we need something a little bit special
 		// because the match between the suggestions and the answers cannot be
@@ -301,10 +302,12 @@ function showQuestion($questionId, $onlyAnswers = false, $origin = false, $curre
                 } elseif ($answerType == MULTIPLE_ANSWER_TRUE_FALSE) {                    
                     $options = array('type'=>'radio','name'=>'choice['.$questionId.']['.$numAnswer.']', 'class'=>'checkbox');
                     $s .='<tr>';     
-                    $s .= Display::tag('td', $answer);       
-                    foreach ($quiz_question_options as $id=>$item) {
-                        $options['value'] = $id;
-                        $s .= Display::tag('td', Display::tag('input','',$options ));                        	
+                    $s .= Display::tag('td', $answer);
+                    if (!empty($quiz_question_options)) {       
+                        foreach ($quiz_question_options as $id=>$item) {
+                            $options['value'] = $id;
+                            $s .= Display::tag('td', Display::tag('input','',$options ));                        	
+                        }
                     }
                     $s.='<tr>';
                 }
@@ -1015,7 +1018,8 @@ function get_exam_results_data($from, $number_of_items, $column, $direction) {
 
                 $ex = show_score($my_res, $my_total);
                 
-                $result_list = round(($my_res / ($my_total != 0 ? $my_total : 1)) * 100, 2) . '% (' . $my_res . ' / ' . $my_total . ') --> '.$ex;
+                //$result_list = round(($my_res / ($my_total != 0 ? $my_total : 1)) * 100, 2) . '% (' . $my_res . ' / ' . $my_total . ')';
+                $result_list = $ex;
 
                 $html_link = '';
                 if ($is_allowedToEdit || $is_tutor) {
@@ -1105,5 +1109,35 @@ function show_score($score, $weight, $show_porcentage = true) {
 }
 
 
+function convert_score($score, $weight) {
+    $html  = '';
+    $score_rounded = $score;   
+     
+    if ($score != '' && $weight != '') {
+        $max_note =  api_get_setting('exercise_max_score');
+        $min_note =  api_get_setting('exercise_min_score');  
+        if ($max_note != '' && $min_note != '') {
+           
+           if (!empty($weight)) {
+          
+               $score        = $min_note + ($max_note - $min_note) * $score /$weight;
+           } else {
+               $score          = $min_note;
+           }
+           $score_rounded  = round($score, 2);          
+        }           
+    }
+    return $score_rounded;
+}
+
+
+function get_all_exercises($course_info = null) {
+    if(!empty($course_info)) {
+        $TBL_EXERCICES              = Database :: get_course_table(TABLE_QUIZ_TEST,$course_info['db_name']);	
+    } else {
+    	$TBL_EXERCICES              = Database :: get_course_table(TABLE_QUIZ_TEST);
+    }    
+    return Database::select('*',$TBL_EXERCICES, array('where'=>array('active <> ?'=>'-1'), 'order'=>'title'));
+}
 
 

+ 5 - 4
main/exercice/exercise_show.php

@@ -578,12 +578,13 @@ if ($show_results) {
 		</tr>
 		</table>
 		<?php
-		$my_total_score  = float_format($questionScore,1);
-		$my_total_weight = float_format($questionWeighting,1);       
+        
+		$my_total_score  = convert_score($questionScore, $total_weighting);
+		$my_total_weight = convert_score($questionWeighting, $total_weighting);       
 
 		echo '<div id="question_score">';
-		//echo get_lang('Score')." : $my_total_score/$my_total_weight";        
-        echo get_lang('Score')." : ".show_score($my_total_score,$total_weighting,false);
+		echo get_lang('Score')." : $my_total_score/$my_total_weight";        
+        //echo get_lang('Score')." : ".show_score($my_total_score, $total_weighting, false);
 		echo '</div>';
 
 		unset($objAnswerTmp);

+ 86 - 54
main/exercice/question.class.php

@@ -46,7 +46,8 @@ abstract class Question
 	public $picture;
 	public $exerciseList;  // array with the list of exercises which this question is in
 	private $isContent;
-
+    public $course;
+    
 	static $typePicture = 'new_question.png';
 	static $explanationLangVar = '';
 	static $questionTypes = array(
@@ -92,20 +93,25 @@ abstract class Question
 	 * @param - integer $id - question ID
 	 * @return - boolean - true if question exists, otherwise false
 	 */
-	static function read($id)
-	{
-		global $_course;
-
-		$TBL_EXERCICES         = Database::get_course_table(TABLE_QUIZ_TEST);
-		$TBL_QUESTIONS         = Database::get_course_table(TABLE_QUIZ_QUESTION);
-		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-
-		$sql="SELECT question,description,ponderation,position,type,picture,level,extra FROM $TBL_QUESTIONS WHERE id='".Database::escape_string($id)."'";
+	static function read($id, $course_id = null) {		
+        
+        if (!empty($course_id)) {            
+            $course_info =  api_get_course_info_by_id($course_id);
+        } else {
+            global $course;
+            $course_info = api_get_course_info();
+        }     
+
+		$TBL_EXERCICES         = Database::get_course_table(TABLE_QUIZ_TEST,          $course_info['db_name']);
+		$TBL_QUESTIONS         = Database::get_course_table(TABLE_QUIZ_QUESTION,      $course_info['db_name']);
+		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $course_info['db_name']);
+        $id = intval($id);
+		$sql="SELECT question,description,ponderation,position,type,picture,level,extra FROM $TBL_QUESTIONS WHERE id= $id ";
 
 		$result=Database::query($sql);
 
 		// if the question has been found
-		if($object=Database::fetch_object($result)) {
+		if ($object=Database::fetch_object($result)) {
 			$objQuestion 				= Question::getInstance($object->type);
 			$objQuestion->id			= $id;
 			$objQuestion->question		= $object->question;
@@ -116,8 +122,9 @@ abstract class Question
 			$objQuestion->picture		= $object->picture;
 			$objQuestion->level			= (int) $object->level;
             $objQuestion->extra         = $object->extra;
+            $objQuestion->course        = $course_info;
 
-			$sql="SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE question_id='".intval($id)."'";
+			$sql="SELECT exercice_id FROM $TBL_EXERCICE_QUESTION WHERE question_id='".$id."'";
 			$result=Database::query($sql);
 
 			// fills the array with the exercises which this question is in
@@ -218,13 +225,11 @@ abstract class Question
 		return $this->picture;
 	}
     
-    function selectPicturePath() {   
-        global $_course;
+    function selectPicturePath() {
         if (!empty($this->picture)) {
-            return api_get_path(WEB_COURSE_PATH).$_course['path'].'/document/images/'.$this->picture;
+            return api_get_path(WEB_COURSE_PATH).$this->course['path'].'/document/images/'.$this->picture;
         }
-        return false;
-        
+        return false;        
     }
 
 	/**
@@ -312,7 +317,7 @@ abstract class Question
 	 * @param - integer $type - answer type
 	 */
 	function updateType($type) {
-		global $TBL_REPONSES;
+		$TBL_REPONSES           = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 
 		// if we really change the type
 		if($type != $this->type) {
@@ -336,16 +341,16 @@ abstract class Question
 	 * @return - boolean - true if uploaded, otherwise false
 	 */
 	function uploadPicture($Picture,$PictureName) {
-		global $picturePath, $_course, $_user;
+		global $picturePath;
 
 		if (!file_exists($picturePath)) {
 			if (mkdir($picturePath, api_get_permissions_for_new_directories())) {
 				// document path
-				$documentPath = api_get_path(SYS_COURSE_PATH) . $_course['path'] . "/document";
+				$documentPath = api_get_path(SYS_COURSE_PATH) . $this->course['path'] . "/document";
 				$path = str_replace($documentPath,'',$picturePath);
 				$title_path = basename($picturePath);
-				$doc_id = add_document($_course, $path, 'folder', 0,$title_path);
-				api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'FolderCreated', $_user['user_id']);
+				$doc_id = add_document($this->course, $path, 'folder', 0,$title_path);
+				api_item_property_update($this->course, TOOL_DOCUMENT, $doc_id, 'FolderCreated', api_get_user_id());
 			}
 		}
 
@@ -356,15 +361,15 @@ abstract class Question
 			if($extension == 'gif' || $extension == 'png') {
 				$o_img = new image($Picture);
 				$o_img->send_image('JPG',$picturePath.'/'.$this->picture);
-				$document_id = add_document($_course, '/images/'.$this->picture, 'file', filesize($picturePath.'/'.$this->picture),$this->picture);
+				$document_id = add_document($this->course, '/images/'.$this->picture, 'file', filesize($picturePath.'/'.$this->picture),$this->picture);
 			}
 			else
 			{
 				move_uploaded_file($Picture,$picturePath.'/'.$this->picture)?true:false;
 			}
-			$document_id = add_document($_course, '/images/'.$this->picture, 'file', filesize($picturePath.'/'.$this->picture),$this->picture);
+			$document_id = add_document($this->course, '/images/'.$this->picture, 'file', filesize($picturePath.'/'.$this->picture),$this->picture);
 			if($document_id) {
-				return api_item_property_update($_course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', $_user['user_id']);
+				return api_item_property_update($this->course, TOOL_DOCUMENT, $document_id, 'DocumentAdded', api_get_user_id);
 			}
 		}
 
@@ -589,10 +594,9 @@ abstract class Question
 	 * @param - integer $exerciseId - exercise ID if saving in an exercise
 	 */
 	function save($exerciseId=0) {
-		global $_course,$_user;
 
-		$TBL_EXERCICE_QUESTION	= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-		$TBL_QUESTIONS			= Database::get_course_table(TABLE_QUIZ_QUESTION);
+		$TBL_EXERCICE_QUESTION	= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course['db_name']);
+		$TBL_QUESTIONS			= Database::get_course_table(TABLE_QUIZ_QUESTION, $this->course['db_name']);
 
 		$id=$this->id;
 		$question=$this->question;
@@ -618,7 +622,7 @@ abstract class Question
 				WHERE id='".Database::escape_string($id)."'";
 			Database::query($sql);
 			if(!empty($exerciseId)) {
-			api_item_property_update($_course, TOOL_QUIZ, $id,'QuizQuestionUpdated',$_user['user_id']);
+			api_item_property_update($this->course, TOOL_QUIZ, $id,'QuizQuestionUpdated',api_get_user_id);
 			}
             if (api_get_setting('search_enabled')=='true') {
                 if ($exerciseId != 0) {
@@ -653,12 +657,12 @@ abstract class Question
 
 			$this->id=Database::insert_id();
 
-			api_item_property_update($_course, TOOL_QUIZ, $this->id,'QuizQuestionAdded',$_user['user_id']);
+			api_item_property_update($this->course, TOOL_QUIZ, $this->id,'QuizQuestionAdded',api_get_user_id());
 
 			// If hotspot, create first answer
 			if ($type == HOT_SPOT || $type == HOT_SPOT_ORDER) {
 				$TBL_ANSWERS = Database::get_course_table(TABLE_QUIZ_ANSWER);
-				$sql="INSERT INTO $TBL_ANSWERS (`id` , `question_id` , `answer` , `correct` , `comment` , `ponderation` , `position` , `hotspot_coordinates` , `hotspot_type` ) VALUES ('1', '".Database::escape_string($this->id)."', '', NULL , '', '10' , '1', '0;0|0|0', 'square')";
+				$sql="INSERT INTO $TBL_ANSWERS (id , question_id , answer , correct , comment , ponderation , position , hotspot_coordinates , hotspot_type ) VALUES ('1', '".Database::escape_string($this->id)."', '', NULL , '', '10' , '1', '0;0|0|0', 'square')";
 				Database::query($sql);
             }
 
@@ -802,7 +806,7 @@ abstract class Question
      * @param - boolean $fromSave - comming from $this->save() or not
 	 */
 	function addToList($exerciseId, $fromSave = FALSE) {
-		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
+		$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course['db_name']);
 		$id = $this->id;
 		// checks if the exercise ID is not in the list
 		if (!in_array($exerciseId,$this->exerciseList)) {            
@@ -861,7 +865,7 @@ abstract class Question
 	}
 
 	/**
-	 * deletes a question from the database
+	 * Deletes a question from the database
 	 * the parameter tells if the question is removed from all exercises (value = 0),
 	 * or just from one exercise (value = exercise ID)
 	 *
@@ -871,9 +875,9 @@ abstract class Question
 	function delete($deleteFromEx=0) {
 		global $_course,$_user;
 
-		$TBL_EXERCICE_QUESTION	= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-		$TBL_QUESTIONS			= Database::get_course_table(TABLE_QUIZ_QUESTION);
-		$TBL_REPONSES          = Database::get_course_table(TABLE_QUIZ_ANSWER);
+		$TBL_EXERCICE_QUESTION	= Database::get_course_table(TABLE_QUIZ_TEST_QUESTION, $this->course['db_name']);
+		$TBL_QUESTIONS			= Database::get_course_table(TABLE_QUIZ_QUESTION, $this->course['db_name']);
+		$TBL_REPONSES           = Database::get_course_table(TABLE_QUIZ_ANSWER, $this->course['db_name']);
 
 		$id=$this->id;
 
@@ -900,7 +904,7 @@ abstract class Question
 			$sql="DELETE FROM $TBL_REPONSES WHERE question_id='".Database::escape_string($id)."'";
 			Database::query($sql);
 
-			api_item_property_update($_course, TOOL_QUIZ, $id,'QuizQuestionDeleted',$_user['user_id']);
+			api_item_property_update($this->course, TOOL_QUIZ, $id,'QuizQuestionDeleted',api_get_user_id());
 			$this->removePicture();
 
 			// resets the object
@@ -914,7 +918,7 @@ abstract class Question
                 // disassociate question with this exercise
                 $this -> search_engine_edit($deleteFromEx, FALSE, TRUE);
             }
-            api_item_property_update($_course, TOOL_QUIZ, $id,'QuizQuestionDeleted',$_user['user_id']);
+            api_item_property_update($this->course, TOOL_QUIZ, $id,'QuizQuestionDeleted',api_get_user_id());
 		}
 	}
 
@@ -923,9 +927,16 @@ abstract class Question
 	 *
 	 * @author - Olivier Brouckaert
 	 * @return - integer - ID of the new question
-	 */
-	function duplicate() {
-		global $TBL_QUESTIONS, $picturePath;
+    */
+     
+	function duplicate($course_info = null) {        
+        if (empty($course_info)) {
+        	$course_info = $this->course;
+        } else {
+        	$course_info = $course_info;
+        }
+        $TBL_QUESTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION, $course_info['db_name']);
+        $TBL_QUESTION_OPTIONS = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION, $course_info['db_name']);
 
 		$question     = $this->question;
 		$description  = $this->description;
@@ -933,15 +944,33 @@ abstract class Question
 		$position     = $this->position;
 		$type         = $this->type;
 		$level        = intval($this->level);
-
-		$sql="INSERT INTO $TBL_QUESTIONS(question, description, ponderation, position, type, level ) VALUES('".Database::escape_string($question)."','".Database::escape_string($description)."','".Database::escape_string($weighting)."','".Database::escape_string($position)."','".Database::escape_string($type)."' ,'".Database::escape_string($level)."')";
-		Database::query($sql);
-
-		$id=Database::insert_id();
+        $extra        = $this->extra;
+        
+        require_once api_get_path(LIBRARY_PATH).'document.lib.php';
+        if ($course_info['db_name'] != $this->course['db_name']) {
+            $description  = DocumentManager::replace_urls_inside_content_html_from_copy_course($description, $this->course['id'], $course_info['id']);
+            $question     = DocumentManager::replace_urls_inside_content_html_from_copy_course($question, $this->course['id'], $course_info['id']);
+        }
+        
+        $options = self::readQuestionOption($this->id);
+                
+		$sql="INSERT INTO $TBL_QUESTIONS(question, description, ponderation, position, type, level, extra ) VALUES('".Database::escape_string($question)."','".Database::escape_string($description)."','".Database::escape_string($weighting)."','".Database::escape_string($position)."','".Database::escape_string($type)."' ,'".Database::escape_string($level)."' ,'".Database::escape_string($extra)."'  )";
+		Database::query($sql);    
+            
+		$new_question_id =Database::insert_id();
+          
+        if (!empty($options)) {
+            //Saving the quiz_options      
+            foreach ($options as $item) {
+                $item['question_id'] = $new_question_id;
+                unset($item['id']); 
+                Database::insert($TBL_QUESTION_OPTIONS,$item);	
+            }
+        }
+        
 		// duplicates the picture
-		$this->exportPicture($id);
-
-		return $id;
+		$this->exportPicture($new_question_id);
+		return $new_question_id;
 	}
 
 	/**
@@ -967,8 +996,7 @@ abstract class Question
 	 * A subclass can redifine this function to add fields...
 	 * @param FormValidator $form the formvalidator instance (by reference)
 	 */
-	function createForm (&$form,$fck_config=0)
-	{
+	function createForm (&$form,$fck_config=0) {
 		echo '	<style>
 					div.row div.label{ width: 5%; }
 					div.row div.formw{ width: 92%; }
@@ -1227,9 +1255,13 @@ abstract class Question
     }
     
     
-    static function readQuestionOption($question_id) {
-        $TBL_EXERCICE_QUESTION_OPTION    = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);
-        $result = Database::find($TBL_EXERCICE_QUESTION_OPTION, '*', array('question_id = ?' =>$question_id));
+    static function readQuestionOption($question_id, $db_name = null) {
+        if (empty($db_name)) {            
+            $TBL_EXERCICE_QUESTION_OPTION    = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION);	
+        } else {
+            $TBL_EXERCICE_QUESTION_OPTION    = Database::get_course_table(TABLE_QUIZ_QUESTION_OPTION, $db_name);	
+        }        
+        $result = Database::select('*', $TBL_EXERCICE_QUESTION_OPTION, array('where'=>array('question_id = ?' =>$question_id), 'order'=>'id'));
         return $result;        
     }
 }

+ 2 - 7
main/exercice/question_list_admin.inc.php

@@ -146,14 +146,9 @@ if ($nbrQuestions) {
                     echo '<p>';			  	
                         echo $actions;
                         echo get_lang($question_class.$label);
-                        echo '<br />'; 
-                        
+                        echo '<br />';                        
                         echo get_lang('Level').': '.$objQuestionTmp->selectLevel();
-                        echo '<br />';
-                        $description = $objQuestionTmp->selectDescription();             
-                        if (!empty($description)) {
-                            echo get_lang('Description').': '.$description;
-                        }
+                        echo '<br />';                        
                         showQuestion($id, false, '', '',false, true);                   
                     echo '</p>';
                     

+ 344 - 270
main/exercice/question_pool.php

@@ -7,26 +7,25 @@
 * 	One question can be in several exercises
 *	@package chamilo.exercise
 * 	@author Olivier Brouckaert
-* 	@version $Id: question_pool.php 20451 2009-05-10 12:02:22Z ivantcholakov $
+*   @author Julio Montoya adding support to query all questions from all session, courses, exercises  
 */
 
 // name of the language file that needs to be included
 $language_file='exercice';
 
 require_once 'exercise.class.php';
+require_once 'exercise.lib.php';
 require_once 'question.class.php';
 require_once 'answer.class.php';
 require_once '../inc/global.inc.php';
+require_once api_get_path(LIBRARY_PATH).'course.lib.php';
+require_once api_get_path(LIBRARY_PATH).'sessionmanager.lib.php';
+
 
 $this_section=SECTION_COURSES;
 
 $is_allowedToEdit=api_is_allowed_to_edit(null,true);
 
-$TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION);
-$TBL_EXERCICES         = Database::get_course_table(TABLE_QUIZ_TEST);
-$TBL_QUESTIONS         = Database::get_course_table(TABLE_QUIZ_QUESTION);
-$TBL_REPONSES          = Database::get_course_table(TABLE_QUIZ_ANSWER);
-
 if ( empty ( $delete ) ) {
     $delete = intval($_GET['delete']);
 }
@@ -60,17 +59,22 @@ if(!empty($_GET['type'])){
 	$type = intval($_GET['type']);
 }
 
+$session_id = intval($_GET['session_id']);
+
+$selected_course = intval($_GET['selected_course']);
+
+
 // maximum number of questions on a same page
 $limitQuestPage=50;
 
 // document path
 $documentPath=api_get_path(SYS_COURSE_PATH).$_course['path'].'/document';
-
 // picture path
 $picturePath=$documentPath.'/images';
 
+
 if(!($objExcercise instanceOf Exercise) && !empty($fromExercise)) {
-    $objExercise = new Exercise();
+    $objExercise = new Exercise();    
     $objExercise->read($fromExercise);
 }
 if(!($objExcercise instanceOf Exercise) && !empty($exerciseId)) {
@@ -78,23 +82,31 @@ if(!($objExcercise instanceOf Exercise) && !empty($exerciseId)) {
     $objExercise->read($exerciseId);
 }
 
-if($is_allowedToEdit) {
+if ($is_allowedToEdit) {
 	
-	//copy exercise 
+	//Duplicating a Question
+    
 	if ($copy_question != 0 && isset($fromExercise)) {
-		
-		$old_question_id = $copy_question;
-		$old_question_obj = Question::read($old_question_id);
-		$old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));
-		$new_id = $old_question_obj->duplicate();
+        $origin_course_id   = intval($_GET['course_id']);
+        $origin_course_info = api_get_course_info_by_id($origin_course_id);
+        $current_course     = api_get_course_info();     
+        $old_question_id = $copy_question;       
+        
+        //Reading the source question
+		$old_question_obj = Question::read($old_question_id, $origin_course_id);
+		$old_question_obj->updateTitle($old_question_obj->selectTitle().' - '.get_lang('Copy'));     
+        
+        //Duplicating question in the current course
+		$new_id = $old_question_obj->duplicate($current_course);
 		
 		$new_question_obj = Question::read($new_id);			
-		$new_question_obj->addToList($fromExercise);			
-								
-		$new_answer_obj = new Answer($old_question_id);
+		$new_question_obj->addToList($fromExercise);
+        			
+        //Reading Answer obj from origin course 
+		$new_answer_obj = new Answer($old_question_id, $origin_course_id);
 		$new_answer_obj->read();
-		$new_answer_obj->duplicate($new_id);
-		
+        //Duplicating the answers in this course
+		$new_answer_obj->duplicate($new_id, $current_course);		
 		
 		// destruction of the Question object
 		unset($new_question_obj);
@@ -107,6 +119,7 @@ if($is_allowedToEdit) {
 		// adds the question ID represented by $recup into the list of questions for the current exercise
 		//$objExercise->addToList($new_id);
 		api_session_register('objExercise');
+        exit;
 		
 		header("Location: admin.php?".api_get_cidreq()."&exerciseId=$fromExercise");
 		exit();	
@@ -175,298 +188,364 @@ if (isset($_SESSION['gradebook'])){
 }
 
 if (!empty($gradebook) && $gradebook=='view') {
-	$interbreadcrumb[]= array (
-			'url' => '../gradebook/'.Security::remove_XSS($_SESSION['gradebook_dest']),
-			'name' => get_lang('ToolGradebook')
-		);
+	$interbreadcrumb[]= array ('url' => '../gradebook/'.Security::remove_XSS($_SESSION['gradebook_dest']),'name' => get_lang('ToolGradebook'));
 }
 
 $nameTools=get_lang('QuestionPool');
-
 $interbreadcrumb[]=array("url" => "exercice.php","name" => get_lang('Exercices'));
-
 // if admin of course
-if($is_allowedToEdit) {
-	Display::display_header($nameTools,'Exercise');
-	echo '<h3>'.$nameTools.'</h3>';
-	echo '<div class="actions">';
-	if (isset($type)) {
-		$url = api_get_self().'?type=1';
-	} else {
-		$url = api_get_self();
-	}
-	echo '<form method="GET" action="'.$url.'" style="display:inline;">';
-	 
-	if (isset($type)) {
-		echo '<input type="hidden" name="type" value="1">';
-	}
-	echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
-	echo get_lang('Exercice').' :';	
-	echo '<select name="exerciseId">';	
-	echo '<option value="0">'.get_lang('AllExercises').'</option>';
-	?>
-	<option value="-1" <?php if($exerciseId == -1) echo 'selected="selected"'; ?>><?php echo get_lang('OrphanQuestions'); ?></option>
-	<?php
-	$sql="SELECT id,title FROM $TBL_EXERCICES WHERE id<>'".Database::escape_string($fromExercise)."' AND active<>'-1' ORDER BY id";
-	$result=Database::query($sql);
-
-	// shows a list-box allowing to filter questions
-	while($row=Database::fetch_array($result)) {
-		?>
-		<option value="<?php echo $row['id']; ?>" <?php if($exerciseId == $row['id']) echo 'selected="selected"'; ?>><?php echo $row['title']; ?></option>
-		<?php
+if (!$is_allowedToEdit) {
+    api_not_allowed(true);
+}
+
+$htmlHeadXtra[] = ' <script type="text/javascript"> 
+                
+	function submit_form(obj) {            
+		document.question_pool.submit();
 	}
-	?>
-    </select>
-    &nbsp;
+		
+	</script>';
+Display::display_header($nameTools,'Exercise');
+echo '<h3>'.$nameTools.'</h3>';
+echo '<div class="actions">';
+if (isset($type)) {
+	$url = api_get_self().'?type=1';
+} else {
+	$url = api_get_self();
+}
+echo '<form name="question_pool" method="GET" action="'.$url.'" style="display:inline;">';
+     
+    if (isset($type)) {
+    	echo '<input type="hidden" name="type" value="1">';
+    }    
+    //echo '<input type="hidden" name="cidReq" value="'.api_get_cidreq().'">';
+    echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
+    
+    //Session list  
+    $session_list = SessionManager::get_sessions_by_coach(api_get_user_id());
+    $session_select_list = array();
+    foreach($session_list as $item) {
+        $session_select_list[$item['id']] = $item['name'];
+    }
+    echo get_lang('Session').' : ';
+    echo Display::select('session_id', $session_select_list, $session_id, array('onchange'=>'submit_form(this);'));
+    
+    //Course list
+    if (!empty($session_id) && $session_id != '-1') {
+        $course_list = SessionManager::get_course_list_by_session_id($session_id);
+    } else {        
+        $course_list = CourseManager::get_course_list_of_user_as_course_admin(api_get_user_id());        
+    }    
+    
+    $course_select_list = array();
+    foreach ($course_list as $item) {
+    	$course_select_list[$item['id']] = $item['title'];
+    }    
+         
+    echo get_lang('Course').' : ';
+    echo Display::select('selected_course', $course_select_list, $selected_course, array('onchange'=>'submit_form(this);'));    
+    
+    if (empty($selected_course) || $selected_course == '-1') {
+        $course_info = api_get_course_info();
+        $db_name = $course_info['db_name'];
+    } else {        
+    	$course_info = CourseManager::get_course_information_by_id($selected_course);                
+        $db_name = $course_info['db_name'];
+    }
+    
+    //Redefining table calls
+    $TBL_EXERCICE_QUESTION = Database::get_course_table(TABLE_QUIZ_TEST_QUESTION,   $db_name);
+    $TBL_EXERCICES         = Database::get_course_table(TABLE_QUIZ_TEST,            $db_name);
+    $TBL_QUESTIONS         = Database::get_course_table(TABLE_QUIZ_QUESTION,        $db_name);
+    $TBL_REPONSES          = Database::get_course_table(TABLE_QUIZ_ANSWER,          $db_name);
+    
+    $exercise_list         = get_all_exercises($course_info);
+    
+    echo '<input type="hidden" name="fromExercise" value="'.$fromExercise.'">';
+    
+    //Exercise List
+    echo get_lang('Exercice').' :';
+    
+    $my_exercise_list = array();
+    $my_exercise_list['0']  = get_lang('AllExercises');
+    $my_exercise_list['-1'] = get_lang('OrphanQuestions'); 
+        
+    if (is_array($exercise_list)) {
+        foreach($exercise_list as $row) {        
+            if ($row['id'] !=  $fromExercise) {       
+                $my_exercise_list[$row['id']] = $row['title'];
+            }
+        }
+    }    
+    
+    echo Display::select('exerciseId', $my_exercise_list, $exerciseId, array('onchange'=>'submit_form(this);'), false);
+    
+    echo get_lang('Difficulty');    	
+    
+    //Difficulty list (only from 1 to 5)                
+    echo Display::select('exerciseLevel', array(1=>1,2=>2,3=>3,4=>4,5=>5), $exerciseLevel, array('onchange'=>'submit_form(this);'));
+    
+    $question_list = Question::get_types_information();
+    $new_question_list = array();
+    foreach($question_list as $key=>$item) {
+    	$new_question_list[$key] = get_lang($item[1]);
+    }
+    //Answer type list
+    echo get_lang('AnswerType');
+    echo Display::select('answerType', $new_question_list, $answerType, array('onchange'=>'submit_form(this);'));
+    ?>
+    <button class="save" type="submit" name="name" value="<?php echo get_lang('Ok') ?>"><?php echo get_lang('Filter') ?></button>
     <?php
-    	echo get_lang('Difficulty');
-    	echo ' : <select name="exerciseLevel">';
-		//echo '<option value="-1">-- '.get_lang('AllExercises').' --</option>';
-		//level difficulty only from 1 to 5
-		if (!isset($exerciseLevel)) $exerciseLevel = -1;
-
-		for ($level = -1; $level <=5; $level++) {
-			$selected ='';
-			if ($level!=0) {
-				if ($exerciseLevel == $level)
-					$selected = ' selected="selected" ';
-				if ($level==-1) {
-					echo '<option value="'.$level.'" '.$selected.'>'.get_lang('Any').'</option>';
-				} else   {
-					echo '<option value="'.$level.'" '.$selected.'>'.$level.'</option>';
-				}
-			}
-		}
-		echo '</select> ';
-
-		//
-    	echo get_lang('AnswerType');
-    	echo ' : <select name="answerType">';
-		//answer type
-		if (!isset($answerType)) $answerType = -1; {
-			for ($answer_type = -1; $answer_type <=9; $answer_type++) {
-				$selected ='';
-				if ($answer_type!=0) {
-					if ($answerType == $answer_type)
-						$selected = ' selected="selected" ';
-					if ($answer_type==-1) {echo '<option value="-1" '.$selected.'>'.get_lang('Any').'</option>'; } // check 0 or -1
-					elseif ($answer_type==1) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('UniqueAnswer').'</option>'; }
-					elseif ($answer_type==2) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('MultipleAnswer').'</option>'; }
-					elseif ($answer_type==3) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('langFillBlanks').'</option>'; }
-					elseif ($answer_type==4) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('langMatching').'</option>'; }
-					elseif ($answer_type==5) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('FreeAnswer').'</option>'; }
-					elseif ($answer_type==6) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('HotSpot').'</option>'; }
-					elseif ($answer_type==9) {echo '<option value="'.$answer_type.'" '.$selected.'>'.get_lang('MultipleSelectCombination').'</option>'; }
-				}
-			}
-		}
-		echo '</select> ';
-	?>
-
-	<button class="save" type="submit" name="name" value="<?php echo get_lang('Ok') ?>"><?php echo get_lang('Filter') ?></button>
-	<?php
-	echo '<a href="admin.php?',api_get_cidreq(),'&exerciseId='.$fromExercise.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList')),get_lang('GoBackToQuestionList'),'</a>';
-	/*if(!empty($fromExercise)) {
-		echo '<a href="admin.php?',api_get_cidreq(),'&exerciseId=',$fromExercise,'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList')),get_lang('GoBackToQuestionList'),'</a>';
-	} else {
-		echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes">'.Display::return_icon('more.png'),get_lang('NewQu').'</a>';
-	}*/
-	?>
+    echo '<a href="admin.php?',api_get_cidreq(),'&exerciseId='.$fromExercise.'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList')),get_lang('GoBackToQuestionList'),'</a>';
+    /*if(!empty($fromExercise)) {
+    	echo '<a href="admin.php?',api_get_cidreq(),'&exerciseId=',$fromExercise,'">'.Display::return_icon('back.png', get_lang('GoBackToQuestionList')),get_lang('GoBackToQuestionList'),'</a>';
+    } else {
+    	echo '<a href="admin.php?'.api_get_cidreq().'&newQuestion=yes">'.Display::return_icon('more.png'),get_lang('NewQu').'</a>';
+    }*/
+    ?>
     </form>
 </div>
 <form method="post" action="<?php echo $url.'?'.api_get_cidreq().'&fromExercise='.$fromExercise; ?>" >
-<table class="data_table">
-<?php
-	$from=$page*$limitQuestPage;
-	// if we have selected an exercise in the list-box 'Filter'
-	if ($exerciseId > 0) {
-		//$sql="SELECT id,question,type FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS WHERE question_id=id AND exercice_id='".Database::escape_string($exerciseId)."' ORDER BY question_order LIMIT $from, ".($limitQuestPage + 1);
-		$where = '';
-		if (isset($type) && $type==1) {
-			$where = ' type = 1 AND ';
-		}
 
-		if (isset($exerciseLevel) && $exerciseLevel != -1) {
-			$where .= ' level='.$exerciseLevel.' AND ';
-		}
+<?php
+echo '<table class="data_table">';
+$from=$page*$limitQuestPage;
+// if we have selected an exercise in the list-box 'Filter'
+
+if ($exerciseId > 0) {
+	//$sql="SELECT id,question,type FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS WHERE question_id=id AND exercice_id='".Database::escape_string($exerciseId)."' ORDER BY question_order LIMIT $from, ".($limitQuestPage + 1);
+	$where = '';
+	if (isset($type) && $type==1) {
+		$where = ' type = 1 AND ';
+	}
 
-		if (isset($answerType) && $answerType != -1) {
-			$where .= ' type='.$answerType.' AND ';
-		}
+	if (isset($exerciseLevel) && $exerciseLevel != -1) {
+		$where .= ' level='.$exerciseLevel.' AND ';
+	}
 
-		$sql="SELECT id,question,type,level
-				FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS
-			  	WHERE $where question_id=id AND exercice_id='".Database::escape_string($exerciseId)."'
-				ORDER BY question_order";
+	if (isset($answerType) && $answerType != -1) {
+		$where .= ' type='.$answerType.' AND ';
+	}
 
+	$sql="SELECT id,question,type,level
+			FROM $TBL_EXERCICE_QUESTION,$TBL_QUESTIONS
+		  	WHERE $where question_id=id AND exercice_id='".Database::escape_string($exerciseId)."'
+			ORDER BY question_order";
+            
+    $result=Database::query($sql);
+    while($row = Database::fetch_array($result, 'ASSOC')) {
+    	$main_question_list[] = $row;
+    }    
 
-	} elseif($exerciseId == -1) {
 
-		// if we have selected the option 'Orphan questions' in the list-box 'Filter'
+} elseif($exerciseId == -1) {
 
-		// 1. Old logic: When a test is deleted, the correspondent records in 'quiz' and 'quiz_rel_question' tables are deleted.
-		//$sql='SELECT id, question, type, exercice_id FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id WHERE exercice_id IS NULL LIMIT $from, '.($limitQuestPage + 1);
+	// if we have selected the option 'Orphan questions' in the list-box 'Filter'
 
-		// 2. New logic: When a test is deleted, the field 'active' takes value -1 (it is in the correspondent record in 'quiz' table).
-		//$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id FROM '.$TBL_QUESTIONS.
-		//	' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.
-		//	' as exercices ON exercice_id=exercices.id WHERE exercices.active = -1 LIMIT $from, '.($limitQuestPage + 1);
+	// 1. Old logic: When a test is deleted, the correspondent records in 'quiz' and 'quiz_rel_question' tables are deleted.
+	//$sql='SELECT id, question, type, exercice_id FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id WHERE exercice_id IS NULL LIMIT $from, '.($limitQuestPage + 1);
 
-		// 3. This is more safe to changes, it is a mix between old and new logic.
+	// 2. New logic: When a test is deleted, the field 'active' takes value -1 (it is in the correspondent record in 'quiz' table).
+	//$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id FROM '.$TBL_QUESTIONS.
+	//	' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.
+	//	' as exercices ON exercice_id=exercices.id WHERE exercices.active = -1 LIMIT $from, '.($limitQuestPage + 1);
 
-		/*$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id FROM '.$TBL_QUESTIONS.
-			' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.
-			' as exercices ON exercice_id=exercices.id WHERE quizz_questions.exercice_id IS NULL OR exercices.active = -1 LIMIT '.$from.', '.($limitQuestPage + 1);
-		*/
+	// 3. This is more safe to changes, it is a mix between old and new logic.
 
-		/*	4. Query changed because of the Level feature implemented
-		$sql='SELECT id, question, type, exercice_id,level FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions
-			ON questions.id=quizz_questions.question_id AND exercice_id IS NULL '.
-			(!is_null($exerciseLevel) && $exerciseLevel >= 0 ? 'WHERE level=\''.$exerciseLevel.'\' ' : '');
-		*/
-		// 5. this is the combination of the 3 and 4 query because of the level feature implementation
+	/*$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id FROM '.$TBL_QUESTIONS.
+		' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.
+		' as exercices ON exercice_id=exercices.id WHERE quizz_questions.exercice_id IS NULL OR exercices.active = -1 LIMIT '.$from.', '.($limitQuestPage + 1);
+	*/
 
-		// we filter the type of question, because in the DirectFeedback we can only add questions with type=1 = UNIQUE_ANSWER
-		$type_where= '';
-		if (isset($type) && $type==1) {
-			$type_where = ' AND questions.type = 1 ';
-		}
+	/*	4. Query changed because of the Level feature implemented
+	$sql='SELECT id, question, type, exercice_id,level FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions
+		ON questions.id=quizz_questions.question_id AND exercice_id IS NULL '.
+		(!is_null($exerciseLevel) && $exerciseLevel >= 0 ? 'WHERE level=\''.$exerciseLevel.'\' ' : '');
+	*/
+	// 5. this is the combination of the 3 and 4 query because of the level feature implementation
 
-		$level_where = '';
-		if (isset($exerciseLevel) && $exerciseLevel!= -1 ) {
-			$level_where = ' level='.$exerciseLevel.' AND ';
-		}
+	// we filter the type of question, because in the DirectFeedback we can only add questions with type=1 = UNIQUE_ANSWER
+	$type_where= '';
+	if (isset($type) && $type==1) {
+		$type_where = ' AND questions.type = 1 ';
+	}
 
-		$answer_where = '';
-		if (isset($answerType) && $answerType!= -1 ) {
-			$answer_where = ' questions.type='.$answerType.' AND ';
-		}
+	$level_where = '';
+	if (isset($exerciseLevel) && $exerciseLevel!= -1 ) {
+		$level_where = ' level='.$exerciseLevel.' AND ';
+	}
 
-		$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id , level, session_id
-				FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions
-				ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.' as exercices
-				ON exercice_id=exercices.id
-				WHERE '.$answer_where.' '.$level_where.' (quizz_questions.exercice_id IS NULL OR exercices.active = -1 )  '.$type_where.'
-				LIMIT '.$from.', '.($limitQuestPage + 1);
+	$answer_where = '';
+	if (isset($answerType) && $answerType!= -1 ) {
+		$answer_where = ' questions.type='.$answerType.' AND ';
+	}
 
-	} else {
-		// if we have not selected any option in the list-box 'Filter'
+	$sql='SELECT questions.id, questions.question, questions.type, quizz_questions.exercice_id , level, session_id
+			FROM '.$TBL_QUESTIONS.' as questions LEFT JOIN '.$TBL_EXERCICE_QUESTION.' as quizz_questions
+			ON questions.id=quizz_questions.question_id LEFT JOIN '.$TBL_EXERCICES.' as exercices
+			ON exercice_id=exercices.id
+			WHERE '.$answer_where.' '.$level_where.' (quizz_questions.exercice_id IS NULL OR exercices.active = -1 )  '.$type_where.'
+			LIMIT '.$from.', '.($limitQuestPage + 1);
 
-		//$sql="SELECT id,question,type FROM $TBL_QUESTIONS LIMIT $from, ".($limitQuestPage + 1);
-		$filter = '';
+} else {
+	// if we have not selected any option in the list-box 'Filter'
 
-		if (isset($type) && $type==1){
-			$filter  .= ' AND qu.type = 1 ';
-		}
+	//$sql="SELECT id,question,type FROM $TBL_QUESTIONS LIMIT $from, ".($limitQuestPage + 1);
+	$filter = '';
 
+	if (isset($type) && $type==1){
+		$filter  .= ' AND qu.type = 1 ';
+	}
 
-		if (isset($exerciseLevel) && $exerciseLevel != -1) {
-			$filter .= ' AND level='.$exerciseLevel.' ';
-		}
+	if (isset($exerciseLevel) && $exerciseLevel != -1) {
+		$filter .= ' AND level='.$exerciseLevel.' ';
+	}
 
-		if (isset($answerType) && $answerType != -1) {
-			$filter .= ' AND qu.type='.$answerType.' ';
-		}
-		$new_limit_page = $limitQuestPage + 1;
-		$sql="SELECT qu.id, question, qu.type, level, q.session_id FROM $TBL_QUESTIONS as qu, $TBL_EXERCICE_QUESTION as qt, $TBL_EXERCICES as q
-			  WHERE q.id=qt.exercice_id AND qu.id=qt.question_id AND qt.exercice_id<>".$fromExercise." $filter ORDER BY session_id ASC LIMIT $from, $new_limit_page";
-		// forces the value to 0
-		//echo $sql;
-		$exerciseId=0;
+	if (isset($answerType) && $answerType != -1) {
+		$filter .= ' AND qu.type='.$answerType.' ';
 	}
+	$new_limit_page = $limitQuestPage + 1;
+    if ($session_id != 0) {        
+
+        $main_question_list = array();
+        if (!empty($course_list))
+        foreach ($course_list as $course_item) {        
+            if (!empty($selected_course) && $selected_course != '-1')
+                if ($selected_course != $course_item['id']) {                
+                	continue;
+                }
+            $exercise_list = get_all_exercises($course_item);
+            
+            if (!empty($exercise_list)) {        
+                foreach ($exercise_list as $exercise) {                    
+                    $my_exercise = new Exercise($course_item['id']);
+                    $my_exercise->read($exercise['id']);
+            
+                    if (!empty($my_exercise)) {
+                        if (!empty($my_exercise->questionList))
+                        foreach ($my_exercise->questionList as $question) {
+                            
+                        	$question_obj = Question::read($question['id'], $course_item['id']);
+                            if ($exerciseLevel != '-1')
+                            if ($exerciseLevel != $question_obj->level) {
+                            	continue;
+                            }
+                            
+                            if ($answerType != '-1')
+                            if ($answerType != $question_obj->type) {
+                            	continue;
+                            }                        
+                            $question_row       = array('id'=>$question_obj->id, 'question'=>$question_obj->question, 'type'=>$question_obj->type, 'level'=>$question_obj->level, 'exercise_id'=>$exercise['id']);                            
+                            $main_question_list[]    = $question_row;                        
+                        }
+                    }                    
+                }
+            }           	
+        }    
+      
+    } else {
+        //By default
+    	$sql="SELECT qu.id, question, qu.type, level, q.session_id FROM $TBL_QUESTIONS as qu, $TBL_EXERCICE_QUESTION as qt, $TBL_EXERCICES as q
+          WHERE q.id=qt.exercice_id AND qu.id=qt.question_id AND qt.exercice_id<>".$fromExercise." $filter ORDER BY session_id ASC LIMIT $from, $new_limit_page";
+    }
+	// forces the value to 0
+	//echo $sql;
+	$exerciseId=0;
+}
+
+$result=Database::query($sql);
+//$nbrQuestions=Database::num_rows($result);
+$nbrQuestions=count($main_question_list);
+
+echo '<tr>',
+  '<td colspan="',($fromExercise?4:4),'">',
+	'<table border="0" cellpadding="0" cellspacing="0" width="100%">',
+	'<tr>',
+	  '<td>';
+echo '</td>',
+ '<td align="right">';
+
+if(!empty($page)) {
+	echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page-1),'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">';
+	echo Display::return_icon('action_prev.png');
+	echo '&nbsp;'.get_lang('PreviousPage'),'</a> | ';
 	
-	$result=Database::query($sql);
-	$nbrQuestions=Database::num_rows($result);
-
-    echo '<tr>',
-      '<td colspan="',($fromExercise?4:4),'">',
-    	'<table border="0" cellpadding="0" cellspacing="0" width="100%">',
-    	'<tr>',
-    	  '<td>';
-	echo '</td>',
-	 '<td align="right">';
-
-	if(!empty($page)) {
-		echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page-1),'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">';
-		echo Display::return_icon('action_prev.png');
-		echo '&nbsp;'.get_lang('PreviousPage'),'</a> | ';
-		
-	} elseif($nbrQuestions > $limitQuestPage) {
-		echo Display::return_icon('action_prev_na.png');
-		echo '&nbsp;'.get_lang('PreviousPage'),' | ';
-	}
+} elseif($nbrQuestions > $limitQuestPage) {
+	echo Display::return_icon('action_prev_na.png');
+	echo '&nbsp;'.get_lang('PreviousPage'),' | ';
+}
 
-	if($nbrQuestions > $limitQuestPage) {
-    	echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page+1),'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">',get_lang('NextPage').'&nbsp;';
-    	echo Display::return_icon('action_next.png');
-    	echo '</a>';
-    	
-	} elseif($page) {
-	   echo get_lang('NextPage');
-	   echo '&nbsp;'.Display::return_icon('action_next_na.png');
-	}
-    echo '</td>
+if($nbrQuestions > $limitQuestPage) {
+	echo '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&fromExercise=',$fromExercise,'&page=',($page+1),'&answerType=',$answerType,'&exerciseLevel='.$exerciseLevel.'">',get_lang('NextPage').'&nbsp;';
+	echo Display::return_icon('action_next.png');
+	echo '</a>';
+	
+} elseif($page) {
+   echo get_lang('NextPage');
+   echo '&nbsp;'.Display::return_icon('action_next_na.png');
+}
+echo '</td>
 	</tr>
 	</table>
   </td>
 </tr>
 <tr bgcolor="#e6e6e6">';
 
-	if(!empty($fromExercise)) {
-		if (api_get_session_id() == 0 ){
-        	echo '<th width="4%"> </th>';
-		}
-        echo '<th>',get_lang('Question'),'</th>',
-            '<th>',get_lang('Level'),'</th>',
-            '<th>',get_lang('Reuse'),'</th>';
-	} else {
-        echo '<td width="60%" align="center">',get_lang('Question'),'</td>',
-            '<td width="20%" align="center">',get_lang('Modify'),'</td>',
-            '<td width="16%" align="center">',get_lang('Delete'),'</td>';
+if(!empty($fromExercise)) {
+	if (api_get_session_id() == 0 ){
+    	echo '<th width="4%"> </th>';
 	}
-    echo '</tr>';
-	$i=1;
+    echo '<th>',get_lang('Question'),'</th>',
+        '<th>',get_lang('Level'),'</th>',
+        '<th>',get_lang('Reuse'),'</th>';
+} else {
+    echo '<td width="60%" align="center">',get_lang('Question'),'</td>',
+        '<td width="20%" align="center">',get_lang('Modify'),'</td>',
+        '<td width="16%" align="center">',get_lang('Delete'),'</td>';
+}
+echo '</tr>';
+$i=1;
 
-	$session_id  = api_get_session_id();
-	while ($row = Database::fetch_array($result,'ASSOC')) {
-        
-		
-		// if we come from the exercise administration to get a question,
-        // don't show the questions already used by that exercise
-
-        /*if (!$fromExercise) {echo '1'; }
-        if (!isset($objExercise)){echo '2';}
-        if (!($objExercise instanceOf Exercise)){echo '3';}
-        if (!$objExercise->isInList($row['id'])) {echo '4';}
-        */
-
-        // original recipe -
-      //if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (!$objExercise->isInList($row['id'])))
-		if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (is_array($objExercise->questionList)) ) {
-            echo '<tr ',($i%2==0?'class="row_odd"':'class="row_even"'),'>';
-            if (api_get_session_id() == 0 ){
-            	echo '<td align="center"> <input type="checkbox" value="'.$row['id'].'" name="recup[]"/></td>';
-            }
-            echo '  <td><a href="admin.php?',api_get_cidreq(),'&editQuestion=',$row['id'],'&fromExercise='.$fromExercise.'&answerType='.$row['type'].'">',$row['question'],'</a></td>';
-            echo '  <td align="center" >';
-			if (empty($fromExercise)) {
-                echo '<a href="admin.php?'.api_get_cidreq().'&amp;editQuestion=',$row['id'],'"><img src="../img/edit.gif" border="0" alt="',get_lang('Modify'),'"></a>',
-                    '</td>',
-                    '<td align="center">',
-                    '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
-                    //'<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
-			} else {
-                //echo $row['level'],'</td>',
+$session_id  = api_get_session_id();
+if (!empty($main_question_list))
+foreach ($main_question_list as $row) {
+    
+	
+	// if we come from the exercise administration to get a question,
+    // don't show the questions already used by that exercise
+
+    /*if (!$fromExercise) {echo '1'; }
+    if (!isset($objExercise)){echo '2';}
+    if (!($objExercise instanceOf Exercise)){echo '3';}
+    if (!$objExercise->isInList($row['id'])) {echo '4';}
+    */
+
+    // original recipe -
+  //if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (!$objExercise->isInList($row['id'])))
+	if (!$fromExercise || !isset($objExercise) || !($objExercise instanceOf Exercise) || (is_array($objExercise->questionList)) ) {
+        echo '<tr ',($i%2==0?'class="row_odd"':'class="row_even"'),'>';
+        if (api_get_session_id() == 0 ){
+        	echo '<td align="center"> <input type="checkbox" value="'.$row['id'].'" name="recup[]"/></td>';
+        }
+        echo '  <td><a href="admin.php?',api_get_cidreq(),'&editQuestion=',$row['id'],'&fromExercise='.$fromExercise.'&answerType='.$row['type'].'">',$row['question'],'</a></td>';
+        echo '  <td align="center" >';
+		if (empty($fromExercise)) {
+            echo '<a href="admin.php?'.api_get_cidreq().'&amp;editQuestion=',$row['id'],'"><img src="../img/edit.gif" border="0" alt="',get_lang('Modify'),'"></a>',
+                '</td>',
+                '<td align="center">',
+                '<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
+                //'<a href="',api_get_self(),'?',api_get_cidreq(),'&exerciseId=',$exerciseId,'&delete=',$row['id'],'" onclick="javascript:if(!confirm(\'',addslashes(api_htmlentities(get_lang('ConfirmYourChoice'),ENT_QUOTES,$charset)),'\')) return false;"><img src="../img/delete.gif" border="0" alt="',get_lang('Delete'),'"></a>';
+		} else {
+            //echo $row['level'],'</td>',
 //					'<td><a href="',api_get_self(),'?',api_get_cidreq(),'&recup=',$row['id'],'&fromExercise=',$fromExercise,'"><img src="../img/view_more_stats.gif" border="0" alt="',get_lang('Reuse'),'"></a>';
 				echo $row['level'],'</td>',
 							'<td align="center"><a href="',api_get_self(),'?',api_get_cidreq(),'&recup=',$row['id'],'&fromExercise=',$fromExercise,'">';
 				if ($row['session_id'] == $session_id){
 					echo '<img src="../img/view_more_stats.gif" border="0" title="'.get_lang('Reuse').'" alt="'.get_lang('Reuse').'"></a>';
-				}
-							
-				echo ' <a href="',api_get_self(),'?',api_get_cidreq(),'&copy_question=',$row['id'],'&fromExercise=',$fromExercise,'">' .
-							'<img src="../img/cd.gif" border="0" title="'.get_lang('ReUseACopyInCurrentTest').'" alt="'.get_lang('ReUseACopyInCurrentTest').'"></a>';
+				}                							
+				echo '<a href="'.api_get_self().'?'.api_get_cidreq().'&amp;copy_question='.$row['id'].'&course_id='.$selected_course.'&fromExercise=',$fromExercise,'">';                
+                echo ' '.Display::return_icon('cd.gif', get_lang('ReUseACopyInCurrentTest'));
+                echo '</a>';
 			}
             echo '</td>';
             echo '</tr>';
@@ -492,8 +571,3 @@ if($is_allowedToEdit) {
     	  	</div></form>';
     }
 	Display::display_footer();
-} else {
-	// if not admin of course
-	api_not_allowed(true);
-}
-?>

+ 14 - 3
main/inc/lib/course.lib.php

@@ -133,6 +133,17 @@ class CourseManager {
             WHERE code='".Database::escape_string($course_code)."'"),'ASSOC'
         );
     }
+    
+    /**
+     * Returns all the information of a given coursecode
+     * @param   int     the course id
+     * @return an array with all the fields of the course table
+
+     */
+    public static function get_course_information_by_id($course_id) {
+        return Database::select('*', Database::get_main_table(TABLE_MAIN_COURSE), array('where'=>array('id = ?' =>intval($course_id))),'first');        
+    }
+    
 
     /**
      * Returns a list of courses. Should work with quickform syntax
@@ -612,7 +623,7 @@ class CourseManager {
         $user_id = intval($user_id);
         $data = array();
 
-        $sql_nb_cours = "SELECT course_rel_user.course_code, course.title
+        $sql_nb_cours = "SELECT course_rel_user.course_code, course.title, course.id, course.db_name
             FROM $tbl_course_user as course_rel_user
             INNER JOIN $tbl_course as course
                 ON course.code = course_rel_user.course_code
@@ -623,7 +634,7 @@ class CourseManager {
             $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
             $access_url_id = api_get_current_access_url_id();
             if ($access_url_id != -1) {
-                $sql_nb_cours = "	SELECT course_rel_user.course_code, course.title
+                $sql_nb_cours = "	SELECT course_rel_user.course_code, course.title, course.id, course.db_name
                     FROM $tbl_course_user as course_rel_user
                     INNER JOIN $tbl_course as course
                         ON course.code = course_rel_user.course_code
@@ -636,7 +647,7 @@ class CourseManager {
 
         $result_nb_cours = Database::query($sql_nb_cours);
         if (Database::num_rows($result_nb_cours) > 0) {
-            while ($row = Database::fetch_array($result_nb_cours)) {
+            while ($row = Database::fetch_array($result_nb_cours,'ASSOC')) {
                 $data[$row['course_code']] = $row;
             }
         }

+ 55 - 31
main/inc/lib/database.lib.php

@@ -1328,8 +1328,10 @@ class Database {
      * @todo lot of stuff to do here
     */
     
-    public static function find($table_name, $columns = '*' , $where_conditions = array(), $option = 'ASSOC') {
-    	$where_return = self::parse_where_conditions($where_conditions);        
+    public static function select($columns = '*' , $table_name,  $conditions = array(), $type_result = 'all', $option = 'ASSOC') {        
+    	$conditions = self::parse_conditions($conditions); 
+        
+        //@todo we could do a describe here to check the columns ...       
         $clean_columns = '';
         if (is_array($columns)) {
         	$clean_columns = implode(',', $columns);
@@ -1339,54 +1341,76 @@ class Database {
         	} else {
         		$clean_columns = (string)$columns;
         	}
-        }        
-        $sql    = "SELECT $clean_columns FROM $table_name $where_return ";
-        $result = self::query($sql);
+        }
         
-        $array = array();
-        if ($result !== false) { // For isolation from database engine's behaviour.
+             
+         $sql    = "SELECT $clean_columns FROM $table_name $conditions";
+      
+               
+        
+        $result = self::query($sql);        
+        $array = array();        
+        //if (self::num_rows($result) > 0 ) {        
+        if ($type_result == 'all') {  
             while ($row = self::fetch_array($result, $option)) {
                 if (isset($row['id'])) {
                     $array[$row['id']] = $row;
                 } else {
                 	$array[] = $row;
                 }                    
-            }
+            }         
+        } else {
+        	$array = self::fetch_array($result, $option);
         }
         return $array;
     }
     
     /**
-     * Parses where conditionsof this form: array('id = ?' =>'4')
+     * Parses WHERE/ORDER conditions i.e array('where'=>array('id = ?' =>'4'), 'order'=>'id DESC'))
+     * @param   array   
      * @todo lot of stuff to do here
     */
-    private function parse_where_conditions($conditions) {  
+    private function parse_conditions($conditions) {  
         if (empty($conditions)) {
         	return '';
         }
-        $where_return = '';  
-        foreach ($conditions as $condition => $value_array) {                     
-            if (is_array($value_array)) {
-                $clean_values = array();                            
-                foreach($value_array as $item) {
-                    $item = Database::escape_string($item);
-                    $clean_values[]= "'$item'";
-                }
-            } else {
-                $value_array = Database::escape_string($value_array);
-                $clean_values = "'$value_array'";
-            }
-            if (!empty($condition) && !empty($clean_values)) {    
-                $condition = str_replace('?','%s', $condition); //we treat everything as string                
-                $condition = vsprintf($condition, $clean_values);
-                $where_return .= $condition;                            
-            }
-        }
         
-        if (!empty($where_return)) {            
-        	$where_return = " WHERE $where_return ";
+        $return_value = '';     
+        foreach ($conditions as $type_condition => $condition_data) {            
+             switch($type_condition) {
+                case 'where':                    
+                    foreach ($condition_data as $condition => $value_array) {                     
+                        if (is_array($value_array)) {
+                            $clean_values = array();                            
+                            foreach($value_array as $item) {
+                                $item = Database::escape_string($item);
+                                $clean_values[]= "'$item'";
+                            }
+                        } else {
+                            $value_array = Database::escape_string($value_array);
+                            $clean_values = "'$value_array'";
+                        }
+                        if (!empty($condition) && !empty($clean_values)) {    
+                            $condition = str_replace('?','%s', $condition); //we treat everything as string                
+                            $condition = vsprintf($condition, $clean_values);
+                            $where_return .= $condition;                            
+                        }
+                    }
+                    if (!empty($where_return)) {
+                        $return_value = " WHERE $where_return" ;	
+                    }
+                break;
+                case 'order':
+                    $return_value .= " ORDER BY $condition_data";
+                break;
+                
+            } 
         }
-        return $where_return;       
+        return $return_value;       
+    }
+    
+    private function parse_where_conditions($coditions){
+    	return self::parse_conditions(array('where'=>$coditions));
     }
     
     /**

+ 1402 - 0
main/inc/lib/fckeditor/editor/plugins/asciisvg/ASCIIsvgPI.js

@@ -0,0 +1,1402 @@
+/* ASCIIsvgPI.js
+==============
+This version contains modifications needed for ASCIIsvg to work with
+tinyMCE editor plugins.  Modifications made by David Lippman, (c) 2008
+Revised 8/14/09
+
+JavaScript routines to dynamically generate Scalable Vector Graphics
+using a mathematical xy-coordinate system (y increases upwards) and
+very intuitive JavaScript commands (no programming experience required).
+ASCIIsvg.js is good for learning math and illustrating online math texts.
+Works with Internet Explorer+Adobe SVGviewer and SVG enabled Mozilla/Firefox.
+
+Ver 1.2.7 Oct 13, 2005 (c) Peter Jipsen http://www.chapman.edu/~jipsen
+Latest version at http://www.chapman.edu/~jipsen/svg/ASCIIsvg.js
+If you use it on a webpage, please send the URL to jipsen@chapman.edu
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at
+your option) any later version.
+
+This program 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 (at http://www.gnu.org/copyleft/gpl.html) 
+for more details.*/
+
+//var AScgiloc = 'http://www.imathas.com/imathas/filter/graph/svgimg.php';
+var ASnoSVG = false;
+var checkIfSVGavailable = true;
+var notifyIfNoSVG = false;
+var alertIfNoSVG = false;
+var xunitlength = 20;  // pixels
+var yunitlength = 20;  // pixels
+var origin = [0,0];   // in pixels (default is bottom left corner)
+var defaultwidth = 300; defaultheight = 200; defaultborder = [0,0,0,0];
+var border = defaultborder;
+var strokewidth, strokedasharray, stroke, fill;
+var fontstyle, fontfamily, fontsize, fontweight, fontstroke, fontfill, fontbackground;
+var markerstrokewidth = "1";
+var markerstroke = "black";
+var markerfill = "yellow";
+var marker = "none";
+var arrowfill = stroke;
+var dotradius = 4;
+var ticklength = 4;
+var axesstroke = "black";
+var gridstroke = "grey";
+var pointerpos = null;
+var coordinates = null;
+var above = "above";
+var below = "below";
+var left = "left";
+var right = "right";
+var aboveleft = "aboveleft";
+var aboveright = "aboveright";
+var belowleft = "belowleft";
+var belowright = "belowright";
+var cpi = "\u03C0", ctheta = "\u03B8";
+var pi = Math.PI, ln = Math.log, e = Math.E;
+var arcsin = Math.asin, arccos = Math.acos, arctan = Math.atan;
+var sec = function(x) { return 1/Math.cos(x) };
+var csc = function(x) { return 1/Math.sin(x) };
+var cot = function(x) { return 1/Math.tan(x) };
+var xmin, xmax, ymin, ymax, xscl, yscl, 
+    xgrid, ygrid, xtick, ytick, initialized;
+var isIE = document.createElementNS==null;
+var picture, svgpicture, doc, width, height, a, b, c, d, i, n, p, t, x, y;
+var arcsec = function(x) { return arccos(1/x) };
+var arccsc = function(x) { return arcsin(1/x) };
+var arccot = function(x) { return arctan(1/x) };
+var sinh = function(x) { return (Math.exp(x)-Math.exp(-x))/2 };
+var cosh = function(x) { return (Math.exp(x)+Math.exp(-x))/2 };
+var tanh = 
+  function(x) { return (Math.exp(x)-Math.exp(-x))/(Math.exp(x)+Math.exp(-x)) };
+var sech = function(x) { return 1/cosh(x) };
+var csch = function(x) { return 1/sinh(x) };
+var coth = function(x) { return 1/tanh(x) };
+var arcsinh = function(x) { return ln(x+Math.sqrt(x*x+1)) };
+var arccosh = function(x) { return ln(x+Math.sqrt(x*x-1)) };
+var arctanh = function(x) { return ln((1+x)/(1-x))/2 };
+var sech = function(x) { return 1/cosh(x) };
+var csch = function(x) { return 1/sinh(x) };
+var coth = function(x) { return 1/tanh(x) };
+var arcsech = function(x) { return arccosh(1/x) };
+var arccsch = function(x) { return arcsinh(1/x) };
+var arccoth = function(x) { return arctanh(1/x) };
+var sign = function(x) { return (x==0?0:(x<0?-1:1)) };
+var logten = function(x) { return (Math.LOG10E*Math.log(x)) };
+
+
+function factorial(x,n) {
+  if (n==null) n=1;
+  for (var i=x-n; i>0; i-=n) x*=i;
+  return (x<0?NaN:(x==0?1:x));
+}
+
+
+function C(x,k) {
+  var res=1;
+  for (var i=0; i<k; i++) res*=(x-i)/(k-i);
+  return res;
+}
+
+
+function chop(x,n) {
+  if (n==null) n=0;
+  return Math.floor(x*Math.pow(10,n))/Math.pow(10,n);
+}
+
+
+function ran(a,b,n) {
+  if (n==null) n=0;
+  return chop((b+Math.pow(10,-n)-a)*Math.random()+a,n);
+}
+
+
+function myCreateElementXHTML(t) {
+  if (isIE) return document.createElement(t);
+  else return document.createElementNS("http://www.w3.org/1999/xhtml",t);
+}
+
+
+function isSVGavailable() {
+//Safari 3 can do SVG, but still has issues.  
+  if ((ver = navigator.userAgent.toLowerCase().match(/safari\/(\d+)/))!=null) {
+		//if (ver[1]>524) {
+		//	return null;
+		//}
+		return 1;
+ } 
+//Opera can do SVG, but not very pretty, so might want to skip it 
+ if ((ver = navigator.userAgent.toLowerCase().match(/opera\/([\d\.]+)/))!=null) {
+		if (ver[1]>9.1) {
+			return null;
+		}
+ }
+ //Mozillas. 
+  if (navigator.product && navigator.product=='Gecko') {
+	   var rv = navigator.userAgent.toLowerCase().match(/rv:\s*([\d\.]+)/);
+	   if (rv!=null) {
+		rv = rv[1].split('.');
+		if (rv.length<3) { rv[2] = 0;}
+		if (rv.length<2) { rv[1] = 0;}
+	   }
+	   if (rv!=null && 10000*rv[0]+100*rv[1]+1*rv[2]>=10800) return null;
+	   else return 1;
+  }
+  //IE + AdobeSVGviewer
+  if (navigator.appName.slice(0,9)=="Microsoft")
+    try	{
+      var oSVG=eval("new ActiveXObject('Adobe.SVGCtl.3');");
+        return null;
+    } catch (e) {
+        return 1;
+    }
+  else return 1;
+}
+
+function less(x,y) { return x < y }  // used for scripts in XML files
+                                     // since IE does not handle CDATA well
+function setText(st,id) { 
+  var node = document.getElementById(id);
+  if (node!=null)
+    if (node.childNodes.length!=0) node.childNodes[0].nodeValue = st;
+    else node.appendChild(document.createTextNode(st));
+}
+
+
+function myCreateElementSVG(t) {
+  if (isIE) return doc.createElement(t);
+  else return doc.createElementNS("http://www.w3.org/2000/svg",t);
+}
+
+
+function getX() {
+  return (doc.getElementById("pointerpos").getAttribute("cx")-origin[0])/xunitlength;
+}
+
+
+function getY() {
+  return (height-origin[1]-doc.getElementById("pointerpos").getAttribute("cy"))/yunitlength;
+}
+
+
+function mousemove_listener(evt) {
+  if (svgpicture.getAttribute("xbase")!=null)
+    pointerpos.cx.baseVal.value = evt.clientX-svgpicture.getAttribute("xbase");
+  if (svgpicture.getAttribute("ybase")!=null)
+    pointerpos.cy.baseVal.value = evt.clientY-svgpicture.getAttribute("ybase");
+}
+
+
+function top_listener(evt) {
+  svgpicture.setAttribute("ybase",evt.clientY);
+}
+
+
+function bottom_listener(evt) { 
+  svgpicture.setAttribute("ybase",evt.clientY-height+1);
+}
+
+
+function left_listener(evt) {
+  svgpicture.setAttribute("xbase",evt.clientX);
+}
+
+
+function right_listener(evt) {
+  svgpicture.setAttribute("xbase",evt.clientX-width+1);
+}
+
+
+function switchTo(id) {
+//alert(id);
+  picture = document.getElementById(id);
+  width = picture.getAttribute("width")-0;
+  height = picture.getAttribute("height")-0;
+  strokewidth = "1" // pixel
+  stroke = "black"; // default line color
+  fill = "none";    // default fill color
+  marker = "none";
+  if ((picture.nodeName == "EMBED" || picture.nodeName == "embed") && isIE) {
+    svgpicture = picture.getSVGDocument().getElementById("root");
+    doc = picture.getSVGDocument();
+  } else {
+    picture.setAttribute("onmousemove","updateCoords"+(id.slice(id.length-1)-1)+"()");
+//alert(picture.getAttribute("onmousemove")+"***");
+    svgpicture = picture;
+    doc = document;
+  }
+  xunitlength = svgpicture.getAttribute("xunitlength")-0;
+  yunitlength = svgpicture.getAttribute("yunitlength")-0;
+  xmin = svgpicture.getAttribute("xmin")-0;
+  xmax = svgpicture.getAttribute("xmax")-0;
+  ymin = svgpicture.getAttribute("ymin")-0;
+  ymax = svgpicture.getAttribute("ymax")-0;
+  origin = [svgpicture.getAttribute("ox")-0,svgpicture.getAttribute("oy")-0];
+}
+
+
+function updatePicture(obj) {
+//alert(typeof obj)
+  var src = document.getElementById((typeof obj=="string"?
+              obj:"picture"+(obj+1)+"input")).value;
+  xmin = null; xmax = null; ymin = null; ymax = null;
+  xscl = null; xgrid = null; yscl = null; ygrid = null;
+  initialized = false;
+  switchTo((typeof obj=="string"?obj.slice(0,8):"picture"+(obj+1)));
+  src = src.replace(/plot\(\x20*([^\"f\[][^\n\r]+?)\,/g,"plot\(\"$1\",");
+  src = src.replace(/plot\(\x20*([^\"f\[][^\n\r]+)\)/g,"plot(\"$1\")");
+  src = src.replace(/([0-9])([a-zA-Z])/g,"$1*$2");
+  src = src.replace(/\)([\(0-9a-zA-Z])/g,"\)*$1");
+//alert(src);
+  try {
+    with (Math) eval(src);
+  } catch(err) {alert(err+"\n"+src)}
+}
+
+
+function showHideCode(obj) {
+  var node = obj.nextSibling;
+  while (node != null && node.nodeName != "BUTTON" && 
+
+    node.nodeName != "button") node = node.nextSibling;
+  if (node.style.display == "none") node.style.display = "";
+  else node.style.display = "none";
+  while (node != null && node.nodeName != "TEXTAREA" && 
+    node.nodeName != "textarea") node = node.previousSibling;
+  if (node.style.display == "none") node.style.display = "";
+  else node.style.display = "none";
+//  updatePicture(node.getAttribute("id"));
+}
+
+
+function hideCode() { //do nothing
+}
+
+
+function showcode() { //do nothing
+}
+
+
+function nobutton() { //do nothing
+}
+
+
+function setBorder(l,b,r,t) { 
+	if (t==null) {
+		border = new Array(l,l,l,l);
+	} else {
+		border = new Array(l,b,r,t);
+	}
+}
+
+
+function initPicture(x_min,x_max,y_min,y_max) {
+ if (!initialized) {
+  strokewidth = "1"; // pixel
+  strokedasharray = null;
+  stroke = "black"; // default line color
+  fill = "none";    // default fill color
+  fontstyle = "italic"; // default shape for text labels
+  fontfamily = "times"; // default font
+  fontsize = "16";      // default size
+  fontweight = "normal";
+  fontstroke = "black";  // default font outline color
+  fontfill = "black";    // default font color
+  fontbackground = "none";
+  marker = "none";
+  initialized = true;
+  if (x_min!=null) xmin = x_min;
+  if (x_max!=null) xmax = x_max;
+  if (y_min!=null) ymin = y_min;
+  if (y_max!=null) ymax = y_max;
+  if (xmin==null) xmin = -5;
+  if (xmax==null) xmax = 5;
+ if (typeof xmin != "number" || typeof xmax != "number" || xmin >= xmax) 
+   alert("Picture requires at least two numbers: xmin < xmax");
+ else if (y_max != null && (typeof y_min != "number" || 
+          typeof y_max != "number" || y_min >= y_max))
+   alert("initPicture(xmin,xmax,ymin,ymax) requires numbers ymin < ymax");
+ else {
+  //if (width==null) 
+  width = picture.getAttribute("width");
+  //else picture.setAttribute("width",width);
+  if (width==null || width=="") width=defaultwidth;
+  //if (height==null) 
+  height = picture.getAttribute("height");
+  //else picture.setAttribute("height",height);
+  if (height==null || height=="") height=defaultheight;
+  xunitlength = (width-border[0]-border[2])/(xmax-xmin);
+  yunitlength = xunitlength;
+//alert(xmin+" "+xmax+" "+ymin+" "+ymax)
+  if (ymin==null) {
+    origin = [-xmin*xunitlength+border[0],height/2];
+    ymin = -(height-border[1]-border[3])/(2*yunitlength);
+    ymax = -ymin;
+  } else {
+    if (ymax!=null) yunitlength = (height-border[1]-border[3])/(ymax-ymin);
+    else ymax = (height-border[1]-border[3])/yunitlength + ymin;
+    origin = [-xmin*xunitlength+border[0],-ymin*yunitlength+border[1]];
+  }
+  winxmin = Math.max(border[0]-5,0);
+  winxmax = Math.min(width-border[2]+5,width);
+  winymin = Math.max(border[3]-5,0);
+  winymax = Math.min(height-border[1]+5,height);
+//  if (true ||picture.nodeName == "EMBED" || picture.nodeName == "embed") {
+    if (isIE) {
+      svgpicture = picture.getSVGDocument().getElementById("root");
+      while (svgpicture.childNodes.length()>5) 
+        svgpicture.removeChild(svgpicture.lastChild); 
+      svgpicture.setAttribute("width",width);
+      svgpicture.setAttribute("height",height);
+      doc = picture.getSVGDocument();
+    } else {
+      var qnode = document.createElementNS("http://www.w3.org/2000/svg","svg");
+      qnode.setAttribute("id",picture.getAttribute("id"));
+      qnode.setAttribute("style","display:inline; "+picture.getAttribute("style"));
+      qnode.setAttribute("width",picture.getAttribute("width"));
+      qnode.setAttribute("height",picture.getAttribute("height"));
+      if (picture.parentNode!=null)
+        picture.parentNode.replaceChild(qnode,picture);
+      else
+        svgpicture.parentNode.replaceChild(qnode,svgpicture);
+      svgpicture = qnode;
+      doc = document;
+      pointerpos = doc.getElementById("pointerpos");
+      if (pointerpos==null) {
+        pointerpos = myCreateElementSVG("circle");
+        pointerpos.setAttribute("id","pointerpos");
+        pointerpos.setAttribute("cx",0);
+        pointerpos.setAttribute("cy",0);
+        pointerpos.setAttribute("r",0.5);
+        pointerpos.setAttribute("fill","red");
+        svgpicture.appendChild(pointerpos);
+      }
+    }
+//  } else {
+//    svgpicture = picture;
+//    doc = document;
+//  }
+  svgpicture.setAttribute("xunitlength",xunitlength);
+  svgpicture.setAttribute("yunitlength",yunitlength);
+  svgpicture.setAttribute("xmin",xmin);
+  svgpicture.setAttribute("xmax",xmax);
+  svgpicture.setAttribute("ymin",ymin);
+  svgpicture.setAttribute("ymax",ymax);
+  svgpicture.setAttribute("ox",origin[0]);
+  svgpicture.setAttribute("oy",origin[1]);
+  var node = myCreateElementSVG("rect");
+  node.setAttribute("x","0");
+  node.setAttribute("y","0");
+  node.setAttribute("width",width);
+  node.setAttribute("height",height);
+  node.setAttribute("style","stroke-width:1;fill:white");
+  svgpicture.appendChild(node);
+  if (!isIE && picture.getAttribute("onmousemove")!=null) {
+    svgpicture.addEventListener("mousemove", mousemove_listener, true);
+    var st = picture.getAttribute("onmousemove");
+    svgpicture.addEventListener("mousemove", eval(st.slice(0,st.indexOf("("))), true);
+    node = myCreateElementSVG("polyline");
+    node.setAttribute("points","0,0 "+width+",0");
+    node.setAttribute("style","stroke:white; stroke-width:3");
+    node.addEventListener("mousemove", top_listener, true);
+    svgpicture.appendChild(node);
+    node = myCreateElementSVG("polyline");
+    node.setAttribute("points","0,"+height+" "+width+","+height);
+    node.setAttribute("style","stroke:white; stroke-width:3");
+    node.addEventListener("mousemove", bottom_listener, true);
+    svgpicture.appendChild(node);
+    node = myCreateElementSVG("polyline");
+    node.setAttribute("points","0,0 0,"+height);
+    node.setAttribute("style","stroke:white; stroke-width:3");
+    node.addEventListener("mousemove", left_listener, true);
+    svgpicture.appendChild(node);
+    node = myCreateElementSVG("polyline");
+    node.setAttribute("points",(width-1)+",0 "+(width-1)+","+height);
+    node.setAttribute("style","stroke:white; stroke-width:3");
+    node.addEventListener("mousemove", right_listener, true);
+    svgpicture.appendChild(node);
+  }
+  border = defaultborder;
+ }
+ }
+}
+
+
+function line(p,q,id) { // segment connecting points p,q (coordinates in units)
+  var node;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("path");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+  node.setAttribute("d","M"+(p[0]*xunitlength+origin[0])+","+
+    (height-p[1]*yunitlength-origin[1])+" "+
+    (q[0]*xunitlength+origin[0])+","+(height-q[1]*yunitlength-origin[1]));
+  node.setAttribute("stroke-width", strokewidth);
+  if (strokedasharray!=null) 
+    node.setAttribute("stroke-dasharray", strokedasharray);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+  if (marker=="dot" || marker=="arrowdot") {
+    ASdot(p,4,markerstroke,markerfill);
+    if (marker=="arrowdot") arrowhead(p,q);
+    ASdot(q,4,markerstroke,markerfill);
+  } else if (marker=="arrow") arrowhead(p,q);
+}
+
+
+function path(plist,id,c) {
+  if (c==null) c="";
+  var node, st, i;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("path");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+  if (typeof plist == "string") st = plist;
+  else {
+    st = "M";
+    st += (plist[0][0]*xunitlength+origin[0])+","+
+          (height-plist[0][1]*yunitlength-origin[1])+" "+c;
+    for (i=1; i<plist.length; i++)
+      st += (plist[i][0]*xunitlength+origin[0])+","+
+            (height-plist[i][1]*yunitlength-origin[1])+" ";
+  }
+  node.setAttribute("d", st);
+  node.setAttribute("stroke-width", strokewidth);
+  if (strokedasharray!=null) 
+    node.setAttribute("stroke-dasharray", strokedasharray);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+  if (marker=="dot" || marker=="arrowdot")
+    for (i=0; i<plist.length; i++)
+      if (c!="C" && c!="T" || i!=1 && i!=2)
+        ASdot(plist[i],4,markerstroke,markerfill);
+}
+
+
+function curve(plist,id) {
+  path(plist,id,"T");
+}
+
+
+function circle(center,radius,id) { // coordinates in units
+  var node;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("circle");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+
+  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
+  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
+  node.setAttribute("r",radius*xunitlength);
+  node.setAttribute("stroke-width", strokewidth);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+}
+
+
+function loop(p,d,id) { 
+// d is a direction vector e.g. [1,0] means loop starts in that direction
+  if (d==null) d=[1,0];
+  path([p,[p[0]+d[0],p[1]+d[1]],[p[0]-d[1],p[1]+d[0]],p],id,"C");
+  if (marker=="arrow" || marker=="arrowdot") 
+    arrowhead([p[0]+Math.cos(1.4)*d[0]-Math.sin(1.4)*d[1],
+               p[1]+Math.sin(1.4)*d[0]+Math.cos(1.4)*d[1]],p);
+}
+
+
+function arc(start,end,radius,id) { // coordinates in units
+  var node, v;
+//alert([fill, stroke, origin, xunitlength, yunitlength, height])
+  if (id!=null) node = doc.getElementById(id);
+  if (radius==null) {
+    v=[end[0]-start[0],end[1]-start[1]];
+    radius = Math.sqrt(v[0]*v[0]+v[1]*v[1]);
+  }
+  if (node==null) {
+    node = myCreateElementSVG("path");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+  node.setAttribute("d","M"+(start[0]*xunitlength+origin[0])+","+
+    (height-start[1]*yunitlength-origin[1])+" A"+radius*xunitlength+","+
+     radius*yunitlength+" 0 0,0 "+(end[0]*xunitlength+origin[0])+","+
+    (height-end[1]*yunitlength-origin[1]));
+  node.setAttribute("stroke-width", strokewidth);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+  if (marker=="arrow" || marker=="arrowdot") {
+    u = [(end[1]-start[1])/4,(start[0]-end[0])/4];
+    v = [(end[0]-start[0])/2,(end[1]-start[1])/2];
+//alert([u,v])
+    v = [start[0]+v[0]+u[0],start[1]+v[1]+u[1]];
+  } else v=[start[0],start[1]];
+  if (marker=="dot" || marker=="arrowdot") {
+    ASdot(start,4,markerstroke,markerfill);
+    if (marker=="arrowdot") arrowhead(v,end);
+    ASdot(end,4,markerstroke,markerfill);
+  } else if (marker=="arrow") arrowhead(v,end);
+}
+
+
+function ellipse(center,rx,ry,id) { // coordinates in units
+
+  var node;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("ellipse");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
+  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
+  node.setAttribute("rx",rx*xunitlength);
+  node.setAttribute("ry",ry*yunitlength);
+  node.setAttribute("stroke-width", strokewidth);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+}
+
+
+function rect(p,q,id,rx,ry) { // opposite corners in units, rounded by radii
+  var node;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("rect");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+  }
+  node.setAttribute("x",p[0]*xunitlength+origin[0]);
+  node.setAttribute("y",height-q[1]*yunitlength-origin[1]);
+  node.setAttribute("width",(q[0]-p[0])*xunitlength);
+  node.setAttribute("height",(q[1]-p[1])*yunitlength);
+  if (rx!=null) node.setAttribute("rx",rx*xunitlength);
+  if (ry!=null) node.setAttribute("ry",ry*yunitlength);
+  node.setAttribute("stroke-width", strokewidth);
+  node.setAttribute("stroke", stroke);
+  node.setAttribute("fill", fill);
+}
+
+function text(p,st,pos,angle) {
+	p[0] = p[0]*xunitlength+origin[0];
+	p[1] = p[1]*yunitlength+origin[1];
+	textabs(p,st,pos,angle);
+}
+
+function textabs(p,st,pos,angle,id,fontsty) {
+  if (angle==null) {
+	  angle = 0;
+  } else {
+	  angle = (360 - angle)%360;
+  }
+  var textanchor = "middle";
+  var dx=0; var dy=0;
+  if (angle==270) {
+	  var dy = 0; var dx = fontsize/3;
+	  if (pos!=null) {
+	    if (pos.match(/left/)) {dx = -fontsize/2;}
+	    if (pos.match(/right/)) {dx = fontsize-0;}
+	    if (pos.match(/above/)) {
+	      textanchor = "start";
+	      dy = -fontsize/2;
+	    }
+	    if (pos.match(/below/)) {
+	      textanchor = "end";
+	      dy = fontsize/2;
+	    }
+	  }
+  } 
+  if (angle==90) {
+	  var dy = 0; var dx = -fontsize/3;
+	  if (pos!=null) {
+	    if (pos.match(/left/)) dx = -fontsize-0;
+	    if (pos.match(/right/)) dx = fontsize/2;
+	    if (pos.match(/above/)) {
+	      textanchor = "end";
+	      dy = -fontsize/2;
+	    }
+	    if (pos.match(/below/)) {
+	      textanchor = "start";
+	      dy = fontsize/2;
+	    }
+	  }
+  }
+  if (angle==0) {
+	  var dx = 0; var dy = fontsize/3;
+	  if (pos!=null) {
+	    if (pos.match(/above/)) { dy = -fontsize/3; }
+	    if (pos.match(/below/)) { dy = fontsize-0; }
+	    if (pos.match(/right/)) {
+	      textanchor = "start";
+	      dx = fontsize/3;
+	    }
+	    if (pos.match(/left/)) {
+	      textanchor = "end";
+	      dx = -fontsize/3;
+	    }
+	  }
+  }
+ 
+  var node;
+  if (id!=null) node = doc.getElementById(id);
+  if (node==null) {
+    node = myCreateElementSVG("text");
+    node.setAttribute("id", id);
+    svgpicture.appendChild(node);
+    node.appendChild(doc.createTextNode(st));
+  }
+  node.lastChild.nodeValue = st;
+  node.setAttribute("x",p[0]+dx);
+  node.setAttribute("y",height-p[1]+dy);
+  if (angle != 0) {
+	  node.setAttribute("transform","rotate("+angle+" "+(p[0]+dx)+" "+(height-p[1]+dy)+")");
+  }
+  node.setAttribute("font-style",(fontsty!=null?fontsty:fontstyle));
+  node.setAttribute("font-family",fontfamily);
+  node.setAttribute("font-size",fontsize);
+  node.setAttribute("font-weight",fontweight);
+  node.setAttribute("text-anchor",textanchor);
+  if (fontstroke!="none") node.setAttribute("stroke",fontstroke);
+  if (fontfill!="none") node.setAttribute("fill",fontfill);
+  node.setAttribute("stroke-width","0px");
+  if (fontbackground!="none") {
+	  var bgnode = myCreateElementSVG("rect");
+	  var bb = node.getBBox();
+	  bgnode.setAttribute("fill",fontbackground);
+	  bgnode.setAttribute("stroke-width","0px");
+	  bgnode.setAttribute("x",bb.x-2);
+	  bgnode.setAttribute("y",bb.y-2);
+	  bgnode.setAttribute("width",bb.width+4);
+	  bgnode.setAttribute("height",bb.height+4);
+	  if (angle != 0) {
+		   bgnode.setAttribute("transform","rotate("+angle+" "+(p[0]+dx)+" "+(height-p[1]+dy)+")");
+	  }
+	  svgpicture.insertBefore(bgnode,node);
+		  
+  }
+  return p;
+}
+
+
+function ASdot(center,radius,s,f) { // coordinates in units, radius in pixel
+  if (s==null) s = stroke; if (f==null) f = fill;
+  var node = myCreateElementSVG("circle");
+  node.setAttribute("cx",center[0]*xunitlength+origin[0]);
+  node.setAttribute("cy",height-center[1]*yunitlength-origin[1]);
+  node.setAttribute("r",radius);
+  node.setAttribute("stroke-width", strokewidth);
+  node.setAttribute("stroke", s);
+  node.setAttribute("fill", f);
+  svgpicture.appendChild(node);
+}
+
+
+function dot(center, typ, label, pos, id) {
+  var node;
+  var cx = center[0]*xunitlength+origin[0];
+  var cy = height-center[1]*yunitlength-origin[1];
+  if (id!=null) node = doc.getElementById(id);
+  if (typ=="+" || typ=="-" || typ=="|") {
+    if (node==null) {
+      node = myCreateElementSVG("path");
+      node.setAttribute("id", id);
+      svgpicture.appendChild(node);
+    }
+    if (typ=="+") {
+      node.setAttribute("d",
+        " M "+(cx-ticklength)+" "+cy+" L "+(cx+ticklength)+" "+cy+
+        " M "+cx+" "+(cy-ticklength)+" L "+cx+" "+(cy+ticklength));
+      node.setAttribute("stroke-width", .5);
+      node.setAttribute("stroke", axesstroke);
+    } else {
+      if (typ=="-") node.setAttribute("d",
+        " M "+(cx-ticklength)+" "+cy+" L "+(cx+ticklength)+" "+cy);
+      else node.setAttribute("d",
+        " M "+cx+" "+(cy-ticklength)+" L "+cx+" "+(cy+ticklength));
+      node.setAttribute("stroke-width", strokewidth);
+      node.setAttribute("stroke", stroke);
+    }
+  } else {
+    if (node==null) {
+      node = myCreateElementSVG("circle");
+      node.setAttribute("id", id);
+      svgpicture.appendChild(node);
+    }
+    node.setAttribute("cx",cx);
+    node.setAttribute("cy",cy);
+    node.setAttribute("r",dotradius);
+    node.setAttribute("stroke-width", strokewidth);
+    node.setAttribute("stroke", stroke);
+    node.setAttribute("fill", (typ=="open"?"white":stroke));
+  }
+  if (label!=null) 
+    text(center,label,(pos==null?"below":pos),(id==null?id:id+"label"))
+}
+
+
+function arrowhead(p,q) { // draw arrowhead at q (in units)
+  var up;
+  var v = [p[0]*xunitlength+origin[0],height-p[1]*yunitlength-origin[1]];
+  var w = [q[0]*xunitlength+origin[0],height-q[1]*yunitlength-origin[1]];
+  var u = [w[0]-v[0],w[1]-v[1]];
+  var d = Math.sqrt(u[0]*u[0]+u[1]*u[1]);
+  if (d > 0.00000001) {
+    u = [u[0]/d, u[1]/d];
+    up = [-u[1],u[0]];
+    var node = myCreateElementSVG("path");
+    node.setAttribute("d","M "+(w[0]-15*u[0]-4*up[0])+" "+
+      (w[1]-15*u[1]-4*up[1])+" L "+(w[0]-3*u[0])+" "+(w[1]-3*u[1])+" L "+
+      (w[0]-15*u[0]+4*up[0])+" "+(w[1]-15*u[1]+4*up[1])+" z");
+    node.setAttribute("stroke-width", markerstrokewidth);
+    node.setAttribute("stroke", stroke); /*was markerstroke*/
+    node.setAttribute("fill", stroke); /*was arrowfill*/
+    svgpicture.appendChild(node);    
+  }
+}
+
+
+function chopZ(st) {
+  var k = st.indexOf(".");
+  if (k==-1) return st;
+  for (var i=st.length-1; i>k && st.charAt(i)=="0"; i--);
+  if (i==k) i--;
+  return st.slice(0,i+1);
+}
+
+
+function grid(dx,dy) { // for backward compatibility
+  axes(dx,dy,null,dx,dy)
+}
+
+
+function noaxes() {
+  if (!initialized) initPicture();
+}
+
+
+function axes(dx,dy,labels,gdx,gdy,dox,doy) {
+//xscl=x is equivalent to xtick=x; xgrid=x; labels=true;
+  var x, y, ldx, ldy, lx, ly, lxp, lyp, pnode, st;
+  if (!initialized) initPicture();
+  if (typeof dx=="string") { labels = dx; dx = null; }
+  if (typeof dy=="string") { gdx = dy; dy = null; }
+  if (xscl!=null) {dx = xscl; gdx = xscl; labels = dx}
+  if (yscl!=null) {dy = yscl; gdy = yscl}
+  if (xtick!=null) {dx = xtick}
+  if (ytick!=null) {dy = ytick}
+  if (dox==null) {dox = true;}
+  if (doy==null) {doy = true;}
+  if (dox=="off" || dox==0) { dox = false;} else {dox = true;}
+  if (doy=="off" || doy==0) { doy = false;} else {doy = true;}
+//alert(null)
+  dx = (dx==null?xunitlength:dx*xunitlength);
+  dy = (dy==null?dx:dy*yunitlength);
+  fontsize = Math.floor(Math.min(dx/1.5,dy/1.5,16));//alert(fontsize)
+  ticklength = fontsize/4;
+  if (xgrid!=null) gdx = xgrid;
+  if (ygrid!=null) gdy = ygrid;
+  if (gdx!=null) {
+    gdx = (typeof gdx=="string"?dx:gdx*xunitlength);
+    gdy = (gdy==null?dy:gdy*yunitlength);
+    pnode = myCreateElementSVG("path");
+    st="";
+    if (dox && gdx>0) {
+	    for (x = origin[0]; x<=winxmax; x = x+gdx)
+	      if (x>=winxmin) st += " M"+x+","+winymin+" "+x+","+winymax;
+	    for (x = origin[0]-gdx; x>=winxmin; x = x-gdx)
+	      if (x<=winxmax) st += " M"+x+","+winymin+" "+x+","+winymax;
+    }
+    if (doy && gdy>0) {
+	    for (y = height-origin[1]; y<=winymax; y = y+gdy)
+	      if (y>=winymin) st += " M"+winxmin+","+y+" "+winxmax+","+y;
+	    for (y = height-origin[1]-gdy; y>=winymin; y = y-gdy)
+	      if (y<=winymax) st += " M"+winxmin+","+y+" "+winxmax+","+y;
+    }
+    pnode.setAttribute("d",st);
+    pnode.setAttribute("stroke-width", .5);
+    pnode.setAttribute("stroke", gridstroke);
+    pnode.setAttribute("fill", fill);
+    svgpicture.appendChild(pnode);
+  }
+  pnode = myCreateElementSVG("path");
+  if (dox) {
+	  st="M"+winxmin+","+(height-origin[1])+" "+winxmax+","+
+    (height-origin[1]);
+  }
+  if (doy) {
+	  st += " M"+origin[0]+","+winymin+" "+origin[0]+","+winymax;
+  }
+  if (dox) {
+	  for (x = origin[0]; x<winxmax; x = x+dx)
+	    if (x>=winymin) st += " M"+x+","+(height-origin[1]+ticklength)+" "+x+","+
+		   (height-origin[1]-ticklength);
+	  for (x = origin[0]-dx; x>winxmin; x = x-dx)
+	   if (x<=winxmax) st += " M"+x+","+(height-origin[1]+ticklength)+" "+x+","+
+		   (height-origin[1]-ticklength);
+  }
+  if (doy) {
+	  for (y = height-origin[1]; y<winymax; y = y+dy)
+	    if (y>=winymin) st += " M"+(origin[0]+ticklength)+","+y+" "+(origin[0]-ticklength)+","+y;
+	  for (y = height-origin[1]-dy; y>winymin; y = y-dy)
+	    if (y<=winymax) st += " M"+(origin[0]+ticklength)+","+y+" "+(origin[0]-ticklength)+","+y;
+  }
+  if (labels!=null) with (Math) {
+    ldx = dx/xunitlength;
+    ldy = dy/yunitlength;
+    lx = (xmin>0 || xmax<0?xmin:0);
+    ly = (ymin>0 || ymax<0?ymin:0);
+    lxp = (ly==0?"below":"above");
+    lyp = (lx==0?"left":"right");
+    var ddx = floor(1.1-log(ldx)/log(10))+1;
+    var ddy = floor(1.1-log(ldy)/log(10))+1;
+    if (ddy<0) { ddy = 0;}
+    if (ddx<0) { ddx = 0;}
+    if (dox) {
+	    for (x = (doy?ldx:0); x<=xmax; x = x+ldx)
+	      if (x>=xmin) text([x,ly],chopZ(x.toFixed(ddx)),lxp);
+	    for (x = -ldx; xmin<=x; x = x-ldx)
+	      if (x<=xmax) text([x,ly],chopZ(x.toFixed(ddx)),lxp);
+    }
+    if (doy) {
+	    for (y = (dox?ldy:0); y<=ymax; y = y+ldy)
+	      if (y>=ymin) text([lx,y],chopZ(y.toFixed(ddy)),lyp);
+	    for (y = -ldy; ymin<=y; y = y-ldy)
+	      if (y<=ymax) text([lx,y],chopZ(y.toFixed(ddy)),lyp);
+    }
+  }
+  pnode.setAttribute("d",st);
+  pnode.setAttribute("stroke-width", .5);
+  pnode.setAttribute("stroke", axesstroke);
+  pnode.setAttribute("fill", fill);
+  svgpicture.appendChild(pnode);
+}
+
+function safepow(base,power) {
+	if (base<0 && Math.floor(power)!=power) {
+		for (var j=3; j<50; j+=2) {
+			if (Math.abs(Math.round(j*power)-(j*power))<.000001) {
+				if (Math.round(j*power)%2==0) {
+					return Math.pow(Math.abs(base),power);
+				} else {
+					return -1*Math.pow(Math.abs(base),power);
+				}
+			}
+		}
+		return sqrt(-1);
+	} else {
+		return Math.pow(base,power);
+	}
+}
+
+function nthroot(n,base) {
+	return safepow(base,1/n);
+}
+function nthlogten(n,v) {
+	return ((Math.log(v))/(Math.log(n)));
+}
+function matchtolower(match) {
+	return match.toLowerCase();
+}
+
+function mathjs(st,varlist) {
+  //translate a math formula to js function notation
+  // a^b --> pow(a,b)
+  // na --> n*a
+  // (...)d --> (...)*d
+  // n! --> factorial(n)
+  // sin^-1 --> arcsin etc.
+  //while ^ in string, find term on left and right
+  //slice and concat new formula string
+  //parenthesizes the function variables
+  st = st.replace("[","(");
+  st = st.replace("]",")");
+  st = st.replace(/arc(sin|cos|tan)/g,"a#r#c $1");
+  if (varlist != null) {
+	  var reg = new RegExp("(sqrt|ln|log|sin|cos|tan|sec|csc|cot|abs)[\(]","g");
+	  st = st.replace(reg,"$1#(");
+	  var reg = new RegExp("("+varlist+")("+varlist+")$","g");
+	  st = st.replace(reg,"($1)($2)");
+	  var reg = new RegExp("("+varlist+")(a#|sqrt|ln|log|sin|cos|tan|sec|csc|cot|abs)","g");
+	  st = st.replace(reg,"($1)$2");
+	  var reg = new RegExp("("+varlist+")("+varlist+")([^a-df-zA-Z\(#])","g"); // 6/1/09 readded \( for f(350/x)
+	  st = st.replace(reg,"($1)($2)$3"); //get xy3
+	  //var reg = new RegExp("("+varlist+")("+varlist+")(\w*[^\(#])","g");
+	  //st = st.replace(reg,"($1)($2)$3"); //get xysin
+	  var reg = new RegExp("([^a-df-zA-Z#])("+varlist+")([^a-df-zA-Z#])","g");
+	  st = st.replace(reg,"$1($2)$3");	  
+	  var reg = new RegExp("^("+varlist+")([^a-df-zA-Z])","g");
+	  st = st.replace(reg,"($1)$2");
+	  var reg = new RegExp("([^a-df-zA-Z])("+varlist+")$","g");
+	  st = st.replace(reg,"$1($2)");
+  }
+  st = st.replace(/#/g,"");
+  st = st.replace(/a#r#c\s+(sin|cos|tan)/g,"arc$1");
+  st = st.replace(/\s/g,"");
+  st = st.replace(/(Sin|Cos|Tan|Sec|Csc|Cot|Arc|Abs|Log|Ln)/g, matchtolower);
+  st = st.replace(/log_(\d+)\(/,"nthlog($1,");
+  st = st.replace(/log/g,"logten");
+  
+  if (st.indexOf("^-1")!=-1) {
+    st = st.replace(/sin\^-1/g,"arcsin");
+    st = st.replace(/cos\^-1/g,"arccos");
+    st = st.replace(/tan\^-1/g,"arctan");
+    st = st.replace(/sec\^-1/g,"arcsec");
+    st = st.replace(/csc\^-1/g,"arccsc");
+    st = st.replace(/cot\^-1/g,"arccot");
+    st = st.replace(/sinh\^-1/g,"arcsinh");
+    st = st.replace(/cosh\^-1/g,"arccosh");
+    st = st.replace(/tanh\^-1/g,"arctanh");
+    st = st.replace(/sech\^-1/g,"arcsech");
+    st = st.replace(/csch\^-1/g,"arccsch");
+    st = st.replace(/coth\^-1/g,"arccoth");
+  }
+  
+  st = st.replace(/root\((\d+)\)\(/,"nthroot($1,");
+  //st = st.replace(/E/g,"(EE)");
+  st = st.replace(/([0-9])E([\-0-9])/g,"$1(EE)$2");
+  
+  st = st.replace(/^e$/g,"(E)");
+  st = st.replace(/pi/g,"(pi)");
+  st = st.replace(/^e([^a-zA-Z])/g,"(E)$1");
+  st = st.replace(/([^a-zA-Z])e$/g,"$1(E)");
+  
+  st = st.replace(/([^a-zA-Z])e([^a-zA-Z])/g,"$1(E)$2");
+  st = st.replace(/([0-9])([\(a-zA-Z])/g,"$1*$2");
+  st = st.replace(/(!)([0-9\(])/g,"$1*$2");
+  //want to keep scientific notation
+  st= st.replace(/([0-9])\*\(EE\)([\-0-9])/,"$1e$2");
+
+  
+  st = st.replace(/\)([\(0-9a-zA-Z])/g,"\)*$1");
+  
+  var i,j,k, ch, nested;
+  while ((i=st.indexOf("^"))!=-1) {
+
+    //find left argument
+    if (i==0) return "Error: missing argument";
+    j = i-1;
+    ch = st.charAt(j);
+    if (ch>="0" && ch<="9") {// look for (decimal) number
+      j--;
+      while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
+      if (ch==".") {
+        j--;
+        while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
+      }
+    } else if (ch==")") {// look for matching opening bracket and function name
+      nested = 1;
+      j--;
+      while (j>=0 && nested>0) {
+        ch = st.charAt(j);
+        if (ch=="(") nested--;
+        else if (ch==")") nested++;
+        j--;
+      }
+      while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z")
+        j--;
+    } else if (ch>="a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
+      j--;
+      while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z")
+        j--;
+    } else { 
+      return "Error: incorrect syntax in "+st+" at position "+j;
+    }
+    //find right argument
+    if (i==st.length-1) return "Error: missing argument";
+    k = i+1;
+    ch = st.charAt(k);
+    nch = st.charAt(k+1);
+    if (ch>="0" && ch<="9" || (ch=="-" && nch!="(") || ch==".") {// look for signed (decimal) number
+      k++;
+      while (k<st.length && (ch=st.charAt(k))>="0" && ch<="9") k++;
+      if (ch==".") {
+        k++;
+        while (k<st.length && (ch=st.charAt(k))>="0" && ch<="9") k++;
+      }
+    } else if (ch=="(" || (ch=="-" && nch=="(")) {// look for matching closing bracket and function name
+      if (ch=="-") { k++;}
+      nested = 1;
+      k++;
+      while (k<st.length && nested>0) {
+        ch = st.charAt(k);
+        if (ch=="(") nested++;
+        else if (ch==")") nested--;
+        k++;
+      }
+    } else if (ch>="a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
+      k++;
+      while (k<st.length && (ch=st.charAt(k))>="a" && ch<="z" ||
+               ch>="A" && ch<="Z") k++;
+      if (ch=='(' && st.slice(i+1,k).match(/^(sin|cos|tan|sec|csc|cot|logten|log|ln|exp|arcsin|arccos|arctan|arcsec|arccsc|arccot|sinh|cosh|tanh|sech|csch|coth|arcsinh|arccosh|arctanh|arcsech|arccsch|arccoth|sqrt|abs|nthroot)$/)) {
+	      nested = 1;
+	      k++;
+	      while (k<st.length && nested>0) {
+		ch = st.charAt(k);
+		if (ch=="(") nested++;
+		else if (ch==")") nested--;
+		k++;
+	      }
+      }
+    } else { 
+      return "Error: incorrect syntax in "+st+" at position "+k;
+    }
+    st = st.slice(0,j+1)+"safepow("+st.slice(j+1,i)+","+st.slice(i+1,k)+")"+
+           st.slice(k);
+  }
+  while ((i=st.indexOf("!"))!=-1) {
+    //find left argument
+    if (i==0) return "Error: missing argument";
+    j = i-1;
+    ch = st.charAt(j);
+    if (ch>="0" && ch<="9") {// look for (decimal) number
+      j--;
+      while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
+      if (ch==".") {
+        j--;
+        while (j>=0 && (ch=st.charAt(j))>="0" && ch<="9") j--;
+      }
+    } else if (ch==")") {// look for matching opening bracket and function name
+      nested = 1;
+      j--;
+      while (j>=0 && nested>0) {
+        ch = st.charAt(j);
+        if (ch=="(") nested--;
+        else if (ch==")") nested++;
+        j--;
+      }
+      while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z")
+        j--;
+    } else if (ch>="a" && ch<="z" || ch>="A" && ch<="Z") {// look for variable
+      j--;
+      while (j>=0 && (ch=st.charAt(j))>="a" && ch<="z" || ch>="A" && ch<="Z")
+        j--;
+    } else { 
+      return "Error: incorrect syntax in "+st+" at position "+j;
+    }
+    st = st.slice(0,j+1)+"factorial("+st.slice(j+1,i)+")"+st.slice(i+1);
+  }
+  return st;
+}
+
+
+function slopefield(fun,dx,dy) {
+  var g = fun;
+  if (typeof fun=="string") 
+    eval("g = function(x,y){ with(Math) return "+mathjs(fun)+" }");
+  var gxy,x,y,u,v,dz;
+  if (dx==null) dx=1;
+  if (dy==null) dy=1;
+  dz = Math.sqrt(dx*dx+dy*dy)/6;
+  var x_min = Math.ceil(xmin/dx);
+  var y_min = Math.ceil(ymin/dy);
+  for (x = x_min; x <= xmax; x += dx)
+    for (y = y_min; y <= ymax; y += dy) {
+      gxy = g(x,y);
+      if (!isNaN(gxy)) {
+        if (Math.abs(gxy)=="Infinity") {u = 0; v = dz;}
+        else {u = dz/Math.sqrt(1+gxy*gxy); v = gxy*u;}
+        line([x-u,y-v],[x+u,y+v]);
+      }
+    }
+}
+
+
+//ASCIIsvgAddon.js dumped here
+function drawPictures() {
+	drawPics()
+}
+
+//ShortScript format:
+//xmin,xmax,ymin,ymax,xscl,yscl,labels,xgscl,ygscl,width,height plotcommands(see blow)
+//plotcommands: type,eq1,eq2,startmaker,endmarker,xmin,xmax,color,strokewidth,strokedash
+function parseShortScript(sscript,gw,gh) {
+	if (sscript == null) {
+		initialized = false;
+		sscript = picture.sscr;
+	}
+	
+	var sa= sscript.split(",");
+	
+	if (gw && gh) {
+		sa[9] = gw;
+		sa[10] = gh;
+		sscript = sa.join(",");
+		picture.setAttribute("sscr", sscript);
+	}
+	picture.setAttribute("width", sa[9]);
+	picture.setAttribute("height", sa[10]);
+	picture.style.width = sa[9] + "px";
+	picture.style.height = sa[10] + "px";
+	
+	if (sa.length > 10) {
+		commands = 'setBorder(5);';
+		commands += 'width=' +sa[9] + '; height=' +sa[10] + ';';
+		commands += 'initPicture(' + sa[0] +','+ sa[1] +','+ sa[2] +','+ sa[3] + ');';
+		commands += 'axes(' + sa[4] +','+ sa[5] +','+ sa[6] +','+ sa[7] +','+ sa[8]+ ');';
+				
+		var inx = 11;
+		var eqnlist = 'Graphs: ';
+		
+		while (sa.length > inx+9) {
+		   commands += 'stroke="' + sa[inx+7] + '";';
+		   commands += 'strokewidth="' + sa[inx+8] + '";'
+		   //commands += 'strokedasharray="' + sa[inx+9] + '";'	
+		   if (sa[inx+9] != "") {
+			   commands += 'strokedasharray="' + sa[inx+9].replace(/\s+/g,',') + '";';
+		   }
+		   if (sa[inx]=="slope") {
+			   eqnlist += "dy/dx="+sa[inx+1] + "; ";
+			commands += 'slopefield("' + sa[inx+1] + '",' + sa[inx+2] + ',' + sa[inx+2] + ');'; 
+		   } else {
+			if (sa[inx]=="func") {
+				eqnlist += "y="+sa[inx+1] + "; ";
+				eqn = '"' + sa[inx+1] + '"';
+			} else if (sa[inx] == "polar") {
+				eqnlist += "r="+sa[inx+1] + "; ";
+				eqn = '["cos(t)*(' + sa[inx+1] + ')","sin(t)*(' + sa[inx+1] + ')"]';
+			} else if (sa[inx] == "param") {
+				eqnlist += "[x,y]=["+sa[inx+1] + "," + sa[inx+2] + "]; ";
+				eqn = '["' + sa[inx+1] + '","'+ sa[inx+2] + '"]';
+			}
+			
+			
+			if (typeof eval(sa[inx+5]) == "number") {
+		//	if ((sa[inx+5]!='null')&&(sa[inx+5].length>0)) {
+				//commands += 'myplot(' + eqn +',"' + sa[inx+3] +  '","' + sa[inx+4]+'",' + sa[inx+5] + ',' + sa[inx+6]  +');';
+				commands += 'plot(' + eqn +',' + sa[inx+5] + ',' + sa[inx+6] +',null,null,' + sa[inx+3] +  ',' + sa[inx+4] +');';
+			
+			} else {
+				commands += 'plot(' + eqn +',null,null,null,null,' + sa[inx+3] +  ',' + sa[inx+4]+');';
+			}
+		   }
+		   inx += 10;
+		}
+		
+		try {
+			eval(commands);
+		} catch (e) {
+			setTimeout(function() {parseShortScript(sscript,gw,gh)},100);
+			//alert("Graph not ready");
+		}
+		
+		picture.setAttribute("alt",eqnlist);
+		//picture.setAttribute("width", sa[9]);
+		//picture.setAttribute("height", sa[9]);
+		
+		return commands;
+	}
+}
+
+
+
+
+function drawPics() {
+  var index, nd;
+  pictures = document.getElementsByTagName("embed");
+ // might be needed if setTimeout on parseShortScript isn't working
+  if (!ASnoSVG) {
+	   try {
+		  for (var i = 0; i < pictures.length; i++) {
+			  if (pictures[i].getAttribute("sscr")!='' || pictures[i].getAttribute("script")!='') {
+				  if (pictures[i].getSVGDocument().getElementById("root") == null) {
+					setTimeout(drawPics,100);
+					return;
+				  }
+			  }
+		  }
+	  } catch (e) {
+		  setTimeout(drawPics,100);
+		  return;
+	  }
+ }
+  var len = pictures.length;
+  
+  
+  for (index = 0; index < len; index++) {
+	  picture = ((!ASnoSVG && isIE) ? pictures[index] : pictures[0]);
+   // for (index = len-1; index >=0; index--) {
+	//  picture = pictures[index];
+	  
+	  if (!ASnoSVG) {
+		  initialized = false;
+		  var sscr = picture.getAttribute("sscr");
+		  if ((sscr != null) && (sscr != "")) { //sscr from editor
+			  try {
+				  parseShortScript(sscr);
+			  } catch (e) {}
+		  } else {
+			  src = picture.getAttribute("script"); //script from showplot
+			  if ((src!=null) && (src != "")) {
+				  try {
+					  with (Math) eval(src);
+				  } catch(err) {alert(err+"\n"+src)}
+			  }
+		  }
+	  } else {
+		  if (picture.getAttribute("sscr")!='') {
+			  n = document.createElement('img');
+			  n.setAttribute("style",picture.getAttribute("style"));
+			  n.setAttribute("src",AScgiloc+'?sscr='+encodeURIComponent(picture.getAttribute("sscr")));
+			  pn = picture.parentNode;
+			  pn.replaceChild(n,picture);
+		  }
+		  
+	  }
+	  
+  }
+}
+
+//modified by David Lippman from original in AsciiSVG.js by Peter Jipsen
+//added min/max type:  0:nothing, 1:arrow, 2:open dot, 3:closed dot
+function plot(fun,x_min,x_max,points,id,min_type,max_type) {
+  var pth = [];
+  var f = function(x) { return x }, g = fun;
+  var name = null;
+  if (typeof fun=="string") 
+    eval("g = function(x){ with(Math) return "+mathjs(fun)+" }");
+  else if (typeof fun=="object") {
+    eval("f = function(t){ with(Math) return "+mathjs(fun[0])+" }");
+    eval("g = function(t){ with(Math) return "+mathjs(fun[1])+" }");
+  }
+  if (typeof x_min=="string") { name = x_min; x_min = xmin }
+  else name = id;
+  var min = (x_min==null?xmin:x_min);
+  var max = (x_max==null?xmax:x_max);
+  if (max <= min) { return null;}
+  //else {
+  var inc = max-min-0.000001*(max-min);
+  inc = (points==null?inc/200:inc/points);
+  var gt;
+//alert(typeof g(min))
+  for (var t = min; t <= max; t += inc) {
+    gt = g(t);
+    if (!(isNaN(gt)||Math.abs(gt)=="Infinity")) pth[pth.length] = [f(t), gt];
+  }
+  path(pth,name);
+  if (min_type == 1) {
+	arrowhead(pth[1],pth[0]);
+  } else if (min_type == 2) {
+	dot(pth[0], "open");
+  } else if (min_type == 3) {
+	dot(pth[0], "closed");
+  }
+  if (max_type == 1) {
+	arrowhead(pth[pth.length-2],pth[pth.length-1]);
+  } else if (max_type == 2) {
+	dot(pth[pth.length-1], "open");
+  } else if (max_type == 3) {
+	dot(pth[pth.length-1], "closed");
+  }
+
+  return p;
+  //}
+}
+
+//end ASCIIsvgAddon.js dump
+
+function updateCoords(ind) {
+  switchTo("picture"+(ind+1));
+  var gx=getX(), gy=getY();
+  if ((xmax-gx)*xunitlength > 6*fontsize || (gy-ymin)*yunitlength > 2*fontsize)
+    text([xmax,ymin],"("+gx.toFixed(2)+", "+gy.toFixed(2)+")",
+         "aboveleft","AScoord"+ind,"");
+  else text([xmax,ymin]," ","aboveleft","AScoord"+ind,"");
+}
+
+
+function updateCoords0() {updateCoords(0)}
+function updateCoords1() {updateCoords(1)}
+function updateCoords2() {updateCoords(2)}
+function updateCoords3() {updateCoords(3)}
+function updateCoords4() {updateCoords(4)}
+function updateCoords5() {updateCoords(5)}
+function updateCoords6() {updateCoords(6)}
+function updateCoords7() {updateCoords(7)}
+function updateCoords8() {updateCoords(8)}
+function updateCoords9() {updateCoords(9)}
+ASfn = [function() {updatePicture(0)},
+  function() {updatePicture(1)},
+  function() {updatePicture(2)},
+  function() {updatePicture(3)},
+  function() {updatePicture(4)},
+  function() {updatePicture(5)},
+  function() {updatePicture(6)},
+  function() {updatePicture(7)},
+
+  function() {updatePicture(8)},
+  function() {updatePicture(9)}];
+ASupdateCoords = [function() {updateCoords(0)},
+  function() {updateCoords(1)},
+  function() {updateCoords(2)},
+  function() {updateCoords(3)},
+  function() {updateCoords(4)},
+  function() {updateCoords(5)},
+  function() {updateCoords(6)},
+  function() {updateCoords(7)},
+  function() {updateCoords(8)},
+  function() {updateCoords(9)}];
+
+
+// GO1.1 Generic onload by Brothercake 
+// http://www.brothercake.com/
+//onload function
+function generic()
+{
+  drawPictures();
+};
+//setup onload function
+if(typeof window.addEventListener != 'undefined')
+{
+  //.. gecko, safari, konqueror and standard
+  window.addEventListener('load', generic, false);
+}
+else if(typeof document.addEventListener != 'undefined')
+{
+  //.. opera 7
+  document.addEventListener('load', generic, false);
+}
+else if(typeof window.attachEvent != 'undefined')
+{
+  //.. win/ie
+  window.attachEvent('onload', generic);
+}
+//** remove this condition to degrade older browsers
+else
+{
+  //.. mac/ie5 and anything else that gets this far
+  //if there's an existing onload function
+  if(typeof window.onload == 'function')
+  {
+    //store it
+    var existing = onload;
+    //add new onload handler
+    window.onload = function()
+    {
+      //call existing onload function
+      existing();
+      //call generic onload function
+      generic();
+    };
+  }
+  else
+  {
+    //setup onload function
+    window.onload = generic;
+  }
+}
+
+
+if (checkIfSVGavailable) {
+  checkifSVGavailable = false;
+  nd = isSVGavailable();
+  ASnoSVG = nd!=null;
+}

+ 12 - 11
main/inc/lib/fckeditor/editor/plugins/asciisvg/fck_asciisvg.html

@@ -15,7 +15,8 @@
         <meta name="robots" content="noindex, nofollow" />
 
         <script type="text/javascript">
-document.write( '<scr' + 'ipt type="text/javascript" src="' + window.parent.frameElement._DialogArguments.Editor.FCKConfig.ScriptASCIIMathML + '"><\/scr' + 'ipt>' ) ;
+//document.write( '<scr' + 'ipt type="text/javascript" src="' + window.parent.frameElement._DialogArguments.Editor.FCKConfig.ScriptASCIIMathML + '"><\/scr' + 'ipt>' ) ;
+document.write( '<scr' + 'ipt type="text/javascript" src="ASCIIsvgPI.js"><\/scr' + 'ipt>' ) ;
         </script>
 
         <script src="../../dialog/common/fck_dialog_common.js" type="text/javascript"></script>
@@ -85,27 +86,27 @@ End with: <Select id="gend">
 
 <hr/>
 
-xmin: <input type="text" id="xmin" size="4" value="-7.5" onChange='javascript: AsciisvgDialog.graphit();'/>
-xmax: <input type="text" id="xmax" size="4" value="7.5" onChange='javascript: AsciisvgDialog.graphit();'/>
-xscl: <input type="text" id="xscl" size="3" value="1" onChange='javascript: AsciisvgDialog.graphit();'/>
+xmin: <input type="text" id="xmin" size="4" value="-7.5" onChange='javascript: UpdatePreview();'/>
+xmax: <input type="text" id="xmax" size="4" value="7.5" onChange='javascript: UpdatePreview();'/>
+xscl: <input type="text" id="xscl" size="3" value="1" onChange='javascript: UpdatePreview();'/>
 &nbsp;&nbsp;
-ymin: <input type="text" id="ymin" size="4" value="-5" onChange='javascript: AsciisvgDialog.graphit();'/>
-ymax: <input type="text" id="ymax" size="4" value="5" onChange='javascript: AsciisvgDialog.graphit();'/>
-yscl: <input type="text" id="yscl" size="3" value="1" onChange='javascript: AsciisvgDialog.graphit();'/>
+ymin: <input type="text" id="ymin" size="4" value="-5" onChange='javascript: UpdatePreview();'/>
+ymax: <input type="text" id="ymax" size="4" value="5" onChange='javascript: UpdatePreview();'/>
+yscl: <input type="text" id="yscl" size="3" value="1" onChange='javascript: UpdatePreview();'/>
 <hr/>
 
-Show axis labels: <input type="checkbox" id="labels" value="Show Labels" onClick='javascript: AsciisvgDialog.graphit();' checked="checked"/>
-Show XY grid: <input type="checkbox" id="grid" value="Show Grid" onClick='javascript: AsciisvgDialog.graphit();' checked="checked"/>
+Show axis labels: <input type="checkbox" id="labels" value="Show Labels" onClick='javascript: UpdatePreview();' checked="checked"/>
+Show XY grid: <input type="checkbox" id="grid" value="Show Grid" onClick='javascript: UpdatePreview();' checked="checked"/>
 &nbsp;&nbsp;
 Resize to: <input type="text" id="gwidth" size="5" value="300"/> by <input type="text" id="gheight" size="5" value="200"/>
-<input type="button" value="Update" onclick="javascript: AsciisvgDialog.graphit();"/>
+<input type="button" value="Update" onclick="javascript: UpdatePreview();"/>
 <hr/>
 
 <input type="button" value="Add Graph" onclick="javascript: AsciisvgDialog.addgraph();"/>
 Graphs: <select id="graphs" onchange="javascript: AsciisvgDialog.loadeqn();"></select>
 <input type="button" value="Replace Selected Graph" onclick="javascript: AsciisvgDialog.replacegraph();"/>
 <input type="button" value="Remove" onclick="javascript: AsciisvgDialog.removegraph();"/>
-<select id="alignment" onchange="javascript: AsciisvgDialog.graphit();">
+<select id="alignment" onchange="javascript: UpdatePreview();">
 <option value="text-top">Top</option>
 <option value="middle">Middle</option>
 <option value="text-bottom">Bottom</option>

+ 25 - 21
main/inc/lib/fckeditor/editor/plugins/asciisvg/fck_asciisvg.js

@@ -40,6 +40,14 @@ var showasciiformulaonhover = false ;
 // Font size of the formulas in this dialog.
 var mathfontsize = "1.1em" ;
 
+var noSVG = ASnoSVG ; // Temporarily added.
+var width = 300 ;
+var height = 200 ;
+var alignm = 'middle' ;
+//var sscr = '' ;
+var sscr = '-7.5,7.5,-5,5,1,1,1,1,1,300,200' ;
+//var isnew = null ;
+var isnew = true ;
 
 function LoadSelection()
 {
@@ -98,7 +106,6 @@ var AsciisvgDialog =
     sscr: '-7.5,7.5,-5,5,1,1,1,1,1,300,200' ,
     //isnew: null ,
     isnew: true ,
-    AScgiloc: null ,
 
     init : function()
     {
@@ -110,16 +117,13 @@ var AsciisvgDialog =
         this.height = tinyMCEPopup.getWindowArg( 'height' ) ;
         this.isnew = tinyMCEPopup.getWindowArg( 'isnew' ) ;
         this.sscr = tinyMCEPopup.getWindowArg( 'sscr' ) ;
-        */
-        //this.AScgiloc = tinyMCEPopup.getWindowArg( 'AScgiloc' ) ;
-        this.AScgiloc = AScgiloc ;
-        /*
+        this.AScgiloc = tinyMCEPopup.getWindowArg( 'AScgiloc' ) ;
         this.alignm = tinyMCEPopup.getWindowArg( 'alignm' ) ;
         */
 
         if ( noSVG )
         {
-            GetE( 'preview' ).innerHTML = '<img id="previewimg" style="width:' + this.width + 'px; height: ' + this.height + 'px; vertical-align: middle; float: none;" src="' + this.AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) + '" script=" " />' ;
+            GetE( 'preview' ).innerHTML = '<img id="previewimg" style="width:' + this.width + 'px; height: ' + this.height + 'px; vertical-align: middle; float: none;" src="' + AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) + '" script=" " />' ;
         }
         else
         {
@@ -143,13 +147,13 @@ var AsciisvgDialog =
             {
                 aligntxt = 'vertical-align: ' + this.alignm + '; float: none;' ;
             }
-            tinyMCEPopup.editor.execCommand( 'mceInsertContent', false, '<img style="width: 300px; height: 200px; ' + aligntxt + '" src="' + this.AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) + '" sscr="' + this.sscr + '" script=" " />') ;
+            tinyMCEPopup.editor.execCommand( 'mceInsertContent', false, '<img style="width: 300px; height: 200px; ' + aligntxt + '" src="' + AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) + '" sscr="' + this.sscr + '" script=" " />') ;
         }
         else
         {
             el = tinyMCEPopup.editor.selection.getNode() ;
             ed.dom.setAttrib( el , 'sscr' , this.sscr ) ;
-            ed.dom.setAttrib( el , 'src' , this.AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) ) ;
+            ed.dom.setAttrib( el , 'src' , AScgiloc + '?sscr=' + encodeURIComponent( this.sscr ) ) ;
             ed.dom.setAttrib( el , 'width' , this.width ) ;
             ed.dom.setAttrib( el , 'height' , this.height ) ;
             ed.dom.setStyle( el , 'width' , this.width + 'px' ) ;
@@ -214,7 +218,7 @@ var AsciisvgDialog =
 
         graphs.options[ graphs.options.length ] = newopt ;
         graphs.selectedIndex = graphs.options.length - 1 ;
-        this.graphit() ;
+        UpdatePreview() ;
         GetE( 'equation' ).focus() ;
     } ,
 
@@ -235,7 +239,7 @@ var AsciisvgDialog =
             graphs.options[ graphs.selectedIndex ] = null ;
             if ( graphs.options.length > 0 ) { this.loadeqn() ; }
         }
-        this.graphit() ;
+        UpdatePreview() ;
         GetE( 'equation' ).focus() ;
     } ,
 
@@ -294,18 +298,18 @@ var AsciisvgDialog =
         this.sscr = commands ;
         this.alignm = GetE( 'alignment' ).value ;
 
-        if ( noSVG )
-        {
-            pvimg = GetE( 'previewimg' ) ;
-            pvimg.src = this.AScgiloc + '?sscr=' + encodeURIComponent(commands) ;
-            //ed.dom.setStyle( pvimg, 'width' , this.width + 'px' ) ;
-            //ed.dom.setStyle( pvimg, 'height' , this.height + 'px' ) ;
-        }
-        else
-        {
+        //if ( noSVG )
+        //{
+        //    pvimg = GetE( 'previewimg' ) ;
+        //    pvimg.src = AScgiloc + '?sscr=' + encodeURIComponent(commands) ;
+        //    //ed.dom.setStyle( pvimg, 'width' , this.width + 'px' ) ;
+        //    //ed.dom.setStyle( pvimg, 'height' , this.height + 'px' ) ;
+        //}
+        //else
+        //{
             pvsvg = GetE( 'previewsvg' ) ;
             parseShortScript( commands , this.width , this.height ) ;
-        }
+        //}
     } ,
 
     changetype : function()
@@ -486,7 +490,7 @@ var AsciisvgDialog =
             default: GetE( 'alignment' ).selectedIndex = 0 ; break ;
         }
 
-        //this.graphit() ;
+        //UpdatePreview() ;
     } ,
 
     chgtext : function( tag , text )

+ 13 - 26
main/inc/lib/main_api.lib.php

@@ -1049,6 +1049,7 @@ function api_get_course_info($course_code = null) {
             global $_configuration;
             $cData = Database::fetch_array($result);
             $_course['id'           ]         = $cData['code'           ];
+            $_course['code'         ]         = $cData['code'           ];
             $_course['name'         ]         = $cData['title'          ];
             $_course['official_code']         = $cData['visual_code'    ]; // Use in echo statements.
             $_course['sysCode'      ]         = $cData['code'           ]; // Use as key in db.
@@ -1061,40 +1062,26 @@ function api_get_course_info($course_code = null) {
             $_course['extLink'      ]['name'] = $cData['department_name'];
             $_course['categoryCode' ]         = $cData['faCode'         ];
             $_course['categoryName' ]         = $cData['faName'         ];
-
-            $_course['visibility'   ]        = $cData['visibility'      ];
-            $_course['subscribe_allowed']    = $cData['subscribe'       ];
-            $_course['unubscribe_allowed']   = $cData['unsubscribe'     ];
+            $_course['visibility'   ]         = $cData['visibility'      ];
+            $_course['subscribe_allowed']     = $cData['subscribe'       ];
+            $_course['unubscribe_allowed']    = $cData['unsubscribe'     ];
 
             // The real_id is an integer. It is mandatory for future implementations.
-            $_course['real_id'     ]         = $cData['id'              ];
+            $_course['real_id'     ]          = $cData['id'              ];
         }
         return $_course;
     }
-    global $_course;
+    global $_course;    
     return $_course;
 }
 
 
 /**
  * Returns the current course info array.
- * Array elements:
- * ['name']
- * ['official_code']
- * ['sysCode']
- * ['path']
- * ['dbName']
- * ['dbNameGlu']
- * ['titular']
- * ['language']
- * ['extLink']['url' ]
- * ['extLink']['name']
- * ['categoryCode']
- * ['categoryName']
+
  * Now if the course_code is given, the returned array gives info about that
  * particular course, not specially the current one.
  */
-
 function api_get_course_info_by_id($id = null) {
     if (!empty($id)) {
         $id = intval($id);
@@ -1127,13 +1114,13 @@ function api_get_course_info_by_id($id = null) {
             $_course['categoryCode' ]         = $cData['faCode'         ];
             $_course['categoryName' ]         = $cData['faName'         ];
 
-            $_course['visibility'   ]        = $cData['visibility'      ];
-            $_course['subscribe_allowed']    = $cData['subscribe'       ];
-            $_course['unubscribe_allowed']   = $cData['unsubscribe'     ];
+            $_course['visibility'   ]         = $cData['visibility'      ];
+            $_course['subscribe_allowed']     = $cData['subscribe'       ];
+            $_course['unubscribe_allowed']    = $cData['unsubscribe'     ];
 
-            $_course['real_id'      ]        = $cData['id'              ];
-            $_course['db_name'      ]        = $cData['db_name'         ];
-            $_course['title'        ]        = $cData['title'           ];
+            $_course['real_id'      ]         = $cData['id'              ];
+            $_course['db_name'      ]         = $cData['db_name'         ];
+            $_course['title'        ]         = $cData['title'           ];
 
         }
         return $_course;

+ 5 - 0
main/inc/lib/sessionmanager.lib.php

@@ -1231,4 +1231,9 @@ class SessionManager {
         return $return_array;
     }
     
+    public static function get_sessions_by_coach($user_id) {
+        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
+        return Database::select('*', $session_table, array('where'=>array('id_coach = ?'=>$user_id)));    	
+    }
+    
 }

+ 12 - 8
main/newscorm/lp_stats.php

@@ -14,6 +14,7 @@ require_once 'learnpath.class.php';
 require_once 'resourcelinker.inc.php';
 require_once api_get_path(LIBRARY_PATH).'tracking.lib.php';
 require_once api_get_path(LIBRARY_PATH).'course.lib.php';
+require_once '../exercice/exercise.lib.php';
 
 if (empty($_SESSION['_course']['id']) && isset($_GET['course'])) {
     $course_code = Security::remove_XSS($_GET['course']);
@@ -285,7 +286,9 @@ if (is_array($list) && count($list) > 0) {
                     if (!$is_allowed_to_edit && $result_disabled_ext_all) {
                         $view_score = Display::return_icon('invisible.gif', get_lang('ResultsHiddenByExerciseSetting'));
                     } else {
-                        $view_score = ($score == 0 ? '/' : ($maxscore === 0 ? $score : $score . '/' . float_format($maxscore, 1)));
+                        //$view_score = ($score == 0 ? '/' : ($maxscore === 0 ? $score : $score . '/' . float_format($maxscore, 1)));
+                        $view_score = show_score($score,$maxscore, false);
+                        
                     }
                     $output .= "<tr class='$oddclass'>\n" . "<td></td>\n" . "<td>$extend_attempt_link</td>\n" . '<td colspan="3">' . get_lang('Attempt') . ' ' . $row['iv_view_count'] . "</td>\n"
                      . '<td colspan="2"><font color="' . $color . '"><div class="mystatus">' . $my_lesson_status . "</div></font></td>\n" . '<td colspan="2"><div class="mystatus" align="center">' . $view_score . "</div></td>\n" . '<td colspan="2"><div class="mystatus">'.$time.'</div></td><td></td></tr>';
@@ -296,7 +299,6 @@ if (is_array($list) && count($list) > 0) {
                         $temp[] = Security::remove_XSS($my_lesson_status);
 
                         if ($row['item_type'] == 'quiz') {
-
                             if (!$is_allowed_to_edit && $result_disabled_ext_all) {
                                 $temp[] =  '/';
                             } else {
@@ -546,13 +548,12 @@ if (is_array($list) && count($list) > 0) {
                     $output .= "<td>$extend_link</td>\n" . '<td colspan="4"><div class="mystatus">' .$title. '</div></td>' . "\n";
                     $output .= '<td colspan="2"><font color="' . $color . '"><div class="mystatus">' . $my_lesson_status . "</div></font></td>\n" . '<td colspan="2"><div class="mystatus" align="center">';
                      if ($row['item_type'] == 'quiz') {
-
                          if (!$is_allowed_to_edit && $result_disabled_ext_all) {
                             $output .= Display::return_icon('invisible.gif', get_lang('ResultsHiddenByExerciseSetting'));
                         } else {
-                            $output .= ($score == 0 ? '0/'.float_format($maxscore, 1) : ($maxscore == 0 ? $score : float_format($score, 1) . '/' . float_format($maxscore, 1)));
+                         //   $output .= ($score == 0 ? '0/'.float_format($maxscore, 1) : ($maxscore == 0 ? $score : float_format($score, 1) . '/' . float_format($maxscore, 1)));
+                              $output .= show_score($score, $maxscore, false);
                         }
-
                      } else {
                         $output .= ($score == 0 ? '/' : ($maxscore == 0 ? $score : $score . '/' . $maxscore));
                      }
@@ -642,10 +643,13 @@ if (is_array($list) && count($list) > 0) {
                                 if ($my_score == 0 ) {
                                     $view_score = 	'0/'.$my_maxscore;
                                 } else {
-                                    if ($my_maxscore == 0)
+                                    if ($my_maxscore == 0) {
                                         $view_score = $my_score;
-                                    else
-                                        $view_score = $my_score . '/' . $my_maxscore;
+                                    } else {
+                                        //$view_score = $my_score . '/' . $my_maxscore;
+                                        $view_score = show_score($my_score, $my_maxscore, false);
+                                    }
+                                    
                                 }
                                 //$view_score = ($my_score == 0 ? '0.00/'.$my_maxscore : ($my_maxscore == 0 ? $my_score : $my_score . '/' . $my_maxscore));
                             }