if(typeof(magicMaps) == "undefined") { var magicMaps = new Object; }

magicMaps.ajax =
{
	ajaxObj: {},
	responseData: '',
	
	createXMLHttp: function()
	{
		if(typeof XMLHttpRequest != 'undefined')
		{
			return new XMLHttpRequest();
		}
		else if(window.ActiveXObject)
		{
			var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp",
			"MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0",
			"MSXML2.XmlHttp.5.0"];
			for (var i = avers.length -1; i >= 0; i--)
			{
				try
				{
					httpObj = new ActiveXObject(avers[i]);
					return httpObj;
				}
				catch(e) {}
			}
		}
		alert('XMLHttp (AJAX) not supported');
	},
	
	/* requestTracker is optional and can be used to make sure repeat ajax calls are not queued up. if a previous one is still pending with the same tracker, it will be aborted before the new one is sent */
	loadViaAjax: function(url, callbackSuccess, requestTracker)
	{
		magicMaps.ajax.abortRelatedAjaxRequests(requestTracker);
		magicMaps.ajax.ajaxObj[requestTracker] = {};
		
		magicMaps.ajax.ajaxObj[requestTracker] = magicMaps.ajax.createXMLHttp();
		magicMaps.ajax.ajaxObj[requestTracker].open("GET", url, true);
		magicMaps.ajax.ajaxObj[requestTracker].onreadystatechange = function()
		{
			//* 2 (loaded) - we have sent the request.
			//* 3 (interactive) - a partial response has been received.
			//* 4 (complete) - a complete response has been received and the connection has been closed.
			if(magicMaps.ajax.ajaxObj[requestTracker].readyState == 4)
			{
				var cType = magicMaps.ajax.ajaxObj[requestTracker].getResponseHeader("Content-Type");
				if(cType == 'text/xml')
				{
					magicMaps.ajax.responseData = magicMaps.ajax.ajaxObj[requestTracker].responseXML;
					callbackSuccess();
				}
				else if((cType == 'text/plain') || (cType == 'text/html'))
				{
					magicMaps.ajax.responseData = magicMaps.ajax.ajaxObj[requestTracker].responseText;
					callbackSuccess();
				}
			}
		}
		magicMaps.ajax.ajaxObj[requestTracker].send(null); 
	},
	
	abortRelatedAjaxRequests: function(requestTracker)
	{
		if(requestTracker == "ALL")
		{
			for(aj in magicMaps.ajax.ajaxObj)
			{
				if(magicMaps.ajax.ajaxObj[aj].readyState != 4)
				{
					magicMaps.ajax.ajaxObj[aj].abort();
				}
			}
		}
		else
		{
			if(typeof(magicMaps.ajax.ajaxObj[requestTracker]) != "undefined")
			{
				if(magicMaps.ajax.ajaxObj[requestTracker].readyState != 4)
				{
					magicMaps.ajax.ajaxObj[requestTracker].abort();
				}
			}
		}
	}
}

magicMaps.searchFunctions =
{
	ajaxObj: null,
	
	submitForm: function(formId)
	{
		magicMaps.searchFunctions.ajaxObj = new sack();
		
		// first gather up all the form elements
		for(var i=0; i<document.getElementById(formId).elements.length; i++)
		{
			if((typeof(document.getElementById(formId).elements[i].value) != "undefined") && (typeof(document.getElementById(formId).elements[i].name) != "undefined"))
			{
				magicMaps.searchFunctions.ajaxObj.setVar(document.getElementById(formId).elements[i].name, document.getElementById(formId).elements[i].value);
			}
		}
		
		magicMaps.searchFunctions.ajaxObj.requestFile 	= "/magicLibrary/php/api/google_maps/processSearch.ajax.php";
		magicMaps.searchFunctions.ajaxObj.onLoading 		= magicMaps.searchFunctions.ajaxLoading;
		magicMaps.searchFunctions.ajaxObj.onLoaded 		= magicMaps.searchFunctions.ajaxLoaded;
		magicMaps.searchFunctions.ajaxObj.onCompletion 	= magicMaps.searchFunctions.ajaxCompleted;
		magicMaps.searchFunctions.ajaxObj.runAJAX();
		return false;
	},
	
	ajaxLoading: function()
	{
		// loading
	},
	
	ajaxLoaded: function()
	{
		// loaded
	},
	
	ajaxCompleted: function()
	{
		// try to decode JSON response
		try
		{
			var responseObj = JSON.decode(magicMaps.searchFunctions.ajaxObj.response);
		}
		catch(e)
		{
		   alert(e);
		}
		
		if(typeof(responseObj.coords) == "object")
		{
			magicMaps.searchFunctions.moveMapToPosition(responseObj.coords.latitude, responseObj.coords.longitude);
		}
	},
	
	moveMapToPosition: function(latitude, longitude)
	{
		// move map
		var point = new GLatLng(latitude, longitude);
		map_Test_Map.setCenter(point);
	}
}

/* bubble content functions */
magicMaps.bubbleFunctions =
{
	ajaxObj: null,
	bubbleContent: null,
	marker: null,
	url: "/magicLibrary/php/api/google_maps/loadBubbleContent.ajax.php",
	
	loadBubbleContent: function(marker, point, datasetUID, dataTracker)
	{
		/* cancel any previous 'bubble' requests */
		if(magicMaps.bubbleFunctions.ajaxObj != null)
		{
			if(magicMaps.bubbleFunctions.ajaxObj.xmlhttp != null)
			{
				magicMaps.bubbleFunctions.ajaxObj.xmlhttp.abort();
			}
		}

		magicMaps.bubbleFunctions.marker = marker;
		magicMaps.bubbleFunctions.ajaxObj = new sack();
		magicMaps.bubbleFunctions.ajaxObj.method = "POST";
		
		for(p in point)
		{
			if((typeof(point[p]) != "function") && (typeof(point[p]) != "object"))
			{
				magicMaps.bubbleFunctions.ajaxObj.setVar(p, point[p]);
			}
		}
		
		if(datasetUID != null)
		{
			magicMaps.bubbleFunctions.ajaxObj.setVar("datasetUID", datasetUID);
		}
		
		if(dataTracker != null)
		{
			magicMaps.bubbleFunctions.ajaxObj.setVar("dataTracker", dataTracker);
		}
		
		magicMaps.bubbleFunctions.ajaxObj.requestFile 	= magicMaps.bubbleFunctions.url;
		
		magicMaps.bubbleFunctions.ajaxObj.onLoading 	= magicMaps.bubbleFunctions.ajaxLoading;
		magicMaps.bubbleFunctions.ajaxObj.onLoaded 		= magicMaps.bubbleFunctions.ajaxLoaded;
		magicMaps.bubbleFunctions.ajaxObj.onCompletion 	= magicMaps.bubbleFunctions.ajaxCompleted;
		magicMaps.bubbleFunctions.ajaxObj.runAJAX();
		return false;
	},
	
	ajaxLoading: function()
	{
		// loading
	},
	
	ajaxLoaded: function()
	{
		// loaded
	},
	
	ajaxCompleted: function()
	{
		// try to decode JSON response
		try
		{
			rs = JSON.decode(magicMaps.bubbleFunctions.ajaxObj.response);

			tabs = [];
			for(bc in rs.content)
			{
                chk = bc * 1;
                if(chk==bc) {
				    tabs.push(new GInfoWindowTab(rs.content[bc]['title'], "<div class='bubbleContent'>"+rs.content[bc]['content']+"</div>"));
                }
			}
			magicMaps.bubbleFunctions.marker.openInfoWindowTabsHtml(tabs);
		}
		catch(e)
		{
		   alert(e);
		}
	}
}

/* browser detect functions */
magicMaps.browserDetect =
{
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{
			string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari",
			versionSearch: "Version"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			   string: navigator.userAgent,
			   subString: "iPhone",
			   identity: "iPhone/iPod"
	    },
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]
}


/* JSON functions */
JSON = new function()
{
	this.decode = function(){
		var	filter, result, self, tmp;
		if($$("toString")) {
			switch(arguments.length){
				case	2:
					self = arguments[0];
					filter = arguments[1];
					break;
				case	1:
					if($[typeof arguments[0]](arguments[0]) === Function) {
						self = this;
						filter = arguments[0];
					}
					else
						self = arguments[0];
					break;
				default:
					self = this;
					break;
			};
			if(rc.test(self)){
				try{
					result = e("(".concat(self, ")"));
					if(filter && result !== null && (tmp = $[typeof result](result)) && (tmp === Array || tmp === Object)){
						for(self in result)
							result[self] = v(self, result) ? filter(self, result[self]) : result[self];
					}
				}
				catch(z){}
			}
			else {
				// do nothing
			}
		};
		return result;
	};

	this.encode = function(){
		var	self = arguments.length ? arguments[0] : this,
			result, tmp;
		if(self === null)
			result = "null";
		else if(self !== undefined && (tmp = $[typeof self](self))) {
			switch(tmp){
				case	Array:
					result = [];
					for(var	i = 0, j = 0, k = self.length; j < k; j++) {
						if(self[j] !== undefined && (tmp = JSON.encode(self[j])))
							result[i++] = tmp;
					};
					result = "[".concat(result.join(","), "]");
					break;
				case	Boolean:
					result = String(self);
					break;
				case	Date:
					result = '"'.concat(self.getFullYear(), '-', d(self.getMonth() + 1), '-', d(self.getDate()), 'T', d(self.getHours()), ':', d(self.getMinutes()), ':', d(self.getSeconds()), '"');
					break;
				case	Function:
					break;
				case	Number:
					result = isFinite(self) ? String(self) : "null";
					break;
				case	String:
					result = '"'.concat(self.replace(rs, s).replace(ru, u), '"');
					break;
				default:
					var	i = 0, key;
					result = [];
					for(key in self) {
						if(self[key] !== undefined && (tmp = JSON.encode(self[key])))
							result[i++] = '"'.concat(key.replace(rs, s).replace(ru, u), '":', tmp);
					};
					result = "{".concat(result.join(","), "}");
					break;
			}
		};
		return result;
	};

	this.toDate = function(){
		var	self = arguments.length ? arguments[0] : this,
			result;
		if(rd.test(self)){
			result = new Date;
			result.setHours(i(self, 11, 2));
			result.setMinutes(i(self, 14, 2));
			result.setSeconds(i(self, 17, 2));
			result.setMonth(i(self, 5, 2) - 1);
			result.setDate(i(self, 8, 2));
			result.setFullYear(i(self, 0, 4));
		}
		else if(rt.test(self))
			result = new Date(self * 1000);
		return result;
	};

	var	c = {"\b":"b","\t":"t","\n":"n","\f":"f","\r":"r",'"':'"',"\\":"\\","/":"/"},
		d = function(n){return n<10?"0".concat(n):n},
		e = function(c,f,e){e=eval;delete eval;if(typeof eval==="undefined")eval=e;f=eval(""+c);eval=e;return f},
		i = function(e,p,l){return 1*e.substr(p,l)},
		p = ["","000","00","0",""],
		rc = null,
		rd = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/,
		rs = /(\x5c|\x2F|\x22|[\x0c-\x0d]|[\x08-\x0a])/g,
		rt = /^([0-9]+|[0-9]+[,\.][0-9]{1,3})$/,
		ru = /([\x00-\x07]|\x0b|[\x0e-\x1f])/g,
		s = function(i,d){return "\\".concat(c[d])},
		u = function(i,d){
			var	n=d.charCodeAt(0).toString(16);
			return "\\u".concat(p[n.length],n)
		},
		v = function(k,v){return $[typeof result](result)!==Function&&(v.hasOwnProperty?v.hasOwnProperty(k):v.constructor.prototype[k]!==v[k])},
		$ = {
			"boolean":function(){return Boolean},
			"function":function(){return Function},
			"number":function(){return Number},
			"object":function(o){return o instanceof o.constructor?o.constructor:null},
			"string":function(){return String},
			"undefined":function(){return null}
		},
		$$ = function(m){
			function $(c,t){t=c[m];delete c[m];try{e(c)}catch(z){c[m]=t;return 1}};
			return $(Array)&&$(Object)
		};
	try{rc=new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$')}
	catch(z){rc=/^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/}
}
