/**
 * @author Nivaria Innova Team
 */

function QueryResultsMap() {
	this.id = null;
	this.map = null;
	this.markerMngr = null;
	this.simplefields = new Array();
	this.icon = new google.maps.Icon(QueryResultsMap.baseIcon);
	this.points = new Array();
	this.markersBatch = new Array();
	this.directions = null;
	this.mapAddress = new Array();
	
	this.totalMarkers = 0;
	this.countMarkers = 0;
}

QueryResultsMap.prototype = {
	initialize: function(objectId) {
		this.id = objectId;
		//Getting component simple fields values
		var jspfile = QueryResultsMap.jsp_utils;
		if(jspfile==null)
			jspfile = QueryResultsMap.getProperty("utils_jsp");
		if(jspfile=="") jspfile= new String("components/components-utils.jsp");
		var params = new String("action=2");
		params += "&objId=";
		params += objectId;
		params += "&langName="
		params += QueryResultsMap.language?QueryResultsMap.language:"";
		params += "&pageUrl=";
		params += QueryResultsMap.pageUrl?QueryResultsMap.pageUrl:"";
		params += "&channel=";
		params += QueryResultsMap.channel?QueryResultsMap.channel:"";
		var Me = this;		
		$jq.ajax({
	    	async: false,
        	type: "POST",
        	url: jspfile,
        	data: params,
        	dataType: "json",
        	error: function(request,msg,ex) {
           		QueryResultsMap.showError(msg,ex,request);
        	},
        	success: function(json) {
				if(json.simplefields!=null) {
					for(var i=0;i<json.simplefields.length;i++) {
						Me.simplefields[json.simplefields[i].name]=json.simplefields[i].value;
					}				
				}
        	}
    	});
		//Creating map object
		if(document.getElementById("map"+objectId)!=null) {
			var mapDiv = new String("map");
			mapDiv += objectId;
			this.map = new google.maps.Map2(document.getElementById(mapDiv));
			if(document.getElementById("directions"+this.id)!=null) {
				this.directions = new google.maps.Directions(this.map,document.getElementById("directions"+this.id));
			} else {
				this.directions = new google.maps.Directions(this.map);			
			}
			google.maps.Event.addListener(this.directions, "error", function(){
				var msg = "";
				switch(Me.directions.getStatus().code) {
					case G_GEO_BAD_REQUEST:
						msg = QueryResultsMap.getProperty("G_GEO_BAD_REQUEST");
						break;
					case G_GEO_SERVER_ERROR:
						msg = QueryResultsMap.getProperty("G_GEO_SERVER_ERROR");
						break;
					case G_GEO_MISSING_ADDRESS:
						msg = QueryResultsMap.getProperty("G_GEO_MISSING_ADDRESS");
						break;
					case G_GEO_UNKNOWN_ADDRESS:
						msg = QueryResultsMap.getProperty("G_GEO_UNKNOWN_ADDRESS");
						break;
					case G_GEO_UNAVAILABLE_ADDRESS:
						msg = QueryResultsMap.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
						break;
					case G_GEO_BAD_KEY:
						msg = QueryResultsMap.getProperty("G_GEO_BAD_KEY");
						break;
					case G_GEO_TOO_MANY_QUERIES:
						msg = QueryResultsMap.getProperty("G_GEO_TOO_MANY_QUERIES");
						break;
					default:
						msg = QueryResultsMap.getProperty("LANG_NOT_FOUND");						
						break; 
				}
				alert(msg);
			});
			google.maps.Event.addListener(this.directions,"load",function(){
				if(document.getElementById("directionstop"+Me.id)!=null)
					document.getElementById("directionstop"+Me.id).style.display = "block";
			});
			var scale = this.simplefields["MAP_SCALE"];
			if(scale!=null && typeof(scale)!="undefined") 
				scale = parseInt(scale);
			else 
				scale = 13;
			if (QueryResultsMap.geocoder) {
        		QueryResultsMap.geocoder.getLatLng(
          			this.simplefields["MAP_CENTER"],
          			function(point) {
            			if (!point) {
							var msg = Me.simplefields["MAP_CENTER"];
							msg += " ";
							msg += QueryResultsMap.getProperty("LANG_NOT_FOUND");
              				alert(msg);
            			} else {
              				Me.map.setCenter(point, scale);
							if(QueryResultsMap.inPreview) {
								google.maps.Event.addListener(Me.map,"click",function(overlay,point) {
									if(point==null || typeof(point)=="undefined") return;
									if(document.getElementById("coord_y"+Me.id)!=null)
										document.getElementById("coord_y"+Me.id).innerHTML = point.lat();
									if(document.getElementById("coord_x"+Me.id)!=null)
										document.getElementById("coord_x"+Me.id).innerHTML = point.lng();	
								});
							}
							Me.initMapType();
							Me.initMapControls();
							Me.initMapMarkers();
            			}
          			}
        		);
      		}		
		}
	},
	
	initMapType: function() {
		if(!this.map) return;
		switch(this.simplefields["MAP_VIEW"]) {
			case "G_NORMAL_MAP":
				this.map.setMapType(G_NORMAL_MAP);
				break;
			case "G_SATELLITE_MAP":
				this.map.setMapType(G_SATELLITE_MAP);
				break;
			case "G_HYBRID_MAP":
				this.map.setMapType(G_HYBRID_MAP);
				break;		
		}	
	},
	
	initMapControls: function() {
		if(!this.map) return;
		if(this.simplefields["MAP_CONTROLS"]==null) return;
		if(this.simplefields["MAP_CONTROLS"].length) {
			for(var i=0;i<this.simplefields["MAP_CONTROLS"].length;i++) {
				this.initOneMapControl(this.simplefields["MAP_CONTROLS"][i]);
			}
		} else {
			this.initOneMapControl(this.simplefields["MAP_CONTROLS"]);
		}
	},
	
	initOneMapControl: function(controlName) {
		if(!this.map) return;
		switch(controlName) {
			case "GLargeMapControl":
				this.map.addControl(new GLargeMapControl());
				break;
			case "GSmallMapControl":
				this.map.addControl(new GSmallMapControl());
				break;
			case "GSmallZoomControl":
				this.map.addControl(new GSmallZoomControl());
				break;
			case "GScaleControl":
				this.map.addControl(new GScaleControl());
				break;
			case "GMapTypeControl":
				this.map.addControl(new GMapTypeControl());
				break;
			case "GOverviewMapControl":
				this.map.addControl(new GOverviewMapControl());			
				break;				
		}
	},
	
	initCustomControls: function(arrControls) {
		if(!this.map) return;
		for(var i=0;arrControls!=null && i<arrControls.length;i++) {
			var oneCtrl = arrControls[i];
			this.initOneCustomControl(oneCtrl.simplefields);
		}
	},
	
	initOneCustomControl: function(arrFields) {
		if(!this.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) {
			this.map.addControl(newCtrl, new GControlPosition(newCtrlPos,newCtrlOff));			
		}
	},
	
	initMapMarkers: function(parameters,reload) {
		if(!this.map) return;
		var jspfile = QueryResultsMap.getProperty("jsp");
		if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-queryresults.jsp");
		var params = new String("objId=");
		params += this.id;
		params += "&inPreview="
		params += QueryResultsMap.inPreview?"1":"0";
		params += "&pageUrl=";
		params += QueryResultsMap.pageUrl?QueryResultsMap.pageUrl:"";
		params += "&itpp=";
		params += this.simplefields["NUMROWS"]?this.simplefields["NUMROWS"]:"9999";
		params += "&page=0";
		params += "&infoTpl=";
		params += QueryResultsMap.getProperty("info_window_template");
		params += "&channel=";
		params += QueryResultsMap.channel?QueryResultsMap.channel:"";
		params += "&issueId=";
		params += QueryResultsMap.issueId?QueryResultsMap.issueId:"-1";
		if(parameters!=null) {
			params += "&";
			params += parameters;
		}
		var Me = this;		
		$jq.ajax({
	    	async: true,
        	type: "POST",
        	url: jspfile,
        	data: params,
        	dataType: "json",
        	error: function(request,msg,ex) {
           		QueryResultsMap.showError(msg,ex,request);
        	},
        	success: function(json) {
				//Init searcher
				if(json.hasSearch && !reload) {
					Me.initSearcher();
				}
				if(json.hasSubcategory && !reload) {
					Me.initSubcategories();
				}
				if(json.customcontrols && json.customcontrols.length && !reload) {
					Me.initCustomControls(json.customcontrols);
				}
				//Init icon image
				if(json.mapicon) {
					Me.icon.image = document.location.href.substr(0,document.location.href.lastIndexOf("/")+1)+json.mapicon;
				} else {
					Me.icon.image = "";
				}
				//Init marker manager
				var mgrOptions = { 
					borderPadding: parseInt(QueryResultsMap.getProperty("markerManager_borderPadding")),
					maxZoom: parseInt(QueryResultsMap.getProperty("markerManager_maxZoom")),
					trackMarkers: false
				};
				Me.markerMngr = new MarkerManager(Me.map,mgrOptions);
				//Clearing some variables 
				if(reload) {
					Me.map.clearOverlays();
					Me.markersBatch = new Array();
					Me.points = new Array();
					Me.mapAddress = new Array();
					Me.totalMarkers = 0;
					Me.countMarkers = 0;
				}
				//Creating markers
				if(json.ids.length==0) {
					alert(QueryResultsMap.getProperty("LANG_NO_RESULT"));
					return;
				}
				Me.totalMarkers = json.ids.length;
				for(var i=0;i<json.ids.length;i++) {
					var item = json["item_"+json.ids[i]];
					if(json.geotype==0) {
						var lat = item[json.geofields[0]];
						var lng = item[json.geofields[1]];
						var point = new google.maps.LatLng(lat,lng);
						Me.countMarkers++;
						Me.createMarker(point,json.ids[i],item,json.infofields,json.infotemplate);
					} else {
						var address = new String("");
						var coma = new String("");
						for(var j=0;j<json.geofields.length;j++) {
							address += coma;
							address += item[json.geofields[j]];
							if(coma=="") coma = new String(" ,");
						}
						Me.mapAddress[address] = i;
						QueryResultsMap.geocoder.getLocations(
          					address,
          					function(response) {
								Me.countMarkers++;
								switch(response.Status.code) {
									case G_GEO_SUCCESS:
										var place = response.Placemark[0];
										var point = new google.maps.LatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
										var address = response.name;
										var index = Me.mapAddress[address];
										var itemobj = json["item_"+json.ids[index]];
										Me.createMarker(point,json.ids[index],itemobj,json.infofields,json.infotemplate);
										break;
									case G_GEO_BAD_REQUEST:
										var msg = response.name;
										msg += "\n";
										msg += QueryResultsMap.getProperty("G_GEO_BAD_REQUEST");
										alert(msg);
										break;
									case G_GEO_SERVER_ERROR:
										var msg = response.name;
										msg += "\n";
										msg += QueryResultsMap.getProperty("G_GEO_SERVER_ERROR");
										alert(msg);
										break;
									case G_GEO_MISSING_ADDRESS:
										var msg = QueryResultsMap.getProperty("G_GEO_MISSING_ADDRESS");
										alert(msg);
										break;
									case G_GEO_UNKNOWN_ADDRESS:
										var msg = response.name;
										msg += "\n";
										msg += QueryResultsMap.getProperty("G_GEO_UNKNOWN_ADDRESS");
										alert(msg);
										break;
									case G_GEO_UNAVAILABLE_ADDRESS:
										var msg = response.name;
										msg += "\n";
										msg += QueryResultsMap.getProperty("G_GEO_UNAVAILABLE_ADDRESS");
										alert(msg);
										break;
									case G_GEO_BAD_KEY:
										var msg = QueryResultsMap.getProperty("G_GEO_BAD_KEY");
										alert(msg);
										break;
									case G_GEO_TOO_MANY_QUERIES:
										var msg = QueryResultsMap.getProperty("G_GEO_TOO_MANY_QUERIES");
										alert(msg);
										break;
									default:
										var msg = response.name;
										msg += " ";
										msg += QueryResultsMap.getProperty("LANG_NOT_FOUND");
										alert(msg);
										break;								 
								}
          					}
        				);
					}
				}
        	}
    	});
	},
	
	createMarker: function(point,id,item,aFields,tCode) {
		var marker = null;
		if(this.icon.image=="") {
			marker = new GMarker(point);
		} else {
			marker = new GMarker(point,{icon:this.icon});
		}
		marker.value = id;
		var Me = this;
		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 = Me.simplefields["TITLEDETAIL"];
			if(moretext==null || moretext=="") 
				moretext=QueryResultsMap.getProperty("LANG_MORE_INFO");
			var details = new String("<a href=\"");
			if(item.moreinfo_url!="") {
				details += item.moreinfo_url;
			} else {
				details += Me.simplefields["DETAILSPAGE"];
				details += "?step=3&PRDID=";
				details += id;	
			}
			details += "\" title=\"";
			details += moretext;
			details += "\" style=\"color:";
			details += QueryResultsMap.getProperty("info_window_link_color");
			details += ";\">";
			details += moretext;
			details += "</a>";
			myHtml = myHtml.replace(/\{moreinfo\}/g,details);
			Me.map.openInfoWindowHtml(point,myHtml);
		});
		this.points[this.points.length] = point;
		this.markersBatch[this.markersBatch.length] = marker;
		
		if(this.countMarkers==this.totalMarkers) {
			//Putting all markers in map
			this.markerMngr.addMarkers(this.markersBatch,parseInt(QueryResultsMap.getProperty("markerManager_minZoom")));
			this.markerMngr.refresh();
			//Recalculating the center of map after the last marker has added	
			if(this.simplefields["RECALC_CENTER"]) {
				var avgpoint = this.getAvaragePoint();
				this.map.panTo(avgpoint);
			}
		}
		return marker;
	},
	
	getAvaragePoint: function() {
		var point = null;
		if(QueryResultsMap.getProperty("recalc_center_method")=="avg"){
			var sumlat = 0.0;
			var sumlng = 0.0;
			for(var i=0;i<this.points.length;i++) {
				sumlat += this.points[i].lat();
				sumlng += this.points[i].lng();
			}
			point = new google.maps.LatLng(sumlat/this.points.length,sumlng/this.points.length);
		} else {
			var minlat = 0.0;
			var maxlat = 0.0;
			var minlng = 0.0;
			var maxlng = 0.0;
			for(var i=0;i<this.points.length;i++) {
				if(i==0) {
					minlat = this.points[i].lat();
					maxlat = this.points[i].lat();
					minlng = this.points[i].lng();
					maxlng = this.points[i].lng();
				} else {
					minlat = minlat<this.points[i].lat()?minlat:this.points[i].lat();
					maxlat = maxlat>this.points[i].lat()?maxlat:this.points[i].lat();
					minlng = minlng<this.points[i].lng()?minlng:this.points[i].lng();
					maxlng = maxlng>this.points[i].lng()?maxlng:this.points[i].lng();		
				}
			}
			point = new google.maps.LatLng((minlat+maxlat)/2.0,(minlng+maxlng)/2.0);			
		}
		return point;
	},
	
	initSearcher: function() {
		var jspfile = QueryResultsMap.getProperty("search_jsp");
		if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-search.jsp");
		var params = new String("objId=");
		params += this.id;
		params += "&inPreview="
		params += QueryResultsMap.inPreview?"1":"0";
		params += "&issueId=";
		params += QueryResultsMap.issueId?QueryResultsMap.issueId:"-1";
		params += "&xsltPath=";
		params += QueryResultsMap.getProperty("search_xslt");
		var Me = this;		
		$jq.ajax({
	    	async: true,
        	type: "POST",
        	url: jspfile,
        	data: params,
        	dataType: "json",
        	error: function(request,msg,ex) {
           		QueryResultsMap.showError(msg,ex,request);
        	},
        	success: function(json) {
				if(json.html) {
					if(document.getElementById("mapsearch"+Me.id)!=null)
						document.getElementById("mapsearch"+Me.id).innerHTML = json.html;
				}
        	}
    	});
	},
	
	initSubcategories: function() {
		var jspfile = QueryResultsMap.getProperty("subcategory_jsp");
		if(jspfile=="") jspfile= new String("components/mashups/googlemaps/googlemaps-subcategory.jsp");
		var params = new String("objId=");
		params += this.id;
		params += "&inPreview="
		params += QueryResultsMap.inPreview?"1":"0";
		params += "&issueId=";
		params += QueryResultsMap.issueId?QueryResultsMap.issueId:"-1";
		params += "&xsltPath=";
		params += QueryResultsMap.getProperty("subcategory_xslt");
		var Me = this;		
		$jq.ajax({
	    	async: true,
        	type: "POST",
        	url: jspfile,
        	data: params,
        	dataType: "json",
        	error: function(request,msg,ex) {
           		QueryResultsMap.showError(msg,ex,request);
        	},
        	success: function(json) {
				if(json.html) {
					if(document.getElementById("subcategory"+Me.id)!=null)
						document.getElementById("subcategory"+Me.id).innerHTML = json.html;
				}
        	}
    	});
	},
	
	searchItems: function() {
		var params = $jq("#search"+this.id+" :input").serialize();
		this.initMapMarkers(params,true);
	}, 
	
	searchDirections: function() {
		var selector = "#routesearch"+this.id+" :text";
		var query = "";
		var correct = true;
		$jq(selector).each(function(i){
			correct = $jq.trim(this.value)!="";
			if(i==0) 
				query += "from: "+this.value;
			else if(i==1)
				query += " to: "+this.value;	
		});
		if(!correct)
			alert(QueryResultsMap.getProperty("LANG_WRONG_FROMTO"));
		else
			this.directions.load(query,{locale:QueryResultsMap.getProperty("directions_options_locale")});	
	},
	
	filterSubCategory: function(categoryId) {
		$jq("div.googlemaps-searcher ul li a.selected").each(function(i){
			this.className = "";
		});
		$jq("div.googlemaps-searcher ul li a#catlink"+categoryId).each(function(i){
			this.className = "selected";
		});
		if(document.getElementById("search"+this.id)!=null && document.getElementById("CATID"+this.id)!=null) {
			document.getElementById("CATID"+this.id).value = ""+categoryId;
			this.searchItems();
		} else {
			var params =  "CATID=";
			params += categoryId;
			this.initMapMarkers(params,true);	
		}
		
	}	
};

QueryResultsMap.instances = new Array();
QueryResultsMap.properties = new Array();
QueryResultsMap.datatype = null;
QueryResultsMap.jsp_utils = null;
QueryResultsMap.language = null;
QueryResultsMap.pageUrl = null;
QueryResultsMap.channel = null;
QueryResultsMap.inPreview = false;
QueryResultsMap.issueId = null;
QueryResultsMap.geocoder = new GClientGeocoder();
QueryResultsMap.baseIcon = new google.maps.Icon();
QueryResultsMap.baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";

QueryResultsMap.register = function(objectId) {
	var mapObject = new QueryResultsMap();
	mapObject.initialize(objectId);
	QueryResultsMap.instances[""+objectId] = mapObject;
}

QueryResultsMap.getRegistered = function(objectId) {
	return QueryResultsMap.instances[""+objectId];
}

QueryResultsMap.initProperties = function(options) {
	QueryResultsMap.datatype = options.datatype?options.datatype:null;
	QueryResultsMap.language = options.language?options.language:null;
	QueryResultsMap.jsp_utils = options.jsp_utils?options.jsp_utils:null;
	QueryResultsMap.pageUrl = options.pageUrl?options.pageUrl:null;
	QueryResultsMap.channel = options.channel?options.channel:null;
	QueryResultsMap.inPreview = options.inPreview?options.inPreview:false;
	QueryResultsMap.issueId = options.issueId?options.issueId:null;
	var params = new String("action=1");
	params += "&dataTypeName=";
	params += QueryResultsMap.datatype;
	params += "&langName=";
	params += QueryResultsMap.language;
	params += "&pageUrl=";
	params += QueryResultsMap.pageUrl;
	$jq.ajax({
    	async: false,
        type: "POST",
        url: QueryResultsMap.jsp_utils,
        data: params,
        dataType: "json",
        error: function(request,msg,ex) {
           QueryResultsMap.showError(msg,ex,request);
        },
        success: function(json) {
			if(json.properties!=null) {
				for(var i=0;i<json.properties.length;i++) {
					QueryResultsMap.properties[json.properties[i].name]=json.properties[i].value;
				}				
			}
			QueryResultsMap.baseIcon.iconSize = new GSize(parseInt(QueryResultsMap.getProperty("base_icon_width")), parseInt(QueryResultsMap.getProperty("base_icon_height")));
			QueryResultsMap.baseIcon.shadowSize = new GSize(parseInt(QueryResultsMap.getProperty("base_shadow_width")), parseInt(QueryResultsMap.getProperty("base_shadow_height")));
			QueryResultsMap.baseIcon.iconAnchor = new GPoint(parseInt(QueryResultsMap.getProperty("base_anchor_x")), parseInt(QueryResultsMap.getProperty("base_anchor_y")));
			QueryResultsMap.baseIcon.infoWindowAnchor = new GPoint(parseInt(QueryResultsMap.getProperty("info_window_anchor_x")), parseInt(QueryResultsMap.getProperty("info_window_anchor_y")));
			QueryResultsMap.baseIcon.infoShadowAnchor = new GPoint(parseInt(QueryResultsMap.getProperty("info_shadow_anchor_x")), parseInt(QueryResultsMap.getProperty("info_shadow_anchor_y")));
			QueryResultsMap.geocoder.setBaseCountryCode(QueryResultsMap.getProperty("geocode_base_country"));
        }
    });
}

QueryResultsMap.getProperty = function(propName) {
	var res = QueryResultsMap.properties[propName];
	if(res==null) res="";
	if(typeof(res)=="undefined") res="";
	return res;
}

QueryResultsMap.search = function(objectId) {
	var obj = QueryResultsMap.getRegistered(objectId);
	if(obj!=null) {
		obj.searchItems();
		return true;
	} else {
		return false;
	}
}

QueryResultsMap.searchRoute = function(objectId) {
	var obj = QueryResultsMap.getRegistered(objectId);
	if(obj!=null) {
		obj.searchDirections();
		return true;
	} else {
		return false;
	}
}

QueryResultsMap.filterCategory = function(objectId,categoryId) {
	var obj = QueryResultsMap.getRegistered(objectId);
	if(obj!=null) {
		obj.filterSubCategory(categoryId);
		return true;
	} else {
		return false;
	}
}


QueryResultsMap.showError = function(msg,ex,request) {
	var m = msg + ":\n";
    if(ex) {
    	m += ex.message?ex.message+"\n":"";
        m += ex.fileName?"File: "+ex.fileName+"\n":"";
        m += ex.lineNumber?"Line: "+ex.lineNumber+"\n":"";
        m += ex.stack?"Stack: "+ex.stack+"\n":"";
    }
	if(request!=null) {
		m += request.status?request.status+"\n":"";
		m += request.statusText?request.statusText+"\n":"";
	}
    alert(m);
}

