// -----------------------------------------------------------------------------
// This file is part of [nice] frame
// (c) 2007 Dynamic Media eLearning GmbH
// All rights reserved.
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// $Id: player.js 1585 2008-02-11 10:44:45Z dynamicmedia\Arnold $
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Imports
// -----------------------------------------------------------------------------

NICE.include("util.Browser");

NICE.use("event.EventRegistry");
NICE.use("util.String");
NICE.use("util.Array");
NICE.use("util.DOMQuery");
NICE.use("util.SWFMovie");
NICE.use("ui.Button");
NICE.use("ui.CheckButton");
NICE.use("ui.ModalDialog");
NICE.use("ui.DropdownList");
NICE.use("ui.ProgressBar");
NICE.use("debug.DebugConsole");
NICE.use("debug.DebugHelper");

// -----------------------------------------------------------------------------
// Globals
// -----------------------------------------------------------------------------

// Set up the global Player object. This object encapsulates all player
// information and functionality.
var Player = {
	
	// Version information -----------------------------------------------------
	majorVersion:           1,
	minorVersion:           1,
	bugfixVersion:          0,
	revision:              "$Rev: 1585 $",
	
	// The course ID of the loaded course --------------------------------------
	courseID:             null,
	
	// The content frame -------------------------------------------------------
	contentFrame:         null,
	
	// Arguments ---------------------------------------------------------------
	args:                 null,
	
	// Custom events -----------------------------------------------------------
	events:               null,
	
	// Interface buttons -------------------------------------------------------
	buttons:              {},
	
	// Progress bar ------------------------------------------------------------
	progress:             null,
	
	// Language selection ------------------------------------------------------
	langSelect:           null,
	
	// Reference to main SWF ---------------------------------------------------
	main:                 null,
	
	// Reference to host SWF ---------------------------------------------------
	host:                 null,
	
	// External SCORM API ------------------------------------------------------
	externalAPI:          null,
	
	// Debug console -----------------------------------------------------------
	debug:                null,
	
	// Cache for settings ------------------------------------------------------
	settings:             {},
	
	// Fast forward ------------------------------------------------------------
	fastforward:          1,
	
	// Exception handling ------------------------------------------------------
	handleException:      function(e) {
		
		if(window.console) console.error(e);
		else alert(e);
		
	},
	
	// Initialization function -------------------------------------------------
	initialize:           function() {
		
		try {
			// Create the debug console
			if(this.args.debug) {
				this.debug = new NICE.debug.DebugConsole(window.console);
				// Additional debugging commands
				this.debug.defineCommand("version", function() {
					Player.debug.log(Player.getVersion());
				}, "Print the player version");
			}
			
			// Set a reference to the content frame
			this.contentFrame = $$("content-frame");
			
			// Hide/show function for content frame
			this.contentFrame.hide = function() {
				this.style.visiblity = "hidden";
				this._width = this.width;
				this.width = 0;
			};
			this.contentFrame.show = function() {
				this.style.visiblity = "visible";
				if(this._width) this.width = this._width;
			};
			
			// Set up the buttons
			this._setupButtons();
			
			// Set up the progressbar
			this.progress = new NICE.ui.ProgressBar("nice-progress", {
				identifier:    "progress-bar"
			});
			this.progress._label = "";
			
			// Set up language selection
			this.langSelect = new NICE.ui.DropdownList("nice-container", {
				identifier:           "nice-langselect",
				selectchangehandler:  function(item) {
					var id = item.id;
					var langid = id.substr(id.lastIndexOf('-') + 1);
					Player.main.SetActiveLanguage(langid);
				},
				showhandler:          function() {
					Player.contentFrame.hide();
				},
				hidehandler:          function() {
					Player.contentFrame.show();
				}
			});
		} catch(e) {
			this.handleException(e);
		}
		
	},
	
	setFeatures:         function(supports) {
		
		try {
			var features = ["pause", "print", "prev", "next"];
			var value;
			if(typeof(supports) == "object") {
				for(var i = 0; i < features.length; i++) {
					value = features[i];
					if(typeof(supports[value]) == "undefined") continue;
					if(supports[value]) {
						Player.buttons[value].enable();
					} else {
						Player.buttons[value].disable();
					}
				}
			}
		} catch(e) {}
		
	},
	
	// Messagebox --------------------------------------------------------------
	showMessageBox:         function(title, message, type, buttoncaption) {
		
		var msg = new NICE.ui.ModalDialog({
			identifier:   "nice-msgbox",
			callback:     function() {
				Player.contentFrame.show();
			}
		});
		var ntitle = document.createElement("h3");
		var nmsg = document.createElement("p");
		var nbuttons = document.createElement("div");
		var icon = document.createElement("div");
		
		msg.addElement("msgbox-icon", icon);
		if(typeof(type) != "undefined") {
			icon.className = type;
		}
		if(title) {
			ntitle.appendChild(document.createTextNode(title));
			msg.addElement("msgbox-title", ntitle);
		}
		if(message) {
			var para = message.split("\n");
			var node = null;
			for(var i = 0; i < para.length; i++) {
				node = document.createElement("p");
				node.appendChild(document.createTextNode(para[i]));
				nmsg.appendChild(node);
			}
			msg.addElement("msgbox-message", nmsg);
		}
		msg.addElement("msgbox-buttons", nbuttons);
		
		var ok = new NICE.ui.Button("msgbox-buttons", {
			identifier:   "msgbox-ok",
			clickhandler: function() { msg.destroy(); },
			caption:      buttoncaption
		});
		msg.addElement(null, ok);
		
		// Hide the content frame
		Player.contentFrame.hide();
		
		msg.show();
		
	},
	
	// Glossary term -----------------------------------------------------------
	showGlossaryTerm:        function(term) {
		
		var lang = Player.main.GetActiveLanguage();
		var gloss = new NICE.ui.ModalDialog({
			identifier:   "nice-glossaryterm",
			callback:     function() {
				Player.contentFrame.show();
			}
		});
		// Close button
		var buttons = document.createElement("div");
		gloss.addElement("glossaryterm-buttons", buttons);
		var ok = new NICE.ui.Button("glossaryterm-buttons", {
			identifier:   "glossaryterm-close",
			clickhandler: function() { gloss.destroy(); },
			caption:      "x"
		});
		gloss.addElement(null, ok);
		// Content iframe
		var frame = document.createElement("iframe");
		frame.frameBorder = "0";
		frame.src = "./resources/_glossary/" + lang + "/" + term + ".html";
		gloss.addElement("glossaryterm-frame", frame);
		
		// Hide the content frame
		Player.contentFrame.hide();
		
		gloss.show();
		
	},
	
	// Skin --------------------------------------------------------------------
	skin: {
		
		// Skin initialization -------------------------------------------------
		// A player skin will override this method if necessary to make skin
		// specific initializations.
		initialize:          function() {},
		
		// Size handling -------------------------------------------------------
		// A player skin will override this method if necessary to make skin
		// specific size adjustments upon initialization and on resize of the
		// browser window.
		setSize:             function() {},
		
		// Host flash ----------------------------------------------------------
		showHostFlash:       function(mode, size) {},
		
		// User preference setter ----------------------------------------------
		// Stores a user preference as key/value pair
		setUserPref:         function(key, value) {
			
			Player.main.SetUserPref(this.id + "." + key, value);
			
		},
		
		// User preference getter ----------------------------------------------
		// Retrieves a stored user preference
		getUserPref:         function(key) {
			
			return Player.main.GetUserPref(this.id + "." + key);
			
		},
		
		// Version string ------------------------------------------------------
		getVersion:          function() {
			
			return Player.skin.name + " " + Player.skin.version;
			
		}
		
	},
	
	// Version -----------------------------------------------------------------
	getVersion:          function() {
		return (this.majorVersion + "."
			+ this.minorVersion	+ "."
			+ this.bugfixVersion + "."
			+ this.revision);
	},
	
	// Internal functions ------------------------------------------------------
	_setupButtons:       function() {
		
		var id = null;
		// Retrieve list of button containers and create buttons
		$("#nice-options li").each(function(index, node) {
			id = node.id;
			Player.buttons[id.substr(id.indexOf("-") + 1)] =
				new NICE.ui.Button(node, {
					identifier: "b-" + id,
					caption:    id,
					classname:  "nice-button"
				}
			);
		});
		
		Player.buttons.pause.disable();
		Player.buttons.play.disable();
		
		// Retrieve list of checkbutton containers and create checkbuttons
		$("#nice-add-options li").each(function(index, node) {
			id = node.id;
			Player.buttons[id.substr(id.indexOf("-") + 1)] =
				new NICE.ui.CheckButton(node, {
					identifier: "b-" + id,
					caption:    id,
					classname:  "nice-button"
				}
			);
		});
		
		// Set up button click handlers
		var handlers = {
			// Play
			play:      function() {
				if(this._gotoNext === true) {
					Player.main.IssueSequencingRequest("forward");
				} else {
					Player.events.emit("play");	
				}
			},
			// Pause
			pause:     function() {
				Player.events.emit("pause");
			},
			// Forward
			next:      function() {
				Player.main.IssueSequencingRequest("forward");
			},
			// Back
			prev:      function() {
				Player.main.IssueSequencingRequest("backward");
			},
			// Home
			home:      function() {
				Player.main.LoadModule("startPage");
			},
			// Profiles
			profiles:  function() {
				Player.main.LoadModule("profiles");
			},
			// Glossary
			glossary:  function() {
				Player.main.IssueSequencingRequest("choice", "DM_GLOSSARY");
			},
			// Audio
			audio:     function(checked) {
				Player.main.SetCourseSetting("audio", checked.toString());
				Player.events.emit("audiomodechanged", checked);
			},
			// Text
			text:      function(checked) {
				Player.main.SetCourseSetting("text", checked.toString());
				Player.events.emit("textmodechanged", checked);
			},
			// Print
			print:     function() {
				var wnd = Player.contentFrame.contentWindow.window;
				if(wnd.Print) wnd.Print();
			},
			// Status
			status:    function() {
				Player.main.LoadModule("status");
			},
			// Help
			help:      function() {
				Player.main.LoadModule("help");
			},
			// Exit
			exit:      function() {
				/*@if(@_win32)
				window.close();
				@else @*/
				var msg =
					(Player._itemLock === true ? "end-warning" : "end-message");
				var caption = Player.main.GetLangString("i-logic-100");
				var button = Player.main.GetLangString("end-ok");
				msg = Player.main.GetLangString(msg);
				Player.showMessageBox(caption, msg, "info", button);
				/*@end @*/
			}
		}
		for(var button in handlers) {
			Player.buttons[button].setHandler("click", handlers[button]);
		}

	}
	
}

// -----------------------------------------------------------------------------
// Events
// -----------------------------------------------------------------------------

// Create EventRegistry --------------------------------------------------------
Player.events = new NICE.event.EventRegistry();

// -----------------------------------------------------------------------------
// Ad hoc
// -----------------------------------------------------------------------------

(function() {
	// Extract revision
	var rev = /\$Rev:\s*(\d+)\s*\$/.exec(Player.revision);
	Player.revision = (rev ? rev[1] : 0);
	// Create default events
	var events = [
		"initializing", "parsingcompleted", "initialized",
		"sizechanged", "languagechanged", "coursemodechanged",
		"audiomodechanged", "textmodechanged", "progresschanged",
		"fastforwardchanged",
		"beforenavigation", "navigation",
		"beforeloadmodule", "loadmodule",
		"play", "pause",
		"itemlock", "toclock",
		"coursefinished", "objectfinished"
	];
	for(var i = 0, len = events.length; i < len; i++) {
		Player.events.createEvent(events[i]);
	}
})();

// -----------------------------------------------------------------------------
// Attach resize listener
// -----------------------------------------------------------------------------

Browser.attachListener(window, "resize", function() {
	
	var sz = Browser.elementSize(window);
	// Emit the sizechanged event
	Player.events.emit("sizechanged", sz[0], sz[1]);
	
});

// -----------------------------------------------------------------------------
// Attach onload listener
// -----------------------------------------------------------------------------

Browser.attachListener(window, "load", function() {
	
	// Create the splash screen ------------------------------------------------
	var image = document.createElement("div");
	var version = document.createElement("div");
	version.appendChild(document.createTextNode(
		"Version: " + Player.getVersion()));
	version.appendChild(document.createElement("br"));
	version.appendChild(document.createTextNode(Player.skin.getVersion()));
	Player.splashScreen = new NICE.ui.ModalDialog({
		identifier: "nice-splashscreen"
	});
	
	Player.splashScreen.addElement("nice-splashscreen-image", image);
	Player.splashScreen.addElement("nice-splashscreen-version", version);
	
	Player.splashScreen._initialized = false;
	Player.splashScreen.show();
	
	// For some reason, IE doesn't update the window content and the splash
	// screen won't show up. An update can be forced using window.scrollBy().
	/*@if(@_win32)
	window.scrollBy(0, 1);
	window.scrollBy(0, -1);
	@end @*/
	
	// Hide the splash screen after initialization -----------------------------
	var timer = new NICE.util.TimedInterval(1000, function(i) {
		if(Player.splashScreen._initialized) {
			Player.splashScreen.destroy();
			return false;
		}
		return true;
	}, 0);
	timer.start();
	
	// Parse player arguments --------------------------------------------------
	Player.args = Browser.getArgs();
	
	// Check for external SCORM API --------------------------------------------	
	var API = null;
	var APIVersion = "1.2";
	
	function FindAPI(win) {
		while((win.API_1484_11 == null)
		&& (win.API == null)
		&& (win.parent != null)
		&& (win.parent != win)) {
			win = win.parent;
		}
		if(win.API_1484_11) {
			API = win.API_1484_11;
			APIVersion = "1.3";
		} else {
			API = win.API;
		}
	}
	
	function GetAPI (win) {

		FindAPI(win);
		if((API == null) && (win.opener != null)) {
			FindAPI(win.opener);
		}
	}
	
	GetAPI(window);
	
	if(API) {
		Player.externalAPI = API;
		Player._externalAPIVersion = APIVersion;
	}
	
	// Embed main.swf ----------------------------------------------------------
	var mainflashvars = {};
	if(Player.args.profile) {
		mainflashvars["profile"] = Player.args.profile;
	}
	
	var movie = new NICE.util.SWFMovie("./swf/main.swf", {
		width:  "100%",
		height: "100%",
		name:   "niceMain",
		id:     "niceMain"
	});
	movie.addParam("wmode", "transparent");
	movie.addParam("allowscriptaccess", "always");
	movie.addParam("flashvars", mainflashvars);
	movie.embed("nice-toc");
	
	// General initializations -------------------------------------------------
	Player.initialize();
	// Skin specific initializations -------------------------------------------
	Player.skin.initialize();
	// Skin-specific size adjustments ------------------------------------------
	Player.skin.setSize();
	
	Player.events.registerHook("sizechanged", function() {
		Player.skin.setSize();
	});
	
});

// Try to finish the SCORM session when the browser window is closed
Browser.attachListener(window, "unload", function(evt) {
	
	if(Player.externalAPI) {
		if(Player._externalAPIVersion == "1.2") {
			Player.externalAPI.LMSFinish("");
		} else {
			Player.externalAPI.Terminate("");
		}
	}
	
});

// -----------------------------------------------------------------------------
// Event hooks
// -----------------------------------------------------------------------------

Player.events.registerHook("initializing", function(event) {
	
	// Create a reference to the SCORM API -------------------------------------
	var toc = $$("nice-toc");
	if(toc) {
		/*@if(@_win32)
		API_1484_11 = new SCORMWrapper(window.niceMain);
		Player.host = window.niceHost;
		@else @*/
		API_1484_11 = new SCORMWrapper(document.getElementById("niceMain"));
		Player.host = document.getElementById("niceMain");
		/*@end @*/
		// The SCORM 1.2 API will be emulated by the SCORM 2004 adapter
		API = API_1484_11;
		Player.main = API_1484_11.API();
	} else {
		throw new Error("Could not locate SCORM 2004 API");
	}
	
});

Player.events.registerHook("parsingcompleted", function(event) {
	
	var languages = Player.main.GetCourseLanguages();
	var current = Player.main.GetActiveLanguage();
	var audio, text;
	
	// Get the course ID -------------------------------------------------------
	Player.courseID = Player.main.GetCourseID();
	// Insert language entries -------------------------------------------------
	languages.each(function(i, value) {
		Player.langSelect.addItem({
			identifier:   "lang-" + value,
			classname:    "langselect-item lang-" + value,
			selected:     (value === current ? true : false)
		});
	});
	
	// Embed host flash --------------------------------------------------------
	var widgets = {
		search: "./swf/search.swf",
		note:   "./swf/notes.swf",
		filter: "./swf/filter.swf"
	}
	var embed = [];
	for(var widget in widgets) {
		if(Player.main.GetCourseSetting(widget) != "false") {
			embed.push(widgets[widget]);
		}
	}
	var hostflashvars = {
		myClient:   embed.join(",")
	};
	var search = new NICE.util.SWFMovie("./swf/host.swf", {
		width:  "100%",
		height: "100%",
		name:   "niceHost",
		id:     "niceHost"
	});
	search.addParam("wmode", "transparent");
	search.addParam("allowscriptaccess", "always");
	search.addParam("FlashVars", hostflashvars);
	search.embed("nice-hostflash");
	
	if(embed.length == 0) Player.skin.showHostFlash("hide");
	
});

Player.events.registerHook("initialized", function(event) {
	
	var value = true;
	var audio, text;
	
	// Enable/disable player functions -----------------------------------------
	var settings = [
		"prev", "play", "pause", "next", "help",
		"print", "home", "glossary", "status", "profiles"
	];
	
	for(var i = 0; i < settings.length; i++) {
		value = Player.main.GetCourseSetting(settings[i]);
		if(value == "false") {
			Player.buttons[settings[i]].hide();
			// Cache the settings
			Player.settings[settings[i]] = false;
		} else {
			Player.settings[settings[i]] = true;
		}
	}
	
	audio = Player.main.GetCourseSetting("audio");
	Player.settings.audio = (audio == "false" ? false : true);
	Player.buttons.audio.setChecked((audio == "false" ? false : true));
	if(!Player.main.CheckModifiableCourseSetting("audio")) {
		Player.buttons.audio.hide();
	}
	
	text = Player.main.GetCourseSetting("text");
	Player.settings.text = (text == "false" ? false : true);
	Player.buttons.text.setChecked((text == "false" ? false : true));
	if(!Player.main.CheckModifiableCourseSetting("text")) {
		Player.buttons.text.hide();
	}
	
	// Set onclick for status bar ----------------------------------------------
	if(Player.settings.status) {
		Player.progress.DOMNode().className = "clickable";
		Browser.attachListener(
			Player.progress.DOMNode(), "click", function() {
				Player.main.LoadModule("status");
			});
	}
	
	// Splashscreen can be hidden ----------------------------------------------
	Player.splashScreen._initialized = true;
	
});

Player.events.registerHook("languagechanged", function(event, lang) {
	
	var text = null;
	var id = null;

	// Buttons -----------------------------------------------------------------
	var mapping = {
		"b-option-home":      function(id) {
			return Player.main.GetModuleTitle("startPage");
		},
		"b-option-glossary":  function(id) {
			return Player.main.GetItemTitle("DM_GLOSSARY");
		},
		"b-option-audio":     function(id) {
			return [
				Player.main.GetLangString(id),
				Player.main.GetLangString(id + "-unchecked")
			];
		},
		"b-option-text":      function(id) {
			return [
				Player.main.GetLangString(id),
				Player.main.GetLangString(id + "-unchecked")
			];
		}
	}
	for(var button in Player.buttons) {
		id = Player.buttons[button].getID();
		if(mapping[id]) {
			text = mapping[id](id);
		} else {
			text = Player.main.GetLangString(id);
		}
		if(text) {
			Player.buttons[button].setCaption(text);
			Player.buttons[button].setTooltip(text);
		}
	}
	
	// Language selection ------------------------------------------------------
	for(var i = 0; i < Player.langSelect.itemCount(); i++) {
		id = Player.langSelect.items(i).id;
		id = id.substr(id.lastIndexOf('-') + 1);
		text = Player.main.GetLangString(id);
		if(text) {
			Player.langSelect.items(i).setCaption(text);
		}
	}
	
	if(Player.langSelect.itemCount() > 1) {
		Player.langSelect.show();
	}
	
	// Progress bar ------------------------------------------------------------
	// Cache the langstring since since ExternalInterface-calls don't work in
	// the progresschanged-event.
	Player.progress._label = Player.main.GetLangString("b-option-status");
	Player.progress.setTooltip(
		Player.progress._label + ": " +
		Player.progress.getProgress() + "%");
	
	// Host flash --------------------------------------------------------------
	CallRemote("niceHost", { funct: "OnLanguageChanged", p1: lang });
	
});

Player.events.registerHook("progresschanged", function(event, progress) {
	Player.progress.setProgress(progress);
	Player.progress.setTooltip(
		Player.progress._label + ": " + progress + "%");
});

Player.events.registerHook("navigation", ResetFeatures);
Player.events.registerHook("loadmodule", ResetFeatures);

Player.events.registerHook("itemlock", function(event, value) {
	Player._itemLock = (value == "true" ? true : false);
	ForwardEvent(event, value);
});
Player.events.registerHook("toclock", ForwardEvent);

Player.events.registerHook("play", function() {
	Player.buttons.play.disable();
	Player.buttons.pause.enable();
	Player.buttons.play._gotoNext = false;
});

Player.events.registerHook("pause", function() {
	Player.buttons.pause.disable();
	Player.buttons.play.enable();
	Player.buttons.play._gotoNext = false;
});

Player.events.registerHook("objectfinished", function() {
	Player.events.emit("pause");
	Player.buttons.play._gotoNext = true;
});

// -----------------------------------------------------------------------------
// Flash API
// -----------------------------------------------------------------------------

// Event emitter ---------------------------------------------------------------
// Used by flash movies to emit custom events
function EmitEvent(event) {
	
	Player.events.emit.apply(Player, arguments);
	
}

function EmitDeferredEvent(event) {
	
	var args = [];
	for(var i = 0; i < arguments.length; i++) args[i] = arguments[i];
	
	var timer = new NICE.util.TimedInterval(50, function() {
		Player.events.emit.apply(Player, args);
	}, 1);
	timer.start();
	
}

function ForwardEvent(event, state) {
	
	Player.main.OnEvent(event, state);
	
}

function ResetFeatures() {
	
	Player.events.emit("play");
	var disabled = ["pause", "play", "print"];
	disabled.each(function(key, value) {
		Player.buttons[value].disable();
	});
	// Enable prev/next-buttons. These can explicitly be disabled by
	// a content object and should be enabled by default.
	var enabled = ["prev", "next"];
	enabled.each(function(key, value) {
		Player.buttons[value].enable();
	});
	
}

// Title -----------------------------------------------------------------------
// Used to change the displayed course title
function SetTitle(title) {
	
	var tag = $$("title-caption");
	
	tag.replaceChild(document.createTextNode(title), tag.firstChild);
	tag = $_("title")[0];
	tag.replaceChild(document.createTextNode(title), tag.firstChild);
	
}

// MessageBox ------------------------------------------------------------------
// Used to display a modal message box
function MessageBox(title, message, type, buttoncaption) {
	
	Player.showMessageBox(title, message, type, buttoncaption);
	
}

// External SCORM API ----------------------------------------------------------
// Used to call the API methods of an external SCORM adapter
function CallExternalAPI(api, p1, p2) {
	
	var args = [];
	var arg = null;
	var retval = false;
	
	if(Player.externalAPI) {
		switch(api) {
			case "GetAPIVersion":
				return Player._externalAPIVersion;
			default:
				try {
					p1 = (p1 === String.fromCharCode(0x200B) ? "" : p1);
					if(p2) {
						p2 = (p2 === String.fromCharCode(0x200B) ? "" : p2);
						retval = "" + String(Player.externalAPI[api](p1, p2));
					} else {
						retval = "" + String(Player.externalAPI[api](p1));
					}
					if(retval === false && window.console) {
						api =
							(Player._externalAPIVersion == "1.2" ? "LMS" : "");
						api += "GetLastError";
						console.error("SCORM Error: " +
							Player.externalAPI[api]());
					}
					return retval;
				} catch(e) {
					return false;
				}
		}
	}
	
	return false;
	
}

// Generic communication wrapper for Flash movies ------------------------------
// Used to exchange data between different Flash movies in a page
function CallRemote(movie, param) {

	try {
		return document.getElementById(movie).CallRemote(param);
	} catch(e) {
		try {
			if(window[movie]) return window[movie].CallRemote(param);
		} catch(e) {
			if(window.console) console.error(e.message);
		}
	}
	
	return null;

}

// IssueNavigationRequest function wrapper -------------------------------------
function IssueSequencingRequest(mode, id) {

	return Player.main.IssueSequencingRequest(mode, id);

}

// Host Flash API --------------------------------------------------------------
function MinimizeHostFlash() {
	
	return Player.skin.showHostFlash("minimize");
	
}

function MaximizeHostFlash() {
	
	return Player.skin.showHostFlash("maximize");
	
}

function GetCourseTitle() {
	
	return Player.main.GetCourseTitle();
	
}

// Logging API -----------------------------------------------------------------
function LogToConsole(param, type) {
	
	if(Player.debug) Player.debug[type](param);
	
}

// Retrieve stored user preferences --------------------------------------------
function GetFlashPref(param) {

	return Player.skin.getUserPref(param);
	
}

