jQuery(function($) {
    $(window).bind("beforeunload", function() {
    	restWrapper.isLeavingThePage = true;
    });
});

// static properties
var host00 = location.protocol + "\/\/" + location.host;
restWrapper.constDefaultHost = host00 + "\/restapi\/";	
//restWrapper.constDefaultHost = host00 + "\/localrest\/";	

pos=location.pathname.indexOf('elgg\/');
if (pos==1 || pos==0) // if there is elgg as the subfolder
	restWrapper.constDefaultConsumerSite = host00 + "\/elgg\/";		// the elgg site
else
	restWrapper.constDefaultConsumerSite = host00 + "\/";		// the elgg site
//restWrapper.constDefaultHost = "http://alpha.kalengo.com/restapi/";		// the Rest Api site
//restWrapper.constDefaultConsumerSite = "http://alpha.kalengo.com/";	// the elgg site

// change using local mock object
//restWrapper.constDefaultHost = restWrapper.constDefaultConsumerSite + "pg\/restapi\/";

// Ajax's dataType
restWrapper.constDataTypes = ["json", "xml", "html", "script"];
restWrapper.constDataTypeJson = restWrapper.constDataTypes[0];
restWrapper.constDataTypeXml = restWrapper.constDataTypes[1];
restWrapper.constDataTypeHtml = restWrapper.constDataTypes[2];	// HTML (plain text)
restWrapper.constDataTypeScript = restWrapper.constDataTypes[3];
restWrapper.constDefaultDataType = restWrapper.constDataTypeJson;

// Ajax's type
restWrapper.constRestTypes = ["GET", "PUT", "POST", "DELETE"];
restWrapper.constRestTypeGet = restWrapper.constRestTypes[0];
restWrapper.constRestTypePut = restWrapper.constRestTypes[1];
restWrapper.constRestTypePost = restWrapper.constRestTypes[2];
restWrapper.constRestTypeDelete = restWrapper.constRestTypes[3];
restWrapper.constDefaultRestTypes = restWrapper.constRestTypeGet;

restWrapper.constErrors = [];

restWrapper.isLeavingThePage = false;

// Ajax's callback
restWrapper.constSuccess = function( data )	{ 
								return data; 
							};

// constructor for the restWrapper function object
function restWrapper(configParam) {
	// private data
	var host;
	var restDataType;
	var callbackFunctionsParam;
	
	// initialization
	var bInitialized = false;
	var sRestRequestString;
	
	if (!configParam || !configParam.host) {
		host = restWrapper.constDefaultHost; 
	} else {
		host = configParam.host;
	};

	if (!configParam || !configParam.dataType) {
		restDataType = restWrapper.constDefaultDataType; 
	} else {
		restDataType = configParam.dataType;
	};

	if (!configParam || !configParam.callbackFunctionsParam) {
		callbackFunctionsParam = restWrapper.constDefaultDataType; 
	} else {
		callbackFunctionsParam = null;
	};
	
	// private functions
	var isCorrectRestServiceType = function(type) {
		
		switch(type) {
			case restWrapper.constRestTypeGet:
				return true;
				break;
				
			case restWrapper.constRestTypePut:
				return true;
				break;

			case restWrapper.constRestTypePost:
				return true;
				break;

			case restWrapper.constRestTypeDelete:
				return true;
				break;
		};
		return false;
	};
	
	// to get the oauth signature string
	var initialRestService = function() {
		if (!bInitialized) {
			var ajaxParam = {};
			
			ajaxParam.async = false;
			ajaxParam.type = restWrapper.constRestTypeGet;
			ajaxParam.url = restWrapper.constDefaultConsumerSite + "action/oauth/retrieverequest?restmethod=GET&username=guest&resturlprefix="+restWrapper.constDefaultHost;
			ajaxParam.dataType = restWrapper.constDataTypeHtml;
			
			ajaxParam.success = function( data ) {
				bInitialized = true;
				sRestRequestString = data;
			};
			ajaxParam.error = function( data ) {
				bInitialized = false;
				json = {status:"FAIL","code": 60000005, "message": "Error connecting to the rest authorization service: please try again later."};
				handler = new restResponseHandler(json);
				handler.throwRestException();
			};
			//alert("Rest service, wait ...\n" + JSON.stringify(ajaxParam));
			$.ajax(ajaxParam);
		}
	}
	
	
	// At least the following ajax parameters need to be set when calling this function
	//	param.service: the rest url without the host and port number
	//	param.error: the error handling function
	//	param.success: the success handling function
	var ajaxRestService = function(ajaxParam) {
		initialRestService();
		
		if (ajaxParam) {
			if (!ajaxParam.type) ajaxParam.type = restWrapper.constDefaultRestTypes;
			
			if (!ajaxParam.dataType) ajaxParam.dataType = restDataType;
			
			if (!ajaxParam.url && ajaxParam.service) ajaxParam.url = host + ajaxParam.service;
			 
			var beforedSendFunction =  $.isFunction ( ajaxParam.beforeSend ) ?   ajaxParam.beforeSend : function(){};
			ajaxParam.beforeSend = function(req) {
				req.setRequestHeader('Authorization', sRestRequestString);
				beforedSendFunction();
			};
			
			var successFunction = ajaxParam.success ? ajaxParam.success : restWrapper.constSuccess;
			var errorFunction = ajaxParam.error;
			var exceptionFunction = ajaxParam.exception;
			
			ajaxParam.success = function( data ) {
				var _this = this;
		//		console.log( data );
				handler = new restResponseHandler(data,_this);
				handler.throwRestException(exceptionFunction);
				if( handler.getJsonErrorCode() === 0 ){
					successFunction(data);
				}
				
			};
			
			ajaxParam.error = function( XMLHttpRequest, textStatus, errorThrown ) {
				
			//	console.log( XMLHttpRequest );
			//	console.log( textStatus );
			//	console.log( errorThrown );
				// unknow error
			//	if( textStatus = 200) return false;
				
				if (!restWrapper.isLeavingThePage) {
					var _this = this;
					json = {status:"FAIL","code": 60000004, "message": "Service is not available. Please try again later."};
					handler = new restResponseHandler(json,_this);
					handler.throwRestException(exceptionFunction);
					//handler.throwRestException();
				}
			};
			
			if (ajaxParam.url && isCorrectRestServiceType(ajaxParam.type)) {
				$.ajax(ajaxParam);
			};

		};
	};
	
	// privilged getters/setters
	this.getHost = function() {
		return host;
	};
	
	this.setHost = function(_host) {
		host = _host;
	};
	
	this.getDataType = function() {
		return dataType;
	};
	
	this.setDataType = function(_dataType) {
		dataType = _dataType;
	};
	
	// other privilged functions
	this.ajaxRestGet = function(param, extraParam) {
		if (!param) return;
		
		param.type = restWrapper.constRestTypeGet;
		ajaxRestService(param, extraParam);
	};
	
	this.ajaxRestPut = function(param, postData) {
		if (!param) return;
		
		param.type = restWrapper.constRestTypePut;
		if (!param.data && postData) {
			param.data = postData;
		}
		ajaxRestService(param);
	};
	
	this.ajaxRestPost = function(param, postData) {
		if (!param) return;
		
		param.type = restWrapper.constRestTypePost;
		if (!param.data && postData) {
			param.data = postData;
		}
		ajaxRestService(param);
	};
	
	this.ajaxRestDelete = function(param) {
		if (!param) return;
		
		param.type = restWrapper.constRestTypeDelete;
		ajaxRestService(param);
	};

	
}


//constructor for the rest exception function object
function restException(_code, _message,_professionalMsg,_systemMessage) {
	// private data
	var code = _code;
	var message = _message;
	var professionalMsg = _professionalMsg;
	var systemMessage = _systemMessage;
	// privilged getters/setters
	this.getCode = function() {
		return code;
	};
	
	this.getMessage = function() {
		return message;
	};
	
	this.getProfessionalMsg = function(){
		return professionalMsg;
	};
	
	this.getsystemMessage = function(){		
		return systemMessage;
	}
}


//constructor for the rest exception function object
function restResponseHandler(_json,_professionalMsg) {
	if(typeof(_json) == "undefined") return;
	var json = _json;
	// private function
	var isErrorResponse = function() {
		
		if (json.status == 'FAIL' && json.code && json.message) {
			return true;
		}
		return false;
	};
	
	
	// privilged methods
	this.getJsonErrorCode = function() {
		if (json.status == 'FAIL') {
			if (json.code) {
				return json.code;
			} else {
				return 60000001;
			}
		}
		return 0;
	};
	
	this.getJsonErrorMessage = function() {
		if (json.status == 'FAIL') {
			if (json.message) {
				return json.message;
			} else {
				return "Unknown JSON Error";
			}
		}
		return "";
	};
	
	this.getObjectProfessionalMsg = function(){
		if (json.status == 'FAIL' && typeof(_professionalMsg) == "object") {
			return _professionalMsg;
		}
		return {};
	}
	
	this.getServerErrorMessage = function(){
		if (json.status === 'FAIL') {
			if( json.systemMessage ) {
				return json.systemMessage;
			} else {
				return {};
			}
		}
		return {};
	}
	
	// throw Rest Exception only if there is any error
	this.throwRestException = function(callbackForException) {
		if (isErrorResponse()) {
			var ex = new restException(this.getJsonErrorCode(), this.getJsonErrorMessage(),this.getObjectProfessionalMsg(),this.getServerErrorMessage())
			if ($.isFunction(callbackForException)) {
				callbackForException(ex);
			}
			else {
				throw (ex);
			}
		}
		
		// for backward compatibility
		if (json.errorMsg) {
			throw (new restException(60000006, "Unknown rest service error.",this.getObjectProfessionalMsg()));
		}
		// else: do nothing
	}
	
}

