// --------------------------------------- Offline Tracking
//
// Written by Brian Davies
//   Switching based on a prototype by Greg Saunders
// October 2001 - November 2002
// Copyright 2001-4, Cognitive Arts
//
// --------------

// --------------------------------------- Documentation

/*

// -------------- Overview

The offline switching feature allows users to download an entire course,
work offline, and then switch back online and have their state reported
to the LMS.  The first time a user tries to switch offline, they are
directed to the download.htm page.  This page gives them instructions
for downloading and extracting a ZIP archive of the course.  Then they
identify where they put the course, and then click another link to switch.

Whenever a user switches offline or back online, their entire state is
sent to the other version of the course as a URL parameter.  This state
includes escaped versions of both the local and server URLs, so that
both versions of the course know how to find each other.

There are issues regarding synchronization with this feature.  If a user
switches offline, makes progress in the course, quits, and then returns
to the online version, they could potentially have two versions of the
course with different progress.  Courses using offline switching should
usually include a splash screen, as the displayStateMessage will include
warnings about users about to go out of synch.  The splash screen can
then nudge users back into the proper version of the course.

This feature works only with an AICC LMS.  A SCORM version has been
considered.  The feature also runs afoul of security restrictions in
Netscape (not preventable) and in IE 6.0 sp 1 (version 6.0.2600.0000
works, version 6.0.2800.1106 requires the user to add the server to their
list of trusted sites.)

// -------------- Constants

Courses that use the offline switching feature must define three constants:

ENABLE_OFFLINE_SWITCHING
A flag that says whether the feature is enabled or not.

TOP_PATH
The relative pathname from the course folder to the outer frame page.
This will default to assuming the outer frame page is named start.htm and
is located directly within the course folder, but can be modified for other
effects.

ZIP_PATH
The relative pathname from the course folder to the archive that contains
the downloadable version of the course, if that feature is available.

// -------------- Public Functions

	writeSwitchLink (offlinelinktext, onlinelinktext)

Called by each page to generate the toggle for switching between versions.
The linktext arguments are optional, and will default to "Go Offline" and
"Go Online", but are provided to allow customization (for example, use of
icons, bullet points, etc.).

	writeOfflineLink (offlinelinktext)
	writeOnlineLink (onlinelinktext)

If a designer does not want a toggle link, they can call these explicitly.
As with writeSwitchLink, the linktext arguments are optional and the
standard defaults are provided.


	continueOffline ()
	continueOnline ()
	desynchToOffline ()
	desynchToOnline ()

Additional functions that client code would call from the splash page.

// -------------- Wish List

* Timeout & switching is possibly fatal

* Allow user starting on unregistered version to connect to LMS eventually

* Rework the code marked LOCALIZE to allow online and offline versions to use
different file naming conventions (ie: page.cfm versus page.htm).

*/

// --------------------------------------- User Choices From Splash Screen

function desynchToOffline ()
{
	setVariable ("offline", "true");
	setVariable ("desynched", "true");
	start ();
}

function desynchToOnline ()
{
	setVariable ("offline", "false");
	setVariable ("desynched", "true");
	start ();
}

function continueOffline ()
{
	switchinprogress = true;
	top.location = getVariable ("localurl") + TOP_PATH;  /* LOCALIZE */
}

function continueOnline ()
{
	switchinprogress = true;
	top.location = getVariable ("serverurl") + TOP_PATH;  /* LOCALIZE */
}

// --------------------------------------- Writing Controls

function writeSwitchLink (offlinelinktext, onlinelinktext)
{
	if (ENABLE_OFFLINE_SWITCHING)
	{
		if (serverP ())
			writeOfflineLink (offlinelinktext);
		else
			writeOnlineLink (onlinelinktext);
	}
}

function writeOfflineLink (offlinelinktext)
{
	if (offlinelinktext == null)
		offlinelinktext = "Go Offline";
	
	if (ENABLE_OFFLINE_SWITCHING && variableDefined ("username"))
	{
		if (localP ())
		{
			if (variableDefined ("serverurl"))
			{
				courseframe.document.write ('<a class="inactive" id="offlinelink" href="javascript:void (0);">' + offlinelinktext + '</a>');
			}
		}
		else if (serverP ())
		{
			if (variableDefined ("localurl"))
				courseframe.document.write ('<a class="active" id="offlinelink" href="javascript:top.departFromServer ();" oncontextmenu="return top.resetDownload ();">' + offlinelinktext + '</a>');
			else
				courseframe.document.write ('<a class="active" id="offlinelink" href="' + getVariable ("serverurl") + 'lms/download/download.htm">' + offlinelinktext + '</a>');
		}
	}
	else
	{
		courseframe.document.write ('<a class="inactive" id="offlinelink" href="javascript:alert (&quot;This feature is not currently available.&quot;);">' + offlinelinktext + '</a>');
	}
}

function resetDownload ()
{
	top.courseframe.document.location.href = serverURL () + DOWNLOAD_PATH;
	return false;
}

function writeOnlineLink (onlinelinktext)
{
	if (onlinelinktext == null)
		onlinelinktext = "Go Online";
	
	if (ENABLE_OFFLINE_SWITCHING && variableDefined ("username"))
	{
		if (localP ())
		{
			if (variableDefined ("serverurl"))
			{
				courseframe.document.write ('<a class="active" id="onlinelink" href="javascript:top.departFromLocal ();">' + onlinelinktext + '</a>');
			}
		}
		else if (serverP ())
		{
			courseframe.document.write ('<a class="inactive" id="onlinelink" href="javascript:void (0);">' + onlinelinktext + '</a>');
		}
	}
	else
	{
		courseframe.document.write ('<a class="inactive" id="onlinelink" href="javascript:alert (&quot;This feature is not currently available.&quot;);">' + onlinelinktext + '</a>');
	}
}

// --------------------------------------- The Round Trip

function departFromServer ()
{
	setVariable ("offline", true);
	setVariable ("desynched", false);
	
	sendStateToLMS ();  // happens on switch, but state not sent correctly
	
	lmsframe.finish ();
	
	switchinprogress = true;
	
	// should test (userstate.length < 2000) or some such

	// Netscape 4 (maybe 6 also?), IE 6.0sp1 (if site not trusted) will punt here
	top.location = getVariable ("localurl") + TOP_PATH
		+ "?status=arriveAtLocal&state=" + userstate;  /* LOCALIZE */
}

function arriveAtLocal (newstate)
{
	/*

	// check desynch here and confirm before clobbering?
	// what follows is pass 1 at support for multiple users on a single machine
	if ((variableDefined ("username"))
		&& (getVariable ("username") != getTokenListValue (newstate, "username")))
	{
		alert ("The local copy is has saved progress which would be overwritten by this switch."
			+ " You are being sent back on-line.");

		newstate = setTokenListValue (newstate, "offline", false);

		document.location.href = getTokenListValue (newstate, "serverurl") + TOP_PATH
			+ "?status=arriveAtServer&state=" + newstate;
	}
	else
	*/
	{
		userstate = newstate;
		
		lmsframe.initialize (COURSE_ID, aicc_sid);
		
		start ();
	}
}

function departFromLocal ()
{
	setVariable ("offline", false);
	setVariable ("desynched", false);
	
	lmsframe.finish ();
	
	switchinprogress = true;
	
	// should test (userstate.length < 2000) or some such

	top.location = getVariable ("serverurl") + TOP_PATH
		+ "?status=arriveAtServer&state=" + escape (userstate);  /* LOCALIZE */
}

function arriveAtServer (newstate)
{
	//if (getTokenListValue (newstate, "desynched") == "true")
	//	alert ("is this the state where old state is better than new? " + getTokenListValue (newstate, "desynched"));
	
	/*

	// check desynch here and confirm before clobbering?
	// what follows is pass 1 at support for multiple users on a single machine
	if ((variableDefined ("username"))
		&& (getVariable ("username") != getTokenListValue (newstate, "username")))
	{
		alert ("Logging out previous user: " + getVariable ("username") + ".");
		
		// make sendStateToLMS better?
		putParam (getVariable ("username"), userstate);
	}
	*/
	
	userstate = newstate;

	lmsframe.initialize (getVariable ("lmsurl"), getVariable ("username"));
	
	start ();
	
	sendStateToLMS ();
}

// --------------------------------------- End Of File
