// $Revision: 5049 $

var courseUtilities = {
  getFlashNameById: function(id)
  {
    switch(id)
    {
    case '1':
      return "Russian";
    case '2':
      return "Numeric";
    case '3':
      return "Ukranian";
    case '4':
      return "English";
    }
  }
};

var commonInfo = {
	Language: "1", // Russian
	CourseID: 0,
	TypeOfExercise: "",
	
	getFlashLanguage: function()
	{
	 switch(parseInt(this.CourseID))
	 {
	 case 1:
	   return "Russian";
	   break;
	 case 2:
	   return "Russian";
	   break;
   case 3:
     return "Ukranian";
	   break;
   default:
     return "English";   
	 }
	},
	
	getDefaultLayout: function()
	{
	  return "0";
	},
	
  setDefaultSpeed: function(avSpeed)
  {
    this.avSpeed = avSpeed;
  },
  getDefaultSpeed: function(avSpeed)
  {
    return this.avSpeed;
  }	
	
};

function TExerciseInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  this.SortID = "";
  this.Redirect = "";
  this.ID = 0; // exercise global ID. Use in scorm offline version
  this.LessonNumber = "";  
  this.ExerciseNumber = "";
  this.MaxNumOfMistakes = "";
  this.RegWarning = "";
  this.HighSpeed = "";
  this.Difficulty = "";
  this.Text = "";
  this.Text2 = "";
  this.Language = "Russian";
  this.UserName = "";
  this.RefToNext = "";
  this.RefToLast = "";
  
  this.isExam = false; // this is implementation only for the SCORM version
  this.typeExam = "speedTest";
  this.examType = "startExam";
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  };
  
  this.scorm = {};     
  this.scorm.lastExercise = "";
  this.scorm.initById = function()
  {  
	if( ExerciseInfo.ID != undefined )
	{
		var exercise = exercises[ExerciseInfo.ID];
	
		var pointInd = ExerciseInfo.ID.indexOf('.');
			
		ExerciseInfo.LessonNumber = ExerciseInfo.ID.substring(0, pointInd);  
		ExerciseInfo.ExerciseNumber = ExerciseInfo.ID.substring(pointInd + 1, ExerciseInfo.ID.length);
	
		for(var nL = 1; exercises[ExerciseInfo.LessonNumber + "." + String(nL)] != undefined; 
			nL++);
		
		this.lastExercise = nL - 1;
		
		ExerciseInfo.MaxNumOfMistakes = exercise['max_errors'];
		commonInfo.TypeOfExercise = exercise['type'];
		ExerciseInfo.Text = exercise['text'];
		ExerciseInfo.Text2 = exercise['text2'];           
	}
	commonInfo.Language = "Russian";
	ExerciseInfo.UserName = scormExchange.getLearnerName();		
  };
}

function TSpeedTestInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  this.Text = "";
  this.UserName = "";
  this.ID = -1;
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  }
  
// Имитация, что тест был запущен и сформирован.
  this.SimFormed = function()
  {
    this.BRequested = true;
    this.BResponseReceived = true;
  } 
  
}

function TExamInfo()
{
  this.Text = "";
  this.UserName = "";
}

function TCiteInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  this.Text = "";
  this.Author = "";
  this.AuthorInfo = "";
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  }
}

function TTodayResultInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  
  this.NumOfTasks = "";
  this.AvarageSpeed = "";
  this.SymbolsTyped = "";
  this.NumOfErrors = "";
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  }   
}

function TResultInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  
  this.Mark = "";
  this.Text = "";
  this.Header = "";
  this.RefToNext = "";
  this.IDAdd = "";
  this.IDRemove = "";
  this.IDNext = "";
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  } 
}

function TResultSpeedTestInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  
  this.Text = "";
  this.Header = "";
  
  this.nFlds = 8;
  this.nCrit = 0;
  this.sCrits = new Array("dt", "avg_speed", "errors");
  this.nPage = 0;
  
  this.SetNumFields = function(val)
  {
	this.nFlds = val;
  }
  
  this.APos = new Array();
  this.ADate = new Array();
  this.AAvgSpeed = new Array();
  this.AErrors = new Array();
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
    this.nPage = 0;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {  
    return this.BRequested;
  }
}

function TErrorsInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  
  this.MaxNumOfErrors = 500;
  this.NumOfErrors = 0; // not inited
  this.ErrorsDivider = 25; // for offline version
  
  this.Errors = new Array();
  this.BErrorUsed = new Array();
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  }
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  } 
  
  this.MixErrors = function()
  {
    for(var i = 0; i < this.NumOfErrors / 2; i++)
    {
      var first = Math.floor(Math.random() * this.NumOfErrors);
      if(first == this.NumOfErrors) first--;
      var second = Math.floor(Math.random() * this.NumOfErrors);
      if(second == this.NumOfErrors) second--;
      
      var val = this.Errors[first];
      this.Errors[first] = this.Errors[second];
      this.Errors[second] = val;
    }
  }
  
  this.GetError = function()
  {
    var i;
    for(i = 0; i < this.NumOfErrors; i++)
    {
      if(this.BErrorUsed[i] == false)
      {
        this.BErrorUsed[i] = true;
        return this.Errors[i];
      }
    }
    
    for(i = 1; i < this.NumOfErrors; i++)
    {
      this.BErrorUsed[i] = false;
    }
    
    return this.Errors[0];
  };
  
  this.GetErrors = function()
  {
    return this.Errors;
  };
  
}

function TKeyboardInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;

  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  };
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  } 
}

function TRatingInfo()
{
  this.BResponseReceived = false;
  this.BRequested = false;
  
  this.NumOfPages = 0;
  this.UserPage = 0;
  this.UserId = new Array("","","","","","","","","","");
  this.User = new Array("","","","","","","","","","");
  this.Attempts = new Array("","","","","","","","","","");
  this.AvarageSpeed = new Array("","","","","","","","","","");
  this.Number = new Array(0,0,0,0,0,0,0,0,0,0);
  this.Errors = new Array("","","","","","","","","","");
  this.Rating = new Array("","","","","","","","","","");
  this.Active = new Array("","","","","","","","","","");
  
  this.NumOfElemenents = 0;
  
  this.Reset = function()
  {
    this.BResponseReceived = false;
    this.BRequested = false;
  };
  
  this.IsResponseReceived = function()
  {
    return this.BResponseReceived;
  }
  
  this.IsRequested = function()
  {
    return this.BRequested;
  }
}

var RequestAnswer = {};

RequestAnswer.SpeedTestRepeat = function( xml )
{
	if(Environment.IsOnline())
	{
		var xmlDoc=xml.documentElement;
            
		SpeedTestInfo.Text = FormatToStrings(GetXMLElement(xmlDoc, "text"), 40); 
		try
		{
			SpeedTestInfo.UserName = GetXMLElement(xmlDoc, "user-name");
		}
		catch(e) {} 
		
//		SetExerciseUser(SpeedTestInfo.UserName);          

    BUserLogin = (SpeedTestInfo.UserName != "");  
       
		SpeedTestInfo.ID = GetXMLElement(xmlDoc, "text_id");
		commonInfo.CourseID = GetXMLElement(xmlDoc, "course_id");

//		FlashKeyboard.InitLanguage();
//		FlashInput.InitOS();
		ExerciseText = SpeedTestInfo.Text;

//		FlashInput.ResetContent();
		ExerciseText = FormatToStrings(SpeedTestInfo.Text, 40);
//		FlashInput.SetText(ExerciseText);

		GoToBeginningOfExercise(); 
	}
	else
	{
		with(SpeedTestInfo)
		{
			Text = speedTest.getRandomText();
			UserName = scormExchange.getLearnerName();
			ID = speedTest.id;
			Language = _offlineParams.language;				  
		}                                     
		commonInfo.CourseID = Environment.defaultCourse.offline;
	}
	  
	SpeedTestInfo.BResponseReceived = true;
       	BUserLogin = (SpeedTestInfo.UserName != "");
//       	FlashKeyboard.InitLanguage();
//       	FlashInput.InitOS();
       	ExerciseText = SpeedTestInfo.Text;
       	  
//       	FlashInput.ResetContent();
       	ExerciseText = FormatToStrings(SpeedTestInfo.Text, 40);
//       	FlashInput.SetText(ExerciseText);
       	  
       	GoToBeginningOfExercise(); 		  
       	  
       	SpeedTestInfo.BResponseReceived = true;		  
}

RequestAnswer.Errors = function( xml )
{
	var errorText;
	var i;
  
	if(Environment.IsOnline())
	{
		var errorText;
		var i;
  
		var xmlDoc=xml.documentElement;
		for(i = 0; i < ErrorsInfo.MaxNumOfErrors; i++)
		{
			errorText = GetXMLElement(xmlDoc, "text", i);
			if(errorText != "")  
			{
				ErrorsInfo.Errors.push(errorText);
				ErrorsInfo.BErrorUsed.push(false);
			}
			else break;
		}            
		ErrorsInfo.NumOfErrors = i;
		ErrorsInfo.MixErrors();
	}
	else
	{	 
		for(var i = 0, j = 0; errors[j] != undefined; i++)
		{		  
			ErrorsInfo.Errors.push(errors[j]);
			ErrorsInfo.BErrorUsed.push(false);
	  
			j += _specMath.rand(1, Math.floor(ErrorsInfo.MaxNumOfErrors / ErrorsInfo.ErrorsDivider));
		}	 
	}
  
	ErrorsInfo.NumOfErrors = i;
	ErrorsInfo.MixErrors();
      
	ErrorsInfo.BResponseReceived = true;	
}

// moved to resultPage
RequestAnswer.Rating = function( xml )
{
	if(Environment.IsOnline())
	{
		var xmlDoc=xml.documentElement;
                
		for(i = 0; i < ResultPage.nPageUsers; i++)
		{  
			RatingInfo.User[i] = "";
			RatingInfo.UserId[i] = "";
			RatingInfo.Attempts[i] = "";
			RatingInfo.AvarageSpeed[i] = "";
			RatingInfo.Number[i] = 0;
			RatingInfo.Errors[i] = "";
			RatingInfo.Rating[i] = "";              
		}  
              
		RatingInfo.NumOfPages = GetXMLElement(xmlDoc, "pages");  
		RatingInfo.UserPage = GetXMLElement(xmlDoc, "page");
            
		if(RatingInfo.UserPage != "")
		{
			// page specified... set it selected...
			ResultPage.SetCurPage(parseInt(RatingInfo.UserPage) - 1);
              
			try
			{
        	        	ResultPage.CurPage = parseInt(RatingInfo.UserPage) - 1;
                		ResultPage.NumOfPages = parseInt(RatingInfo.NumOfPages);
                		document.getElementById("IDResLsnSel").innerHTML = ResultPage.ResultPageSelector();
			}
        	        catch(e){}                
		} 
            
		for(i = 0; i < ResultPage.nPageUsers; i++)
		{  
			RatingInfo.Number[i] = GetXMLElement(xmlDoc, "no", i);
			if(RatingInfo.Number[i] == "")  break;
			RatingInfo.UserId[i] = GetXMLElement(xmlDoc, "auser_id", i);
			RatingInfo.User[i] = GetXMLElement(xmlDoc, "auser_name", i);
			RatingInfo.Attempts[i] = GetXMLElement(xmlDoc, "attempts", i);
			RatingInfo.Errors[i] = GetXMLElement(xmlDoc, "errors", i);
			RatingInfo.AvarageSpeed[i] = GetXMLElement(xmlDoc, "avg_speed", i);
			RatingInfo.Rating[i] = GetXMLElement(xmlDoc, "rating", i);   
			RatingInfo.Active[i] = GetXMLElement(xmlDoc, "active", i);
			
      var bActive = RatingInfo.Active[i] == "1" ? true:false; 
      
      if(bActive)
        commonInfo.setDefaultSpeed(RatingInfo.AvarageSpeed[i]);          
		}
            
    RatingInfo.NumOfElemenents = i;
          
		ResultPage.UpdateUserTable();
		ResultPage.PostForm();
	}

	RatingInfo.BResponseReceived = true;
	ResultPage.PostForm();      
} 
    
RequestAnswer.TodayResult = function( xml )
{
	if(Environment.IsOnline())
	{
		var stat = $(xml).find("stat");

		TodayResultInfo.NumOfTasks = $(stat).find("exercises").text();
		TodayResultInfo.AvarageSpeed = $(stat).find("avg_speed").text();
		TodayResultInfo.SymbolsTyped = $(stat).find("length").text();
		TodayResultInfo.NumOfErrors = $(stat).find("errors").text();

		TodayResultInfo.BResponseReceived = true;
	}
	else
	{
		with(TodayResultInfo)
		{
			NumOfTasks = _interface.sSkipData;
			AvarageSpeed = _interface.sSkipData;
			SymbolsTyped = _interface.sSkipData;
			NumOfErrors = _interface.sSkipData;
		}
	}
	
	TodayResultInfo.BResponseReceived = true;
}
    
// ###Test: do we need the next function ? 
RequestAnswer.CiteResult = function( xml )
{
	if(Environment.IsOnline())
	{
		var cite = $(xml).find("cite");

		CiteInfo.Text = $(cite).find("text").text();
		
		CiteInfo.Author = $(cite).find("author").text();
		CiteInfo.AuthorInfo = $(cite).find("author-info").text();
	}
	else
	{                                  
		with(CiteInfo)
		{
			var cNum = _specMath.rand(0, quotation.length - 1);
			Text = quotation[cNum].text;
			Author = quotation[cNum].author;
			AuthorInfo = quotation[cNum].author_info;
		}
	}

	CiteInfo.BResponseReceived = true;
}

RequestAnswer.CiteUpdate = function( xml )
{
	if(Environment.IsOnline())
	{
		var cite = $(xml).find("cite");

		CiteInfo.Text = $(cite).find("text").text();
		CiteInfo.Author = $(cite).find("author").text();
		CiteInfo.AuthorInfo = $(cite).find("author-info").text();
        }
	else
	{
		with(CiteInfo)
		{
			var cNum = _specMath.rand(0, quotation.length - 1);
			Text = quotation[cNum].text;
			Author = quotation[cNum].author;
			AuthorInfo = quotation[cNum].author_info;
		}
	}

	SetExerciseCite(CiteInfo);
	CiteInfo.BResponseReceived = true;
		
  if(GetExType() == 32 && ExerciseInfo.isExam == false) 
  { 
    RequestSpeedRepeat(); 
  }
  else
  if(ExerciseInfo.isExam)
  {
    SetExerciseText(FormatToStrings(ExamInfo.Text, 40));
    GoToBeginningOfExercise();  
  }
  else
	{
    GoToBeginningOfExercise();  
	}
}

RequestAnswer.ExerciseResult = function( xml )
{  
	if(Environment.IsOnline())
	{
    
		var exercise = $(xml).find("exercise");

		ExerciseInfo.SortID = $(exercise).find("sort-id").text();
		ExerciseInfo.LessonNumber = $(exercise).find("lesson-no").text(); 
		ExerciseInfo.ExerciseNumber = $(exercise).find("exercise-no").text();
		ExerciseInfo.MaxNumOfMistakes = $(exercise).find("errors").text();
		commonInfo.TypeOfExercise = parseInt($(exercise).find("type").text());
		ExerciseInfo.RegWarning = $(exercise).find("regwarning").text();
		ExerciseInfo.HighSpeed = $(exercise).find("highspeed").text();
		ExerciseInfo.Difficulty = $(exercise).find("difficulty").text();
		ExerciseInfo.Text = $(exercise).find("text").text().removeDirtyChars();
		    
		ExerciseInfo.Redirect = $(exercise).find("redirect").text();
		ExerciseInfo.Text2 = $(exercise).find("text2").text();
		commonInfo.CourseID = $(exercise).find("course_id").text();
		ExerciseInfo.UserName = $(exercise).find("user-name").text();
		ExerciseInfo.RefToNext = $(exercise).find("next").text();
	}
	else
	{	
		if( ExerciseInfo.ID != undefined )
		{
			var exercise = exercises[ExerciseInfo.ID];
		
			var pointInd = ExerciseInfo.ID.indexOf('.');
				
			ExerciseInfo.LessonNumber = ExerciseInfo.ID.substring(0, pointInd);  
			ExerciseInfo.ExerciseNumber = ExerciseInfo.ID.substring(pointInd + 1, ExerciseInfo.ID.length);
		
			for(var nL = 1; exercises[ExerciseInfo.LessonNumber + "." + String(nL)] != undefined; 
				nL++);
			
			ExerciseInfo.scorm.lastExercise = nL - 1;

			scormExchange.setNLastExercise(ExerciseInfo.scorm.lastExercise);
			
			ExerciseInfo.MaxNumOfMistakes = exercise['max_errors'];
			commonInfo.TypeOfExercise = exercise['type'];
			ExerciseInfo.Text = exercise['text'];
			ExerciseInfo.Text2 = exercise['text2'];
      commonInfo.Language = "1"; // 1 - Russian   
      commonInfo.CourseID = Environment.defaultCourse.offline;        
		}
		ExerciseInfo.UserName = scormExchange.getLearnerName();		 
	}
	
//	FlashKeyboard.InitLanguage();
//	FlashInput.InitOS();			
//	SetExerciseUser(ExerciseInfo.UserName);				
	ExerciseInfo.BResponseReceived = true;
}

RequestAnswer.SpeedTest = function( xml )
{
	if(Environment.IsOnline())
	{
		var test = $(xml).find("test");

		SpeedTestInfo.Text = FormatToStrings($(test).find("text").text(), 40);
		try
		{
			SpeedTestInfo.UserName = $(test).find("user-name").text();
		}
		catch(e) {}  

		SpeedTestInfo.ID = $(test).find("text_id").text();
		
		commonInfo.CourseID = $(test).find("course_id").text();
		
	}
	else
	{
		with(SpeedTestInfo)
		{
			Text = FormatToStrings(speedTest.getRandomText(), 40);
			UserName = scormExchange.getLearnerName();
			BUserLogin = (UserName != "");
		}                               
		commonInfo.CourseID = Environment.defaultCourse.offline;
	}
	
	SetExerciseUser(SpeedTestInfo.UserName);
//	FlashKeyboard.InitLanguage();
//	FlashInput.InitOS();
	SpeedTestInfo.BResponseReceived = true;
	commonInfo.TypeOfExercise = 32; // bad...
}

RequestAnswer.ExamGot = function() // now it is only implementation for the SCORM version
{                   
  with(ExamInfo)
  {                 
    Text = FormatToStrings(exam['text'], 40);
		UserName = scormExchange.getLearnerName();
    BUserLogin = (UserName != "");   
  }
  
	commonInfo.Language = "Russian";	  
  
	SetExerciseUser(ExamInfo.UserName);
	commonInfo.TypeOfExercise = 32; // bad... for an exam and for a speed test?  
	ExerciseInfo.IsExam = true;            
};

RequestAnswer.Result = function( xml )
{
	if(Environment.IsOnline())
	{	
		var result = $(xml).find("result");
        
        	ResultInfo.Rating = $(result).find("rating").text();
	        ResultInfo.Header = $(result).find("header").text();
	        ResultInfo.Text = $(result).find("text").text();
        
        	with(ResultPage)
	        {
        		RegRes = RegExRes;
	        }
        
	        if(ResultPage.IsSetRefToNext() == false)  
        	{
        		ResultInfo.RefToNext = $(result).find("next_lesson").text();
		        ResultPage.RefToNextHasSet(true);
	        }    
        
	        ResultInfo.IDAdd = $(result).find("add_id").text();
	        ResultInfo.IDRemove = $(result).find("remove_id").text();
	        ResultInfo.IDNext = $(result).find("next_id").text();
	        ResultInfo.TextRepeat = $(result).find("repeat").text();
	        
        	ResultInfo.RefToLast = $(result).find("last_lesson").text();
        
	        if(ResultInfo.RefToLast != "")
        	{
	        	ResultPage.SetRefToLast(ResultInfo.RefToLast);      
	        }  
        
//            if(ResultInfo.RefToNext != "")  ResultPage.SetRefToNextExercise(ResultInfo.RefToNext);        
	}
	else
	{
		var mark = scormUtils.mark.calculate(exerciseUserStatus.getNumErrors(), ExerciseInfo.MaxNumOfMistakes)/*'3'*/;
		var lenHeader = resultTexts[mark]['header'].length;
		var headerArray = resultTexts[mark]['header'];
		ResultInfo.Header = headerArray[_specMath.rand(0, headerArray.length-1)];
		var textArray = resultTexts[mark]['text'];
		ResultInfo.Text = textArray[_specMath.rand(0, textArray.length-1)];
		
		with(ResultPage)
		{
			RegRes = RegExRes;
		}     
	}
    
	if(ResultInfo.RefToLast != "")
	{
        	ResultPage.SetRefToLast(ResultInfo.RefToLast);      
	}  
        
        ResultInfo.BResponseReceived = true;
}

RequestAnswer.ResultSpeedTest = function( xml )
{

	if(Environment.IsOnline())
	{
		var xmlDoc=xml.documentElement;
        
		ResultSpeedTestInfo.Header = GetXMLElement(xmlDoc, "header");
        
		ResultSpeedTestInfo.Text = GetXMLElement(xmlDoc, "text");
        
		with(ResultPage)
		{
			RegRes = RegSpdRes;
		}
        
		if(IsUserLogin())
		{
        	
			with(ResultPage)
        		{
        			NumOfPages = parseInt(GetXMLElement(xmlDoc, "pages"));
	        		CurPage = parseInt(GetXMLElement(xmlDoc, "page"));
        			// ###
        			//
	        	}
            
			var d = new Date();
	        	for(var i = 0; i < ResultSpeedTestInfo.nFlds; i++)
        		{
        			with(ResultSpeedTestInfo)
        			{
        				APos[i] = GetXMLElement(xmlDoc, "num", i);
	        			try
        				{ 
        					ADate[i] = d.GetRusStr(GetXMLElement(xmlDoc, "dt", i)); 
        				} 
        				catch(e)
	        			{       	
        					ADate[i] = "";
        				}
        				AAvgSpeed[i] = GetXMLElement(xmlDoc, "avg_speed", i);
        				AErrors[i] = GetXMLElement(xmlDoc, "errors", i);
	        		}
        		}
	        }
	}
	else
	{
		ResultSpeedTestInfo.Header = _interface.sNoData;		
		ResultSpeedTestInfo.Text = speedTestResultTexts[scormUtils.markSpeed.getIndexByErrors(exerciseUserStatus.getNumErrors())][scormUtils.markSpeed.getIndexBySpeed(Speed.GetTotalSpeed())]['header'];
		
		for(var i = 0; i < ResultSpeedTestInfo.nFlds; i++)
		{
			with(ResultSpeedTestInfo)
			{
				APos[i] = _interface.sSkipData;
				ADate[i] = _interface.sSkipData; 
				AAvgSpeed[i] = _interface.sSkipData;
				AErrors[i] = _interface.sSkipData;
			}
		}		
	}
	
       	document.getElementById("IDResSpeedSel").innerHTML = ResultPage.ResultPageSelector();
       	
       	ResultSpeedTestInfo.BResponseReceived = true;
       	
       	for(var j in ResultSpeedTestInfo.ADate)
       	{
       		with(ResultSpeedTestInfo)
       		{
       			if(isNaN(parseInt(APos[j])))
       			{
       				ResultPage.SetTabSpeedRowVis(j, false);
       			}
       			else
       			{
       				ResultPage.SetTabSpeedRowVis(j, true);
       				ResultPage.SetResSpeedPos(j, String(parseInt(APos[j])));
       				ResultPage.SetResSpeedDate(j, ADate[j]); // test
       				ResultPage.SetResSpeedErrors(j, AErrors[j]);
       				ResultPage.SetResSpeedSpeed(j, AAvgSpeed[j]);
       			}
       		}
       	}
         
        commonInfo.setDefaultSpeed(ResultSpeedTestInfo.AAvgSpeed[0]); 		
}

RequestAnswer.KeyboardLayoutGot = function( xml )
{
	if(Environment.IsOnline())
	{
		var keyboard = $(xml).find("keyboard");
    KeyboardInfo.Layout = $(keyboard).find("layout").text();
	}
	else
	{
		KeyboardInfo.Layout = _offlineParams.layout;
	}
      
	KeyboardInfo.BResponseReceived = true;
}

RequestAnswer.KeyboardParamsGot = function( xml )
{

	if(Environment.IsOnline())
	{
		var keyboard = $(xml).find("keyboard");	
		
		var layout = $(keyboard).find("layout").text();
		var bNextKey = $(keyboard).find("next_key").text();
		var bShowChars = $(keyboard).find("show_chars").text();
    var bColored = $(keyboard).find("keyboard_colored").text();
		
		if(layout == "")
		  KeyboardInfo.Layout = commonInfo.getDefaultLayout();
		else
		  KeyboardInfo.Layout = layout;
		
    if(bNextKey == "")
      KeyboardInfo.bNextKey = true;
    else
      KeyboardInfo.bNextKey = bNextKey;
      
    if(bShowChars == "")
      KeyboardInfo.bShowChars = true;
    else
      KeyboardInfo.bShowChars = bShowChars;
      
    if(bColored == "")
      KeyboardInfo.bColored = true;
    else
      KeyboardInfo.bColored = bColored;                              
	}
	else
	{
    KeyboardInfo.Layout = _offlineParams.layout;
  	KeyboardInfo.bNextKey = _offlineParams.bNextKey;
    KeyboardInfo.bShowChars = _offlineParams.bShowChars;
    KeyboardInfo.bColored = _offlineParams.bColored; 	
	}
                 
	SetCurKeyboardKey();        
	KeyboardInfo.BResponseReceived = true;
}

// for AJAX requests...

var ExerciseInfo = new TExerciseInfo();
var SpeedTestInfo = new TSpeedTestInfo();
var ExamInfo = new TExamInfo(); // implementation for the SCORM version
var CiteInfo = new TCiteInfo();
var ResultInfo = new TResultInfo();

var ResultSpeedTestInfo = new TResultSpeedTestInfo();

var RatingInfo = new TRatingInfo();
var ErrorsInfo = new TErrorsInfo();
var TodayResultInfo = new TTodayResultInfo();
var KeyboardInfo = new TKeyboardInfo();
var TimeoutAJAX = 250; // ms

// end of "for AJAX requests"

var ajaxData =
{
	rating :
	{
		url : "/study/exercise_rating.html", 
		callbackSuccess : RequestAnswer.Rating, 
		responseFlag : RatingInfo.BResponseReceived
	},
	speedTest :
	{
		url : "/test/get_text.html", 
		callbackSuccess : RequestAnswer.SpeedTest, 
		responseFlag : SpeedTestInfo.BResponseReceived
	},
	speedTestRepeat :
	{
		url : "/test/get_text.html", 
		callbackSuccess : RequestAnswer.SpeedTestRepeat, 
		responseFlag : SpeedTestInfo.BResponseReceived
	},
	cite :
	{
		url : "/study/cite.html", 
		callbackSuccess : RequestAnswer.CiteResult, 
		responseFlag : CiteInfo.BResponseReceived
	},
	citeupdate : 
	{
		url : "/study/cite.html", 
		callbackSuccess : RequestAnswer.CiteUpdate,
		responseFlag : null
	},
	exercise :
	{
		url : "/study/get_exercise.html", 
		callbackSuccess : RequestAnswer.ExerciseResult, 
		responseFlag : ExerciseInfo.BResponseReceived
	},
	result :
	{
		url : "/study/result.html", 
		callbackSuccess : RequestAnswer.Result, 
		responseFlag : ResultInfo.BResponseReceived
	},
	resultSpeedTest : 
	{
		url : "/test/get_result.html", 
		callbackSuccess : RequestAnswer.ResultSpeedTest, 
		responseFlag : ResultSpeedTestInfo.BResponseReceived
	},
	todayResult :
	{
		url : "/study/get_stat.html",
		callbackSuccess : RequestAnswer.TodayResult,
		responseFlag : TodayResultInfo.BResponseReceived
	},
	errors :
	{
		url : "/study/error.html",
		callbackSuccess : RequestAnswer.Errors,
		responseFlag : ErrorsInfo.BResponseReceived
	},
   	getLayout :
	{
		url : "/study/keyboard.html", 
		callbackSuccess : RequestAnswer.KeyboardLayoutGot
	},
	getKeybParams :
	{
		url : "/study/keyboard.html", 
		callbackSuccess : RequestAnswer.KeyboardParamsGot
	},
	saveParam :
	{
		url : "/study/keyboard.html", 
		callbackSuccess : function( xml ) {}, 
		responseFlag : null
	}
};

function ReqError( xhr, err )
{
	stop();
}

function empty()
{
	alert("in empty");
}

function Request(itemName, parameters)
{
	var ajaxItem = ajaxData[ itemName ];
	var callbackSuccess = ajaxItem[ "callbackSuccess" ];
	if(Environment.IsOnline())
	{
		var url = ajaxItem[ "url" ];
		var callbackError = ajaxItem[ "callbackError" ];
		var responseFlag = ajaxItem[ "responseFlag" ]; 	
		
		if( !callbackError )
		{
			callbackError = ReqError;
		}
		if( responseFlag )
		{
			responseFlag = false;
		}
		// using Ajax implementation
		jQuery.ajax( {
			type :	"GET",
			url :	url,
			data :	parameters,
			dataType : "xml",
			async :	true,
			success : callbackSuccess,
			error : callbackError
		} );
	}
	else
	{
		callbackSuccess();
	}
} 

function GetXMLElementHTML(xmlDoc, element, index)
{
  if(index == undefined)
  {
    if(xmlDoc.getElementsByTagName(element)[0] != null)
      return  xmlDoc.getElementsByTagName(element)[0];
      /*if(xmlDoc.getElementsByTagName(element)[0].firstChild != null)
      {
        return xmlDoc.getElementsByTagName(element)[0].firstChild.nodeValue;
      }
      else
      {
        return "";
      }*/
    else return "";
  }
}
 
function GetXMLElement(xmlDoc, element, index)
{
  if(index == undefined)
  {
    if(xmlDoc.getElementsByTagName(element)[0] != null)
      if(xmlDoc.getElementsByTagName(element)[0].firstChild != null)
      {
        return xmlDoc.getElementsByTagName(element)[0].firstChild.nodeValue;
      }
      else
      {
        return "";
      }
    else return "";
  }
  else
  {
    if(xmlDoc.getElementsByTagName(element)[index] == undefined)  return "";
    if(xmlDoc.getElementsByTagName(element)[index].firstChild != null)
    {
      return xmlDoc.getElementsByTagName(element)[index].firstChild.nodeValue;
    }
    else
    {
      return "";
    }    
  }
}

function RequestSpeedRepeat()
{
	Request("speedTestRepeat"); 
}

function RequestRatingTableUser(exercise_id, course_id)
{ 
	var params = { "exercise_id" : exercise_id, "count" : ResultPage.nPageUsers, 'course' : course_id };
	Request("rating", params);
	RatingInfo.BRequested = true;  
}

function RequestRatingTablePage(exercise_id, page, sort_order, course_id)
{
	var params = { "exercise_id" : exercise_id, "page" : page, "order" : sort_order, "count" : ResultPage.nPageUsers, 'course' : course_id };
	Request("rating", params);
	RatingInfo.BRequested = true;
}

function RequestSpeedTest(courseId)
{
	var params = {"course" : courseId};
	
	Request("speedTest", params);
	SpeedTestInfo.BRequested = true;
}

function RequestCite()
{
	Request("cite");
	CiteInfo.BRequested = true;
}

function RequestCiteSpeedUpdate()
{
	Request("citeupdate");
}

function RequestExercise(sortID, courseID)
{
	var params = { "sort_id" : sortID, "course" : courseID };
	
	Request("exercise", params);
	ExerciseInfo.BRequested = true;
}

var SupposeSpeed_ = 200;
var SupposeDuration_ = 60; 


function RequestResult(exerciseID, avgSpeed, numOfErrors, duration, courseID)
{
	var avgSpeed_ = avgSpeed;
	var duration_ = duration;

	if(Environment.IsOnline())
	{    
		if(duration_ == 0)  duration_ = SupposeDuration_;

		var params = { "exercise_id" : exerciseID, "avg_speed" : avgSpeed_, "errors" : numOfErrors, "duration" : duration, "course" : courseID };
	}
	else
	{
		// none
	}
  
	Request("result", params);
  
	ResultInfo.BRequested = true;  
}

function RequestSpeedTestResult(avgSpeed, numOfErrors, duration)
{
	
	var params = {};
	
	if(Environment.IsOnline())
	{ 
		if(avgSpeed != undefined)
		{
			if(avgSpeed == Infinity) avgSpeed = SupposeSpeed_;	  
		  	params = { "avg_speed" : avgSpeed, "errors" : numOfErrors, "duration" : duration, "text_id" : SpeedTestInfo.ID, "bfin" : 1 };
		}
  
		with(ResultSpeedTestInfo)
		{
		  params["course"] = commonInfo.CourseID;
		
			params[ "count" ] = nFlds;
			params[ "sort" ] = sCrits[nCrit];
			params[ "page" ] = nPage;
		}
	}
	else
	{
		// scorm.setPrarms ?	  
	}
    
//	var iLen = 0;
//	if(SpeedTestInfo.Language == "English") iLen = 1;
//	params[ "language" ] = String(iLen);
	Request("resultSpeedTest", params);
	ResultSpeedTestInfo.BRequested = true;  
}
 
function RequestTodayResult()
{
	Request("todayResult");
	TodayResultInfo.BRequested = true;
}

function RequestErrors()
{
	Request("errors");
	ErrorsInfo.BRequested = true;
}

function RequestLayout()
{     
	Request("getLayout");
}

function RequestKeyboardParams()
{

  var params = { "course_id" : commonInfo.CourseID};

	Request("getKeybParams", params);
}

function RequestSaveKeyboardParam(param, val)
{
	var params = {"course_id" : commonInfo.CourseID, "paramName" : param, "val" : String(val) };

  switch(param)
  {
    case "keyboard_colored":
      KeyboardInfo.bColored = val;
    break;
    case "next_key":
      KeyboardInfo.bNextKey = val;
    break;
    case "show_chars":
      KeyboardInfo.bShowChars = val;
    case "layout":
      KeyboardInfo.Layout = val;
    break;
    default: ;
  } 
	
	Request("saveParam", params);
}
