(function($){

	//Attach this new method to jQuery
	$.fn.ApplicationStateManager = {};
	
	$.fn.ApplicationStateManager.STATE_PLAYING = "playing";
	$.fn.ApplicationStateManager.STATE_PAUSED = "paused";
	$.fn.ApplicationStateManager.debug = false;
	
 	$.fn.ApplicationStateManager.init = function() 
	{
		_listenerArray = new Array();
		_listenerStateObj = new Object();
		_applicationStateStr = $.fn.ApplicationStateManager.STATE_PLAYING;
		
		debug("ApplicationStateManager()");
		if (_applicationStateStr == null)
		{
			//--applicationStateManger has already been initialised, what to do?
		}
	}
	
	//--GETTER : return String
	$.fn.ApplicationStateManager.getApplicationState = function()
	{
		return _applicationStateStr;
	}
	
	//--SETTER : v:String : return void;
	$.fn.ApplicationStateManager.setApplicationState = function(v)
	{
		debug("ApplicationStateManager.setApplicationState: "+v);
		_applicationStateStr = v;
		notifyListeners();
	}

	$.fn.ApplicationStateManager.listenForStateChange = function(callback, scope)
	{
		_listenerArray.push({callback:callback, scope:scope});
	}
	
	$.fn.ApplicationStateManager.listenForSpecificStateChange = function(state, callback, scope)
	{
		if (_listenerStateObj[state] == null)
		{
			_listenerStateObj[state] = new Array();
		}
		_listenerStateObj[state].push({state:state, callback:callback, scope:scope});
	}

	//--INTERNALS--------------------------------
	var _applicationStateStr;	//--STRING
	var _listenerArray;			//--ARRAY;
	var _listenerStateObj;		//--OBJECT
	
	
	function debug(str)
	{
		if ($.fn.ApplicationStateManager.debug == true)
		{
			alert(str);
		}
	}
	
	//--CALL CALBACK IN THE SCOPE OF ALL LISTENERS
	function notifyListeners()
	{
		if (_listenerArray != undefined) 
		{
			var l = _listenerArray.length;
			for (var i = 0; i < l; i++) {
				var item = _listenerArray[i];
				callFunctionInScope(item.callback, item.scope);
			}
			notifyStateSpecificListeners();
		}
	}
	
	function notifyStateSpecificListeners()
	{
		if (_listenerStateObj[_applicationStateStr] != null)
		{
			var tArray = _listenerStateObj[_applicationStateStr];
			if (tArray.length >0)
			{
				var l = _listenerArray.length;
				for (var i = 0; i < l; i++) 
				{
					var item = _listenerArray[i];
					callFunctionInScope(item.callback, item.scope);
				}
			}			
		}
	}
	
	function callFunctionInScope(callback, scope)
	{
		callback.call(scope, _applicationStateStr);
	}
	
	function garbageCollection()
	{
		var l = _listenerArray.length;
		//--GO BACKWARDS THROUGH THE ARRAY BECAUSE IT'S REMOVING ELEMENTS
		for (var i = l; i > 0; i--) 
		{
			var item = _listenerArray[i];
			if (item.callback == null || item.scope == null)
			{
				_listenerArray.splice(i , 1);
			}
		}		
	}
	//--END INTERNALS---------------------------
})(jQuery);

