/****************************************************************************************
** Meant to be included as part of a source script from another Javascript file:
**		< SCRIPT Language='Javascript' Src='L2PlayerFunctions.js'>< /SCRIPT>
** (The above line has a space after the '<' to prevent IE on the MAC from getting upset)
** Note that the server must have the mime mapping of .js -> application/x-javascript
** enabled for source scripts to work. If this isnt possible, include this file as part of
** the calling file.
******************************************************************************************/
var sL2PlayerFunctionsVer = 'L2PlayerFunctions.js 0501.0017'

// Enable debug window
var g_bDebug = false
var playerDebugWnd = null
if (g_bDebug) CreateDebugWindow()

var isNP = false
var isNP2 = false
var isNP3 = false
var isNP405 = false
var isNP6OrBetter = false
var isNP6 = false
var isNP7 = false
var isIE = false
var isIE3 = false
var isIE4 = false
var isIE5 = false
var isIE6 = false
var isMAC= false
var isAOL = false
var isPlayerExists = false
var isPlayerUndeterm = false
var sUserAgent = ''
var isPlayerNeedsFixup = false

/******************************************************************************************
** Function:	GetQueryString(sSource)
** Inputs:		sSource - If specified, then its an URL string, else use query string
** Return:		Query parameter string
******************************************************************************************/
function GetQueryString (sSource) {
	var sQueryString = (sSource != null && sSource.length) ? sSource : location.search
	if (sQueryString.length == 0)
		sQueryString = location.pathname
	
	// Remove '?' from string	
	var n = sQueryString.indexOf('?')
	sQueryString = (n == -1) ? '' : sQueryString.substring(n+1, sQueryString.length)

	// Some very stupid LMS's dont unescape the query parameter string stored in the imsmanifest.xml href's
	// so we may have to do that. Check for the st= (stream) and wt= (window type) parameters still being escaped
	if (sQueryString.toLowerCase().indexOf('st%3d') != -1 && sQueryString.toLowerCase().indexOf('wt%3d') != -1)
		sQueryString = unescape(sQueryString)

	// As a compromise with Recombo (Sun LMS), they may use '!' as a separator instead of '&'. So if the query
	// string contains '!st=' or '!wt=' or '%21st=' or '%21wt=', replace these with ampersands
	if (sQueryString.toLowerCase().indexOf('!st=') != -1 && sQueryString.toLowerCase().indexOf('!wt=') != -1)
		Replace(sQueryString, '!', '&')
	if (sQueryString.toLowerCase().indexOf('%21st=') != -1 && sQueryString.toLowerCase().indexOf('%21wt=') != -1)
		Replace(sQueryString, '%21', '%26')

	// When launched from a shell (like in VB), the query parameter string may be url encoded.
	// Check for the st= (stream) and wt= (window type) parameters still being escaped
	if (sQueryString.toLowerCase().indexOf('%26st=') != -1 && sQueryString.toLowerCase().indexOf('%26wt=') != -1)
		sQueryString = unescape(sQueryString)
	return sQueryString
}

/******************************************************************************************
** Function:	GetQueryStringArray(sSource)
** Inputs:		sSource - If specified, then its an URL string, else use query string
** Return:		Query parameter string array. Each element of array is var=value pair
******************************************************************************************/
function GetQueryStringArray (sSource) {
	//var sQueryString = GetQueryString(sSource)
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	// I put the parameters into the sQueryString variable so that we wouldn't have to worry
	// about anything else being affected.  Adjust them to fit your needs
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	var sQueryString = 'cp=Learn%2Ecom%20CourseMaker%20Studio%20Demo&wt=standalone&ww=1&hh=1&st=agentSheila.stm&oe=&td=eMentor/'
	//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	
	// Split parameter string into array of var=value pairs
	var aQueryString = sQueryString.split('&')
	return aQueryString
}

/******************************************************************************************
** Function:	GetQueryParameter(aQueryString, sParameter, sDefault)
** Inputs:		aQueryString - Query string array of var=value pairs
**				sParameter - Query parameter to look for
** 				sDefault - Default value to return if query parameter not found
** Return:		Value string corresponding to the query parameter. Return default string if not found
******************************************************************************************/
function GetQueryParameter (aQueryString, sParameter, sDefault) {
	var i;
	for (i=0; i<aQueryString.length; i++) {
		var varEqValue = aQueryString[i].split('=')
		if (varEqValue[0].toLowerCase() == sParameter) {
			return varEqValue[1]
		}
	}
	return sDefault
}

/******************************************************************************************
** Function:	BrowserInfo()
** Inputs:		None
** Return:		Browser's user agent string
** Description:	Parses browser's user agent string to determine browser type, version and platform
** Side Effect:	Sets the above global variables indicating the browser attributes
******************************************************************************************/
function BrowserInfo () {
	sUserAgent = navigator.userAgent.toLowerCase()
	if (sUserAgent.indexOf('msie') != -1) {
		isIE = true
		if (sUserAgent.indexOf('msie 3') != -1)
			isIE3 = true
		else if (sUserAgent.indexOf('msie 4') != -1)
			isIE4 = true
		else if (sUserAgent.indexOf('msie 5') != -1)
			isIE5 = true
		else if (sUserAgent.indexOf('msie 6') != -1)
			isIE6 = true
		if (sUserAgent.indexOf('aol') != -1)
			isAOL = true

	} else if (sUserAgent.indexOf('mozilla/') != -1) {
		isNP = true
		if (sUserAgent.indexOf('mozilla/2') != -1)
			isNP2 = true
		else if (sUserAgent.indexOf('mozilla/3') != -1)
			isNP3 = true
		else if (sUserAgent.indexOf('mozilla/4') != -1) {
			// Determine if Netscape version 4.05 or less. Their Verisign certificates may have expired
			var sAppVersion = ''
			for (n = sUserAgent.indexOf('mozilla/') + 'mozilla/'.length; ;n++) {
				var ch = sUserAgent.charAt(n)
				if (ch == '.' || (ch >= '0' && ch <= '9'))
					sAppVersion += ch
				else
					break
			}
			var fAppVersion = parseFloat(sAppVersion)
			if (fAppVersion <= 4.05) {
				isNP405=true
			}
		} else if (sUserAgent.indexOf('mozilla/5') != -1) {
			isNP6OrBetter = true
			if (sUserAgent.indexOf('Netscape6') != -1 || sUserAgent.indexOf('Netscape/6') != -1)
				isNP6 = true
			else
				isNP7 = true
		}
	}

	if ((isIE && sUserAgent.indexOf('mac_') != -1) || (isNP && sUserAgent.indexOf('macintosh') != -1))
		isMAC = true

	return sUserAgent
}

/******************************************************************************************
** Function:	PlayerVersion(oWindowObj)
** Inputs:		oWindowObj - Name of window in which to load the install pages (default to current window)
** Return:		Player's version string in dotted delimited two part format (e.g., 0501.0027).
**				Return null string if player is not installed or if it can't be determined.
** Description:	Determine if a player is installed and what its version is. Uses VBScript to look
**				for ActiveX player for Internet Explorer and uses navigator object to look for
**				plugin player for Netscape. First looks for existence of session cookie containing
**				a version string which indicates a player was previously installed during this session.
**				This gets around netscape.plugin.refresh() bugs. Not necessary for IE4 and above
** Side Effect:	Sets the global variable isPlayerExists to true if player is istalled (even if downlevel)
**				Sets the global variable isPlayerUndeterm to true if it can't be determined if player is installed
******************************************************************************************/
function PlayerVersion(oWindowObj) {
	var sPlayerVersion = ''
	isPlayerExists = false
	isPlayerUndeterm = false
	
	// I dont get the cookie problem when using frames, but this seems to work
	if (oWindowObj == null) {
		// Assume the install occurs in original window (self)
		oWindowObj = self
	}
	var oCookieObj = (oWindowObj == self) ? self : parent

	if (isIE3 || isNP || (isIE && isMAC)) {
		DebugLog('PlayerVersion: cookie=' + oCookieObj.document.cookie, true)
		var sCookies = ' ' + oCookieObj.document.cookie + ';'
		var sCookieName = ' dlStPlayer='
		var nStartOfCookie = sCookies.indexOf(sCookieName)
		if (nStartOfCookie != -1) {
			if (!isMAC || !isIE)
				navigator.plugins.refresh(true)

			// Assume we know the current version of the player
			nStartOfCookie += sCookieName.length
			var nEndOfCookie = sCookies.indexOf(';', nStartOfCookie)
			sPlayerVersion = sCookies.substring(nStartOfCookie, nEndOfCookie)
			isPlayerExists = true
		}
	}

	if (!isPlayerExists) {
		// Cant tell version without playing a stream if IE3 or IE on MAC. Setting
		// self.location doesnt work with NP3 and source scripts for some reason.
		if (isIE3 || isNP3 || (isIE && isMAC))
			isPlayerUndeterm = true
		else {
			if (isNP || (isIE && isMAC)) {
				if (isNP) {
					for (i=0; i<navigator.plugins.length; i++) {
						if ((!isMAC && navigator.plugins[i].name.indexOf('Street Technologies') != -1) || (isMAC && navigator.plugins[i].name.indexOf('Learn2.com') != -1)) {
							for (j=0; j<navigator.plugins[i].length; j++) {
								if (navigator.plugins[i][j] && navigator.plugins[i][j].type.indexOf('application/street-stream') != -1) break
							}
							if (j < navigator.plugins[i].length) break
						}
					}
					if (i < navigator.plugins.length) {
						var sDesc = navigator.plugins[i].description
						n = sDesc.indexOf('Version ')
						if (n != -1)
							sPlayerVersion = sDesc.substring(n + 8, sDesc.length)
					}
				}
			} else if (isIE) {
				// Have to embed try/catch in eval to prevent Netscape from complaining. Dont know if this works for IE4.
				// Cant find any other way to check if this object was instantiated
				//document.writeln('<' + 'OBJECT id="xL2PlayerObj" classid=clsid:0B72CCA4-5F11-11D0-9CB5-0000C0EC9FDB ' + '>')
				//document.writeln('<' + 'param name=AutoPlay value=off' + '>')
				//document.writeln('<' + '/OBJECT' + '>')
				//eval('try {sPlayerVersion = xL2PlayerObj.getRTVersion() + ".7.1"} catch(err) {sPlayerVersion = ""}')
				// ... or ...
				//var xL2PlayerObj = new ActiveXObject("StWebImage.Street Technologies ActiveX Control.1")
				//sPlayerVersion = (xL2PlayerObj != null) ? xL2PlayerObj.getRTVersion() + '.7.1' : ''
				// ... or ...
				document.writeln('<' + 'SCRIPT LANGUAGE="VBScript"' + '>')
				document.writeln('Function VBPlayerVersion()')
				document.writeln('On Error Resume Next')
				document.writeln('Set objPlugin = CreateObject("StWebImage.Street Technologies ActiveX Control.1")')
				document.writeln('If (IsObject(objPlugin) = False) Then')
				document.writeln('	sPlayerVersion = ""')
				document.writeln('Else')
				document.writeln('	sPlayerVersion = Cstr(objPlugin.getRTVersion()) & ".7.1"')
				document.writeln('End If')
				document.writeln('Set objPlugin = Nothing')
				document.writeln('VBPlayerVersion = sPlayerVersion')
				document.writeln('End Function')
				document.writeln('<' + '/SCRIPT>')
				sPlayerVersion = VBPlayerVersion()

				// If they have this special player version then see if we have to install special fixup control
				if (sPlayerVersion == "0501.0082.7.1") {
					document.writeln('<' + 'SCRIPT LANGUAGE="VBScript"' + '>')
					document.writeln('Function VBPlayerNeedFixup()')
					document.writeln('On Error Resume Next')
					document.writeln('Set objFixup = CreateObject("strunfix.fix")')
					document.writeln('If (IsObject(objFixup) = False) Then')
					document.writeln('	isPlayerNeedsFixup = True')
					document.writeln('Else')
					document.writeln('	isPlayerNeedsFixup = False')
					document.writeln('End If')
					document.writeln('Set objFixup = Nothing')
					document.writeln('VBPlayerNeedFixup = isPlayerNeedsFixup')
					document.writeln('End Function')
					document.writeln('<' + '/SCRIPT>')
					isPlayerNeedsFixup = VBPlayerNeedFixup()
				}
			}
			if (sPlayerVersion.length)
				isPlayerExists = true
		}
	}

	// Only return two part dotted delimited format
	if (sPlayerVersion.length) {
		n = sPlayerVersion.indexOf('.') + 1
		sPlayerVersion = sPlayerVersion.substring(0, sPlayerVersion.indexOf('.', n))
	}
	DebugLog('PlayerVersion: sPlayerVersion=' + sPlayerVersion + ' isPlayerExists=' + isPlayerExists + ' isPlayerUndeterm=' + isPlayerUndeterm + ' isPlayerNeedsFixup=' + isPlayerNeedsFixup, true)

	return sPlayerVersion
}

/******************************************************************************************
** Function:	VersionCompare(sPlayerVersion, sMinRTVersion)
** Inputs:		sPlayerVersion - Player version string in dotted delimited two part format (e.g., 0501.0027)
**				sMinRTVersion - Minimum runtime version string in dotted delimited two part format
** Return:		-1 if sPlayerVersion <  sMinRTVersion
**				 0 if sPlayerVersion == sMinRTVersion
**				 1 if sPlayerVersion >  sMinRTVersion
** Description:	Compare the currently installed player version to the specified minimum runtime version.
** Side Effect:	None
******************************************************************************************/
function VersionCompare(sPlayerVersion, sMinRTVersion) {
	// Compare them as floats
	var fPlayerVersion = parseFloat(sPlayerVersion)
	var fMinRTVersion = parseFloat(sMinRTVersion)
	return (fPlayerVersion < fMinRTVersion) ? -1 : (fPlayerVersion == fMinRTVersion) ? 0 : 1
}

/******************************************************************************************
** Function:	InstallPlayer(sMinRTVersion, sInstallBase, sInstallOnExit, oWindow, bPlayerNeedsFixup)
** Inputs:		sMinRTVersion - Minimum runtime version string in dotted delimited two part format (e.g., 0501.0027).
**				sInstallBase - URL of page which presents installation script
**				sInstallOnExit - URL of page to load after installation is complete
**				oWindowObj - Name of window in which to load the install pages (default to current window)
**				bPlayerNeedsFixup - If false, install normal player. If true, install player fixup control (only IE)
** Return:		None
** Description:	Install the player as either a Netscape plugin or an IE ActiveX control
** Side Effect:	Sets a session cookie dlStPlayer to the minimum version string in order
**				to get around plugin refresh problems.
******************************************************************************************/
function InstallPlayer(sMinRTVersion, sInstallBase, sInstallOnExit, oWindowObj, bPlayerNeedsFixup) {
	// Have we already tried the installation?
	DebugLog('InstallPlayer: sMinRTVersion=' + sMinRTVersion + ' sInstallBase=' + sInstallBase + ' sInstallOnExit=' + sInstallOnExit + ' bPlayerNeedsFixup=' + bPlayerNeedsFixup, true)

	// I dont get the cookie problem when using frames, but this seems to work
	if (oWindowObj == null) {
		// Assume the install occurs in original window (self)
		oWindowObj = self
	}
	var oCookieObj = (oWindowObj == self) ? self : parent
	
	if (!bPlayerNeedsFixup && oCookieObj.document.cookie.indexOf('L2InstallTwice') != -1) {
		alert('You must restart your computer before the new settings will take effect')
		isPlayerExists = true
		return '0.0'
	}
	oCookieObj.document.cookie = 'L2InstallTwice=1; path=/'

	// Remove 'file:///' on sInstallOnExit if IE4 because IE4 doesnt understand location.search method on local file urls which
	// are needed to parse query strings.
	if (isIE4) {
		if (sInstallOnExit.indexOf('file://') == 0)
			sInstallOnExit = sInstallOnExit.substring(7, sInstallOnExit.length)
		if (sInstallOnExit.charAt(0) == '/')
			sInstallOnExit = sInstallOnExit.substring(1, sInstallOnExit.length)
	}

	// Specify the URL and parameters to start installation script
	if (sInstallBase.indexOf('www2.stlu.com') == -1) {
		// Since we arent installing from www2.stlu.com, then we have to do a double escape because of embedded query parameters
		// and the way the local install code handles them
		sInstallOnExit = escape(sInstallOnExit)
	}
	var sInstall = sInstallBase + ((sInstallBase.indexOf('?') == -1) ? '?' : '&') + '7StOnExit=' + escape(sInstallOnExit)

	// Convert runtime version to dotted delimited four part format
	var sMinVersion = sMinRTVersion + '.' + ((isMAC) ? '15' : (isNP) ? '5' : (isIE) ? '7' : '') + '.1'
	oCookieObj.document.cookie = 'dlStPlayer=' + sMinVersion + ';path=/;'

	if (isNP || (isIE && isMAC)) {
		var bSmartUpdate
		if (isNP && (isNP2 || isNP3 || isNP6 || isMAC))
			bSmartUpdate = -1
		else {
			bSmartUpdate = 0
			if (navigator.javaEnabled()) {
				trigger = netscape.softupdate.Trigger
				if (trigger.UpdateEnabled())
					bSmartUpdate = 1
				trigger = 0
			}
		}

		// Determine if we use manual install page or auto install page.
		// Netscape 4.05 or less may have expired Versign certificate
		var sParam
		if (bSmartUpdate == 1 && !isNP405) {
			// Use auto install page to download JAR file
			sParam = (isMAC) ? 'macplayer' : 'npplayer'
		} else {
			// Use manual install page to download self extracting installer
			sParam = (isMAC) ? 'macplayer' : 'npplayer&maninst=true'
		}
		var sNPInstallScript = sInstall + '&comp=' + sParam + '&new=t'
		oWindowObj.location = sNPInstallScript

	} else if (isIE) {
		// Use auto install page to download CAB files (user can choose manual from there)
		var sIEInstallScript = sInstall + ((!bPlayerNeedsFixup) ? '&comp=ieplayer' : '&comp=iefixup')
		oWindowObj.location = sIEInstallScript
	}
}

/******************************************************************************************
** Function:	Replace(sString, sSearch, sReplace)
** Inputs:		sString - string
**				sSearch - pattern to search for
**				sReplace - pattern to replace with
** Return:		String with pattern replaced
** Description:	Replace all occurrences of sPattern with sReplace
** Side Effect:	None
******************************************************************************************/
function Replace(sString, sSearch, sReplace) {
	var n
	while ((n = sString.indexOf(sSearch)) != -1)
		sString = sString.substring(0, n) + sReplace + sString.substring(n + sSearch.length, sString.length)
	return sString
}

/******************************************************************************************
** Function:	Trim(sString, sPattern)
** Inputs:		sString - string
**				sPattern - pattern to search for for trimming
** Return:		String with whitespace trimmed
** Description:	If sPattern is empty, trim trailing and leading whitespace. Otherwise, trim whitespace around
**				first occurrence of sPattern
** Side Effect:	None
******************************************************************************************/
function Trim(sString, sPattern) {
	var nPatLen = sPattern.length
	if (nPatLen == 0) {
		// Trim leading and trailing whitespace
		while (sString.charAt(0) == ' ' || sString.charAt(0) == '\t')
			sString = sString.substring(1, sString.length)
		while (sString.charAt(sString.length - 1) == ' ' || sString.charAt(sString.length - 1) == '\t')
			sString = sString.substring(0, sString.length - 1)

	} else {
		var nNdx = sString.indexOf(sPattern)
		if (nNdx != -1) {
			while (nNdx > 0 && (sLine.charAt(nNdx - 1) == ' ' || sLine.charAt(nNdx - 1) == '\t')) {
				sLine = sLine.substring(0, nNdx - 1) + sLine.substring(nNdx, sLine.length)
				nNdx--
			}
			while (nNdx < (sLine.length - nPatLen + 1) && (sLine.charAt(nNdx + nPatLen) == ' ' || sLine.charAt(nNdx + nPatLen) == '\t')) {
				sLine = sLine.substring(0, nNdx + nPatLen) + sLine.substring(nNdx + nPatLen + 1, sLine.length)
			}
		}
	}
	return sString
}

/******************************************************************************************
** Function:	LaunchPlayer(sRTVersion, sInstallBase, sPluginBase, sWindowType, nWidth, nHeight, sUrl, sStream, sOptions)
** Inputs:		sRTVersion - runtime version in two part dotted delimited format (e.g., 0501.0027)
**				sInstallBase - URL of page which presents installation script
**				sPluginBase - URL to the folder where plugin components are
**				sWindowType - 'full-screen', 'embedded' or 'standalone'
**				nWidth - presentation area width in pixels
**				nHeight - presentation area height in pixels
**				sUrl - url to folder containing starting stream in presentation
**				sStream - starting stream in presentation
**				sOptions - options string containing comma separated, optional name=value pairs. Values may be quote delimited.
**						yes is same as true. no is same as false. these options default to no or false or null string if not specified.
**					caption=string - string to display in title bar of full screen presentation
**					onexit=string - URL of where to exit to when stream completes
**					percentage=string - override 70% value used for pass/fail calculations
**					strategy=numeric: 0:default aicc reporting scheme. 2:aicc lesson_status does not reflect assessments.
**					whitebrush=yes|no|true|false - true if white background is to be used for agent
**					cookies=yes|no|true|false - true if cookies are to be included in object/embed tag
**					scorm=yes|no|true|false - true if variables are to be saved/restored to LMS via Javascript SCORM API
**					compress=yes|no|true|false - true if variables are to be compressed/decompressed when saved/restored to server
**					aicc=yes|no|true|false - true if variables are to be saved/restored to LMS via AICC. If set, then you must also set
**						aiccurl=string - URL of where to post AICC requests to
**						aiccsessionid=string - AICC session id
**					database=yes|no|true|false - true if variables are to be saved/restored to database on server. If set, then you must also set
**						databaseurl=string - URL of where to post database requests to
**					importvariables=string - semicolon delimited list of variable=value pairs to use to preset logic variables
** Return:		Null string if fails, else reference to instantiated player object
** Description:	Launch the player by generating an OBJECT tag for Internet Explorer or
**				or an EMBED tag for Netscape. The player must already have been installed.
** Side Effect:	None
******************************************************************************************/
function LaunchPlayer(sRTVersion, sInstallBase, sPluginBase, sWindowType, nWidth, nHeight, sUrl, sStream, sOptions) {
	// Create plugin folder based on sPluginBase
	DebugLog('LaunchPlayer: sRTVersion=' + sRTVersion + ' sInstallBase=' + sInstallBase + ' sPluginBase=' + sPluginBase + ' sWindowType=' + sWindowType + ' sUrl=' + sUrl + ' sStream=' + sStream + ' sOptions=' + sOptions, true)
	var sPluginFolder = sPluginBase
	if (sInstallBase.indexOf('www2.stlu.com') != -1) {
		// Plugin components are alwyas in this folder on www2.stlu.com
		var sPluginFolder = sPluginBase + 'PluginLatest'
	}

	// Ensure sUrl ends with a folder slash (or is to an .htm file within a folder) and sStream ends with .stm
	if (sUrl.length == 0 || sStream.length == 0)
		return ''
	if (sUrl.substring(sUrl.length - 1, sUrl.length) != '/')
		sUrl = sUrl + '/'
	if (sStream.substring(sStream.length - 4, sStream.length).toLowerCase() != '.stm')
		sStream = sStream + '.stm'

	// Parse optional parameters string. Split the comma separated option=value pairs
	var sCaption = ''
	var sOnExit = ''
	var bWhitebrush = false
	var bCookies = false
	var bScorm = false
	var bCompress = false
	var bDatabase = false
	var sDatabaseUrl = ''
	var bAICC = false
	var sAICCUrl = ''
	var sAICCSessID = ''
	var sImportVariables = ''
	var sPercentage = ''
	var sStrategy = ''
	var bHasAssessments = true
	var sPair = sOptions.split(',')
	for (i=0; i<sPair.length; i++) {
		// Trim whitespace from option=value
		sPair[i] = Trim(sPair[i], '')
		var n = sPair[i].indexOf('=')
		var sOption = sPair[i].substring(0, n)
		var sValue = sPair[i].substring(n+1, sPair[i].length)

		// Remove delimiting quotes in value, if any
		var sQuote = sValue.substring(0, 1)
		if (sQuote == '"' || sQuote == "'") {
			n = sValue.length
			if (sValue.substring(n-1, n) != sQuote)
				return ''
			sValue = sValue.substring(1, n-1)
		}

		// Parse option=value pair
		sOption = sOption.toLowerCase()
		if (sOption == 'caption')
			sCaption = unescape(sValue)
		else if (sOption == 'onexit')
			sOnExit = sValue
		else if (sOption == 'databaseurl')
			sDatabaseUrl = sValue
		else if (sOption == 'aiccurl')
			sAICCUrl = sValue
		else if (sOption == 'aiccsessionid')
			sAICCSessID = sValue
		else if (sOption == 'importvariables')
			sImportVariables = sValue
		else if (sOption == 'percentage')
			sPercentage = sValue
		else if (sOption == 'strategy')
			sStrategy = sValue
		else if (sOption == 'whitebrush' || sOption == 'cookies' || sOption == 'scorm' || sOption == 'compress' || sOption == 'aicc' || sOption == 'database' || sOption == 'hasassessments') {
			// These are boolean values
			sValue = sValue.toLowerCase()
			if (sValue == 'true' || sValue == 'yes')
				var bOpt = true
			else if (sValue == 'false' || sValue == 'no')
				var bOpt = false
			else
				return false
			if (sOption == 'whitebrush')
				bWhitebrush = bOpt
			else if (sOption == 'cookies')
				bCookies = bOpt
			else if (sOption == 'scorm')
				bScorm = bOpt
			else if (sOption == 'compress')
				bCompress = bOpt
			else if (sOption == 'aicc')
				bAICC = bOpt
			else if (sOption == 'database')
				bDatabase = bOpt
			else if (sOption == 'hasassessments')
				bHasAssessments = bOpt
		} else
				return ''
	}

	// Extract components of runtime version string
	if (isNP || (isIE && isMAC)) {
		// Convert runtime version to dotted delimited four part format
		var sPlayerVersion = sRTVersion + '.' + ((isMAC) ? '15' : (isNP) ? '5' : '') + '.1'

		// If for some reason player isnt installed, the browser may redirect us to a manual install page
		var sNPInstallScript = sInstallBase + ((sInstallBase.indexOf('?') == -1) ? '?' : '&') + 'comp=' + ((isMAC) ? 'macplayer' : 'npplayer&maninst=true') + '&new=t'
		if (isIE && isMAC)
			document.writeln('<a href="' + sNPInstallScript +'"><img border="0" src="L2PlayerFunctions_Clickhere.gif"></a>')
		document.writeln('<' + 'EMBED type=application/street-stream')
		document.writeln('	name=L2PlayerObj')
		if (!isMAC)
			document.writeln('	liveconnect="true"')
		document.writeln('	version="' + sPlayerVersion + '"')
		document.writeln('	pluginspage="' + sNPInstallScript + '"')
		document.writeln('	height=' + nHeight + ' width=' + nWidth)
		document.writeln('	window=' + sWindowType)
		document.writeln('	url="' + sUrl + '"')
		document.writeln('	stream="' + sStream + '"')
		if (sCaption.length)
			document.writeln('	caption="' + unescape(sCaption) + '"')
		if (sOnExit.length) {
			// Netscape 4.x often GPFs when player does onexit. Related to Netscape caching bug. Letting Javascript
			// load the onexit page seems to address the problem. Doesnt help on Netscape 3.x so in that case
			// let Netscape load the onexit page. I used to have to have this page loaded in a blank window but that
			// doesnt seem to be the case anymore. If it becomes so, insert a target='_blank' parameter in the EMBED.
			if (sOnExit.toLowerCase().indexOf('javascript:') == 0 || isNP3 || isMAC)
				document.writeln('	onexit="' + sOnExit + '"')
			else
				document.writeln('	onexit="javascript:window.location.href=\'' + sOnExit + '\'"')
		}
		if (bWhitebrush)
			document.writeln('	whitebrush="true"')
		if (bCookies)
			document.writeln('	cookie="' + document.cookie + '"')
		if (bScorm)
			document.writeln('	scormvariables="true"')
		if (bCompress)
			document.writeln('	compressvariables="true"')
		if (bAICC && sAICCUrl.length && sAICCSessID.length) {
			document.writeln('	aiccvariables="true"')
			document.writeln('	aiccconn="' + sAICCUrl + '"')
			document.writeln('	aiccsessid="' + sAICCSessID + '"')
		}
		if (bDatabase && sDatabaseUrl.length) {
			document.writeln('	databasevariables="true"')
			document.writeln('	databaseconn="' + sDatabaseUrl + '"')
		}
		if (sImportVariables.length)
			document.writeln('	importvariables="' + unescape(sImportVariables) + '"')
		if (sPercentage.length)
			document.writeln('	aiccpercentage="' + sPercentage + '"')
		if (sStrategy.length)
			document.writeln('	aiccstrategy="' + sStrategy + '"')
		document.writeln('	hasassessments="' + ((bHasAssessments) ? 'true' : 'false') + '"')
		document.writeln('>')

		// Create reference to player object
		L2PlayerObj = document.L2PlayerObj

} else if (isIE) {
		if (sRTVersion == '0501.0082') {
			// Install control to fixup certain things that were messed up in current player
			document.writeln('<' + 'OBJECT classid=clsid:8AF9A654-6644-46AD-A344-34B71839659E ')
			document.writeln('id=FixupPlayerObj ')
			document.writeln('codebase=' + sPluginFolder + '/fixst.cab' + '#Version=' + '1,0,0,1')
			document.writeln('height=' + '1' + ' width=' + '1' + '>')
			document.writeln('<' + '/OBJECT' + '>')
		}

		// Convert runtime version to comma delimited four part format
		var n = sRTVersion.indexOf('.')
		var sPlayerVersion = sRTVersion.substring(0, n) + ',' + sRTVersion.substring(n+1, sRTVersion.length) + ',7,1'
		document.writeln('<' + 'OBJECT classid=clsid:0B72CCA4-5F11-11D0-9CB5-0000C0EC9FDB ')
		document.writeln('id=L2PlayerObj ')
		document.writeln('codebase=' + sPluginFolder + '/streetnoagent7.cab' + '#Version=' + sPlayerVersion)
		document.writeln('height=' + nHeight + ' width=' + nWidth + '>')
		document.writeln('<' + 'param name=window value=' + sWindowType + '>')
		document.writeln('<' + 'param name=url value=' + sUrl + '>')
		document.writeln('<' + 'param name=src value=' + sStream + '>')
		if (sCaption.length)
			document.writeln('<' + 'param name=caption value="' + unescape(sCaption) + '">')
		if (sOnExit.length)
			document.writeln('<' + 'param name=onexit value="' + sOnExit + '">')
		if (bWhitebrush)
			document.writeln('<' + 'param name=whitebrush value="true">')
		if (bCookies)
			document.writeln('<' + 'param name=cookie value="' + document.cookie + '">')
		if (bScorm)
			document.writeln('<' + 'param name=scormvariables value="true">')
		if (bCompress)
			document.writeln('<' + 'param name=compressvariables value="true">')
		if (bAICC && sAICCUrl.length && sAICCSessID.length) {
			document.writeln('<' + 'param name=aiccvariables value="true">')
			document.writeln('<' + 'param name=aiccconn value="' + sAICCUrl + '">')
			document.writeln('<' + 'param name=aiccsessid value="' + sAICCSessID + '">')
		}
		if (bDatabase && sDatabaseUrl.length) {
			document.writeln('<' + 'param name=databasevariables value="true">')
			document.writeln('<' + 'param name=databaseconn value="' + sDatabaseUrl + '">')
		}
		if (sImportVariables.length)
			document.writeln('<' + 'param name=importvariables value="' + unescape(sImportVariables) + '">')
		if (sPercentage.length)
			document.writeln('<' + 'param name=aiccpercentage value="' + sPercentage + '">')
		if (sStrategy.length)
			document.writeln('<' + 'param name=aiccstrategy value="' + sStrategy + '">')
		document.writeln('<' + 'param name=hasassessments value="' + ((bHasAssessments) ? 'true' : 'false') + '">')
		document.writeln('<' + '/OBJECT' + '>')

		document.writeln('<' + 'SCRIPT LANGUAGE=VBScript' + '>')
		document.writeln('On Error Resume Next')
		document.writeln('Sub L2PlayerObj_OnEvent(ByVal sTag, ByVal sCallback, ByVal sEvent)')
		document.writeln('  Call Learn2_OnEvent(sTag, sCallback, sEvent)')
		document.writeln('End Sub')
		document.writeln('<' + '/SCRIPT' + '>')
	}

	// Return reference to player object
	return L2PlayerObj
}

function CreateDebugWindow() {
	// Create a debug window for Player
	var sWinOpt = 'status=yes,toolbar=yes,scrollbars=yes,resizable=yes,width=200,height=200,left=0,top=0'
	playerDebugWnd = window.open('', 'playerDebugWnd', sWinOpt)
	DebugLog('<HTML><TITLE>Player Debug Window</TITLE>', false)
	
	var oNow = new Date()
	DebugLog('<br>======== ' + oNow, true)
	DebugLog(sL2PlayerFunctionsVer, true)
	DebugLog(navigator.userAgent, true)
	DebugLog('href = ' + self.location.href, true)
	DebugLog('search = ' + self.location.search + '<br>', true)
	delete oNow
}

function DebugLog(sString, bEOL) {
	// Log data to debug window
	if (playerDebugWnd && !playerDebugWnd.closed) playerDebugWnd.document.writeln(sString + ((bEOL) ? '<br>' : ''))
}
