/* =================================================

CaptivateController() Test Suite
by Philip Hutchison, May-June 2009
http://pipwerks.com/lab/captivate

Copyright (c) 2009 Philip Hutchison
MIT-style license. Full license text can be found at 
http://www.opensource.org/licenses/mit-license.php

Thanks to Jesse Warden for supplying a Captivate 2
SWF for testing purposes and Peter Norvig for his 
Gettysburg Address PowerPoint file, which was used 
for creating sample Captivate SWFs.

==================================================== */

/*  Captivate variables  */

var preCP5_captivate_variables = [ "cpCmndVolume", "cpInfoElapsedTimeMS", "cpInfoCurrentDateString", "cpInfoCurrentDate", "cpInfoCurrentMonth", "cpInfoCurrentYear", "cpInfoCurrentDay", "cpInfoCurrentTime", "cpInfoCurrentHour", "cpInfoCurrentMinutes", "cpInfoEpochMS", "cpInfoCurrentSlide", "cpInfoCurrentSlideType", "rdcmndGotoSlide", "cpCmndGotoFrameAndResume", "rdcmndNext", "rdcmndPlaybarMoved", "rdcmndMute", "rdcmndCC", "cpHasSkinSWF", "cpMovieHeight", "cpMovieWidth", "cpAutoPlay", "CaptivateVersion", "rdinfoFPS", "rdinfoFrameCount", "rdinfoSlideCount", "rdinfoCurrentFrame", "rdinfoCurrentSlide", "cpInfoProjectName", "cpInfoDescription", "cpInfoCopyright", "cpInfoAuthor", "cpInfoCompany", "cpInfoEmail", "cpInfoWebsite", "cpInfoHasPlaybar", "cpInfoIsStandalone", "cpInfoCurrentSlideLabel", "cpInfoLastVisitedSlide", "cpInfoPrevSlide", "cpQuizInfoQuizPassPercent", "cpQuizInfoQuizPassPoints", "cpQuizInfoNoQuestionsPerQuiz", "cpQuizInfoTotalQuestionsPerProject", "cpQuizInfoTotalQuizPoints", "cpQuizInfoTotalProjectPoints", "cpQuizInfoPointsPerQuestionSlide", "cpQuizInfoAnswerChoice", "cpQuizInfoQuestionSlideTiming", "cpQuizInfoQuestionSlideType", "cpQuizInfoMaxAttemptsOnCurrentQuestion", "cpQuizInfoAttempts", "cpQuizInfoTotalCorrectAnswers", "cpQuizInfoPointsscored", "cpInfoPercentage", "cpQuizInfoLastSlidePointScored", "cpQuizInfoTotalUnansweredQuestions", "cpCmndNext", "cpCmndShowPlaybar", "cpCmndCC", "cpCmndMute", "cpCmndPlaybarMoved", "isCPMovie", "swfCommenting", "swfCmtAutoPlay", "rdIsPreview", "isPreviewSkin", "isPreview", "LocalConnectionInUse", "inAutoPlayState", "CPMovieType", "rdinfoSlidesInProject", "rdinfocurrFrame", "rdinfoCurrentSlideInProject", "playbarPosition", "playbarHeight", "NoOfTOCEntries", "cpCmndFastForward", "pbcBtnTips", "loadedFromAggregator", "rdcmndHidePlaybar", "rdinfoHasPlaybar", "rdIsMainMovie", "cpInfoFPS", "movieQuality", "TOCEntries", "TOCSettings", "m_quizPoolColl" ];

var cp5_vars = ["isCPMovie", "CPMovieType","waitCount", "expired","rdinfoSlidesInProject","rdinfocurrFrame", "rdinfoCurrentSlideInProject","swfCommenting", "swfCmtAutoPlay","cpMovieHeight","cpMovieWidth","rdIsPreview","rdIsPreviewInBrowser", "rdIsStandalone", "rdIsInLivePreviewMode", "_cpCmndMute", "movieQuality", "CaptivateVersion", "TOCEntries", "TOCStringTable", "TOCSettings", "NoOfTOCEntries", "tocInitDone", "playbarHeight", "isPlayBarBtnClicked", "movie","m_Sub_mc_array", "m_flv_array", "g_serranoViewerController", "movieXML", "PlaybarProperties", "pbcBtnTips_ENU","pbcBtnTips", "isPreviewSkin", "isPreviewForAudioDialog", "isForceMuteAudio", "isPreview","quizPlaybackController", "_slideContent2", "_slideContent", "slideInfo", "LocalConnectionInUse", "contentLeft", "contentTop", "contentWidth", "contentHeight", "loadedFromAggregator", "DoNotRegisterRightClickBecauseOfAggregator", "cpHasSkinSWF", "loadbase", "m_quizPoolColl", "passwordPresent", "cpMovieXForEmbededPlaybar", "cpMovieYForEmbededPlaybar", "cpMovieXForTOC", "cpMovieYForTOC", "cpAutoPlay", "inAutoPlayState","cpCmndFastForward", "endSwfAction", "lmsString", "isContiniousModeRecording", "hasProjectFadeOut", "cpCmndVolume", "cpInfoElapsedTimeMS", "cpInfoCurrentDateString", "cpInfoCurrentDate", "cpInfoCurrentMonth", "cpInfoCurrentYear", "cpInfoCurrentDay", "cpInfoCurrentTime", "cpInfoCurrentHour", "cpInfoCurrentMinutes", "cpInfoEpochMS", "cpInfoCurrentSlide", "cpInfoCurrentSlideType", "rdcmndGotoSlide", "cpCmndGotoFrameAndResume", "rdcmndNext", "rdcmndPlaybarMoved", "rdcmndMute", "cpCmndMute", "rdcmndCC", "rdisMainMovie"];

/* "contentShade_mc", */ /*"cpSkinBorder_mc", */ /*"cpCC_mc", */ /*"cpSkinLoader_mc", *//*"playbar_mc", */ /*"cpPbcBar_mc", */
var CP5_skin_public_vars = ["cpOrgSWFPath", "__loadbase","cpCaptivateSkinSWF", "playbarBarAlign", "cpContentLoadStart", "cpContentScaled", "playbarPosition", "isPreviewSkin", "cpContentLoaded", "cpContentPositioned", "pbcBtnTips", "pbcBtnTips_ENU", "contentHeight", "skinHeight", "contentTop", "contentLeft", "skinWidth", "contentWidth", "isCustomizable", "DoNotRegisterRightClickBecauseOfAggregator", "needToMuteAudioForAggregator", "isCPMovie", "loadedFromAggregator", "CPMovieType", "contentSWF", "PlaybarProperties" ];

//Cause syntax errors: 'TOCEntries',  'TOCSettings', 
/* 'contentShade_mc', */
/* 'cpSkinBorder_mc', */
/*'cpSkinLoader_mc', */
/* 'playbar_mc', */
/* 'cpCC_mc', */
/* 'cpPbcBar_mc', */
/* 'm_Sub_mc_array' */
/* '_slideContent', '_slideContent2',  */
/* 'g_serranoViewerController', */
/* 'movie',  */
/* 'rdIsMainMovie',  */
/* 'rdcmndInfo',  */
/* 'loadbase', */
var motherlode = [ 'CPMovieType', 'CaptivateVersion', 'DoNotRegisterRightClickBecauseOfAggregator', 'LocalConnectionInUse', 'NoOfTOCEntries', 'PlaybarProperties', 'TOCStringTable', '__loadbase', '_cpCmndMute', 'contentHeight', 'contentLeft', 'contentSWF', 'contentTop', 'contentWidth', 'cpAutoPlay', 'cpCaptivateSkinSWF', 'cpCmndCC', 'cpCmndFastForward', 'cpCmndGotoFrameAndResume', 'cpCmndGotoSlide', 'cpCmndMute', 'cpCmndNext', 'cpCmndPlaybarMoved', 'cpCmndShowPlaybar', 'cpCmndVolume', 'cpContentLoadStart', 'cpContentLoaded', 'cpContentPositioned', 'cpContentScaled', 'cpHasSkinSWF', 'cpInfoAuthor', 'cpInfoCompany', 'cpInfoCopyright', 'cpInfoCourseID', 'cpInfoCourseName', 'cpInfoCurrentDate', 'cpInfoCurrentDateString', 'cpInfoCurrentDay', 'cpInfoCurrentHour', 'cpInfoCurrentMinutes', 'cpInfoCurrentMonth', 'cpInfoCurrentSlide', 'cpInfoCurrentSlideLabel', 'cpInfoCurrentSlideType', 'cpInfoCurrentTime', 'cpInfoCurrentYear', 'cpInfoDescription', 'cpInfoElapsedTimeMS', 'cpInfoEmail', 'cpInfoEpochMS', 'cpInfoFPS', 'cpInfoHasPlaybar', 'cpInfoIsStandalone', 'cpInfoLastVisitedSlide', 'cpInfoPercentage', 'cpInfoPrevSlide', 'cpInfoProjectName', 'cpInfoWebsite', 'cpLockTOC', 'cpMovieHeight', 'cpMovieWidth', 'cpMovieXForEmbededPlaybar', 'cpMovieXForTOC', 'cpMovieYForEmbededPlaybar', 'cpMovieYForTOC', 'cpOrgSWFPath', 'cpQuizInfoAnswerChoice', 'cpQuizInfoAttempts', 'cpQuizInfoLastSlidePointScored', 'cpQuizInfoMaxAttemptsOnCurrentQuestion', 'cpQuizInfoNoQuestionsPerQuiz', 'cpQuizInfoPassFail', 'cpQuizInfoPointsPerQuestionSlide', 'cpQuizInfoPointsscored', 'cpQuizInfoQuestionSlideTiming', 'cpQuizInfoQuestionSlideType', 'cpQuizInfoQuizPassPercent', 'cpQuizInfoQuizPassPoints', 'cpQuizInfoTotalCorrectAnswers', 'cpQuizInfoTotalProjectPoints', 'cpQuizInfoTotalQuestionsPerProject', 'cpQuizInfoTotalQuizPoints', 'cpQuizInfoTotalUnansweredQuestions', 'endSwfAction', 'expired',  'hasProjectFadeOut', 'inAutoPlayState', 'isCPMovie', 'isContiniousModeRecording', 'isCustomizable', 'isForceMuteAudio', 'isPlayBarBtnClicked', 'isPreview', 'isPreviewForAudioDialog', 'isPreviewSkin', 'lmsString', 'loadedFromAggregator', 'm_flv_array', 'm_quizPoolColl', 'movieQuality', 'movieXML', 'needToMuteAudioForAggregator', 'passwordPresent', 'pbcBtnTips', 'pbcBtnTips_ENU', 'playbarBarAlign', 'playbarHeight', 'playbarPosition', 'quizPlaybackController', 'rdIsInLivePreviewMode', 'rdIsPreview', 'rdIsPreviewInBrowser', 'rdIsStandalone', 'rdcmndCC', 'rdcmndExit', 'rdcmndGotoFrame', 'rdcmndGotoFrameAndResume', 'rdcmndGotoSlide', 'rdcmndHidePlaybar', 'rdcmndMute', 'rdcmndNext', 'rdcmndNextSlide', 'rdcmndPause', 'rdcmndPlaybarMoved', 'rdcmndPrevious', 'rdcmndResume', 'rdinfoCurrentFrame', 'rdinfoCurrentSlide', 'rdinfoCurrentSlideInProject', 'rdinfoFPS', 'rdinfoFrameCount', 'rdinfoHasPlaybar', 'rdinfoSlideCount', 'rdinfoSlidesInProject', 'rdinfocurrFrame', 'rdisMainMovie', 'skinHeight', 'skinWidth', 'slideInfo', 'swfCmtAutoPlay', 'swfCommenting', 'tocInitDone', 'waitCount' ];


/* A single global variable holds all test suite stuff except the variable array */

var suite = {

	results_table: null,
	captivateSWF: null,
	swfID: "flash",
	testtype: null,
	intervalID: null,
	isMSIE: /*@cc_on!@*/false,
	count: 0,
	test_list: [],

	init: function (type, single_version){
		
		//Reset test_list
		suite.test_list = [];
		suite.testtype = type;
				
		if(single_version){
			for(var i=0; i<suite.swfs.length; i++){
				if(suite.swfs[i].name.indexOf(single_version) !== -1){
					suite.test_list[suite.test_list.length] = suite.swfs[i];
				}
			}
		} else {
			suite.test_list = suite.swfs;
		}
		
		
		alert("Running the " +type +" test. Testing " +suite.test_list.length +" SWF files. This will take a few minutes.");

		suite.results_table = document.getElementById("results").getElementsByTagName("tbody")[0];
		tr = document.createElement("tr");
		tr.className = "queryhead";
		
		if(suite.isMSIE){
			th = document.createElement("<th colspan='3'>");
		} else {
			th = document.createElement("th");
			th.setAttribute("colspan", "3");
		}
		th.innerHTML = "Testing <strong>" +type +"</strong> (" +suite.test_list.length +" swfs)";
		tr.appendChild(th);
		suite.results_table.appendChild(tr);
		
		//Embed first SWF
		suite.swfhandler.loadMovie(suite.test_list[suite.count].url, suite.test_list[suite.count].name);

		return false;

	},
	
	testCurrentSwf: function (){
		
		if(!suite.swfhandler.isObject(suite.swfID)){ return false; }
		
		var swf = document.getElementById(suite.swfID);
		
		//Reset suite.captivateSWF
		suite.captivateSWF = null;
		suite.captivateSWF = CaptivateController("flash");
		
		//Test to see if SWF is ready to communicate
		if(suite.swfIsAccessible(swf)){
			
			//SWF is loaded
			clearInterval(suite.intervalID);
			
			//Wait 3 seconds to ensure communication is available.
			suite.intervalID = setInterval(function() { suite.runTest(); }, 3000);
			
		} else {
			
			//If SWF isn't ready, wait 2 seconds and check again.
			//Yes, 2 seconds is slow, but also more accurate.
			suite.intervalID = setInterval(function() { suite.testCurrentSwf(); }, 2000);
			
		}
	
	},
	
	swfIsAccessible: function (swf){
		//Check to see if one of the accessors is functional
		return (typeof swf.cpGetValue !== "undefined" || typeof swf.GetVariable !== "undefined");
	},
	
	runTest: function(){
		
		//Clear timer
		clearInterval(suite.intervalID);
		
		//Start the process
		suite.captivateSWF.pause();
		
		//Alphabetize variables
		var array = motherlode.sort();
		
		//Test each Captivate variable
		for(var i=0, count = array.length; i < count; i++){
			
			var value = null;
			var isFound = false;
			var param = array[i];
			var skin = "cpSkinLoader_mc.";
			var controller = suite.captivateSWF;
			var swf = controller.swf;
			
			switch(suite.testtype){
				
				case "CaptivateController" :
					try { value = controller.query(param); } catch(e1) {  }
					break;

				case "CaptivateController_xml" :
					try { value = controller.queryXML(param); } catch(e1) {  }
					break;

				case "CaptivateController_external" :
					try { value = controller.queryExternalSkin(param); } catch(e1) {  }
					break;
					
				case "cpGetValue" : 
		
					try {
						value = swf.cpGetValue(param);
					} catch(e2) {
						try { value = swf.cpGetValue(skin +param); } catch(e3){  }
					}
					
					break;
					
				case "GetVariable" : 
		
					try {
						value = swf.GetVariable(param);
					} catch(e4) {
						try { value = swf.GetVariable(skin +param); } catch(e5){  }
					}
					
					break;
					
			}
			
			isFound = (value !== null && typeof value !== "undefined" && value !== "no communication");
			var klass = (isFound) ? false : "notsupported";
			var type = (isFound) ? " [" +typeof value +"]" : "—";
	
			//Display results
			suite.appendResultsToTable("" + param, "" + value, "" + type, klass);
	
		}
				
		//Load next SWF, if available
		if(suite.test_list && suite.count < (suite.test_list.length -1)){
		
			suite.count++;
			suite.swfhandler.loadMovie(suite.test_list[suite.count].url, suite.test_list[suite.count].name);

		} else {
			suite.count = 0;
			alert("Process completed.");	
		}
		
	},
	
	appendResultsToTable: function (prop, value, type, klass){
		
		var tr = document.createElement("tr");
		if(klass){ tr.className = klass; }
		
		var td_prop = document.createElement("td");
		td_prop.innerHTML = prop;
		tr.appendChild(td_prop);
		
		var td_type = document.createElement("td");
		td_type.innerHTML = type;
		tr.appendChild(td_type);
		
		var td_value = document.createElement("td");
		td_value.innerHTML = value;
		tr.appendChild(td_value);
		
		suite.results_table.appendChild(tr);
	
	},
	
	/* ----- SWFObject and loading scripts ----- */
	swfhandler: {
		
		isObject: function (id){
			var el = document.getElementById(id);
			return (el && (el.nodeName === "OBJECT" || el.nodeName === "EMBED"));
		},
		
		replaceObjectWithEmptyDiv: function (id){
			var el = document.getElementById(id);
			if(!el){ return false; }
			var div = document.createElement("div");
			el.parentNode.insertBefore(div, el);
			swfobject.removeSWF(id); //Remove the SWF
			div.setAttribute("id", id); //Give the new DIV the old element's ID
		},
		
		loadMovie: function (url, name){
		
			//Return false if Flash Player is outdated.
			if (!swfobject.hasFlashPlayerVersion("8")) { return false; }
			
			var tr, th, list, li;
	
			// --- Update list of SWFs that have been loaded -----
			list = document.getElementById("loadedList");
			li = document.createElement("li");
			li.innerHTML = "<a href='#swf" +(suite.count +1) +"'>" +name +"</a>";
			list.appendChild(li);
		
			// --- Append SWF's name to results table
			suite.results_table = document.getElementById("results").getElementsByTagName("tbody")[0];
			tr = document.createElement("tr");
			
			if(suite.isMSIE){
				th = document.createElement("<th colspan='3'>");
			} else {
				th = document.createElement("th");
				th.setAttribute("colspan", "3");
			}
			th.innerHTML = "<a name='swf" +(suite.count +1) +"'></a>" +(suite.count +1) +": " +name;
			tr.appendChild(th);
			suite.results_table.appendChild(tr);
			
			
			// --- Load SWF -----
			if(suite.swfhandler.isObject(suite.swfID)){ suite.swfhandler.replaceObjectWithEmptyDiv(suite.swfID); }
			
			var attributes = { data: url, width:"100%", height:"100%" };
			var params = { allowscriptaccess: "always", bgcolor: "#F5F5F5" };
			
			var success = swfobject.createSWF(attributes, params, suite.swfID);
			
			if(success){ suite.testCurrentSwf(); }
		
		}
		
	},

	//This is the array listing all SWFs that will be tested.
	swfs: [


			{ 	name: "Captivate 2 (ActionScript 2): Warden", url: "swf/warden.swf" },

			//AS2 (Captivate 3)
			{ 	name: "Captivate 3 (ActionScript 2): simple example Captivate 3", url: "swf/sample-captivate-movie.swf" },
			{ 	name: "Captivate 3 (ActionScript 2): simple example Captivate 3, skinned", url: "swf/sample-captivate-movie_skin.swf" },

			//AS2 (Captivate 4)
			{ 	name: "Captivate 4 (ActionScript 2): ext. skin, border, TOC", url: "swf/Gettysburg/AS2-external-skin-border-TOC_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): ext. skin, border", url: "swf/Gettysburg/AS2-external-skin-border_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): ext. skin", url: "swf/Gettysburg/AS2-external-skin_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): int. skin, border, TOC", url: "swf/Gettysburg/AS2-internal-skin-border-TOC.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): int. skin, border", url: "swf/Gettysburg/AS2-internal-skin-border.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): int. skin", url: "swf/Gettysburg/AS2-internal-skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 2): no skin", url: "swf/Gettysburg/AS2-no-skin.swf" },

			//AS3
			{ 	name: "Captivate 4 (ActionScript 3): ext. skin, border, TOC", url: "swf/Gettysburg/AS3-external-skin-border-TOC_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): ext. skin, border", url: "swf/Gettysburg/AS3-external-skin-border_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): ext. skin", url: "swf/Gettysburg/AS3-external-skin_skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): int. skin, border, TOC", url: "swf/Gettysburg/AS3-internal-skin-border-TOC.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): int. skin, border", url: "swf/Gettysburg/AS3-internal-skin-border.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): int. skin", url: "swf/Gettysburg/AS3-internal-skin.swf" },
			{ 	name: "Captivate 4 (ActionScript 3): no skin", url: "swf/Gettysburg/AS3-no-skin.swf" },

			//AS3 (Captivate 5)
			{ 	name: "Captivate 5 (ActionScript 3): int. skin, border", url: "swf/Gettysburg-CP5/Gettysburg-internal-skin(default).swf" },
			{ 	name: "Captivate 5 (ActionScript 3): int. skin, border, TOC", url: "swf/Gettysburg-CP5/Gettysburg TOC border internal skin.swf" },
			{ 	name: "Captivate 5 (ActionScript 3): ext. skin, border, TOC", url: "swf/Gettysburg-CP5/Gettysburg TOC, border, external skin_skin.swf" }

	]
	
};


swfobject.addDomLoadEvent(function (){
	suite.results_table = document.getElementById("results").getElementsByTagName("tbody")[0];
	document.getElementById("swfcount").innerHTML = "This test will query " +suite.test_list.length +" SWFs in succession, including CP2, CP3, and CP4 SWFs using ActionScript 2 and ActionScript 3. Please note the test takes a few minutes to complete. Once you start the test, an alert will let you know when it has completed.";
});