(function(undefined){
	var StateManager = function(){
		var that = this;
		// console.log('init state object');
		
		var oldUrl = '';
		var state;
		
		/*
		public accessible functions
		*/
		var fn = {
		    getQuery: function(){
		        // check if there are url variables
				var url = document.location.href;
				
				var query = '';
				if(url.lastIndexOf('#') > -1){
					query = unescape(url.substring(url.lastIndexOf('#')+1));
				}
                
				try{
                    query = jQuery.parseJSON(query);
                }catch(err){
					
                    query = {};
                }
                
				
				
				return(query);
		    },
		    
			check: function(){
				var url = document.location.href;
				
				if(url !== oldUrl){
					oldUrl = url;
					
					var query = fn.getQuery();
					
					if(query){
						// get instance if one was specified
						if(typeof(query.instance) !== 'undefined'){
							instanceController.setInstance(query.instance);
						}
						
						if(typeof(query.lat) !== 'undefined' || typeof(query.lon) !== 'undefined' || typeof(query.zoom) !== 'undefined' || typeof(query.mapType) !== 'undefined'){
							map.updateState(query.lat, query.lon, query.zoom, query.mapType);
                            window.search.performMapSearch();
						}
						
						
						
						if(query.action && typeof(query.action) !== 'undefined'){
							// show the right window
							switch(query.action){
								case 'help':
									help.show();
									break;
								case 'login':
									login.show(query.state, query.destination);
									break;
								case 'profile':
									profileViewController[query.state]();
									break;
								case 'photo':
									var addPhotoViewController = new AddPhotoViewController();
									addPhotoViewController.init();
									break;
								case 'story':
									var addStoryViewController = new AddStoryViewController();
									addStoryViewController.init();
									break;
								case 'link':
									var addLinkViewController = new AddLinkViewController();
									addLinkViewController.init();
									break;
							}
						}
					}else{
					    //init state
					    state = {};
					
					    //capture any possible prechoosen instances via GET
					    var setInstance = instanceController.getPreSetInstance();
						var startScreen = new StartScreen(setInstance);
					}
				}else if(state === null){
				    state = {};
				}
			},
			
			stringify: function(jsonData){
				var strJsonData = '{';
				var itemCount = 0;
				for (var item in jsonData) {
					if (itemCount > 0) {
						strJsonData += ', ';
					}
					strJsonData += '"' + item + '":' + ( (typeof(jsonData[item]) == 'object') ? fn.stringify(jsonData[item]) : '"' + jsonData[item] + '"' ) + '';
					itemCount++;
				}
				strJsonData += '}';
				return strJsonData;
			},
			
			remove: function(key){
				delete state[key];	
			},
			
			change: function(key, value){
				state[key] = value;
			},
			
			update: function(excecuteChange){
			    excecuteChange = (typeof excecuteChange == 'undefined') ? true : false;
			    
				var str = this.stringify(state);
				
				document.location.href = '#' + str;
				
				if(!excecuteChange){
				    oldUrl = document.location.href;
				}
			},
			
			getStateOf: function(key){
			    if(state && typeof(state[key]) != 'undefined'){
			        return state[key];
			    }else{
			        return undefined;
			    }
			},
			
			empty: function(){
			    state = {};
			    document.location.href = '#'
			    oldUrl = document.location.href;
			},
			
			setState: function(newState){
			    state = newState;
			},
			
			getState: function(){
			    return(state);
			}
			
		};
		
		state = fn.getQuery();
		
		fn.startChecking = function(){
		    setInterval(fn.check, 300);
		};
		
		/*
        return public accessible functions
        */        
        return(fn);
		
		
		
	}
	
	window.StateManager = StateManager;
	
}());
