EMA.maps=(function(){
	this.debug=false;
	this.center={x:0,y:0,z:0};

	function init(params){
/**
* Instantiate Google map
*
* @author		mga
* @name			EMA.maps.init()
* @params		type: type of map we want (default=same as destination page) || "city"
* @params		target: html object that will contain the Map
* @params		center: js object that will center the Map {lat:<long>,lng:<long>,z:<int>}
* @params		icon: js object display the icons {normal:<string>,alt:<string>}
* @example		EMA.maps.init({target:$("#gmap").get(0),center:{lat:50.8371,lng:4.3676,z:2},icon:{normal:"http://staticbairv2.emakina.dev/_html/_img/ico_point.png",alt:""}});
*/
		this.loadingClass="ac_loading";
		if (GBrowserIsCompatible()) {
			this.normalIcon=new GIcon();
			this.normalIcon.image=params.icon.normal;
			//normalIcon.shadow="/cs/B2C/googlemap/images/shadow50.png";
			this.normalIcon.iconSize=new GSize(49,55);
			this.normalIcon.shadowSize=new GSize(0,0);
			this.normalIcon.iconAnchor=new GPoint(21,42);
			this.normalIcon.infoWindowAnchor=new GPoint(20,16);
			this.normalIcon.infoShadowAnchor=new GPoint(20,34);
	
			this.altIcon=new GIcon();
			this.altIcon.image="http://staticbairv2.emakina.dev/_html/_img/ico_city.png";
			this.altIcon.iconSize=new GSize(49,55);
			this.altIcon.shadowSize=new GSize(0,0);
			this.altIcon.iconAnchor=new GPoint(21,42);
			this.altIcon.infoWindowAnchor=new GPoint(20,16);
			this.altIcon.infoShadowAnchor=new GPoint(20,34);

			//highlightIcon=new GIcon(normalIcon);
			//highlightIcon.image="/cs/B2C/googlemap/images/marker_hover.png";
			this.map=new GMap2(params.target,{minResolution:"5"});
			this.map.addControl(new GSmallMapControl());
			this.map.addControl(new GMapTypeControl());
				
			this.map.setCenter(new GLatLng(params.center.lat,params.center.lng),params.center.z);
			this.center={x:params.center.lat,y:params.center.lng,z:params.center.z}
			/*
			GEvent.bind(map,"zoomend",this,function() { moveMarker(); });
			GEvent.addListener(map, "dragstart", function(event){resetmarkerstates();})
			GEvent.addListener(map, "click", function(marker, point){
				if(!marker){
						resetmarkerstates();
					}
			})
			GEvent.addListener(this.map, "load", function(event){alert(event);})
			GEvent.addListener(map.getInfoWindow(), "closeclick", function(event){resetmarkerstates();});
			*/
			GEvent.addListener(this.map,"move",function(){checkBounds();});//limiting map range

			//limiting zoomout
			$(this.map.getMapTypes()).each(function(){this.getMinimumResolution=function(){return 2;}});
			function waitTillLoaded(elm){
				if(!EMA.maps.cityfilled){
					EMA.loadings=setTimeout(function(){waitTillLoaded(elm)},10);return false;
				} else {
					clearTimeout(EMA.loadings);
					$(EMA.maps.citypoints).each(function(){
						elm.addPoint({type:"city",point:this});
					});
					$("."+EMA.maps.loadingClass).hide();
					return true;
				}
			}
			switch (params.type){
				case "city":
					var that=this;
					waitTillLoaded(that);
					break;
				default:
					this.interval=setInterval("EMA.maps.drawPoints(EMA.points)",1);
					break;
			}
			var allowedBounds=function(z){
				switch (z){
					case 2:return new GLatLngBounds(new GLatLng(-58,-179), new GLatLng(58,179));
						break;
					case 3:return new GLatLngBounds(new GLatLng(-77,-179), new GLatLng(77,179));
						break
					default:return new GLatLngBounds(new GLatLng(-82,-179), new GLatLng(82,179));
				}
			};
				
			function checkBounds() {
				// Perform the check and return if OK
				if (allowedBounds(EMA.maps.map.getZoom()).contains(EMA.maps.map.getCenter())) {return;}
				// It`s not OK, so find the nearest allowed point and move there
				var C = EMA.maps.map.getCenter();
				var X = C.lng();
				var Y = C.lat();
				
				var AmaxX = allowedBounds(EMA.maps.map.getZoom()).getNorthEast().lng();
				var AmaxY = allowedBounds(EMA.maps.map.getZoom()).getNorthEast().lat();
				var AminX = allowedBounds(EMA.maps.map.getZoom()).getSouthWest().lng();
				var AminY = allowedBounds(EMA.maps.map.getZoom()).getSouthWest().lat();
				
				if (X < AminX) {X = AminX;}
				if (X > AmaxX) {X = AmaxX;}
				if (Y < AminY) {Y = AminY;}
				if (Y > AmaxY) {Y = AmaxY;}
				//alert ("Restricting "+Y+" "+X);
				EMA.maps.map.setCenter(new GLatLng(Y,X));
			}
		}
	}
	var currentPoint=0;
	function drawPoints(pointList){
	
/**
* interval based drawing of points on Google map
*
* @author		mga
* @name			EMA.maps.drawPoints()
* @params		array: html object that will contain the Map
* @example		EMAinterval=setInterval("EMA.maps.drawPoints(EMA.points)",1);
*/
		//used for big lists
		//EMA.drawPoints accepts a param that is a list of airport ID
		//called by EMAinterval=setInterval("EMA.drawPoints(ARRAY)",1);

		if (typeof(pointList)=="undefined") {return false;}
		if (currentPoint>=pointList.length-1){clearInterval(this.interval);$("."+EMA.maps.loadingClass).hide();}
		//console.log(arguments.callee.caller)
		//console.log(arguments.callee.name)
		this.addPoint({type:"destinations",id:pointList[currentPoint].id,point:EMA.airports[pointList[currentPoint].id]});
		currentPoint++;
	}
	


	
	function addPoint(params){
/**
* Drawing a point on Google map
*
* @author		mga
* @name			EMA.maps.addPoint()
* @params		pointid: integer id of an EMA.point
* @params		p: {lat:<long>,lng:<long>}
*/
/*
this.addPoint({type:"destinations",id:pointList[currentPoint].id,point:EMA.airports[pointList[currentPoint].id]});
that.addPoint({type:"city",point:this});
*/
	if (!params.point){return false;}
		function getHTML(args){
			var wr="";
			switch (args.type){
				case "airport":
					//city as airport (all airports closed)
					var name=(args.params.point.closed==true)?args.name:EMA.airports[args.params.point.id].longName
					wr+='<h3 style="margin:0;">'+name+'<\/h3>';
				break;
				default:
					var city=args.name;
					var code=(args.from=="citypage")?args.code:args.params.point.code;
					wr+='<div style="width:220px;height:auto;"><table cellpadding="0" cellspacing="0" border="0" style="width:220px;table-layout:fixed"><tr valign="top">\
							<td style="padding-right:10px;"><img src="/handlers/fromtoimage.ashx?from='+EMA.Themes.sDepartureAirportCode+'&amp;to='+code+'" onerror="this.src=\'http://staticbairv2.emakina.dev/_html/_img/cms/z_promotion.jpg\'" alt="'+city+'" \/><\/td>\
							<td style="width:150px;">\
								<h2 style="margin:0;text-transform:uppercase;font-size:17px">'+city+'<\/h2>';
								if (args.from!="citypage"){//EMA.cities[EMA.airports[13045].cityCode].id
									wr+='<p style="margin:2px 0 0 0;line-height:1.2em;font-size:12px;"><a href="/dynalink.aspx?compid='+EMA.cities[EMA.airports[args.params.id].cityCode].id+'&amp;tempid='+cityTemplateId+'&amp;pubid='+sPublicationId+'" class="discover" style="display:block;text-decoration:none;background-position:0 -45px">'+EMA.labels.Map.moreInfo.replace("__city__",city)+'<\/a><\/p>'
								}
								if (typeof(args.opts.price)!="undefined"&&args.opts.price!=null){
								/*PROMOTION Links*/
								var plink=EMA.maps.getPromoLink({cityCode:code,journeySpan:opts.journeySpan});
								var picon=EMA.maps.getFlightTypeIcon({journeySpan:opts.journeySpan});
									wr+='	<p style="margin:2px 0 0 0;line-height:1.2em;font-size:12px;"><a href="'+plink+'" class="promo" style="display:block;text-decoration:none;background-position:0 -96px;">'+EMA.labels.Map.promo.replace("__city__",city).replace("__price__",args.opts.price.replace(/\s/gi,"&nbsp;"))+' '+picon+'<\/a><\/p>';
									wr+='	<p style="padding-top:0.5em;text-align:center;margin:0;font-size:12px;"><a class="r_btn b_btn" href="'+plink+'"><span><span style="padding:0 25px 0 10px">'+EMA.labels.Map.bookNow+'<\/span><\/span><\/a><\/p>\n';
								} else {
								/*Normal links*/
									wr+='	<p style="padding-top:0.5em;text-align:center;margin:0;font-size:12px;"><a class="r_btn b_btn" href="/'+sLocale+'/book/flights/default.aspx?departureDate='+EMA.outputDate(EMA.Themes.departureDate,"dd-mm-yyyy")+'&amp;returnDate='+EMA.outputDate(EMA.Themes.returnDate,"dd-mm-yyyy")+'&amp;destination='+code+'"><span><span style="padding:0 25px 0 10px">'+EMA.labels.Map.bookNow+'<\/span><\/span><\/a><\/p>\n';
								
								}
					wr+="	<\/td>\n";
					wr+="<\/tr><\/table><\/div>";
				break;
			}
			return wr;
		}
		//var icon=(type=="")
		var opts={},point;
		switch (params.type) {
			case "city":
				var name
				opts.price=params.point.price;
				opts.bclass=params.point.bclass;
				opts.journeySpan=params.point.journeySpan;
				point=params.point.p;
				point.id=(!params.point.id)?0:params.point.id;
				point.icon=(params.point.type==="city")?this.altIcon:this.normalIcon;
				point.html=getHTML({type:params.point.type,opts:opts,name:EMA.cities[cityCode].name,params:params,from:"citypage",code:cityCode});
				EMA.maps.addMarker(point,opts);
			break;
			default:
				var name=EMA.cities[params.point.cityCode].name;
				opts.price=EMA.promos[params.id].price;
				opts.bclass=EMA.promos[params.id].bclass;
				opts.journeySpan=EMA.promos[params.id].journeySpan;
				point=params.point.p;
				point.id=params.id
				point.icon=this.normalIcon;
				point.html=getHTML({params:params,opts:opts,name:name});
				EMA.maps.addMarker(point,opts);
			break;
		}
	}
	
	function addMarker(point,opts){
		//plot a point
		//cleanead by RemoveMapPoints()
		this.gpoints=(typeof(this.gpoints)!="undefined")?this.gpoints:[];
		var marker=new GMarker(new GLatLng(point.lat,point.lng), point.icon);
			marker.EMA=opts;
		
		GEvent.addListener(marker, "click", function() {
			if(!$('#infoWindow').length){$("body").append('<div id="infoWindow" style="font-size:1.2em;display:none;"><\/div>')}
			$('#infoWindow').html(point.html)
			marker.openInfoWindow(point.html.replace("height:auto;","height:"+$('#infoWindow').height()+"px"));
			EMA.gmarker=marker;
		})
		//storing markers for external ref (deleting)
		this.gpoints.push(marker);
		this.map.addOverlay(marker);
		/* debugging gatwick
		if(point.id==13088){
			alert("ya")
			if(!$('#infoWindow').length){$("body").append('<div id="infoWindow" style="font-size:1.2em;display:none;"><\/div>')}
			$('#infoWindow').html(point.html)
			marker.openInfoWindow(point.html.replace("height:auto;","height:"+$('#infoWindow').height()+"px"));
			EMA.gmarker=marker;
		}
		*/
	}
	function removeMapPoints(){
/**
* remove all the points on the map
*
* @author		mga
* @name			EMA.maps.removeMapPoints()
*/
		currentPoint=0;
		if (typeof(this.gpoints)=="undefined"){return true;}
		for (var i=0;i<this.gpoints.length;i++){
		    this.map.removeOverlay(this.gpoints[i]);
		}
		//cleaning array
		this.gpoints=[];
	}
	function getDestinations(params){
		/*AJAX To airports*/
		$.ajax({
			type:"POST",
			url:"/"+sLocale+"/webservices/Destinations.asmx/GetToDestinationsWithPromotions",
			dataType:"xml",
			data:"publicationId="+sPublicationId+"&departureDate="+EMA.Themes.departureDate.replace(/\//gi,'-')+"&departureAirportCode="+EMA.Themes.sDepartureAirportCode,
			processData:false,
			error:function(XMLHttpRequest,textStatus,errorThrown){alert(errorThrown);},
			success:function(xml){
				switch (params.type) {
					case "city":
						EMA.maps.citypoints=[];
						var promofound=0;
						$(EMA.cities[cityCode].airports).each(function(){
							//build city marker lat long from EMA.cities
							//promotions from this:
							$(xml).find('airport[id='+this+']').each(function(){
								promofound++
								EMA.maps.citypoints.push({type:"city",id:$(this).attr("id"),price:$(this).attr("price"),bclass:$(this).attr("bclass"),journeySpan:$(this).attr("js"),p:EMA.cities[cityCode].p})
							});
							
							EMA.maps.citypoints.push({type:"airport",id:this,longName:EMA.airports[this].longName,p:EMA.airports[this].p,code:EMA.airports[this].code})
						});
						if(promofound==0){
							//all aiports closed;
							EMA.maps.citypoints.push({type:"city",id:null,code:cityCode,price:null,bclass:null,journeySpan:null,p:EMA.cities[cityCode].p})
						}
						EMA.maps.cityfilled=true;
						break;
					default:
						/*handling promotions*/
						EMA.points=[],EMA.themes={};EMA.promos={};
						$(xml).find('airport').each(function(){
							var p={id:$(this).attr("id"),price:$(this).attr("price"),bclass:$(this).attr("bclass"),journeySpan:$(this).attr("js")}
							EMA.points.push(p);
							EMA.promos[$(this).attr("id")]=p;
							/*finding promotions*/
							if(typeof($(this).attr("themeid"))!="undefined"){
								/*supports multi themes per airport */
								var themesIdArray=$(this).attr("themeid").split(",");
								var airportId=$(this).attr("id");
								for (var i=0,j=themesIdArray.length;i<j;i++){
									EMA.themes[themesIdArray[i]]=(typeof(EMA.themes[themesIdArray[i]])=="undefined")?[]:EMA.themes[themesIdArray[i]];
									EMA.themes[themesIdArray[i]].push({id:airportId});
								}
							}
						})
						if (typeof(params)!="undefined"&&!params.init){
							EMA.Themes.dateChanged=false;
							currentPoint=0;
							$("."+EMA.maps.loadingClass).show();
							updateResults({fromCallback:true});
						}
						break;
				}
			}
		
		});
	}
	function getPromoLink(point){
		//build promotion link
		var p="http://quicktrip.brusselsairlines.com/SN/search.html";
		p+="?returnDateDay="+EMA.outputDate(EMA.Themes.returnDate,'js').getDate();
		p+="&returnDateMonth="+(parseInt(EMA.outputDate(EMA.Themes.returnDate,'js').getMonth(),10)+1);
		p+="&returnDateYear="+EMA.outputDate(EMA.Themes.returnDate,'js').getUTCFullYear();
		p+="&departDateDay="+EMA.outputDate(EMA.Themes.departureDate,'js').getDate();
		p+="&departDateMonth="+(parseInt(EMA.outputDate(EMA.Themes.departureDate,'js').getMonth(),10)+1);
		p+="&departDateYear="+EMA.outputDate(EMA.Themes.departureDate,'js').getUTCFullYear();
		p+="&cabinClassFareLogicalName=ANY";
		//p+="&returnJourneySpan="+point.journeySpan;
		p+="&searchType=PROMO";
		p+="&departDateRange=1";
		p+="&returnDateRange=1";
		p+="&origin="+EMA.Themes.sDepartureAirportCode;
		p+="&destination="+point.cityCode;
		//need confirmation p+="&journeySpan=OW";
		p+="&journeySpan="+point.journeySpan;
		p+="&lang="+sLang;
		p+="&bookingClass=S";
		return p;
	}
	function getFlightTypeIcon(opts){
		//build flighttype icon
		var p;
		switch (opts.journeySpan.toLowerCase()) {
			case "ow":
				//p='<span class="tag_plane tag" title="One way">&nbsp;</span>';
				p=' ('+EMA.labels.Map.ow+')';
				break;
			case "rt":
				//p='<span class="tag_return tag" title="Return flight">&nbsp;</span>';
				p=' ('+EMA.labels.Map.rt+')';
				break;
			default:
				p='';
				break;
				
		}
		return p;
	};
	function recenter(){
		this.map.setCenter(new GLatLng(this.center.x,this.center.y),this.center.z);
		$("."+this.loadingClass).hide();
		return this;
	}
	return {
		addMarker:addMarker,
		addPoint:addPoint,
		debug:debug,
		drawPoints:drawPoints,
		getDestinations:getDestinations,
		getPromoLink:getPromoLink,
		getFlightTypeIcon:getFlightTypeIcon,
		init:init,
		removeMapPoints:removeMapPoints,
		recenter:recenter
	}
})();
