(function($){
	jQuery.fn.presentationLoader = function(options){
		var $pl = jQuery(this);
		
		var options = jQuery.extend({

		},options);
		
		var start_time = 0;
		var currently_loaded_percent = 0;
		var loaded = false;
		var cancelled = false;
		
		var $loader = $pl.children(".loader_inner").children(".bar_wrapper");
		var $loader_bar = $pl.children(".loader_inner").children(".bar_wrapper").children(".bar_inner");
		var $loader_text = $pl.children(".loader_inner").children(".info_text");
		var $loader_console = $pl.children(".loader_inner").children(".console");
		var $flash_info = $pl.children(".loader_inner").children(".flash_info");
		var $loader_browser_info = $pl.children(".loader_inner").children(".browser_incompatibility_info");
		
		function initialize(){
			startTick();
			start_time = (new Date).getTime();
			setup_selectors();
			setup_metadata();
			setup_events();
			printMsgToLoadingConsole("Loader Initialized 0ms");
			checkFlash(10,0,0);
			setLoaderBarToPercent(0);
		};
		
		function setup_selectors(){
			
		};
		
		function setup_metadata(){
			
		};
		
		function setup_events(){
			$pl.bind("loadStatusEvent",_loadStatusEventHandler);
		};
		
		function _loadStatusEventHandler(e,ui){
			if(!cancelled){
				currently_loaded_percent = currently_loaded_percent + ui.pct;
				setLoaderBarToPercent(currently_loaded_percent,checkComplete);
				if(ui.msg == "Streetview Loading"){
					runBrowserDetection();
				};
				printMsgToLoadingConsole(ui.msg + " " + ((new Date).getTime() - start_time) + "ms");
			};
		};
		
		function startTick(){
			setTimeout("tick()",10);
		};
		
		$pl.tick = function(){
			$loader_console.children("p:first").text($loader_console.children("p:first").text() + ".");
			if(loaded != true){
				setTimeout("tick()",100);
			}
		};
		
		function checkComplete(){
			if(currently_loaded_percent >= 100){
				$pl.trigger("loaderComplete");
				loaded = true;
				hideCurtain();
			};
		};
		
		function hideCurtain(){
			//fixFlashIE();
			$pl.children(".loader_inner").animate({"opacity":"0.0"},500,function(){
				$pl.animate({"opacity":"0.0"},1000,function(){
					$pl.hide();
				})
			})
		}
		
		function runBrowserDetection(){
			// hide loader for FF on Win
			if (jQuery.browser.firefox() && jQuery.browser.win()) {
				$pl.hide();
			};
			// show incompatible browser info for everything except IE, FF, webkit (Safari / Chrome) (requires jquery 1.4, too risky to update)
			// if (!jQuery.browser.firefox() && !jQuery.browser.msie() && !jQuery.browser.webkit()) {
			// 	$loader_browser_info.show();
			// }
		};
		
		function checkFlash(p,s,t){
			printMsgToLoadingConsole("Checking Flash Version "+p+"."+s+"."+t);
			printMsgToLoadingConsole("Detected Flash Version " + GetSwfVer());
			var hasProductInstall = DetectFlashVer(6, 0, 65);
			var hasReqestedVersion = DetectFlashVer(p, s, t);
			if ( hasProductInstall && !hasReqestedVersion ) {
				expressInstallFlash();
				return false;
			} else if (!hasProductInstall) {
				cancelLoader();
				$flash_info.show();
				return false;
			} else {
				printMsgToLoadingConsole("Flash Version "+p+"."+s+"."+t+" Good!");
				return true;
			};
		};
		
		function cancelLoader(){
			$loader.hide();
			$loader_text.hide();
			cancelled = true;
		};
		
		function expressInstallFlash(){
			$flash_info.show();
			cancelLoader();
			var flashvars = {};
			var params = { wmode : "transparent", allowscriptaccess : "sameDomain" };
			var attributes = { id : "express-installer" };
			swfobject.embedSWF("/assets/playerProductInstall_ns11mm.swf", "express-installer", "215px", "138px", "6.0.65", "/assets/expressInstall_ns11mm.swf", flashvars, params, attributes);
		};
		
		function setLoaderBarToPercent(percent,callback){
			$loader_bar.stop().animate({"width":percent+"%"},1000,callback);
		};
		
		function printMsgToLoadingConsole(msg){
			$loader_console.prepend("<p>"+msg+"</p>")
		};
		
		initialize();
		return $pl;
	}	
})(ns11mmPresentation);