/**
 * MediaGServerQuery.js
 * Description: this file contains all the ajax related functions for Geolive/MediaMap
 * 
 * Author: Nicholas Blackwell UBC-Okanagan
 * 
 * License: MIT Style License
 * 
 * GettingStarted: a ServerClient Class instance is created by MediaMap (and attached to it) on initialization and 
 * contians all the client server information for ajax communication. 
 * 
 * All the additional classes defined in this file are the different ajax requests that 
 * Geolive needs to make. they all extend AjaxQuery which defines the core functionality. 
 * basically creating an instance of any of these requests returns an object that 
 * takes a geolive item. eg PolygonDeleteRequest requires a polygon... and the object extracts the 
 * required data from the polygon (serverinfo, mapid, layerid, polyid, ...) 
 * 
 * **notice that each request has 2 names a absolute name, and a AjaxQuery.xxxx name the absolute
 * 	name has been recently been added to make the source much easier to read (especially in eclipse)
 * 	however in most other places where these are actually used (instantiated), the AjaxQuery.xxxx name is used. 
 *  this should be changed someday.
 * 
 * there are two types of requests, ones that return json data and ones that return xml/text data
 * most requests return json, however kml requests for example return xml. 
 * classes that return json extend AjaxQuery.JsonResponse and those that require xml just extend AjaxQuery
 * LayersRequest is interesting becuase It may be conveinent to retrieve data as json objects in the future
 * or even as a json object containing xml within an object so there is a bit of dynamic function rewriting
 * within that request. 
 * 
 * the request url variables are pretty simple. a 'task' string, and an optional 'json' variable 
 * which will contain key value pairs for the server to decode
 * 
 * Optimization and Tasks: there is a ton of stuff that can be done to simplify request classes. 
 *	-   i preprocess kml
 *	 	files and tag every thing with a id number, (and import them into the database). this makes updating super
 *		simple but there is a ton of old code that figured out a unique string for each element, 
 *		sent that to the server, and then the server parsed the unique string and found the item in the kml...
 *		all this code is garbage and can be removed. but first it must be verified that nothing is
 *		still using this code. (it is all at the end of this file. delete it after verifying **DONE NB**)
 */


var ServerClient=new Class({
	options:
	{
	server:null,
	mapId:-1
	},
	initialize:function(options){
		this.setOptions(options);
	},
	executeQuery:function(query, events){
		var me=this;
		$each(events,function(value,name){
			query.addEvent(name,value);
		});
		return query.execute();
	}
});
ServerClient.implement(new Options());

var AjaxQuery=new Class({
	server:"",
	options:
	{
	json:{},
	task:'echo',
	onComplete:function(){},
	onSuccess:function(response){
	},
	onFailure:function(){
		mm_debug(['ServerQuery Failed.', {caller:this}]);
	}
	},
	initialize:function(options, serverClient){
		var me=this;
		//me.options=$merge(me.options,options);
		me.setOptions(options);
		me.serverClient=(serverClient||ServerClient.Instance); //TODO: try not to user ServerClient.Instance
		var ajaxPair=AjaxQuery.Ajax(	
				me.serverClient.options.server+"&task="+me.options.task+"&json="+((AjaxQuery.JsonString(me.options.json)).replace(/&/g, '%26').replace(/#/g,'%23')),
				{
					method:"get",
					urlEncoded:false,
					headers:{'Content-Type': 'text/xml; charset="utf-8"'},
					onSuccess:function(response){
					me.onSuccess(response);
				},
				onFailure:function(){
					me.fireEvent('onFailure');
				},
				onComplete:function(response){
					me.onComplete(response);
				}
				});
		
		me.ajax=ajaxPair.ajax;
		me.ajax.implement=(new Groupable());
		me.send=ajaxPair.send;
	},
	onSuccess:function(response){
		var me=this;
		me.fireEvent('onSuccess', response);
		return response;
	},
	onComplete:function(response){
		var me=this;
		me.fireEvent('onComplete',response);
		
		
	},
	execute:function(){
		var me=this;
		me.send();
		return me.ajax;
	},
	cancel:function(){
		var me=this;
		var result = me.ajax.cancel();
		me.fireEvent('onCancel',result);
		return result;
	}
});
AjaxQuery.implement(new Eventable(), new Options());


if(!(typeof Ajax == 'undefined')){
	mm_debug("Fixing Ajax Call!");
	var GXHR=XHR.extend({
	isSuccess: function( xhr ) {
		    try {
		        // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
		        return !xhr.status && location.protocol === "file:" ||
		            // Opera returns 0 when status is 304
		            ( xhr.status >= 200 && xhr.status < 300 ) ||
		            xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
		    } catch(e) {}

		    return false;
		}


	});

}



AjaxQuery.Ajax=function(url, options){
	var result={};
	if(!(typeof Request == 'undefined'))
	{
		mm_debug("Ajax Method: Request");
		options['url']=url;
		result.ajax=new Request(options);
		result.send=function(){result.ajax.send();};
	}
	else if(!(typeof Ajax == 'undefined'))
	{
		///mm_debug("Ajax Method: GAjax");
		//result.ajax=new GXHR({method: 'get'});
		//result.send=function(){result.ajax.send(url);};
		result.ajax=new Ajax(url,options);
		result.send=function(){result.ajax.request();};	
	}
	return result;
};
AjaxQuery.JsonString=function(mixed){
	if(!(typeof Request == 'undefined'))
	{
		return JSON.encode(object); 
	}
	else if(!(typeof Json == 'undefined'))
	{
		return Json.toString(mixed);
	}
};
AjaxQuery.StringJson=function(string){
	if(!(typeof Request == 'undefined'))
	{
		mm_debug('Json Decode Failed');
		return text;//TODO: might need to decode 
	}
	else if(!(typeof Json == 'undefined'))
	{
		return Json.evaluate(string); 
	}
};


/*
 * JsonResponse Query!!! Used alot.
 */

var JsonQuery=AjaxQuery.extend({

	initialize:function(item, serverClient)
	{
	var me=this;

	var mapItem=item.wrapper||item.sublayer||item;
	var json=me.json||{};
	if(me.identify)me.identify(mapItem,json);
	this.parent(
			{
				'json':json,
				'task':me.task
			}, serverClient||MapFactory.GetMM(mapItem).serverClient);
	},
	onSuccess:function(response)
	{
		var me=this;
		me.fireEvent('onSuccess', AjaxQuery.StringJson(response));
	}
});


//TODO: IconSets use this!

function AjaxRequest(url,options)
{

	//mm_debug(url);
	if(options.onFailure)
	{
		var tmp=options.onFailure;
		options.onFailure=function(){
			mm_debug("AJAX Failure : "+url+(!url||url==""?"Empty URL":""));
			tmp();
		};

	}
	else
	{
		var tmp=options.onFailure;
		options.onFailure=function(){
			mm_debug("AJAX Failure: "+url+(!url||url==""?"Empty URL":""));
		};
	}

	var ajax=null;

	if(!(typeof Request == 'undefined'))
	{
		options['url']=url;
		ajax=new Request(options);
		ajax.send();

	}
	else if(!(typeof Ajax == 'undefined'))
	{
		ajax=new Ajax(url,options);
		ajax.request();	
	}
	return ajax;
}

