SoccerPowerLoader = {};

(function() {
	var State = { uninitialized : 0, updateLoaderDll : 1, updateGame : 2, upToDate : 3, needsPlugin : 4 }
	var _gameUpToDateFunc = null;
	var _state = State.uninitialized;
	var _autoStart = null;
	var _started = false;
	
	var _gameFileList = null;
	var _gameServerVersion = null;
	var _gameServerRoot = null;
	var _loaderDllFileList = null;
	var _loaderDllServerVersion = null;
	var _loaderDllServerRoot = null;
	var _topLoaderServerVersion = null;
	var _gameName = null;	
	var _domainPattern = null;
	var _domainSignature = null;
	
	var _gameSessionVersion = null;
	var _errorRetries = 3;
	var _errorMessage = null;
	var _errorOccured = false;
	
	var _downloadWindowPrefetch = null;
	var _progressWindowPrefetch = null;
	
	
	function constructDownloadTaskList(game, serverRoot, fileList) {
		var tasks = [];
		
		if (serverRoot.substr(serverRoot.length - 1, 1) != "/") {
			serverRoot = serverRoot + "/";
		}

		for( var i=0; i < fileList.length; i++ ) {
			var sourceoffset = "";
			
			if (typeof(fileList[i].sourceoffset) != "undefined")
				sourceoffset = fileList[i].sourceoffset;
				
			tasks.push(PowerLoader.constructDownloadTask(game, serverRoot + sourceoffset + fileList[i].filename, "", fileList[i].signature, fileList[i].size, fileList[i].filename));
		}
		
		return tasks;
	}
	
	
	function startTask(task) {
		var result = PowerLoader.startTask(task);
		if( result != null && typeof(result.error) != "undefined" )
			loaderError(result.error);
	}
	
	
	function gameUpdateComplete() {
		_gameSessionVersion = _gameServerVersion;
		jQuery.get("ajax.php?p=setgamesessionversion&version=" + _gameServerVersion, null, function(data) { goToNextState(); });
	}
	
	
	function updateProgressIcon(event, arg) {
		// This function is from powerloader.js
		setLoaderIconWorking("Updating...", arg.totalProgress);
	}
	
	
	function bindUpdateProgressIcon() {
		//console.log('bindUpdateProgressIcon()');
		bindPowerLoaderEvent("progress", updateProgressIcon);
	}
	
	
	function unbindUpdateProgressIcon() {
		//console.log('unbindUpdateProgressIcon()');
		unbindPowerLoaderEvent("progress", updateProgressIcon);
	}
	
	
	function fetchFilesInfo() {
		//console.log('fetchFilesInfo()');
		var fileListDownloadedFunc = function(data) {
			//console.log('fileListDownloadedFunc(...)')
			parseFilesInfo(data);
			goToNextState();
		}
		
		jQuery.getJSON("ajax.php?p=fileinfo", null, fileListDownloadedFunc);
	}
	
	
	function setState(newState) {	
		unbindUpdateProgressIcon();
	
		switch(newState) {
		
		case State.uninitialized:
			//console.log('setState(State.uninitialized');
			throw "SoccerPowerLoader.setState(), tried to set state back to uninitialized";
			return;
			
		case State.updateLoaderDll:
			//console.log('setState(State.updateLoaderDll)');
			// Get new loader dll, continue to next state when dll is reloaded
			var tasks = constructDownloadTaskList("", _loaderDllServerRoot, _loaderDllFileList);
			tasks.push(PowerLoader.constructUpgradeTask());
			
			PowerLoader.stopTask();
			bindUpdateProgressIcon();
			bindPowerLoaderEventOnce("task_succeeded", function() { bindPowerLoaderEventOnce("loader_initialized", goToNextState); });			
			startTask(tasks);
			break;
			
		case State.updateGame:
			//console.log('setState(State.updateGame)');
			// Get game files, update game version in session when done and move on to next state (hopefully upToDate)
			var tasks = constructDownloadTaskList(_gameName, _gameServerRoot, _gameFileList);
			
			PowerLoader.stopTask();
			bindUpdateProgressIcon();
			bindPowerLoaderEventOnce("task_succeeded", gameUpdateComplete);
			startTask(tasks);
			break;
			
		case State.upToDate:
			//console.log('setState(State.upToDate)');
			// Schedule file info update in 5 minutes, to see if game is updated on the server
			// Removed since it may screw up cups
			// TODO: Think about this
			// window.setTimeout(fetchFilesInfo, 1000 * 300);
			setLoaderIconIdle();
			
			if (_gameUpToDateFunc != null) {
				_gameUpToDateFunc();
				_gameUpToDateFunc = null;
			}
			
			_errorRetries = 3;
			_errorOccured = false;
			break;
			
		case State.needsPlugin:
			//console.log('setState(State.needsPlugin)');
			// Do nothing, we could try to detect the plugin here, but we wait until the popup is up
			break;
			
		default:
			throw "SoccerPowerLoader.setState(), tried to set unknown state " + newState;
			return;
		}
		
		_state = newState;
	}
	
	
	function goToNextState() {
		if (_topLoaderServerVersion > PowerLoader.getTopLoaderVersion()) {
			// Need to download new plugin
			setState(State.needsPlugin);
		} else if (_loaderDllServerVersion > PowerLoader.getLoaderDllVersion()) {
			// Loader DLL is not up to date, get it
			setState(State.updateLoaderDll);
		} else if (_gameServerVersion != _gameSessionVersion) {
			// We need to get the game files
			setState(State.updateGame);
		} else {
			// We are already up to date! No need to check files
			setState(State.upToDate);
		}
	}
	
	
	function parseFilesInfo(data) {
		_gameFileList = data['gameFileList'];
		_gameServerVersion = data['gameServerVersion'];
		_gameServerRoot = data['gameServerRoot'];
		_loaderDllFileList = data['loaderDllFileList'];
		_loaderDllServerVersion = data['loaderDllServerVersion'];
		_loaderDllServerRoot = data['loaderDllServerRoot'];
		_topLoaderServerVersion = data['topLoaderServerVersion'];
		_gameName = data['gameName'];
	}
	
	
	function showProgressWindow() {
		//console.log('showProgressWindow()');
	
		if (_errorOccured) {
			showErrorWindow();
		} else {
			var cancelUpToDateFunc = function() {
				_gameUpToDateFunc = null;
			}
			
			var content = null;
			var type = null;
			
			if (_progressWindowPrefetch != null) {
				content = _progressWindowPrefetch;
				type = 'html';
			} else {
				content = 'ajax.php?p=loaderprogressbar';
				type = 'ajax';
			}
			
			
			$.weeboxs.open(content, {contentType: type, boxid: 'SoccerPowerLoader_ProgressBarBox', unload: cancelUpToDateFunc, width: 300, height: 120, onopen: function(){trackPageLightbox("update_files")}, onclose: function(){trackPageLightbox("update_files_closed");$.weeboxs.getTopBox().close();}});
		}
	}
	
	
	function isProgressWindowOpen() {
		return $.weeboxs.getBoxById('SoccerPowerLoader_ProgressBarBox') != null;
	}
	
	
	function showErrorWindow() {
	    //console.log('showErrorWindow()');
	    
		var progressBox = $.weeboxs.getBoxById('SoccerPowerLoader_ProgressBarBox');
		if (progressBox != null) {
			progressBox.close();
		}
		
		content = '<p><b>An error occured while updating the game!</b></p><p>' + _errorMessage + '</p>';
		$.weeboxs.open(content, {boxid: 'SoccerPowerLoader_Error', width: 700, height: 200, title: "Error", onopen: function(){trackPageLightbox("update_files_error")}});
	}
	
	
	function showDownloadPluginWindow() {
		var pluginInstalled = false;
		var detectPluginIntervalHandle = null;
		
		var detectPlugin = function() {
			PowerLoader.detectPowerLoader();
			
			if(PowerLoader.isAX || PowerLoader.isNP) {
				// Yay, the plugin was installed. Create it!
				pluginInstalled = true;
				PowerLoader.createPlugin(_domainPattern, _domainSignature, _topLoaderServerVersion);
				
				// Remove the weebox and move on.
				var box = $.weeboxs.getBoxById('SoccerPowerLoader_DownloadPlugin');
				
				if (box != null) {
					box.close();
				}
				
				goToNextState();
				showProgressWindow();
			}
		}
		
		detectPluginIntervalHandle = window.setInterval(detectPlugin, 2000);
		
		var stopDetectPlugin = function() {
			window.clearInterval(detectPluginIntervalHandle);
			
			if (!pluginInstalled) {
				_gameUpToDateFunc = null;
			}
		}
		
		var content = null;
		var type = null;
		
		if (_downloadWindowPrefetch != null) {
			content = _downloadWindowPrefetch;
			type = 'html';
		} else {
			content = 'ajax.php?p=downloadplugin';
			type = 'ajax';
		}
		
		$.weeboxs.open(content, {contentType: type, boxid: 'SoccerPowerLoader_DownloadPlugin', unload: stopDetectPlugin, width: 925, height: 330, onopen: function(){trackPageLightbox("download_plugin")}, onclose: function(){trackPageLightbox("download_plugin_closed");$.weeboxs.getTopBox().close();}});
	}
	
	
	function loaderError(errorMessage) {
		//console.log('loaderError("' + errorMessage +'")');
		
		_errorMessage = errorMessage;
		if (_errorRetries > 0) {
			_errorRetries -= 1;
			fetchFilesInfo(); // Retry from beginning
		} else {
			_errorOccured = true;
			setLoaderIconError(errorMessage);
			
			if (isProgressWindowOpen()) {
				showErrorWindow();
			}
		}
	}


////// Public functions /////////////////////////////////
	
	
	SoccerPowerLoader.isGameUpToDate = function() {
		return _state == State.upToDate;
	}
	
	
	SoccerPowerLoader.updateAndRunJs = function(doneFunction) {
		// If we haven't started yet, now would be a good time to do so
		SoccerPowerLoader.start();
		
		if (_state == State.upToDate) {
			doneFunction();
		} else if (_state == State.needsPlugin) {
			_gameUpToDateFunc = doneFunction;
			showDownloadPluginWindow();
		} else {
			_gameUpToDateFunc = doneFunction;
			showProgressWindow();
		}
	}
	
	
	SoccerPowerLoader.updateAndRedirect = function(nextUrl) {
		var redirectFunc = function() {
			location.href = nextUrl;
		}
		
		SoccerPowerLoader.updateAndRunJs(redirectFunc);
	}
	
	
	SoccerPowerLoader.updateAndExecute = function(commandLine, doBeforeStart, doWhenStarted, doWhenExited) {
		var startFunc = function() {
			if( $.isFunction(doWhenStarted) || $.isFunction(doWhenExited) )
			{
				var gameId = 0;
				var pollFunc = function()
				{
					if( PowerLoader.isGameRunning(gameId) )
						setTimeout(pollFunc, 500);
					else
						doWhenExited();
				}
				var executeFunc = function(event, arg) {
					gameId = arg.gameid;
					if( $.isFunction(doWhenStarted) )
						doWhenStarted(arg.gameid);
					if( $.isFunction(doWhenExited) )
						setTimeout(pollFunc, 500);
				}
				bindPowerLoaderEventOnce("execute", executeFunc);
			}
			startTask(PowerLoader.constructExecuteTask(_gameName, "PowerSoccer.exe", commandLine));
			
			if ($.isFunction(doBeforeStart)) {
				doBeforeStart();
			}
		}
		
		SoccerPowerLoader.updateAndRunJs(startFunc);
	}
	
	
	SoccerPowerLoader.getPackages = function() {
		// Extracts all zips from the file list and adds them to a comma separated string.
		// The client needs this as a command line parameter.
		var packages = "";
		var files = _gameFileList;
		var first = true;
		
		for( var i=0; i<files.length; i++ ) {
			if(files[i].filename.length > 4 && files[i].filename.substring(files[i].filename.length-4).toLowerCase() == ".zip") {
				if(!first)
					packages += ",";
				packages += files[i].filename;
				first = false;
			}
		}
		
		return packages;
	}
	
	
	SoccerPowerLoader.start = function() {
		if (!_started) {
			_started = true;
			// Set the initial state, start downloading if neccesary
			goToNextState();
		}
	}
	
	
	SoccerPowerLoader.init = function(gameSessionVersion, filesInfo, domainPattern, domainSignature, autoStart) {
		_autoStart = autoStart;
		_gameSessionVersion = gameSessionVersion;
		parseFilesInfo(filesInfo);
				
		// Bind error callback
		bindPowerLoaderEvent("task_failed", function(event, arg) {
			loaderError(arg.message);
		});		
		
		// Boot up the loader (this function comes from powerloader.js)
		initializePlugin(domainPattern, domainSignature, _topLoaderServerVersion);
				
		// Save these for later, we will need them if the plugin isn't installed
		_domainPattern = domainPattern;
		_domainSignature = domainSignature;
		
		if (autoStart) {
			SoccerPowerLoader.start();
			
			if (_state != State.upToDate) {
				// Prefetch progress window contents
				jQuery.get('ajax.php?p=loaderprogressbar', null, function (data) { _progressWindowPrefetch = data });
			}
			
			if (_state == State.needsPlugin) {
				// Prefetch download window contents
				jQuery.get('ajax.php?p=downloadplugin', null, function (data) { _downloadWindowPrefetch = data });
			}
		} else {
			if (_topLoaderServerVersion > PowerLoader.getTopLoaderVersion()) {
				// We are on the start page. Prefetch download window and progress window contents
				// if plugin is not installed.
				//jQuery.get('ajax.php?p=loaderprogressbar', null, function (data) { _progressWindowPrefetch = data });
				//jQuery.get('ajax.php?p=downloadplugin', null, function (data) { _downloadWindowPrefetch = data });
			}
		}
	}

}());
