/***********************************************************************************
*
*	Sample Movie using the Logging Library
*
*	This movie demonstrates how to use the logging library (CommLoggingLibrary.swf)
*	to log tutor data to PSLC log server.
*
*	The logging library is a .SWF file that is loaded into the tutor.  It contains
*	methods that can be called to log.  This sample includes all the code you will
*	need to write logging calls with the library, including loading the library.  
*
*	The general steps for using the library to log are:
*	1) Load the logging library using loadMovie
*	2) Optionally call startProblem method from the library
*	3) Log messages with the logging methods.
*
*	The ActionScript in this sample is meant to be extended or rewritten to suit your 
*	individual logging needs.
*	A JavaDoc is included that provides details about the API of the logging library.  
*	The Javadoc is in the Documentation folder. 
*
*	Documenation and Resources
*	http://ctat.pact.cs.cmu.edu/index.php?id=logging-flash
*	http://ctat.pact.cs.cmu.edu/index.php?id=tutor_delivery-flash
*	http://ctat.pact.cs.cmu.edu/index.php?id=flashvars
*	
************************************************************************************/
//import CommLogging.ContextMessageTransferData;
//import CommLogging.CommLoggingLibrary;
 
 
/* 
* These variables are used to ensure that a logging session is established which is necessary when 
* not using OLI course delivery.  When useing OLI, the OLI system will send a 
* Set usingOLI to 'true' if your tutor will run in the OLI course delivery system; otherwise
* set it to 'false'.
*/
var usingOLI:Boolean = false;					// set to true if using OLI
//var theDataObj:ContextMessageTransferData;		// typeing depends on having the class in the author's classpath.
var theDataObj;
 
/* 
* 	This variable is referenced in this script when attemps are made so send log messages.
*	For example, when sending a log message for a hint (see: Hint_Button2.onRelease)
*	The log methods will check if it is false and if so, will call newProblem() which will send a 
*	start message to the log server and set the variable to true. 
*	
*  	If you load more than one problem into a running SWF, you should set this false prior to starting each problem.
*	That way a start message will be sent that lets the log server to associate the subsequent log information with that problem.
*/
var problemStarted:Boolean = false;		// set to false prior to logging the first message.  See newProblem method.
 
 
// Main Methods
setInterfaceData();
loadLoggingLibrary();
 
 
function setInterfaceData()
{
	log_service_url_txt.text = _level0.log_service_url;
	question_file_txt.text = _level0.question_file;
	problem_name_txt.text = _level0.problem_name;
	media_file_txt.text = _level0.media_file;
	problem_context_txt.text = _level0.problem_context;
	problem_tutorflag_txt.text = _level0.problem_tutorflag;
	dataset_name_txt.text = _level0.dataset_name;
	unit_name_txt.text = _level0.unit_name;
	section_name_txt.text = _level0.section_name;
	dataset_level_name1_txt.text = _level0.dataset_level_name1;
	dataset_level_type1_txt.text = _level0.dataset_level_type1;
	dataset_level_name2_txt.text = _level0.dataset_level_name2;
	dataset_level_type2_txt.text = _level0.dataset_level_type2;
	user_guid_txt.text = _level0.user_guid;
	school_name_txt.text = _level0.school_name;
	class_name_txt.text = _level0.class_name;
	period_name_txt.text = _level0.period_name;
	class_description_txt.text = _level0.class_description;
	instructor_name_txt.text = _level0.instructor_name;
	study_condition_name1_txt.text = _level0.study_condition_name1;
	study_condition_type1_txt.text = _level0.study_condition_type1;
	study_condition_description1_txt.text = _level0.study_condition_description1;
	study_condition_name2_txt.text = _level0.study_condition_name2;
	study_condition_type2_txt.text = _level0.study_condition_type2;
	study_condition_description2_txt.text = _level0.study_condition_description2;
	container_id_txt.text = _level0.container_id;
	theSource_id_txt.text = _level0.source_id;
	external_object_id_txt.text = _level0.external_object_id;
 
	session_id_txt.text = _level0.session_id !=undefined ? _level0.session_id : "";
	auth_token_txt.text = _level0.auth_token;
	custom_field_name1_txt.text = _level0.custom_field_name1;
	custom_field_value1_txt.text = _level0.custom_field_value1;
	custom_field_name2_txt.text = _level0.custom_field_name2;
	custom_field_value2_txt.text = _level0.custom_field_value2;
 
}
 
 
// ------------------- Load Logging Library -----------------
/*
*  Load the logging library.  In this sample Movie, the path is defined in the flashvars
*  parameter of the HTML Object tag.  The accompanying HTML file contains the necessary data.
*  How does this work?  Well, Flash converts the flashvars to _level0.variables that are being referenced in the method call.  
*  You can find more information about Macromedia Flash's flashvars parameters and the usage in tutors at 
*  http://ctat.pact.cs.cmu.edu/tiki-index.php?page=CTAT_FlashPublish.
*/
function loadLoggingLibrary(){
	System.security.allowInsecureDomain("*");	// Flash 8 Player or above for wildcards.
	System.security.allowInsecureDomain("pslc-qa.andrew.cmu.edu");
	System.security.allowInsecureDomain("localhost");
	System.security.allowInsecureDomain("127.0.0.1");
	System.security.allowInsecureDomain("learnlab.web.cmu.edu");	
 
	System.security.allowDomain("*");	// Flash 8 Player or above for wildcards.
	System.security.allowDomain("pslc-qa.andrew.cmu.edu");
	System.security.allowDomain("localhost");
	System.security.allowDomain("127.0.0.1");
	System.security.allowDomain("learnlab.web.cmu.edu");
 
 
 
	//this.createEmptyMovieClip("LoggingLibrary_mc", 999);
	_level0.createEmptyMovieClip("LoggingLibrary_mc", 999);
 
	// Specify the Library Path in flavhvars or hard code it.
	if (_level0.LoggingLibraryPath == undefined)
	{
		var LoggingLibraryPath = "../CommLoggingLibrary.swf";
		//var LoggingLibraryPath = "http://pslc-qa.andrew.cmu.edu/~pact/tutors/logging/CommLoggingLibrary.swf";
		loadLibrarySWF( LoggingLibraryPath );
	}
	else
	{
		//loadMovie(_level0.LoggingLibraryPath, "LoggingLibrary_mc");
		var LoggingLibraryPath = _level0.LoggingLibraryPath;
		loadLibrarySWF( LoggingLibraryPath );
	}
	trace("loadingLoggingLibrary : " + "  LoggingLibraryPath = " + LoggingLibraryPath);
	loadLibrarySWF( LoggingLibraryPath );
}
 
function loadLibrarySWF( LoggingLibraryPath:String)
{
	// first set of listeners
	var my_mcl:MovieClipLoader = new MovieClipLoader();
 
	var myListener:Object = new Object();
	myListener.onLoadInit = mx.utils.Delegate.create(this, onLoadInit);
	myListener.onLoadStart = mx.utils.Delegate.create(this, onLoadStart);
	myListener.onLoadComplete = mx.utils.Delegate.create(this, onLoadComplete);
	myListener.onLoadError = mx.utils.Delegate.create(this, onLoadError);
	my_mcl.addListener(myListener);
 
	my_mcl.loadClip(LoggingLibraryPath, LoggingLibrary_mc);
 
	// Issue the following statements after the download is complete, 
	// and after my_mcl.onLoadInit has been called.
	// my_mcl.removeListener(myListener);
	// my_mcl.removeListener(myListener2);	
}
 
 
/*
*	After this, the library SWF is ready to use.  You can now call methods on the loaded SWF.
*/
function onLoadInit (target_mc:MovieClip):Void 
{
	trace("onLoadInit : Your load has begun on movie clip = "+target_mc);
 
	// Initialize all the background data in a ContextMessageTransferData object.
	setDataObject();
 
	// Session message : non-oli users need to formally create a session message.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) 
	{
		send_logSessionMessage();	
	}
 
	// Context and Start messages : One per problem solved.  
	// In older vs of the Library, I didn't directly call this method,  instead I let the event handler for the UI controls call it if it hadn't yet been called. John Kowalski suggested that that wasn't clear.
	if (problemStarted == false)
	{
		send_logLoadTutor();
	}
}
 
function onLoadStart (target_mc:MovieClip):Void 
{
	//trace("Your load has begun on movie clip = "+target_mc);
	var loadProgress:Object = my_mcl.getProgress(target_mc);
	//trace(loadProgress.bytesLoaded+" = bytes loaded at start");
	//trace(loadProgress.bytesTotal+" = bytes total at start");
}
function onLoadComplete (target_mc:MovieClip):Void
{
	//trace("Your load is done on movie clip = "+target_mc);
}
 
function onLoadError (target_mc:MovieClip, errorCode:String):Void
{
	trace("*********First my_mcl instance*********");
	trace("ERROR CODE = "+errorCode);
	trace("Your load failed on movie clip = "+target_mc+"\n");
}
 
 
 
 
 
 
// ------------------- END Load Logging Library -----------------
 
 
// ------------------- Session Message -----------------
/*
*	Establish logging session.  A session is a way to group all the logging by one student in a period of time.
*	The OLI course delivery systme sends this message behind the scenes as part of their authentication. 
*	Outside of OLI, you need to manage session. This method will help you do that.
*/
function send_logSessionMessage()
{	
	// Session is something OLI provides, but if you are logging outside of the OLI, this is needed. 
	// This maps to the log_session_start element of the OLI logging DTD.
 
	// plog_service_url:String,  pauth_token:String,  psession_id:String,  puser_guid:String
	LoggingLibrary_mc.LogClass.logSessionMessage(log_service_url_txt.text, auth_token_txt.text, session_id_txt.text, user_guid_txt.text);
	LoggingLibrary_mc.LogClass.setsessionEstablished(true);
 
	//--trace("New session initialized.");
}
// ------------------- END Session Message -----------------
 
 
// ------------------- Context Message and Start Tutor Message -----------------	
 
 
 
 
/**
* Set the data in the ContextMessageTransferData Object.
* This method is redundant with a method in the library named getDefaultDataObj.  It is included her to show the developer how the data object works. 
*/
function setDataObject(){
	// create ContextMessageTransferData object
	theDataObj= LoggingLibrary_mc.LogClass.createContextMessageTransferData();
 
	theDataObj.setthe_action_msg_type("LOAD_TUTOR");	// The library defaults to LOAD_TUTOR. The developer can override it. 
 
 
	// getTheDataObj().setthe_action_msg_type("LOAD_TUTOR"); 	// The developer could just call this method and skip the rest of this method.
 
// URL & Question File	
	if (checkValid(log_service_url_txt.text) == true )
		theDataObj.setlog_service_url(log_service_url_txt.text);								// Req
	else	
		theDataObj.setlog_service_url("http://pslc-qa.andrew.cmu.edu/log/server");		// Req
 
	if (checkValid(question_file_txt.text) == true )
		theDataObj.setquestion_file(question_file_txt.text);									// Req
	else
		theDataObj.setquestion_file("theDefaultaQustion_file.brd");						// Req
 
	if (checkValid(media_file_txt.text) == true )
		theDataObj.setmedia_file(media_file_txt.text);									
 
 
 
// Problem	
	// Problem : Optional.  In CTAT tutors, we will use question_file if problem_name is unavailable.
	if (checkValid(problem_name_txt.text) == true )
		theDataObj.setproblem_name(problem_name_txt.text);		
	else if (checkValid(theDataObj.getquestion_file()) == true )
		theDataObj.setproblem_name( theDataObj.getquestion_file() );
	else if (checkValid(theDataObj.getmedia_file()) == true )
		theDataObj.setproblem_name( theDataObj.getmedia_file() );
 
 
	// Problem Context : Optional
	if (checkValid(problem_context_txt.text) == true )
		theDataObj.setproblem_context(problem_context_txt.text);		
 
	// Problem tutorFlag : Optional
	if (checkValid(problem_tutorflag_txt.text) == true )
		theDataObj.setproblem_tutorflag(problem_tutorflag_txt.text);		
 
	// Problem tutorFlag : Optional
	if (checkValid(problem_tutorflag_txt.text) == true )
		theDataObj.setproblem_tutorflag(problem_tutorflag_txt.text);	
 
	// Problem otherproblemflag : Optional
	if (checkValid(_level0.problem_otherproblemflag) == true )
		theDataObj.setproblem_otherproblemflag(_level0.problem_otherproblemflag);	
 
// Custom Fields : e.g., name="Repetition Series" value="Problem 2 of 5"
// Used to represent unique types of data.  For example, User Interface version, Repetition problem sequence number, etc.
	var aCustom_field_obj:Object = new Object();
	aCustom_field_obj.name = new Array();
	aCustom_field_obj.value = new Array();
 
	// Here, I look for custom field variables set from flashvars
	if ( checkValid(custom_field_name1_txt.text) == true)  aCustom_field_obj.name.push(custom_field_name1_txt.text);
	if ( checkValid(custom_field_value1_txt.text) == true)  aCustom_field_obj.value.push(custom_field_value1_txt.text);
	if ( checkValid(custom_field_name1_txt.text) == true)  aCustom_field_obj.name.push(custom_field_name1_txt.text);
	if ( checkValid(custom_field_value1_txt.text) == true)  aCustom_field_obj.value.push(custom_field_value2_txt.text);
	var aCustom_field_objSerName:String= aCustom_field_obj.name.join();
	var aCustom_field_objSerValue:String = aCustom_field_obj.value.join();
 
	//theDataObj.setcustom_field_obj( aCustom_field_obj );	// formerly sent a object but this fails when loading lib over network.
	theDataObj.setcustom_field_obj( aCustom_field_objSerName, aCustom_field_objSerValue );
 
// Dataset	
	// Dataset name (use dataset_name if defined, else used course_name if defined) (0 or1)
	var prefValue:String = dataset_name_txt.text;
	if (checkValid(prefValue) == true )
	{
		theDataObj.setdataset_name(prefValue);
	}
 
 
 
 
// Dataset Levels
	var aDataset_level_obj:Object = new Object();
	aDataset_level_obj.type = new Array();
	aDataset_level_obj.name = new Array();
 
	// Map unit and section into dataset levels. This is done to support unit_name and section_name (flashvars) for backward compatibility.
	if ( checkValid(unit_name_txt.text) == true)
	{
		aDataset_level_obj.type.push("unit");
		aDataset_level_obj.name.push(unit_name_txt.text);
	}
	if ( checkValid(section_name_txt.text ) == true)
	{
		aDataset_level_obj.type.push("section");
		aDataset_level_obj.name.push(section_name_txt.text );
	}		
 
	// Levels in a data set. - dataset_level_name1, dataset_level_name2 | in the library get method, this uses a loop with an index for the name. i.e., name+idx, type+idx	
	if ( checkValid(dataset_level_name1_txt.text) == true)  aDataset_level_obj.name.push(dataset_level_name1_txt.text);
	if ( checkValid(dataset_level_type1_txt.text) == true)  aDataset_level_obj.type.push(dataset_level_type1_txt.text);
	if ( checkValid(dataset_level_name2_txt.text) == true)  aDataset_level_obj.name.push(dataset_level_name2_txt.text);
	if ( checkValid(dataset_level_type2_txt.text) == true)  aDataset_level_obj.type.push(dataset_level_type2_txt.text);
	var aDataset_level_objSerName:String= aDataset_level_obj.name.join();
	var aDataset_level_objSerType:String = aDataset_level_obj.type.join();
 
	theDataObj.setdataset_level_obj( aDataset_level_objSerName, aDataset_level_objSerType);
	// theDataObj.setdataset_level_obj( aDataset_level_obj );	// formerly sent a object but this fails when loading lib over network.
 
// User & School
	if (checkValid(user_guid_txt.text) == true )
		theDataObj.setuser_guid(user_guid_txt.text);	
	else 
		theDataObj.setuser_guid("theUserName");
 
	if (checkValid(class_name_txt.text) == true )
		theDataObj.setclass_name(class_name_txt.text);	
 
	if (checkValid(school_name_txt.text) == true )
		theDataObj.setschool_name(school_name_txt.text);
 
	if (checkValid(period_name_txt.text) == true )
		theDataObj.setperiod_name(period_name_txt.text);
 
	if (checkValid(class_description_txt.text) == true )
		theDataObj.setclass_description(class_description_txt.text);
 
	if (checkValid(instructor_name_txt.text) == true )
		theDataObj.setinstructor_name(instructor_name_txt.text);
 
// Study Condition		
	// study_condition_name1, study_condition_name2 ...
	var aStudy_condition_obj:Object = new Object();
	aStudy_condition_obj.name = new Array();
	aStudy_condition_obj.type = new Array();
	aStudy_condition_obj.description = new Array();
 
	if ( checkValid(study_condition_name1_txt.text) == true)  aStudy_condition_obj.name.push(study_condition_name1_txt.text);
	if ( checkValid(study_condition_type1_txt.text) == true)  aStudy_condition_obj.type.push(study_condition_type1_txt.text);
	if ( checkValid(study_condition_description1_txt.text) == true)  aStudy_condition_obj.description.push(study_condition_description1_txt.text);
 
	if ( checkValid(study_condition_name2_txt.text) == true)  aStudy_condition_obj.name.push(study_condition_name2_txt.text);
	if ( checkValid(study_condition_type2_txt.text) == true)  aStudy_condition_obj.type.push(study_condition_type2_txt.text);
	if ( checkValid(study_condition_description2_txt.text) == true)  aStudy_condition_obj.description.push(study_condition_description2_txt.text);
 
	var aStudy_condition_objSerName:String= aStudy_condition_obj.name.join();
	var aStudy_condition_objSerType:String = aStudy_condition_obj.type.join();
	var aStudy_condition_objSerDescription:String = aStudy_condition_obj.description.join();
 
	//theDataObj.setstudy_condition_obj( aStudy_condition_obj );	// formerly sent a object but this fails when loading lib over network.
	theDataObj.setstudy_condition_obj( aStudy_condition_objSerName,  aStudy_condition_objSerType,  aStudy_condition_objSerDescription);	
 
 
// Student Session & OLI Identifiers	
 
 
	//if (checkValid(auth_token_txt.text) == true )
		//theDataObj.setauth_token(auth_token_txt.text);
	//else
		//theDataObj.setauth_token("");
		//
	//if (checkValid(container_id_txt.text) == true )
		//theDataObj.setcontainer_id(container_id_txt.text);
	//else	
		//theDataObj.setcontainer_id("");
	//
	//if (checkValid(theSource_id_txt.text) == true )
		//theDataObj.setsource_id(theSource_id_txt.text);
	//else	
		//theDataObj.setsource_id("SAMPLE_LLL_APP");
	//trace("setDataObject : theDataObj.getsource_id() = " + theDataObj.getsource_id() );
	//
	//if (checkValid(external_object_id_txt.text) == true )
		//theDataObj.setexternal_object_id(external_object_id_txt.text);
	//else
		//theDataObj.setexternal_object_id("");
		//
	// (optional item)
	//if (checkValid(_level0.class_id) == true )
		//theDataObj.setclass_id(_level0.class_id);
	//else
		//theDataObj.setclass_id("");
		//
	// (optional item)
	//if (checkValid(_level0.info_type) == true )
		//theDataObj.setinfo_type(_level0.info_type);
	//else
		//theDataObj.setinfo_type("tutor_message.dtd");
		//
	// (optional item)
	//if (checkValid(_level0.treatment_id) == true )
		//theDataObj.settreatment_id(_level0.treatment_id);
	//else
		//theDataObj.settreatment_id("");
		//
	// (optional item)
	//if (checkValid(_level0.assignment_id) == true )
		//theDataObj.setassignment_id(_level0.assignment_id);
	//else
		//theDataObj.setassignment_id("");
 
}
 
 
 
// ------------------- END Context Message and Start Tutor Message -----------------
 
 
// ------------------- Utility Methods -----------------
 
function checkValid(aVaraible:String):Boolean
{
	if ( aVaraible == null ||  aVaraible == undefined ||  aVaraible== "" || aVaraible.length <= 0) 
	{
		return false
	}
	else 
	{
		return true;
	}
}
 
function checkValidObj( theDataObj:Object )
{
	if ( aVaraible == null ||  aVaraible == undefined ) 
	{
		return false
	}
	else 
	{
		return true;
	}
}
// ------------------- END Utility Methods -----------------
 
 
 
 
 
// ------------------- UI Interaction -----------------
LogTextField1_txt.addEventListener("enter", mx.utils.Delegate.create(this, q1handler));
 
/*
*  Log a user interaction with the Question 1 Text Field when the 'Enter' key is pressed.
*  Calling logAttempt followed by logResult produces 2 log messages.   (two calls-two messages)
*  Note the generation of semantic IDs which are necessary parameters for the logAttempt and logResult methods.
*/
function q1handler( eventObject ):Void
{
	// Failsafe: Initialize the session for the tutor.  This is only needed outside the OLI environment.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) send_logSessionMessage();	
 
	// Failsafe: Call an initialization method for the problem.
	if (problemStarted == false) newProblem();
 
	// Set basic data to log.
	var mySelection:String = String(LogTextField1_txt);
	var myAction:String = "UpdateTextField";
	var myInput:String = LogTextField1_txt.text;
	var myDesiredInput:String = "123";
	var myActionEvaluation:String;
	var mySuccessText:String = "That's correct, great job!";
	var myErrorText:String = "Your answer is not correct.";
	var mySkillName:Array = new Array("1-TextEntryforGUIs", "2-TextEntryforGUIs");
	var mySkillCategory:Array = new Array("1-SkillCategoryX", "2-SkillCategoryY");
	//var mySkillModel:Array = new Array("HaoFactoredModel", "HaoFactoredModel");
 
	// ID used to associate the attempt (student input) and result (evaluation) messages.
	 var theTransactionID:String = LoggingLibrary_mc.LogClass.getGuid();
 
	 // Call logAction which internally produces a logAttempt msg and a logResult msg. 
	 // Use this technique if you do NOT distinguish between student input and assessment.
 
	 if (myInput == myDesiredInput) 
	 {
		 myActionEvaluation = "CORRECT";
	 	LoggingLibrary_mc.LogClass.logAction (mySelection, myAction, myInput, myActionEvaluation, mySuccessText, mySkillName, mySkillCategory);
		LogTextField1_txt.setStyle("color", "0x00FF000");
	 } 
	  // Call logAttempt and logResult separately, which produces two log messages.  CTAT Pseudo Tutors take this approach.
	 // Use this technique if you distinguish between student input and assessment.  One reason to do this is to record intended Selection, Action, and Input of an erroneous result.
	 else 
	 {
		myActionEvaluation = "INCORRECT";
	 	LoggingLibrary_mc.LogClass.logAttempt (theTransactionID, mySelection, myAction, myInput);
	 	LoggingLibrary_mc.LogClass.logResult (theTransactionID, mySelection, myAction, myInput, myActionEvaluation, myErrorText, mySkillName, mySkillCategory);
 
		//trace("sample : skills: mySkillName[0] = " + mySkillName[0]);
		LogTextField1_txt.setStyle("color", "0xff0000");
	 } 
}
 
 
 
/*
*  Log a user hint for the Question 1 Text Field with the Hint 1 button.
*  Calling logHintRequest followed by logHintResponse produces 2 log messages (two calls-two messages)
*  Note the generation of semantic IDs for parameters in the logHintRequest and logHintResponse methods.
*/
Hint_Button1.onRelease = function(){
	// Failsafe: Initialize the session for the tutor.  This is only needed outside the OLI environment.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) send_logSessionMessage();	
 
	// Failsafe: Call an initialization method for the problem.
	if (problemStarted == false) newProblem();	
 
 
	var mySelection = String(LogTextField1_txt);		// selection item the hint was requested for
	var myAction = "UpdateTextField";		// action of the item the hint was requested for
	var myDesiredInput = "123";			// desired input of the item the hint was requested for
	var myActionEvaluation = "HINT";
	var myHintText = "A hint, consider spelling mistakes ";
	var mySkillName:Array = new Array("1-TextEntryforGUIs", "2-HintRequstforGUIs");
	var mySkillCategory:Array = new Array("1-SkillCategoryX", "2-SkillCategoryY");
	//var mySkillModel:Array = new Array("HaoFactoredModel", "HaoFactoredModel");
	var myHintLevel = "2";
	var myNumberOfHints= "3";
 
	//trace("Logging hint for " + mySelection + " from Hint Button 1.");
 
	// Call logHintRequest and logHintResponse separately to produce the two log messages.  
	// CTAT Pseudo Tutors take this approach.
	// Use this technique if you separate input and assessment (CTAT gets hints from a data model).
	var theTransactionID:String = LoggingLibrary_mc.LogClass.getGuid();
 
	LoggingLibrary_mc.LogClass.logHintRequest(theTransactionID, mySelection, myAction, myDesiredInput);
	LoggingLibrary_mc.LogClass.logHintMessage(theTransactionID, mySelection, myAction, myDesiredInput, 
		myActionEvaluation, myHintText, myHintLevel, myNumberOfHints, mySkillName, mySkillCategory);
}
 
 
LogTextField2_txt.addEventListener("enter", mx.utils.Delegate.create(this, q2handler));
/*
*  Log a user interaction with the Question 2 Text Field when the 'Enter' key is pressed.
*  Calling logAction produces 2 log messages (one call-two messages).  
*/
function q2handler(eventObject):Void {
	// Failsafe: Initialize the session for the tutor.  This is only needed outside the OLI environment.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) send_logSessionMessage();	
 
	// Failsafe: Call an initialization method for the problem.
	if (problemStarted == false) newProblem();	
 
 
	// Set basic data that is logged.
	var theSemanticTrigger:String = "DATA";
	var theSemanticSubType:String = "tutor-performed";
	var mySelection = String(LogTextField2_txt);
	var myAction:String = "UpdateTextField";
	var myInput:String = LogTextField2_txt.text;
	var myDesiredInput:String = "123";
	var myActionEvaluation:String;
	var mySuccessText:String = "That's correct, great job!";
	var myErrorText:String = "Your answer is not correct.";
 
	var mySkillName:Array = new Array("1-TextEntryforGUIs", "2-TextEntryforGUIs");
	var mySkillCategory:Array = new Array("1-SkillCategoryX", "2-SkillCategoryY");
	var mySkillModel:Array = new Array("HaoFactoredModel", "HaoFactoredModel");
	var mySkillProbability:String = "0.678"; // Used with knowledge tracing in CTAT tutors.
	var mySkillBuggy:String = "";	// CTAT will eventually use buggy, to label anti-skills--that is, skills attached to explicitly-modeled buggy steps
 
	//trace("Logging " + myInput + " from Text Field 2.");
 
	// Call the combined method, logActionFull,  which in turn calls logAttemptFull and logResultFull, each producing a log msg.  
	// Use this technique if your tutor combines user input and assessment.  
	// CTAT Pseudo Tutorslog the student input in the attempt message and the correct answer details in the results and, therefore, don't use this combined format.
	if (myInput == myDesiredInput) {
		 myActionEvaluation = "CORRECT";
		LoggingLibrary_mc.LogClass.logActionFull (theSemanticTrigger, theSemanticSubType, mySelection, myAction, myInput, myActionEvaluation, mySuccessText, mySkillName, mySkillCategory, arSkillModel, mySkillProbability, mySkillBuggy);
		LogTextField2_txt.setStyle("color", "0x00FF000");
	} else {
		myActionEvaluation = "INCORRECT";
		LoggingLibrary_mc.LogClass.logActionFull (theSemanticTrigger, theSemanticSubType, mySelection, myAction, myInput, myActionEvaluation, myErrorText, mySkillName, mySkillCategory, arSkillModel, mySkillProbability, mySkillBuggy);
		LogTextField2_txt.setStyle("color", "0xff0000");
	}
}
 
/*
*  Log a user hint for the Question 2 Text Field with the Hint2 button. (one call-two messages)
*  Calling the logHint method will produce 2 log messages by calling logHintRequest and logHintResponse in turn.
*/
Hint_Button2.onRelease = function(){
	// Failsafe: Initialize the session for the tutor.  This is only needed outside the OLI environment.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) send_logSessionMessage();	
 
	// Failsafe: Call an initialization method for the problem.
	if (problemStarted == false) newProblem();	
 
	var theSemanticTrigger:String = "DATA";
	var theSemanticSubType:String = "tutor-performed";
	var mySelection = String(LogTextField2_txt);		// selection item the hint was requested for
	var myAction = "UpdateTextField";		// action of the item the hint was requested for
	var myDesiredInput = "123";			// desired input of the item the hint was requested for
	var myActionEvaluation = "HINT";
	var myHintText = "A hint, consider spelling mistakes ";
	var myHintLevel = "2";
	var myNumberOfHints= "3";
 
	var mySkillName:Array = new Array("1-TextEntryforGUIs", "2-HintRequstforGUIs");
	var mySkillCategory:Array = new Array("1-SkillCategoryX", "2-SkillCategoryY");
	var mySkillModel:Array = new Array("HaoFactoredModel", "HaoFactoredModel");
	var mySkillProbability:String = "0.410"; // Used with knowledge tracing in CTAT tutors.
	var mySkillBuggy:String = "";	// CTAT will eventually use buggy, to label anti-skills--that is, skills attached to explicitly-modeled buggy steps
 
	//var mySkillModel:Array = new Array("HaoFactoredModel", "HaoFactoredModel");
 
 
	//trace("Logging hint for " + mySelection + " from Hint Button 2.");
 
	 // Call the combined method which in turn calls logHintRequest and logHintResponse, each producing a log msg.  
	 // Use this technique if your tutor combines user hint request and hint delivery into a single message.  
	 // CTAT Pseudo Tutors have separate hint request and delivery and, therefore, don't use the combined method.
	 LoggingLibrary_mc.LogClass.logHintFull (theSemanticTrigger, theSemanticSubType, mySelection, myAction, myDesiredInput, myActionEvaluation, myHintText, myHintLevel, 
	 	myNumberOfHints, mySkillName, mySkillCategory, mySkillModel, mySkillProbability, mySkillBuggy);
 
}
 
//video1.addEventListener("click", listenerObject)
video1.addEventListener("click", mx.utils.Delegate.create(this, video1Handler))
 
 
function video1Handler(eventObject):Void
{
	// Failsafe: Initialize the session for the tutor.  This is only needed outside the OLI environment.
	if (usingOLI == false && LoggingLibrary_mc.LogClass.getsessionEstablished() == false) send_logSessionMessage();	
 
	// Failsafe: Call an initialization method for the problem.
	if (problemStarted == false) newProblem();	
 
	// Selection
	var theSelection:String = String(eventObject.target);
	var theMediaFile:String = media_file_txt.text;
	var theClipLength:String = "00:08:00.0";
	var theTime:String = "00:02:34.2";
	var theMessageText:String = "a video play button";
 
	 // Log Video Message
	 if (eventObject.detail == "play")
		LoggingLibrary_mc.LogClass.logVideoPlay (theSelection, theMediaFile, theClipLength, theTime, theMessageText);
	if (eventObject.detail == "pause")
		LoggingLibrary_mc.LogClass.logVideoPause (theSelection, theMediaFile, theClipLength, theTime, theMessageText);
 
}
// ------------------- END UI Interactions  -----------------
 
 
 
// ------------------------------------ Button Bar -----------------------------------
 
LOAD_TUTORbtn.onRelease = function(){
	send_logSessionMessage();
	setDataObject();
	send_logLoadTutor()
}
 
START_TUTORbtn.onRelease = function(){
	send_logSessionMessage();
	setDataObject();
	send_logStartTutor();
}
 
LOAD_VIDEObtn.onRelease = function(){
	send_logSessionMessage();
	setDataObject();
	send_logLoadVideo();
}
 
START_VIDEObtn.onRelease = function(){
	send_logSessionMessage();
	setDataObject();
	send_logStartVideo();
}
 
 
startProblemOldBtn.onRelease = function(){
	send_logSessionMessage();
	setDataObject();
	send_startProblemOld();
}
 
resetParametersBtn.onRelease = function(){
	setInterfaceData();
 
}
 
logVideoPlayBtn.onRelease = function(){
	// Selection
	var theSelection:String = String(eventObject.target);
	var theMediaFile:String = media_file_txt.text;
	var theClipLength:String = "00:08:00.0";
	var theTime:String = "00:02:34.2";
	var theMessageText:String = "a video play button";
 
	 // Log Video Message
	LoggingLibrary_mc.LogClass.logVideoPlay (theSelection, theMediaFile, theClipLength, theTime, theMessageText);
 
}
 
logVideoPauseBtn.onRelease = function(){
	// Selection
	var theSelection:String = String(eventObject.target);
	var theMediaFile:String = media_file_txt.text;
	var theClipLength:String = "00:08:00.0";
	var theTime:String = "00:02:34.2";
	var theMessageText:String = "a video pause button";
 
	 // Log Video Message
	LoggingLibrary_mc.LogClass.logVideoPause (theSelection, theMediaFile, theClipLength, theTime, theMessageText);
 
}
 
 
 
 
 
 
// ------------------------------------ END utton Bar -----------------------------------
 
 
 
// ------------------------------------ EXTRA Logging -----------------------------------
 
function send_logLoadVideo(){		
	LoggingLibrary_mc.LogClass.logLoadVideo( theDataObj );
	problemStarted = true;
}
 
function send_logStartVideo(){		
	LoggingLibrary_mc.LogClass.logStartVideo( theDataObj );
	problemStarted = true;
}
 
/*
*  This method is used to initialize each problem and distinguish problems in the log.
*  If you are loading multiple problems in a SWF then you should call this method when the problem starts so that a new context log message is sent.
*  For this sample, the data parameters are defined in the flashvars parameter of the HTML Object tag.  The accompanying HTML file contains the necessary data.
*  How does this work?  Well, Flash converts the flashvars to _level0.variables that are being referenced in the method call.
*  These data could also be assigned in this frame script.  For example by reading them in through a remote method such as 
*  LoadVars, XML, remoting etc., providing flexibility to the developer.  Note, the underlying class also has a fallback
*  for calling start problem with the _level0.variables.  Please see setProblemStarted, getProblemStarted, startProblem etc. 
*  in the JavaDoc API for details.  For more information on flashvars, see http://ctat.pact.cs.cmu.edu/tiki-index.php?page=CTAT_FlashPublish
*/
function send_logLoadTutor(){		
	LoggingLibrary_mc.LogClass.logLoadTutor( theDataObj );
	problemStarted = true;
}
 
function send_logStartTutor(){		
	LoggingLibrary_mc.LogClass.logStartTutor( theDataObj );
	problemStarted = true;
}
 
function send_startProblemOld(){		
 
	LoggingLibrary_mc.LogClass.startProblemOld (log_service_url_txt.text, question_file_txt.text, problem_name_txt.text,  
		_level0.course_name, unit_name_txt.text,  section_name_txt.text ,  school_name_txt.text, user_guid_txt.text,  
		session_id_txt.text,  container_id_txt.text, theSource_id_txt.text,	external_object_id_txt.text, auth_token_txt.text);
 
	problemStarted = true;
}
 
// ------------------------------------ END EXTRA Logging -----------------------------------