/**
 * @author Joel
 */

$.extend({
	/*
	 * the model of our model-view-controller architecture
	 */
	model: function(){
		
		/*
		 * local cache of data
		 */
		this.cache = new Array();
		this.ajaxItemsInProgress = new Array();
		var that = this;
		
		/*
		 * look in the cache to retrieve an item,
		 * if it's not there then load it via ajax
		 */
		this.getItem = function(item, parameters, callback, noCache){
			if(noCache === undefined) noCache = false;
			if(parameters === undefined) parameters = false;
			
			var cacheString = that.getCacheString(item, parameters);
			if(!noCache && that.ajaxItemsInProgress[cacheString] === true) {
				that.waitForItem(item, parameters, callback);
			}
			else {
				if (that.cache[cacheString]) {
					if (callback !== undefined) callback(that.cache[cacheString]);
					that.ajaxItemsInProgress[cacheString] = false;
				}
				else {
					that.ajaxItemsInProgress[cacheString] = true;
					if (parameters !== false) {
						/* Use POST to send parameters and retrieve JSON */
						$.post("/ajax/" + item + "/", parameters, function(json){
							that.cache[cacheString] = json;
							if (callback !== undefined) 
								callback(json);
							that.ajaxItemsInProgress[cacheString] = false;
						}, "json");
					}
					else {
						/* No parameters need to be sent, so GET will suffice */
						$.getJSON("/ajax/" + item + "/", function(json){
							that.cache[cacheString] = json;
							if (callback !== undefined) 
								callback(json);
							that.ajaxItemsInProgress[cacheString] = false;
						});
					}
				}
			}
		}
		/*
		 * perform an update and optionally update a cache item with the
		 * response from the AJAX call
		 */
		this.performUpdate = function(updateFunction, parameters, updateCache, callback){
			if(updateCache === undefined) updateCache = false;
			if(updateCache) {
				var cacheString = that.getCacheString(parameters.cache_item, parameters.cache_item_parameters);
				that.ajaxItemsInProgress[cacheString] = true;
				$.each(parameters.cache_item_parameters, function(id, item){
					parameters[id] = item;
				});
				delete parameters.cache_item_parameters;
			}
			
			var dt = new Date(); // +dt.getHours() + "_" + dt.getMinutes() + "_" + dt.getSeconds() + "_" + dt.getMilliseconds()
			$.post("/ajax/" + updateFunction + "/", parameters, function(json){
				if(updateCache){
					that.cache[cacheString] = json;
					if (callback !== undefined) 
						callback(json);
					that.ajaxItemsInProgress[cacheString] = false;
				}
				else{
					if (callback !== undefined) 
						callback(json);
				}
			}, "json");
		}
		
		/*
		 * wait for the item if it is currently being
		 * retrieved via ajax (to avoid multiple ajax
		 * calls for the same item)
		 */
		this.waitForItem = function(item, parameters, callback) {
			setTimeout(function(){
				that.getItem(item, parameters, callback);
			}, 200);
		}
		
		/* 
		 * remove an item from the cache
		 */
		this.unCache = function(item, parameters){
			delete that.cache[this.getCacheString(item, parameters)];
		}
		
		this.getCacheString = function(item, parameters){
			var cacheString = item;
			if(parameters === undefined) parameters = false;
			if(parameters !== false){
				$.each(parameters, function(id, item){
					cacheString += "-"+id+":"+item;
				});
			}
			return cacheString;
		}
		
		/*
		 * clear the local cache of data
		 */
		this.clearCache = function(){
			cache = new Array();
		}
	},
	
	/*
	 * the view of our model-view-controller architecture
	 */
	view: function(){
		this.disable = function(element){
			element.attr("disabled", "disabled");
		}
		this.enable = function(element){
			element.removeAttr("disabled");
		}
		this.blockUserInput = function(){
			$("#dummydialog").modal({overlay: 0, containerId: "dummydialog-container"});
    		$("#modalContainer").addClass("hidden");
		}
		this.unBlockUserInput = function(){
			$.modal.close();
		}
	},
	
	/*
	 * the controller of our model-view-controller architecture
	 */
	controller: function(model, view){
		// nothing yet
	}
});