/**
 * Service call functionality bundled in here 
 */
var Service = {
	//: all the post requests	
	post_requests : [],
	//: one get request (to be enhanced to allow multiple requests + parameters)
	get_request : false,
	//: has the dom:loaded event fired yet?
	dom_loaded : false,
	//: class set to element while request is pending
	css_class_loading : false,
	//: class set to element when request is complete
	css_class_complete : false,
	//: save callbacks by ids
	callbacks : [],
	
	//: init the common parameters and set listener to dom loaded event
	initialize : function(){
		this.post_requests = [];
		this.get_request = false;
		this.dom_loaded = false;
		this.css_class_loading = 'service-loading';
		this.css_class_complete = 'service-complete';
		this.callbacks = [];
		
		Event.observe(document, 'dom:loaded', function(){Service.domLoaded();});
	},
	
	/* 
	 * PUBLIC FUNCTIONS 
	 */
	
	//: clear all request queues
	clear : function() {
		this.clearPost();
		this.clearGet();
	},
	
	//: add a post request
	add : function( $id, $service, $call, $params, $callback ) {
		if ($params == null) $params = [];
		if ($callback == null) $callback = false;
		
		var requestObj = {id: $id, service: $service, call: $call, callparams: $params, callback: $callback};
		if (!this.dom_loaded)
			this.post_requests.push(requestObj);
		else
			//: short wire if dom has already loaded
			this.submitPost([requestObj]);
	},
	
	//: set the get request
	setGetRequest : function (req, callback) {
		//: replace only temporary for seo optimization
		this.get_request = req.replace(/\|/g, '/');
		this.get_request_callback = callback;
	},
	
	/* 
	 * PROTECTED FUNCTIONS (pseudo) 
	 */
	
	//: clear the post queue
	clearPost : function() {
		this.post_requests.clear();
	},
	
	//: clear the get queue
	clearGet : function() {
		this.get_request = false;
	},
	
	/* SUBMISSION */
	
	//: submit all added requests
	submit : function() {
		//: submit post requests and clear the queue
		this.submitPost(this.post_requests);
		this.clearPost();
		
		//: submit get requests and clear the queue
		this.submitGet(this.get_request);
		this.clearGet();
	},
	
	//: submit given params as post call
	submitPost : function(params){
		
		params = params.filter(function(req){
			return (!!$(req.id) || req.id == null);
		});
		
		for (var i=0; i<params.length; i++){
			if (params[i].id != null) {
				//: set loading class to each element
				this.setLoadingStatus(params[i].id);
				//: write callback to callback array
				this.addCallback(params[i].id, params[i].callback);
			}
		}
		
		if(params.length > 0) {
			new Ajax.Request('/service/', {
				method: 'post',
				parameters: 'data='+Object.toJSON(params),
				onComplete: this.processResponse
			});
		}
	},
	
	//: submit given get request
	submitGet : function(request) {
		if (request) {
			new Ajax.Request('/lazyloader/index/' + request, {
	            method: 'get',
	            onComplete: this.processResponse
	        });
		}
	},
	
	/* CALLBACKS */
	
	//: append a callback for a given object id
	addCallback : function(id, callback) {
		if (typeof(callback) == 'function') {
			if (typeof(this.callbacks[id]) !== 'object') {
				this.callbacks[id] = [];
			}
			this.callbacks[id].push(callback);
		}
	},
	
	//: trigger callbacks for a given id
	triggerCallback : function (id, reqObject, remove) {
		if (remove != false) remove = true;
		if (typeof(this.callbacks[id]) !== 'undefined') {
			//: trigger all callbacks
			this.callbacks[id].each(function(eachObj){
				try {
					eachObj(reqObject);
				} catch (e) {}
			});
			//: remove callback from queue
			if (remove) delete(this.callbacks[id]);
		}
	},
	
	/* ELEMENT STATUS */
	
	//: set the configured loading class to the object with the given id
	setLoadingStatus : function(id) {
		this.cleanStatus(id);
		$(id).addClassName(this.css_class_loading);
	},
	
	//: set the configured complete class to the object with the given id
	setCompleteStatus : function (id) {
		this.cleanStatus(id);
		$(id).addClassName(this.css_class_complete);
	},
	
	//: remove any status classes
	cleanStatus : function (id) {
		$(id).removeClassName(this.css_class_loading);
		$(id).removeClassName(this.css_class_complete);
	},
	
	/* EVENTS */
	
	//: triggered if dom has loaded
	domLoaded : function (e) {
		this.dom_loaded = true;
		//: submit all requests added
		this.submit();
	},
	
	//: default callback for request response
	processResponse : function (transport) {
		if (transport.readyState == 4) {
			$H(transport.responseText.evalJSON(true)).each(function(responseObj) {
				if($(responseObj.key) != undefined) {
					
					//: set status
					Service.setCompleteStatus(responseObj.key);
					

						
					
					if (responseObj.value instanceof Array) {
						// is array
						var responseHtml = '';
						responseObj.value.each(function(responseObj2) {
							responseHtml = responseHtml + responseObj2;
						});
						$(responseObj.key).update(responseHtml);
						handleATagOverId('#'+responseObj.key, decodeId_1);
					}else{
						// is string
						$(responseObj.key).update(responseObj.value);
						handleATagOverId('#'+responseObj.key, decodeId_1);
					}

                    //: trigger callbacks
                    if (transport.request.method == 'post')
                        Service.triggerCallback(responseObj.key, responseObj);
                    else if (typeof(Service.get_request_callback) == 'function') {
                        Service.get_request_callback(responseObj);
                    }
				}
			});
		}
		//: reset get request callback method
		if (transport.request.method == 'get')
			Service.get_request_callback = false;
	}
};

//: initialize the service class
Service.initialize();
