/** 
  * Specific code for feedback controller classes. 
  * Also creates specific namespace for each controller class. 
  * @author Ivars Veksins
  */
document.ctad_feedback = function() 
{
  // TODO: implement garbage 
}

/** 
  * Shows question answer by hidding 
  * current popup window 
  */
document.ctad_feedback.show_answer = function (){
  
   //close the popup
  document.ctad_feedback.feedback_close(); 

   //restore the question
   document.ctad.current_question.load_answer_data();
   document.ctad.current_question.save_user_data();
   
   document.ctad_feedback.hide_submit(); 
   
   // make sure combo boxes load their data in them 
   if (typeof ComboBoxMgr != "undefined") 
     ComboBoxMgr.load_user_data(); 
} 

/** 
  * Hides submit button if visible
  */
document.ctad_feedback.hide_submit = function() 
{
  	// using image 
   var elements = document.getElementsByTagName("input"); 
   
	for (var i = 0; i < elements.length; i++) 
		if (elements[i].name == "submit") elements[i].style.display = 'none'; 	
}

/** 
  * Disabled submit button 
  */
document.ctad_feedback.disable_submit = function() 
{
  	// using image 
   var elements = document.getElementsByTagName("input"); 
   
	for (var i = 0; i < elements.length; i++) 
		if (elements[i].name == "submit") elements[i].style.disabled = true; 	
}

/** 
  * Enable submit button 
  */
document.ctad_feedback.enable_submit = function() 
{
  	// using image 
   var elements = document.getElementsByTagName("input"); 
   
	for (var i = 0; i < elements.length; i++) 
		if (elements[i].name == "submit") elements[i].style.disabled = false; 	
}


/** 
  * Shows submit button if hidden 
  */
document.ctad_feedback.show_submit = function()
{
  	// using image 
   var elements = document.getElementsByTagName("input"); 
   
	for (var i = 0; i < elements.length; i++) 
		if (elements[i].name == "submit") elements[i].style.display = 'block'; 	
}

  /** 
   * Close active feedback controller window 
   */
document.ctad_feedback.feedback_close = function() {
   if (document.ctad_feedback.$controller) 
     document.ctad_feedback.$controller.close();
}


/** 
 * Question for validating graded feedback 
 * @param object activity question 
 */
var graded_feedback = function(question) {
  this.$question = question; 

  /* populated variables once marked */ 
  this.$correct_answers = 0; 
  this.$incorrect = Array();
  this.$result = "n"; 

  this.mark(); 
}

graded_feedback.prototype = {
  mark: function() 
  {
    if (!this.$question) 
      ctad_error("[graded_feedback].mark(): Failed to grade graded feedback, question in constrcutor not provided"); 
    
    this.$question.get_question_answer(); 
    
    if (!this.$question.user_data || this.$question.user_data.match(/^\^|\^\^/)) return false; 
    
    this.$result = "m";
    
    var ar_u = this.$question.user_data.split("^"); 
    var ar_a = this.$question.answer.split("^"); 

    for (var i = 0; i < ar_u.length; i++) {
      if (ar_u[i]==ar_a[i]) {
        this.$correct_answers++;
      } else { this.$incorrect[i] = ar_u[i]; }
    }    
    
    return true; 
  }
}



/** 
 * Marks question answer and creates instance of feedback controller 
 * to show the feedback. 
 * @param object attributes 
 */
document.ctad_feedback.check_answer = function (attributes)
{
  if (!CTAD_SETTINGS['feedback_controller'])
    ctad_error("check_answer(): feedback controller not set in settings file, abort!"); 
  
  //first lets set the current question on this page 
  if (!attributes.question_name || !attributes.activity_name) {
    document.ctad.current_question = document.ctad.last_question;
  } else { 
    document.ctad.current_question = document.ctad.current_module.Activitys[
      attributes.activity_name].Questions[attributes.question_name];
  }
  
  document.ctad.current_activity_name=attributes.activity_name;
  

  
  // mark current question 
  var result=document.ctad.current_question.mark();
  
  // magic numbers: c:correct, i:incorrect, m:model answer n:no entry
	if (!attributes.graded && attributes.incorrect_action=="model" && result!="n"){
		result="m"; //always show model answer whether correct or otherwise
	} else if (result=="i" && attributes.incorrect_action!="none"){
		//only increment question tries on incorrect answer (ie not on 'no entry')
		document.ctad.question_attempts++;
      
		if (attributes.incorrect_action=="show"){
			var allow_attempts=CTAD_SETTINGS["question_attempts_before_show"];
			//if incorrect for the nth time, show answer
			var alternative="s";
		}else if (attributes.incorrect_action=="next"){
			var allow_attempts=CTAD_SETTINGS["question_attempts_before_next"];
			//if incorrect for the nth time, go to next
			var alternative="x";
		}else if (attributes.incorrect_action=="model"){
			var allow_attempts=CTAD_SETTINGS["question_attempts_before_model"];
			//if incorrect for the nth time, go to model
			var alternative="m";
		}

		if (document.ctad.question_attempts>allow_attempts-1)
			result=alternative;
	}
   
   
   
  // graded feedback here. 
   if (attributes.graded) attributes.graded = new graded_feedback(document.ctad.current_question)
    
  var feedback = ""; 
  var button = "";
  var items = ""; 
  
  // create a controller which would process our 
  var controller = eval(CTAD_SETTINGS['feedback_controller']); 
  
  
  if (window.popup_html) {
       // multi text feedback 
      feedback = window.popup_html; 
      button = CTAD_SETTINGS['button_close']; 
      
      // if it is not the original popup type figure out feedback texts 
  } else if  (CTAD_SETTINGS['feedback_controller'] != 'document.ctad_feedback.original') {
    var next = parseInt(attributes.page_number, 10) + 1;       
    if (next < 10) next='0' + next;
    
    // check if has next button 
    var hasNext = (parseInt(attributes.page_number) < attributes.page_total && CTAD_SETTINGS['feedback_use_next']); 

    // force the default button to be close or next 
    var button = (hasNext) ? CTAD_SETTINGS['button_next'].
      replace("%next%", "body" + next + ".htm") : CTAD_SETTINGS['button_close'];  
        
      
    if (!attributes.graded)
    {
      var feedback = feedbacktext[attributes.question_name].split("^");
      // place where the feedback text and buttons 
      // will be stored for the popup window 
      var popup_feedback = ""; 
	  var prepend='';
      
      switch (result) 
      {
         case "i": 
          feedback = feedback[1]; 
		  prepend=CTAD_SETTINGS['feedback_prepend_incorrect'];
          button= CTAD_SETTINGS['button_tryagain']; 
          break; 
          
        case "x": 
		  prepend=CTAD_SETTINGS['feedback_prepend_incorrect'];
          feedback = feedback[1]; 
          break; 
          
        case "c": 
		  prepend=CTAD_SETTINGS['feedback_prepend_correct'];
          feedback = feedback[0]; 
          break; 
          
        case "m": 
		  prepend=CTAD_SETTINGS['feedback_prepend_model'];
          feedback = feedbacktext[attributes.question_name];
          break; 
          
        case "n": 
          feedback = CTAD_SETTINGS['feedback_no_answer']
          button = CTAD_SETTINGS['button_tryagain'];               
          break; 
          
        case "s": 
		  prepend=CTAD_SETTINGS['feedback_prepend_incorrect'];
          feedback = CTAD_SETTINGS['feedback_show_answer']; 
          button = CTAD_SETTINGS['button_show'];   
          break; 
      }
    } else  { 
      var graded = attributes.graded; 
      var correct = graded.$correct_answers; 
	  var prepend='';

      if (graded.$result == "n") 
      {
        feedback = CTAD_SETTINGS['feedback_answer_all']; 
      } else { 
      

        // get the feedback text from qdata 
        // feedback has to be in a range 
        for (option in feedbacktext[attributes.question_name]) { 
            var ar_range = option.split("_");
            
            if (correct >= ar_range[0] && correct <= ar_range[1])  {
              feedback = feedbacktext[graded.$question.$name][option]; 
              break; 
            }    
        }  
        
        feedback = feedback.replace("###1###", graded.$correct_answers).replace("###2###",
          graded.$correct_answers + graded.$incorrect.length - 1); 
          
        // continue only if incorrect answers are present 
        if (graded.$incorrect.length > 0) 
        {
          for (var i = 0; i < graded.$incorrect.length; i++) 
            if (graded.$incorrect[i]) items += CTAD_SETTINGS['feedback_graded_item'].replace("%n%", i + 1)
        }
      }
      //
    }
    if(typeof(prepend)!='undefined')feedback=prepend+feedback;
    var content = ((!attributes.graded) ? CTAD_SETTINGS['feedback_template'] :
      CTAD_SETTINGS['feedback_template_graded']).replace("%feedback%", feedback).
      replace("%button%", button).replace("%items%", items);     
      
    controller = new controller(result, attributes, content);
  } else { 
    // use default popups 
    controller = new controller(result, attributes);
  }
  
  // process 
  controller.toggle(); 
}


/** 
  * Next generation popups, shows javascript window instead of 
  * original ones. Attributes must specify which window object 
  * to use to show and hide 
  */ 
var feedback_jscript_window = function(result, attributes, content) 
{
  this.$mark = result; 
  this.$attributes = attributes; 
  this.$content = content; 
  
  this.object = eval(CTAD_SETTINGS['feedback_object']); 
  
  if (!this.object) 
    ctad_error("[feedback_jscript_window]: Popup window object not specified in check_answer attributes."); 
}

feedback_jscript_window.prototype = {
  
  /** 
    * Shows popup window type
    */
  toggle: function()   {
    document.ctad_feedback.$controller = this; 
   
    eval(CTAD_SETTINGS['feedback_object']).set_text(this.$content); 
    eval(CTAD_SETTINGS['feedback_object']).show(true); 
  }, 
  
  /** 
   * Closes popup window 
   */
  close: function()
  {
    document.ctad_feedback.$controller = null; 
    if ( CTAD_SETTINGS['feedback_object'] ) 
       eval(CTAD_SETTINGS['feedback_object']).hide(); 
  }
}  

document.ctad_feedback.jscript_window = feedback_jscript_window;

/** 
  * Name space which processes the original popup windows
  * by opening a new browser window 
  * @param integer result marked question status 
  * @param object object passed to check_answer button 
  */
var feedback_original_window = function(result, attributes) 
{
  this.$mark = result; 
  this.$attributes = attributes; 
  this.$window; 
}

feedback_original_window.prototype = 
{
  /** 
    * Show feedback window in this 
    * particular namespace
    */
  toggle: function () 
  {
    // set active controller 
    document.ctad_feedback.$controller = this; 
    
    page_number=("00"+this.$attributes.page_number).slice(-2);
    var popup_page = "body" + this.$attributes.page_number + this.$mark +".htm";
    
    //popup fixed size cos it auto-resizes - unless width and height are specified
    //make it initially large so resize works nicely
    if (this.$attributes.width && this.$attributes.height)  {
    
      this.$window = newwindow(popup_page,'myfeedback', 
        this.$attributes.width,this.$attributes.height, "yes");
        
    } else {  
      this.$window = newwindow(popup_page,'myfeedback',500,200,"none");  
    } 
    
  },
  
  /** 
   * Hide, destroy feedback window 
   * TODO: 
   */
  close: function() 
  {
    if (this.$window) 
      this.$window.close(); 
    
    document.ctad_feedback.$controller = null; 
  }
}

// set original popup window namespace
document.ctad_feedback.original = feedback_original_window; 



/** 
 * Scrolling feedback implementation 
 */
var feedback_jscript_scrolling = function (result, attributes, content) 
{
  this.$result = result; 
  this.$attributes = attributes; 
  this.$content = content

  this.object = eval(CTAD_SETTINGS['feedback_object']); 
  
  if (!this.object) 
    ctad_error("[feedback_jscript_window]: Popup window object not specified in check_answer attributes."); 
    
  this.object.innerHTML = this.$content; 
}

feedback_jscript_scrolling.prototype = 
{
  toggle: function() {
    document.ctad_feedback.$controller = this; 
    $(this.object).animate({height: 'toggle', opacity: 'show'}, 'slow');
    document.ctad_feedback.hide_submit(); 
  }, 
  
  close: function() {
    $(this.object).animate({height: 'toggle', opacity: 'hide'}, 'slow');
    document.ctad_feedback.$controller = null; 
    document.ctad_feedback.show_submit(); 
  }
}

document.ctad_feedback.scrolling = feedback_jscript_scrolling; 
