function ScoLoader(intermediatePage, popupLauncherPage, pathToCourse, scoLaunchType, wrapScoWindowWithApi, standard){
	
	this.IntermediatePage = intermediatePage;
	this.PopupLauncherPage = popupLauncherPage;
	this.PathToCourse = pathToCourse;
	this.ScoLaunchType = scoLaunchType;
	this.WrapScoWindowWithApi = wrapScoWindowWithApi;
	this.Standard = standard;
	
	this.ContentFrame = ScoLoader_FindContentFrame(window);
	
	if (this.ContentFrame === null){
		Debug.AssertError("Unable to locate the content frame-" + IntegrationImplementation.CONTENT_FRAME_NAME);
	}
}

ScoLoader.prototype.LoadSco = ScoLoader_LoadSco;
ScoLoader.prototype.UnloadSco = ScoLoader_UnloadSco;	

function ScoLoader_LoadSco(activity){
	
	activity.LaunchedThisSession = false;
	
	var aiccParams = "";
	if (this.Standard == STANDARD_AICC){
		aiccParams = "AICC_SID=" + escape(ExternalRegistrationId + "~" + ExternalConfig + "~" + activity.GetDatabaseIdentifier() + "~" + RegistrationToDeliver.Package.Id);
		// The forth parameter of the AICC_SID indicates whether tracking is turned on
		if (RegistrationToDeliver.TrackingEnabled === false) {
			aiccParams += escape("~false");
		} else {
			aiccParams += escape("~true");
		}
		aiccParams += "&AICC_URL=" + escape(AICC_RESULTS_PAGE);
	}
	
	var pathToSco = "";
	
	if (this.PathToCourse.length > 0){
		
		pathToSco = this.PathToCourse;
		
		if (this.PathToCourse.lastIndexOf ("/") != (this.PathToCourse.length - 1)){
			pathToSco += "/";
		}
		
		pathToSco += activity.GetLaunchPath();
		
	}
	else{
		pathToSco = activity.GetLaunchPath();
	}
	
	var launchPath;
	
	if (aiccParams !== ""){
	
		pathToSco = MergeQueryStringParameters(pathToSco, aiccParams);
	}
	
	if (this.ScoLaunchType == LAUNCH_TYPE_FRAMESET){

		Control.WriteDetailedLog("Loading Sco In Frameset at: " + pathToSco);
		
		this.ContentFrame.location = pathToSco;
		
		Control.Api.InitTrackedTimeStart();
		activity.SetLaunchedThisSession();
	}
	else if (this.ScoLaunchType == LAUNCH_TYPE_POPUP || this.ScoLaunchType == LAUNCH_TYPE_POPUP_WITHOUT_BROWSER_TOOLBAR){
		
		if (this.ScoLaunchType == LAUNCH_TYPE_POPUP_WITHOUT_BROWSER_TOOLBAR) {
			var showToolbar = "false";
		} else {
			var showToolbar = "true";
		}
		
		if (this.WrapScoWindowWithApi === true){
			launchPath = MergeQueryStringParameters(this.PopupLauncherPage.PageHref, 
													this.PopupLauncherPage.Parameters, 
													"ScoUrl=" + escape(pathToSco),
													"WrapApi=true",
													"ShowToolbar=" + showToolbar);
		}
		else{
			launchPath = MergeQueryStringParameters(this.PopupLauncherPage.PageHref, 
													this.PopupLauncherPage.Parameters, 
													"ScoUrl=" + escape(pathToSco),
													"ShowToolbar=" + showToolbar);
		}
		this.ContentFrame.location = launchPath;
	}
	else if (this.ScoLaunchType == LAUNCH_TYPE_POPUP_AFTER_CLICK){
	
		if (this.WrapScoWindowWithApi === true){
			launchPath = MergeQueryStringParameters(this.PopupLauncherPage.PageHref, 
													this.PopupLauncherPage.Parameters, 
													"ScoUrl=" + escape(pathToSco),
													"LaunchAfterClick=true",
													"WrapApi=true");
		}
		else{
			launchPath = MergeQueryStringParameters(this.PopupLauncherPage.PageHref, 
												this.PopupLauncherPage.Parameters, 
												"ScoUrl=" + escape(pathToSco),
												"LaunchAfterClick=true");
		}
								
		this.ContentFrame.location = launchPath;
	}
	else{
		Debug.AssertError("Invalid Sco Launch Type");
	}
}

function ScoLoader_UnloadSco(messageToDisplay){

	var path = "";

	if (messageToDisplay === true){
		path = MergeQueryStringParameters(this.IntermediatePage.PageHref, this.IntermediatePage.Parameters, "MessageWaiting=true");
	}
	else{
		path = MergeQueryStringParameters(this.IntermediatePage.PageHref, this.IntermediatePage.Parameters);
	}
	
	//TODO: test this sco unloading with a popup...use the Articulate v4 content that does all its processing in the onunload event to make sure it works
	if ( ( this.ScoLaunchType == LAUNCH_TYPE_POPUP || 
		   this.ScoLaunchType == LAUNCH_TYPE_POPUP_AFTER_CLICK) && 
		 this.ContentFrame.CloseSco){
		
		Control.WriteDetailedLog("Closing Sco");
		this.ContentFrame.CloseSco();
		
		Control.WriteDetailedLog("Launching intermediate page from " + path);
		window.setTimeout("Control.ScoLoader.ContentFrame.location = '" + path + "'", 250);
	}
	else{
		Control.WriteDetailedLog("UnLoading Sco and launching intermediate page from " + path);
		this.ContentFrame.location = path;
	}
}


function ScoLoader_FindContentFrame(wnd){
	//search all child frames recursively until we find the content frame
	
	//TODO - does this work if the call originates from the content itself? will that ever happen? does it matter since we got a pointer to the content frame when the object was created?
	
	var contentWindow = null;
	
	for (var i=0; i < wnd.frames.length; i++){
		
		if (wnd.frames[i].name == IntegrationImplementation.CONTENT_FRAME_NAME){
			contentWindow = wnd.frames[i];
			return contentWindow;
		}
		
		contentWindow = ScoLoader_FindContentFrame(wnd.frames[i]);
		
		if (contentWindow !== null){
			return contentWindow;
		}
	}
	
	return null;
}
