/**
 * @author Nivaria Innova Team
 */

var ncmGMap = {
	version: "1.0.0"
}

ncmGMap.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;            
        }      
	};
	
	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++) {
                    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.manager.getProperty("markerManager_borderPadding")),
			maxZoom: parseInt(object.manager.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);
    };
	
	//Initialize the scale of map
    object.scale = object.simplefields["MAP_SCALE"]?parseInt(object.simplefields["MAP_SCALE"]):13;
    //Creating map object
    var selector = new String("#map");
    selector += object.id;
	$jq(selector).each(function(i){
		object.map = new google.maps.Map2(this);
		var coord = ncmGMap.getDefaultCoordinates(object,centerField);
		var point = new google.maps.LatLng(coord[0],coord[1]);
		try {
			object.center = point;
		} catch(mErr){}
		object.map.setCenter(point,object.scale);
		if(object.manager.inPreview) {
			google.maps.Event.addListener(object.map,"click",function(overlay,point) {
				if(point==null || typeof(point)=="undefined") return;
				$jq("#coord_y"+object.id).html(""+point.lat());
				$jq("#coord_x"+object.id).html(""+point.lng());
			});
		}
		initMapType();
		initMapControls();
		initMarkerManager();
		if(options && options.setBounds) {
			initMapBounds(point,options.distanceField);
		}
	});
}

ncmGMap.geoCodeAddress = function(object,address) {
	var res = [0,0];
	var jspfile = object.manager.getProperty("jsp_ncm_gmap");
	if(jspfile=="") jspfile = "/components/helpers/googlemaps/ncmgmap.jsp";
	var params = new String("action=0");
	params += "&address=";
	params += address?address:"";
	params += "&apikey=";
	params += object.manager.getProperty("google_api_key");
	params += "&country=";
	params += object.manager.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.manager.inPreview,object.manager.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.manager.getProperty("G_GEO_BAD_REQUEST");
					} else if(json.status == "" + G_GEO_SERVER_ERROR) {
						msg += object.manager.getProperty("G_GEO_SERVER_ERROR");
					} else if(json.status==""+G_GEO_MISSING_ADDRESS){
						msg += object.manager.getProperty("G_GEO_MISSING_ADDRESS");
					} else if(json.status==""+G_GEO_UNKNOWN_ADDRESS) {
						msg += object.manager.getProperty("G_GEO_UNKNOWN_ADDRESS");
					} else if(json.status==""+G_GEO_UNAVAILABLE_ADDRESS) {
						msg += object.manager.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
					} else if(json.status==""+G_GEO_BAD_KEY) {
						msg += object.manager.getProperty("G_GEO_BAD_KEY");
					} else if(json.status==""+G_GEO_TOO_MANY_QUERIES) {
						msg += object.manager.getProperty("G_GEO_TOO_MANY_QUERIES");
					} else {
						msg += object.manager.getProperty("LANG_NOT_FOUND");
					}
					ncm.showDialog(object.id,msg,true);					
				}
			}
        }
    });
	return res;
} 

ncmGMap.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;            
    }
}

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

ncmGMap.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;
}

ncmGMap.getDefaultRequestParams = function(object) {
	var params = "";
	if(object) {
		params += "objId=";
		params += object.id;
		params += "&inPreview="
		params += object.manager.inPreview?"1":"0";
		params += "&pageUrl=";
		params += object.manager.pageUrl?object.manager.pageUrl:"";
		params += "&channel=";
		params += object.manager.channel?object.manager.channel:"";
		params += "&issueId=";
		params += object.manager.issueId?object.manager.issueId:"-1";
		params += "&language=";
		params += object.manager.language?object.manager.language:"DEF";
		params += "&pageId=";
		params += object.manager.pageId?object.manager.pageId:"";
	}
	return params;
}

ncmGMap.initDirections = function(object) {
	if(!object) return;
	if(!object.map) return;
	var selector = new String("#directions");
	selector += object.id;
	$jq(selector).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.manager.getProperty("G_GEO_BAD_REQUEST");
				break;
			case G_GEO_SERVER_ERROR:
				msg = object.manager.getProperty("G_GEO_SERVER_ERROR");
				break;
			case G_GEO_MISSING_ADDRESS:
				msg = object.manager.getProperty("G_GEO_MISSING_ADDRESS");
				break;
			case G_GEO_UNKNOWN_ADDRESS:
				msg = object.manager.getProperty("G_GEO_UNKNOWN_ADDRESS");
				break;
			case G_GEO_UNAVAILABLE_ADDRESS:
				msg = object.manager.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
				break;
			case G_GEO_BAD_KEY:
				msg = object.manager.getProperty("G_GEO_BAD_KEY");
				break;
			case G_GEO_TOO_MANY_QUERIES:
				msg = object.manager.getProperty("G_GEO_TOO_MANY_QUERIES");
				break;
			default:
				msg = object.manager.getProperty("LANG_NOT_FOUND");						
				break; 
		}
		ncm.showDialog(object.id,msg,false);
	});
	google.maps.Event.addListener(object.directions,"load",function(){
		$jq("#directionstop"+object.id).css("display","block");
	});
}

ncmGMap.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++) {
			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++) {
		var oneCtrl = arrControls[i];
		initOneCustomControl(oneCtrl.simplefields);
	}
}

ncmGMap.initSearcher = function(object) {
	if(!object) return;
	var jspfile = object.manager.getProperty("jsp_search");
	if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-search.jsp");
	var params = ncm.getComponentConstructorParams(object,object.manager);
	params += "&xsltPath=";
	params += object.manager.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.manager.inPreview,object.manager.jsp_utils);
    	},
    	success: function(json) {
			if(json.html) {
				$jq("#mapsearch"+object.id).html(json.html);
			}
    	}
	});
}

ncmGMap.initSubcategories = function(object) {
	if(!object) return;
	var jspfile = object.manager.getProperty("jsp_subcategory");
	if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-subcategory.jsp");
	var params = ncm.getComponentConstructorParams(object,object.manager);
	params += "&xsltPath=";
	params += object.manager.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.manager.inPreview,object.manager.jsp_utils);
    	},
    	success: function(json) {
			if(json.html) {
				$jq("#subcategory"+object.id).html(json.html);
			}
    	}
	});
}

ncmGMap.initMapIcon = function(object,mapicon) {
	if(mapicon) {
		object.icon.image = document.location.href.substr(0,document.location.href.lastIndexOf("/")+1)+mapicon;
	} else {
		object.icon.image = "";
	}
}

ncmGMap.createMarker = function(object,point,id,item,aFields,tCode) {
	if(!object) return;
	var marker = null;
	var itemIcon = null;
	if (item["icon"]) {
		itemIcon = item["icon"];
	} else if(item["mapicon"]) {
		itemIcon = item["mapicon"];
	}	
	if (itemIcon) {
		//Init icon image
      	var customIcon = new google.maps.Icon();
      	customIcon.iconSize = new google.maps.Size(parseInt(object.manager.getProperty("base_icon_width")), parseInt(object.manager.getProperty("base_icon_height")));
      	customIcon.shadowSize = new google.maps.Size(parseInt(object.manager.getProperty("base_shadow_width")), parseInt(object.manager.getProperty("base_shadow_height")));
      	customIcon.iconAnchor = new google.maps.Point(parseInt(object.manager.getProperty("base_anchor_x")), parseInt(object.manager.getProperty("base_anchor_y")));
      	customIcon.infoWindowAnchor = new google.maps.Point(parseInt(object.manager.getProperty("info_window_anchor_x")), parseInt(object.manager.getProperty("info_window_anchor_y")));
      	customIcon.infoShadowAnchor = new google.maps.Point(parseInt(object.manager.getProperty("info_shadow_anchor_x")), parseInt(object.manager.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++){
			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.manager.getProperty("LANG_MORE_INFO");
		var details = "";
		if (!object.simplefields["NO_MORE_INFO"]) {
			details = new String("<a href=\"");
			if (item.moreinfo_url != "") {
				details += item.moreinfo_url;
			} else {
				details += object.simplefields["DETAILSPAGE"];
				details += "?step=3&ID=";
				details += id;
			}
			details += "\" title=\"";
			details += moretext;
			details += "\" style=\"color:";
			details += object.manager.getProperty("info_window_link_color");
			details += ";\">";
			details += moretext;
			details += "</a>";
		}	
		myHtml = myHtml.replace(/\{moreinfo\}/g,details);
		myHtml = myHtml.replace(new RegExp("\{fields:[0-9]+\}","g"),"");
		object.map.openInfoWindowHtml(point,myHtml);
	});
	if(typeof(object.points)!="undefined") {
		object.points[object.points.length] = point;	
	}
	object.markersBatch[object.markersBatch.length] = marker;
	return marker;
}

ncmGMap.drawMarkers = function(object) {
	if(!object) return;
	if(!object.map) return;
	//Putting all markers in map
	object.markerMngr.clearMarkers();
	object.markerMngr.addMarkers(object.markersBatch,parseInt(object.manager.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.manager.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);	
	}
}

ncmGMap.getAvaragePoint = function(object) {
	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.manager.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.manager.getProperty("adjust_zoom")=="1") {
				if(object.bounds) {
					var pdelta = object.manager.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;
}






