/**
 * @author Nivaria Innova Team
 */

var ncmGMap = {
	version: "1.1.0",
	
	createMap: function(object,centerField,options) {
		var initMapType = function() {
	    	if(!object.map) return;
	        switch(object.simplefields["MAP_VIEW"]) {
	          case "G_NORMAL_MAP":
	              object.map.setMapType(G_NORMAL_MAP);
	              break;
	          case "G_SATELLITE_MAP":
	              object.map.setMapType(G_SATELLITE_MAP);
	              break;
	          case "G_HYBRID_MAP":
	              object.map.setMapType(G_HYBRID_MAP);
	              break; 
	          case "G_PHYSICAL_MAP":
	        	  object.map.setMapType(G_PHYSICAL_MAP);
	        	  break;
	        }      
		};
	
		var initMapControls = function() {
	      	if(!object.map) return;
	        if(!object.simplefields["MAP_CONTROLS"]) return;
	        if(typeof(object.simplefields["MAP_CONTROLS"])=="object") {
	              for(var i=0;i<object.simplefields["MAP_CONTROLS"].length;i+=1) {
	                    initOneMapControl(object.simplefields["MAP_CONTROLS"][i]);
	              }
	        } else {
	              initOneMapControl(object.simplefields["MAP_CONTROLS"]);
	        }
		};
	
		var initOneMapControl = function(controlName) {
	        if(!object.map) return;
	        switch(controlName) {
	              case "GLargeMapControl":
	                    object.map.addControl(new google.maps.LargeMapControl());
	                    break;
	              case "GSmallMapControl":
	                    object.map.addControl(new google.maps.SmallMapControl());
	                    break;
	              case "GSmallZoomControl":
	                    object.map.addControl(new google.maps.SmallZoomControl());
	                    break;
	              case "GScaleControl":
	                    object.map.addControl(new google.maps.ScaleControl());
	                    break;
	              case "GMapTypeControl":
	                    object.map.addControl(new google.maps.MapTypeControl());
	                    break;
	              case "GOverviewMapControl":
	                    object.map.addControl(new google.maps.OverviewMapControl());                  
	                    break;                        
	        }
		};
	
		var initMarkerManager = function() {
			var mgrOptions = { 
				borderPadding: parseInt(object.constructor.getProperty("markerManager_borderPadding")),
				maxZoom: parseInt(object.constructor.getProperty("markerManager_maxZoom")),
				trackMarkers: false
			};
			object.markerMngr = new MarkerManager(object.map,mgrOptions);
		};
	
		var initMapBounds = function(centerPoint,distanceField) {
	        var lat = centerPoint.latRadians();
	        var lng = centerPoint.lngRadians();
			var radius = 6731; /* earth's mean radius in km*/
	        var distance = object.simplefields[distanceField]?object.simplefields[distanceField]:1;
	        var dr = distance / radius;
			var brng = -45 * Math.PI / 180;
			var upperLeftLat = Math.asin(Math.sin(lat) * Math.cos(dr) + Math.cos(lat) * Math.sin(dr) * Math.cos(brng));
			var upperLeftLng = lng + Math.atan2(Math.sin(brng) * Math.sin(dr) * Math.cos(lat), Math.cos(dr) - Math.sin(lat) * Math.sin(upperLeftLat));
			brng = 135 * Math.PI / 180;
			var lowerRightLat = Math.asin(Math.sin(lat) * Math.cos(dr) + Math.cos(lat) * Math.sin(dr) * Math.cos(brng));
			var lowerRightLng = lng + Math.atan2(Math.sin(brng) * Math.sin(dr) * Math.cos(lat), Math.cos(dr) - Math.sin(lat) * Math.sin(lowerRightLat));
			upperLeftLng = (upperLeftLng + Math.PI) % (2 * Math.PI) - Math.PI;
			lowerRightLng = (lowerRightLng + Math.PI) % (2 * Math.PI) - Math.PI;
	        object.bounds["minx"] = upperLeftLng * (180 / Math.PI);
	        object.bounds["maxy"] = upperLeftLat * (180 / Math.PI); 
	        object.bounds["maxx"] = lowerRightLng * (180 / Math.PI);
	        object.bounds["miny"] = lowerRightLat * (180 / Math.PI);
	    };
	
		var initEBubble = function() {
			if(!object.map) return;
			if(object.simplefields["USE_EBUBBLE"]){
				if(window["ebubble"+object.id]) {
					object["ebubble"] = new EBubble(object.map,window["ebubble"+object.id]["bgimage_url"],new google.maps.Size(window["ebubble"+object.id]["bgimage_w"],window["ebubble"+object.id]["bgimage_h"]), new google.maps.Size(window["ebubble"+object.id]["inner_w"],window["ebubble"+object.id]["inner_h"]), new google.maps.Point(window["ebubble"+object.id]["inner_off_x"],window["ebubble"+object.id]["inner_off_y"]), new google.maps.Point(window["ebubble"+object.id]["anchor_x"],window["ebubble"+object.id]["anchor_y"]), true, window["ebubble"+object.id]["img_close"], window["ebubble"+object.id]["img_close_h"]);      
				}
			}
		};
	
		/*Initialize the scale of map*/
	    object.scale = object.simplefields["MAP_SCALE"]?parseInt(object.simplefields["MAP_SCALE"]):13;
		var coord = ncmGMap.getDefaultCoordinates(object,centerField);
		var point = null;
	    /*Creating map object*/
	    if(!ncm.isIE6) {
			$jq(ncm.concat("#map",object.id)).each(function(i){
				object.map = new google.maps.Map2(this);
				point = new google.maps.LatLng(coord[0],coord[1]);
				try {
					object.center = point;
				} catch(mErr){}
				object.map.setCenter(point,object.scale);
				initEBubble();
				google.maps.Event.addListener(object.map,"click",function(overlay,point) {
					if(point==null || typeof(point)=="undefined") return;
					if(object.constructor.inPreview) {
						$jq("#coord_y"+object.id).html(""+point.lat());
						$jq("#coord_x"+object.id).html(""+point.lng());
					}
					if(object["ebubble"]) {
						object["ebubble"].hide();
					}
				});
				initMapType();
				initMapControls();
				initMarkerManager();
			});
	    } else {
	    	point = {lat:coord[0],lng:coord[1],latRadians:function(){return this.lat*Math.PI/180.0;},lngRadians:function(){return this.lng*Math.PI/180.0;}};
	    }	
		if(options && options.setBounds) {
			initMapBounds(point,options.distanceField);
		}
	},
	
	geoCodeAddress: function(object,address) {
		var res = [0,0];
		var jspfile = object.constructor.getProperty("jsp_ncm_gmap");
		if(jspfile=="") jspfile = "/components/helpers/googlemaps/ncmgmap.jsp";
		var params = ncm.concat("action=0&address=",address?address:"","&apikey=",object.constructor.getProperty("google_api_key"),"&country=",object.constructor.getProperty("geocode_base_country"));
		$jq.ajax({
	    	async: false,
	        type: "POST",
	        url: jspfile,
	        data: params,
	        dataType: "json",
	        error: function(request,msg,ex) {
	           ncm.showError(msg,ex,request,object.constructor.inPreview,object.constructor.jsp_utils);
	        },
	        success: function(json) {
				if(json.status) {
					if(json.status==""+G_GEO_SUCCESS) {
						res[0] = parseFloat(json.lat);
						res[1] = parseFloat(json.lng);
					} else {
						var msg = address;
						msg += "\n";
						if(json.status == "" + G_GEO_BAD_REQUEST) {
							msg += object.constructor.getProperty("G_GEO_BAD_REQUEST");
						} else if(json.status == "" + G_GEO_SERVER_ERROR) {
							msg += object.constructor.getProperty("G_GEO_SERVER_ERROR");
						} else if(json.status==""+G_GEO_MISSING_ADDRESS){
							msg += object.constructor.getProperty("G_GEO_MISSING_ADDRESS");
						} else if(json.status==""+G_GEO_UNKNOWN_ADDRESS) {
							msg += object.constructor.getProperty("G_GEO_UNKNOWN_ADDRESS");
						} else if(json.status==""+G_GEO_UNAVAILABLE_ADDRESS) {
							msg += object.constructor.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
						} else if(json.status==""+G_GEO_BAD_KEY) {
							msg += object.constructor.getProperty("G_GEO_BAD_KEY");
						} else if(json.status==""+G_GEO_TOO_MANY_QUERIES) {
							msg += object.constructor.getProperty("G_GEO_TOO_MANY_QUERIES");
						} else {
							msg += object.constructor.getProperty("lang_not_found");
						}
						ncm.showDialog(object.id,msg,true);					
					}
				}
	        }
	    });
		return res;
	}, 

	getMapType: function(object) {
	    if(!object.map) return G_NORMAL_MAP;
	    switch(object.simplefields["MAP_VIEW"]) {
			case "G_NORMAL_MAP":
			    return G_NORMAL_MAP;
			    break;
			case "G_SATELLITE_MAP":
			    return G_SATELLITE_MAP;
			    break;
			case "G_HYBRID_MAP":
			    return G_HYBRID_MAP;
			    break;            
	    }
	},

	showDefaultMap: function(object) {
		if(!object) return;
		var coord = ncmGMap.getDefaultCoordinates(object);
		if(object.map) {
			object.map.setCenter(new google.maps.LatLng(coord[0],coord[1]),object.scale);
			/*Clearing some variables*/
			object.map.clearOverlays();
		} else {
			ncmGMap.drawStaticMap(object);
		}	
		if(object.markerMngr){
			object.markerMngr.clearMarkers();
			object.markerMngr.refresh();
		}	
	},

	getDefaultCoordinates: function(object,centerField) {
		var res = [0,0];
		if(object) {
			res[0] = object.simplefields["MAP_DEFAULT_LATITUDE"]?object.simplefields["MAP_DEFAULT_LATITUDE"]:0;
			res[1] = object.simplefields["MAP_DEFAULT_LONGITUDE"]?object.simplefields["MAP_DEFAULT_LONGITUDE"]:0;
			if(res[0]==0 && res[1]==0) {
				if(!centerField) centerField = "MAP_CENTER";
				var centerFieldVal = object.simplefields[centerField];
				if(!centerFieldVal) centerFieldVal="";
				var pat = new RegExp("\\s*-?\\d+\\.?\\d*\\s*,\\s*-?\\d+\\.?\\d*\\s*");
				if(pat.test(centerFieldVal)) {
					var coords = centerFieldVal.split(/\s*,\s*/);
					res[0] = parseFloat($jq.trim(coords[0]));
					res[1] = parseFloat($jq.trim(coords[1]));
				} else {
					res = ncmGMap.geoCodeAddress(object,centerFieldVal?centerFieldVal:"");				
				}
				if(res[0]==0 && res[1]==0) {
					res = [28.47063,-16.25137];
				}
			} 
		}
		return res;
	},
	
	getDefaultRequestParams: function(object) {
		var params = "";
		if(object) {
			params = ncm.getComponentConstructorParams(object,object.constructor,false);
		}
		return params;
	},
	
	initDirections: function(object) {
		if(!object) return;
		if(!object.map) return;
		$jq(ncm.concat("#directions",object.id)).each(function(i){
			object.directions = new google.maps.Directions(object.map,this);
		});
		if(object.directions==null) {
			object.directions = new google.maps.Directions(object.map);			
		}
		google.maps.Event.addListener(object.directions, "error", function(){
			var msg = "";
			switch(object.directions.getStatus().code) {
				case G_GEO_BAD_REQUEST:
					msg = object.constructor.getProperty("G_GEO_BAD_REQUEST");
					break;
				case G_GEO_SERVER_ERROR:
					msg = object.constructor.getProperty("G_GEO_SERVER_ERROR");
					break;
				case G_GEO_MISSING_ADDRESS:
					msg = object.constructor.getProperty("G_GEO_MISSING_ADDRESS");
					break;
				case G_GEO_UNKNOWN_ADDRESS:
					msg = object.constructor.getProperty("G_GEO_UNKNOWN_ADDRESS");
					break;
				case G_GEO_UNAVAILABLE_ADDRESS:
					msg = object.constructor.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
					break;
				case G_GEO_BAD_KEY:
					msg = object.constructor.getProperty("G_GEO_BAD_KEY");
					break;
				case G_GEO_TOO_MANY_QUERIES:
					msg = object.constructor.getProperty("G_GEO_TOO_MANY_QUERIES");
					break;
				default:
					msg = object.constructor.getProperty("lang_not_found");						
					break; 
			}
			ncm.showDialog(object.id,msg,false);
		});
		google.maps.Event.addListener(object.directions,"load",function(){
			$jq(ncm.concat("#directionstop",object.id)).css("display","block");
		});
	},

	initCustomControls: function(object,arrControls) {
		if(!object) return;
		if(!object.map) return;
		
		var initOneCustomControl = function(arrFields) {
			if(!object.map) return;
			var localFields = new Array();
			for(var i=0;arrFields!=null && i<arrFields.length;i+=1) {
				localFields[arrFields[i].name] = arrFields[i].value;
			}
			var newCtrl = null;
			switch(localFields["CONTROL"]) {
				case "GLocalSearch":
					newCtrl = new google.maps.LocalSearch();
					break;
				default:
					newCtrl = null;
					break;	
			}
			var newCtrlPos = null;
			switch(localFields["POSITION"]){
				case "G_ANCHOR_BOTTOM_RIGHT":
					newCtrlPos = G_ANCHOR_BOTTOM_RIGHT;
					break;
				case "G_ANCHOR_BOTTOM_LEFT":
					newCtrlPos = G_ANCHOR_BOTTOM_LEFT;
					break;
				case "G_ANCHOR_TOP_RIGHT":
					newCtrlPos = G_ANCHOR_TOP_RIGHT;
					break;
				case "G_ANCHOR_TOP_LEFT":
					newCtrlPos = G_ANCHOR_TOP_LEFT;
					break;
			}
			var newCtrlOff = new google.maps.Size(localFields["OFFSET_X"]!=null?localFields["OFFSET_X"]:0,localFields["OFFSET_Y"]!=null?localFields["OFFSET_Y"]:0);
			if(newCtrl!=null && newCtrlPos!=null) {
				object.map.addControl(newCtrl, new google.maps.ControlPosition(newCtrlPos,newCtrlOff));			
			}
		};
		
		for(var i=0;arrControls!=null && i<arrControls.length;i+=1) {
			var oneCtrl = arrControls[i];
			initOneCustomControl(oneCtrl.simplefields);
		}
	},

	initSearcher: function(object) {
		if(!object) return;
		if(ncm.isIE6) return;
		var jspfile = object.constructor.getProperty("jsp_search");
		if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-search.jsp");
		var params = ncm.getComponentConstructorParams(object,object.constructor);
		params = ncm.concat(params,"&xsltPath=",object.constructor.getProperty("xsl_search"));
		$jq.ajax({
	    	async: true,
	    	type: "POST",
	    	url: jspfile,
	    	data: params,
	    	dataType: "json",
	    	error: function(request,msg,ex) {
	       		ncm.showError(msg,ex,request,object.constructor.inPreview,object.constructor.jsp_utils);
	    	},
	    	success: function(json) {
				if(json.html) {
					$jq(ncm.concat("#mapsearch",object.id)).html(json.html);
				}
	    	}
		});
	},
	
	initSubcategories: function(object) {
		if(!object) return;
		if(ncm.isIE6) return;
		var jspfile = object.constructor.getProperty("jsp_subcategory");
		if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-subcategory.jsp");
		var params = ncm.getComponentConstructorParams(object,object.constructor);
		params = ncm.concat(params,"&xsltPath=",object.constructor.getProperty("xsl_subcategory"));
		$jq.ajax({
	    	async: true,
	    	type: "POST",
	    	url: jspfile,
	    	data: params,
	    	dataType: "json",
	    	error: function(request,msg,ex) {
	       		ncm.showError(msg,ex,request,object.constructor.inPreview,object.constructor.jsp_utils);
	    	},
	    	success: function(json) {
				if(json.html) {
					$jq(ncm.concat("#subcategory",object.id)).html(json.html);
				}
	    	}
		});
	},

	initMapIcon: function(object,mapicon) {
		if(ncm.isIE6) return;
		if(mapicon) {
			object.icon.image = document.location["href"].substr(0,document.location["href"].lastIndexOf("/")+1)+mapicon;
		} else {
			object.icon.image = "";
		}
	},
	
	createMarker: function(object,point,id,item,aFields,tCode) {
		if(!object) return;
		if(ncm.isIE6) return;
		var marker = null;
		var itemIcon = null;
		if (item["icon"]) {
			itemIcon = item["icon"];
		} else if(item["mapicon"]) {
			itemIcon = item["mapicon"];
		}	
		if (itemIcon) {
			/*Initialize icon image*/
	      	var customIcon = new google.maps.Icon();
	      	customIcon.iconSize = new google.maps.Size(parseInt(object.constructor.getProperty("base_icon_width")), parseInt(object.constructor.getProperty("base_icon_height")));
	      	customIcon.shadowSize = new google.maps.Size(parseInt(object.constructor.getProperty("base_shadow_width")), parseInt(object.constructor.getProperty("base_shadow_height")));
	      	customIcon.iconAnchor = new google.maps.Point(parseInt(object.constructor.getProperty("base_anchor_x")), parseInt(object.constructor.getProperty("base_anchor_y")));
	      	customIcon.infoWindowAnchor = new google.maps.Point(parseInt(object.constructor.getProperty("info_window_anchor_x")), parseInt(object.constructor.getProperty("info_window_anchor_y")));
	      	customIcon.infoShadowAnchor = new google.maps.Point(parseInt(object.constructor.getProperty("info_shadow_anchor_x")), parseInt(object.constructor.getProperty("info_shadow_anchor_y")));
	      	customIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
			customIcon.image = document.location["href"].substr(0,document.location["href"].lastIndexOf("/")+1)+itemIcon;
			marker = new google.maps.Marker(point,{icon:customIcon});
		} else if($jq.trim(object.icon.image)!="") {
			marker = new google.maps.Marker(point,{icon:object.icon});
		} else {
			marker = new google.maps.Marker(point);
		}
		marker.value = id;
		google.maps.Event.addListener(marker,"mouseover",function(){
			var myHtml = tCode;
			for(var i=0;i<aFields.length;i+=1){
				var val = item[aFields[i]];
				myHtml = myHtml.replace(new RegExp("\{fields:"+i+"\}","g"),val);
			}
			var moretext = object.simplefields["TITLEDETAIL"];
			if(moretext==null || $jq.trim(moretext)=="") 
				moretext=object.constructor.getProperty("lang_more_info");
			var details = "";
			if (!object.simplefields["NO_MORE_INFO"]) {
				details = ncm.concat("<a href=\"",item.moreinfo_url?item.moreinfo_url:ncm.concat(object.simplefields["DETAILSPAGE"],"?step=3&PROID=",id),"\" title=\"",moretext,"\" >",moretext,"<\/a>");
			}	
			myHtml = myHtml.replace(/\{moreinfo\}/g,details);
			myHtml = myHtml.replace(new RegExp("\{fields:[0-9]+\}","g"),"");
			if(object["ebubble"]) {
				object["ebubble"].openOnMarker(marker,myHtml);			
			} else {
				object.map.openInfoWindowHtml(point,myHtml);	
			}
		});
		if(typeof(object.points)!="undefined") {
			object.points.push(point);	
		}
		object.markersBatch.push(marker);
		return marker;
	},

	createStaticMarker: function(object,point) {
		if(!object) return;
		if(typeof(object.points)!="undefined") {
			object.points.push(point);	
		}
		object.markersBatch.push(point.lat+","+point.lng+",blue");
	},
	
	drawMarkers: function(object) {
		if(!object) return;
		if(!object.map && !ncm.isIE6) return;
		if(!ncm.isIE6) {
			/*Putting all markers in map*/
			object.markerMngr.clearMarkers();
			object.markerMngr.addMarkers(object.markersBatch,parseInt(object.constructor.getProperty("markerManager_minZoom")));
			object.markerMngr.refresh();
			/*Recalculating the center of map after the last marker has added*/	
			if(object.simplefields["RECALC_CENTER"]) {
				var avgpoint = ncmGMap.getAvaragePoint(object);
				var newZoom = object.scale;
				if (object.constructor.getProperty("adjust_zoom") == "1") {
					if (object.bounds) {
						if (!(object.bounds["minx"] == 0 && object.bounds["miny"] == 0 && object.bounds["maxx"] == 0 && object.bounds["maxy"] == 0)) {
							var sw = new google.maps.LatLng(object.bounds["miny"], object.bounds["minx"]);
							var ne = new google.maps.LatLng(object.bounds["maxy"], object.bounds["maxx"]);
							var b = new google.maps.LatLngBounds(sw, ne);
							newZoom = object.map.getBoundsZoomLevel(b);
						}
					}
				}	
				if(avgpoint!=null) object.map.setCenter(avgpoint,newZoom);	
			}
		} else {
			ncmGMap.drawStaticMap(object);
		}	
	},
	
	drawStaticMap: function(object,isPath){
		var mapSrc = ncm.concat("http://maps.google.com/staticmap?size=",object.simplefields["MAP_WIDTH"],"x",object.simplefields["MAP_HEIGHT"],"&maptype=mobile");
		if(!object.markersBatch || object.markersBatch.length===0) {
			var cc = ncmGMap.getDefaultCoordinates(object);
			mapSrc = ncm.concat(mapSrc,"&center=",cc[0],",",cc[1],"&zoom=",object.scale);
		} else {
			if(isPath){
				mapSrc = ncm.concat(mapSrc,"&path=rgba:0xff0000ff,weight:5|");
			} else {	
				mapSrc = ncm.concat(mapSrc,"&markers=");
			}
			mapSrc = ncm.concat(mapSrc,object.markersBatch.join("|"));
		}
		mapSrc = ncm.concat(mapSrc,"&key=",object.constructor.getProperty("google_api_key"),"&sensor=false");
		var img = ncm.concat("<img src=\"",mapSrc,"\" title=\"\" \/>");
		$jq(ncm.concat("#map",object.id)).html(img);
	},
	
	getAvaragePoint: function(object) {
		if(ncm.isIE6) return;
		var point = null;
		if(object && typeof(object.points)!="undefined") {
			if(object.bounds) {
		        object.bounds["minx"] = 0.0;
		        object.bounds["maxy"] = 0.0; 
	    	    object.bounds["maxx"] = 0.0;
	        	object.bounds["miny"] = 0.0;
			}
			if(object.points.length > 0) {
				var sumlat = 0.0, sumlng = 0.0, minlat = 0.0, maxlat = 0.0, minlng = 0.0, maxlng = 0.0;
				$jq.each(object.points, function(arrIndex, value){
					sumlat += this.lat();
					sumlng += this.lng();
					if (arrIndex === 0) {
						minlat = maxlat = this.lat();
						minlng = maxlng = this.lng();
					}
					else {
						minlat = Math.min(minlat, this.lat());
						maxlat = Math.max(maxlat, this.lat());
						minlng = Math.min(minlng, this.lng());
						maxlng = Math.max(maxlng, this.lng());
					}
				});
				if(object.constructor.getProperty("recalc_center_method") == "avg") {
					point = new google.maps.LatLng(sumlat/object.points.length, sumlng/object.points.length);
				} else {
					point = new google.maps.LatLng((minlat+maxlat)/2.0, (minlng+maxlng)/2.0);
				}
				if(point.lat()==0 && point.lng()==0) {
					point = null;
				}
				if(object.constructor.getProperty("adjust_zoom")=="1") {
					if(object.bounds) {
						var pdelta = object.constructor.getProperty("adjust_zoom_delta");
						var delta = 0.05;
						if($jq.trim(pdelta)!=="") {
							delta = parseFloat(pdelta);
						}
						object.bounds["maxy"] = maxlat + delta; 
	    	    		object.bounds["maxx"] = maxlng + delta;
	        			object.bounds["miny"] = minlat - delta;
		        		object.bounds["minx"] = minlng - delta;
					}
				}
			}	
		}
		if(point == null) {
			var coord = ncmGMap.getDefaultCoordinates(object); 
			point = new google.maps.LatLng(coord[0],coord[1]);
		}	
		return point;
	}
}
