function modelBase(name){
	
	var myName 			// The user exposable name for the data held by this model.
	var myData; 		// The actual data, i.e. values, held by this model
	var myDomainData; 	// The meta data held by this model, e.g.possible values
	var myValidationListeners;
	var myUpdateListers;
	var mySaveURL;
	var userIsAuthenticated;
	var me;				// My context
	
	// Set initial values
	me = this;
	myValidationListeners = new Array();
	myUpdateListers = new Array();
	myDomainData = new Array(); // In case no domain is loaded
	myData = {} // In case no data is loaded
	myName = name;
	
	 
	this.saved = true;
	
	// Define get functions for publically available data
	this.getName = function() {return myName;}
	this.getData = function() { return myData ;}
	this.getDomainData = function() {return myDomainData;}
	this.setSaveUrl = function(saveURL) {mySaveURL =  saveURL;}
	this.isUserAuthenticated = function() {return userIsAuthenticated;}


	/***
	 * This function is always overwritten with object augmentation if it is to be used
	 * for real validation since the actual validation code is specific per UI control.
	 * The method must return a boolean stating if data was valid or not.
	 * If not overridden, i.e. when no validation is needed, the method always returns true. 
	 * @param {Object} group A string that can be used to only validate a subgroup, e.g. a panel    
	 */
	this.validate = function(group) {
		// return true as default if the validation has not been augmented since we then assume that there is nothing to validate 
		return true;		
	}
	
	/***
	 * 'Key' is the model key and 'value' is its value. If the model is empty the 'type' will 
	 *  determine how to update the control. TargetType is 'mulitple' or 'single' to determine if we are 
	 *  keeping the values in an array or a string. 
	 */
	this.update = function(key, value, targetType) {
		
		console.log("ENTER UPDATE IN MODEL");
		this.saved = false;
		
		// It is possible that the key doesn't exist in the model.
		// Therefore we might have to create the value array for the key. 
		if(targetType == 'multiple'){
			console.log("Uppdating array: " + key);
			// Create an empty array if the key doesn't exist 
			if(typeof(myData[key]) === "undefined"){
				myData[key] = new Array();
				console.log(myData);
			}
			
			var pos = $.inArray(value, myData[key]);
			// An update means that an existing array element should be removed 
			if(pos >= 0){
				myData[key].remove(pos);
			}
			else {myData[key].push(value);}
		}
		// Target type is a single value
		else{
			 console.log("setting single value");
			 myData[key] = value;
		}
		
		console.log(key +" got value " + myData[key]);		
		
		// Notify the control that triggered the update that the model was updated		
		this.notifyUpdateListers({"Reciever" :key});

	}
	
	this.addValidationListeners = function(callBackFunction, context){
		myValidationListeners.push([callBackFunction, context]);	
	}
	this.addUpdateListers = function(callBackFunction, context){
		myUpdateListers.push([callBackFunction, context]);	
	}
	     
	
	/***
	 * Loads all the domains for the GUI controls that should be retrieved 
	 * from the server, e.g. all languages and instruments.
	 * @param {Object} controllerCallback
	 * @param {Object} callBackContext
	 */
	this.loadDomains = function(url, controllerCallback, callBackContext){		
		$.ajax({
		  url: url,
		  dataType: 'json',
		  data: '',
		  success: function(data){ myDomainData = data;}, // The domain is kept locally in the model		  
		  error: ajaxError,
		  complete: controllerCallback,
		  context: callBackContext
		});		
	}
	
	/***
	 * Loads all the DB stored values for the model  
	 * @param {Object} url
	 * @param {Object} controllerCallback
	 * @param {Object} callBackContext
	 * @param {Object} data to be sent as parameters 
	 */
	this.loadData = function(url, controllerCallback, callBackContext, parameterData){
						
		var thisContext = this;				
		var data = typeof(parameterData) === 'undefined' ? {} : parameterData;
		data.action = "readData";
		
		$.ajax({
		  type: 'POST',
		  url: url,
		  dataType: 'json',
		  data: data,
		  success: function(data){

		  				// mt.userAuthenticated is now set on the serverside as a global variable

		  				
		  				
			  			// Perform some simple sanity checking
			  			// console.info(data);			  			 
				  		if(typeof(data.status) == "undefined" || data.status !== "ok"){
				  			console.error(data.status, data.messages);
				  			// Replace the page with an error page with a back button
				  			var errorString = "error.php?error=" + encodeURI(data.status).toString();
				  			errorString += data.msgToUser ? "&msg="+encodeURI(data.msgToUser) : "";
				  			$('body').load(errorString);
				  		}				  		
				  		else {
				  			
				  			myData = data.data;
				  			myData = thisContext.preProcessDataBeforeShow(data.data);
				  			console.info(" recieved data model:");
				  			controllerCallback.call(callBackContext);
				  			// console.info(myData);
				  		}
		  			}, // The data is kept locally in the model
		  error: ajaxError,
		  // complete: controllerCallback,
		  // context: callBackContext
		});
		console.log("sent ajax request");
	}
	

		
	/***
	 * Sends a request object to the specified url and returns the answer 
	 * @param {Object} requestObject, object data to be sent to the server
	 * @param {string} url to send data to	
	 * @param {string} callbackFunction
	 * @param {string} context
	 */
	this.simpleServerRequest = function(requestObject, url, callbackFunction, context){		
		var JSONwrapper = {"json" : requestObject};
		$.ajax({
		  url: url,
		  dataType: 'json',
		  data: JSONwrapper,
		  success: function(data){
		  				// Perform some simple sanity checking			  			 
				  		if(typeof(data.status) == "undefined" || data.status !== "ok"){
				  			console.error(data.status, data.messages);
				  		}
				//callbackFunction.call(context, data);
				processServerResponse(data, callbackFunction, context, this); // Postprocess response data before controller callback
			}, 
		  error: ajaxError,
		  complete:null,
		  context: context
		});
		console.log("sent ajax request");
	}
	
	this.save = function(controllerCallback, callBackContext){
				
		// Create a copy and trim the data before saving
		var copyOfData = $.extend(true,{}, myData);
		
		// Trim away unneeded data
		var trimmedData = this.trimBeforeSave.call(this, copyOfData);
		
		// Pre process data befoew save. e.g. set default values for non mandatory fields
		var trimmedWithDefault = this.processBeforeSave.call(this, trimmedData);;
		
//		console.info(trimmedData);
		var JSONwrapper = {"json" : trimmedWithDefault};
		
		console.log("will save data: ");
		console.log(JSONwrapper);
		
		try {
			console.log("will send ajax request");
			$.ajax({
				type: 'POST',	 			
			  url: mySaveURL,
			  dataType: 'json',
			  data: JSONwrapper,
			  success: function(data){processServerResponse(data, controllerCallback, callBackContext, this);}, // Postprocess response data before controller callback 
			  error: ajaxError,
			  complete: "",
			  context: this
			});
			console.log("sent ajax request");
			}
		catch(exc){
			console.error(exc);
		}
	}
	
	
	/**
	 * Exactly the same as save() but with jsonp to support communication 
	 * over SSL which is considered cross domain.
	 */
	this.saveSecure = function(controllerCallback, callBackContext){
				
		// Create a copy and trim the data before saving
		var copyOfData = $.extend(true,{}, myData);
		
		// Trim away unneeded data
		var trimmedData = this.trimBeforeSave.call(this, copyOfData);
		
		// Pre process data befoew save. e.g. set default values for non mandatory fields
		var trimmedWithDefault = this.processBeforeSave.call(this, trimmedData);;
		
//		console.info(trimmedData);
		var JSONwrapper = {"json" : trimmedWithDefault};
		
		console.log("will save data: ");
		console.log(JSONwrapper);
		
		try {
			console.log("will send ajax request");
			$.ajax({
				type: 'POST',	 			
			  url: mySaveURL,
			  dataType: 'jsonp',
			  data: JSONwrapper,
			  success: function(data){processServerResponse(data, controllerCallback, callBackContext, this);}, // Postprocess response data before controller callback 
			  error: ajaxError,
			  complete: "",
			  context: this
			});
			console.log("sent ajax request");
			}
		catch(exc){
			console.error(exc);
		}
	}	
	
	/***
	 * This function is always overwritten with object augmentation if it is to be used
	 * since the actual trimbeforeSave code is specific per model instance.
	 * The method will when overridden alter the data it recieves.  
	 */
	this.trimBeforeSave = function(dataToBeTrimmed){
		// Overwrite this function
		return dataToBeTrimmed; 		
	}
	
	/***
	 * This function is always overwritten with object augmentation if it is to be used
	 * since the actual processBeforeSave code is specific per model instance.
	 * The method will when overridden alter the data it recieves. 
	 * Example usage is adding default values for non mandatory fields or turning text to lower case 
	 */
	this.processBeforeSave = function(dataWithoutDefaults){
		// Overwrite this function
		return dataWithoutDefaults; 		
	}


	/***
	 * Can be used to pre process data before the controller gets a hold of it.
	 * This function is almost always overwritten with object augmentation if it is to be used
	 * since the actual preProcessDataBeforeShow code is specific per model instance.
	 * The method will when overridden alter the data it receives.  
	 */
	this.preProcessDataBeforeShow = function(dataToPreProcess){
		// Overwrite this function
		return dataToPreProcess; 		
	}
		
	
	/***
	 * This function must be public since it can be augmented by specialized models
	 */
	this.notifyValidationListers = function(message){
		for (var li=0; li<myValidationListeners.length; li++) {
			// myListeners[li][0] is the function and myListeners[li][1] has the context
			myValidationListeners[li][0].call(myValidationListeners[li][1],message);
		};
	}
	
	this.notifyUpdateListers = function(message){
		for (var li=0; li<myUpdateListers.length; li++) {
			// myListeners[li][0] is the function and myListeners[li][1] has the context
			myUpdateListers[li][0].call(myUpdateListers[li][1],message);
		};
	}
	
	// The AJAX was sucessful but we need to check if the server was able to carry out its task
	var processServerResponse = function(responseData, callBackFunction, context, modelContext){
				
		
		if(typeof(responseData) === "undefined" || responseData === null){
			$('body').load("error.php?error=empty_return_value_from_server");
		}
		
		else if(responseData.status === "validation_failed"){
			for (i=0;i<responseData.messages.length;i++){
				console.log("Notification " + i );
				console.log(responseData.messages[i]);
				me.notifyValidationListers(responseData.messages[i]);	
			}
						
		}
		else{
			modelContext.saved = true;
		}
		
		callBackFunction.call(context, responseData)		
	}
	
	var ajaxError = function(XMLHttpRequest, textStatus, errorThrown){		
		$('body').load("error.php?error=ajax_call_failed");
		console.error(textStatus);
		console.error(errorThrown);
	} 	
	
}

