var GX_parcels = [];
var state = "init";
var GX_gazetteer_tile_cache = [];
var GX_gazetteer_tile_status = [];
var GX_tile_active_feature = [];
var numTiles = 0;
var gbTimeProfiler = new TimeProfiler();
var gbProfilerMsg = "";
var TileUtil = new Tile();
var delayRefreshVisibleGazList = true;
var GX_newsQuery;
var GX_gazGeomMap =[];
var GX_prevNorthEastBounds;
var GX_moveEndTimer=0;
var GX_getNewsTimeout = 1000;

//var GX_log = "";
			
//DataStructure for storing gazetteer information
function GX_Gazetteer(p_tileID, p_gazNum, p_gaz) {
	this.tileID = p_tileID;
	this.gazNum = p_gazNum;
	this.gaz = p_gaz;
	this.images = p_gaz.images.split2(";");
	this.isPoint = (p_gaz.geom.indexOf("POINT (") != -1)? true: false;
	this.isRoad = (p_gaz.featureType == "Road")? true: false;
	this.centerPoint = GX_getGeomCenter(p_gaz.geom);
		
	this.marker = null;	
	this.roadMarker = []; 
	this.numRoadMarker = 0;
	this.roadPointMarker = [];
	
	this.news = [];
	this.newsFetched = false;
	this.newsText = "&nbsp;&nbsp;No news found";
	this.dateSortedNewsText = "&nbsp;&nbsp;No news found";
	
	this.docs = [];
	this.docsFetched = false;
	this.docsText = "&nbsp;&nbsp;No documents found";
	this.dateSortedDocsText = "&nbsp;&nbsp;No documents found";	
}

GX_Gazetteer.prototype.getZIndex = function() {
	if(this.news.length > 0)
		return GX_getMarkerZIndex(this.gaz.featureType, "news");
	return GX_getMarkerZIndex(this.gaz.featureType);
}
GX_Gazetteer.prototype.getMarkerIconImage = function() {
	if(this.news.length > 0)
		return GX_getMarker(this.gaz.featureType + "_news");
	return GX_getMarker(this.gaz.featureType);
}
GX_Gazetteer.prototype.getMarkerWidth = function() {
	return imageWidth;
} 
GX_Gazetteer.prototype.getMarkerHeight = function() {
	return imageHeight;
}
GX_Gazetteer.prototype.getTooltipText = function() {
	var sameGeomGazList = GX_gazGeomMap[this.tileID][this.gaz.geom];
	
	var tooltipTxt = new StringBuffer();
	tooltipTxt.append(this.gaz.featureName);											
	
	var gazNum = this.gazNum;						
	var numItems = 1;					
	for(var j=0; j<sameGeomGazList.length; j++) {
		var gp2 = sameGeomGazList[j];
		if(gp2.gazNum == gazNum) continue;
		if(GX_isFeatureChecked(gp2.gaz.featureType)) {
			tooltipTxt.append(",\n ").append(gp2.gaz.featureName);
		}
		numItems++;
		if(numItems >= 10 && j<(sameGeomGazList.length-1)) {
			tooltipTxt.append("...");
			break;
		}
	}	
	return tooltipTxt.toString();
}

GX_Gazetteer.prototype.getMarkerWindowText = function() {
	var sameGeomGazList = GX_gazGeomMap[this.tileID][this.gaz.geom];
	
	var windowText = new StringBuffer();
	windowText.append("<B>").append(this.getGazetteerText()).append("</B>");
	
	var gazNum = this.gazNum;
	
	var gazs = [];					
	for(var j=0; j<sameGeomGazList.length; j++) {
		var gp2 = sameGeomGazList[j];
		if(gp2.gazNum == gazNum) continue;
		if(GX_isFeatureChecked(gp2.gaz.featureType)) {
			gazs.push(gp2);				
		}
	}
	if(gazs.length > 0) windowText.append("<input type='hidden' name='multipleGazs' />");
	GX_SortGazetteers(gazs);
	
	for(var j=0; j<gazs.length; j++) {
		var gp2 = gazs[j];
		windowText.append("<BR>").append(gp2.getGazetteerText());
	}
	return windowText.toString();
}

GX_Gazetteer.prototype.getGazetteerText = function() {
	var ret = new StringBuffer();
	if(this.isPoint == true) {
		
		
		if(this.gaz.website != "")
			ret.append("<a class=\"onGoogle\" href=\"").append(this.gaz.website).append("\" target='_blank'>");
		ret.append(this.gaz.featureName);
		
		if(this.gaz.website != "")
			ret.append("</a>");
		ret.append(" (" + this.gaz.featureType + ")");
		//ret.append("&nbsp;&nbsp;<a href=\"?loc=").append(this.centerPoint.GX_lat).append(",").append(this.centerPoint.GX_lon).append("&tid=").append(this.tileID).append("&feature=").append(URLencode(this.gaz.featureName)).append("\">Link</a>");
		ret.append("<BR>");
		var sep = "";
		if(this.gaz.street != "") {
			ret.append(sep).append(this.gaz.street);
			sep = ", ";
		}
		if(this.gaz.city != "") {
			ret.append(sep).append(this.gaz.city);
			sep = ", ";
		}
		if(this.gaz.state != "") {
			ret.append(sep).append(this.gaz.state);
		}
		if(this.gaz.description != "") {
			ret.append("<BR/>").append(this.gaz.description);
		}

		
		var images = this.images;
		var numImages = images.length; 
		if(numImages > 0) {
			var cr = GX_createCarousel(this.tileID + "_" + this.gazNum, 1);
			for(var i=0; i<numImages; i++) {
				cr.addItem(this.gaz.imagesDir + "/" + images[i]);
			}
			ret.append(cr.getJS());
		}

		//alert(gazetteer.gaz.featureName + ":" + gazetteer.newsFetched);
		var showGetNews = false;
		if(this.newsFetched == false || this.news.length > 0) {
			ret.append("<a class=\"getNewsButton\" onclick=\"javascript:GX_getNews('").append(this.tileID).append("','").append(this.gazNum).append("');\" style=\"margin-left:100px;\">&nbsp;&nbsp;&nbsp;</a>");		
			showGetNews = true;
		}
		
		if(applicationMode == "admin") {
			ret.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"javascript:addNews('").append(this.tileID).append("',").append(this.gazNum).append(",'").append(this.gaz.featureName.quote()).append("','").append(this.gaz.street.quote()).append("','").append(this.gaz.city.quote()).append("','").append(this.gaz.state.quote()).append("');\"><img src=\"images/db_add.png\" border='0' style=\"width:16px;height:16px\" alt=\"addNews\" title=\"Add News\"></a>");
		}
		//ret.append("<BR>");
		if(showGetNews == false)
			ret.append("<BR>");
		
		ret.append("<div style=\"clear: both; height:2px;\">&nbsp;</div>");
		
		
	} else {
		ret.append(this.gaz.featureName).append(" (").append(this.gaz.featureType).append(")");
	}
	return ret;
}

function GX_compareGazetteers(g1, g2) {
	if(g1.gaz.featureName < g2.gaz.featureName) {
		return -1;
	} 
	return 1;
}

function GX_SortGazetteers(items){
	items.sort(GX_compareGazetteers);
}

function GX_withinBounds(point, minlat, minlon, maxlat, maxlon) {
	if(point.GX_lat >= minlat && point.GX_lat <= maxlat &&
		point.GX_lon >= minlon && point.GX_lon <= maxlon) {
			return true;		
	}
	return false;
}

function GX_createGazetteerMarker(gp) {

		var marker = new GX_GazetteerMarker(gp);
		
		GEvent.addListener(marker, "click", function() {			
			GX_showGazetteer(gp.tileID, gp.gazNum);
		});
				
		return marker;
}

function GX_Parcel(p_latitude, p_longitude, p_geom, p_text, p_Marker, p_polyline) {
	this.GX_latitude = p_latitude;
	this.GX_longitude = p_longitude;
	this.geom = p_geom;
	this.GX_text = p_text;
	this.marker = p_Marker;
	this.GX_polyline = p_polyline;
}

function GX_getGeomCenter(str) {		
	if(str.indexOf("POINT (") != -1) {			
		return GX_getCenterOfPoint(str);		
	} else {			
		var points = GX_getPointsOnLine(str);
		var idMid = parseInt("" + points.length/2);
		return points[idMid];			
	}
}

function GX_getGeomPoints (str) {
	var points = [];		
	if(str.indexOf("POINT (") != -1) {
		points[0] = GX_getCenterOfPoint(str);		
	} else {
		points = GX_getPointsOnLine(str);
	}
	return points;
}
	
function GX_getPointsOnLine(lineString) {
	//LINESTRING (-118.39609 33.9194, -118.3942 33.91939, -118.39099 33.91943)
	//MULTILINESTRING((-118.39355 34.02536,-118.39363 34.02544))
	//idx = lineString.indexOf("LINESTRING (");
	var idx = lineString.lastIndexOf("(");
	var latlon = lineString.substring(idx+1, lineString.indexOf(")"));
		
	var points = [];
	var i = 0;
	
	while(true) {
		idx = latlon.indexOf(" ");
		if(idx == -1) break;
		
		var GX_lon = latlon.substring(0, idx);
		latlon = latlon.substring(idx+1).trim();
		idx = latlon.indexOf(",");
		
		var GX_lat = latlon;
		if(idx != -1)
			GX_lat = latlon.substring(0, idx).trim();	
	
		points[i] = new GX_Point(GX_lat, GX_lon);
		i++;
		
		if(idx != -1) 		
			latlon = latlon.substring(idx+1).trim();		
	}
	return points;
}

function GX_getCenterOfPoint(pointString) {
	var idx = pointString.indexOf("POINT (");
	var latlon = pointString.substring(idx+7, pointString.length-1);
	var idx = latlon.indexOf(" ");
	var GX_lon = latlon.substring(0, idx);
	var GX_lat = latlon.substring(idx+1);
	var point = new GX_Point(GX_lat, GX_lon);
	return point;
}

function GX_Point(pLat, pLon) {
	this.GX_lon = pLon;
	this.GX_lat = pLat;
}

function GX_createPolygon(geom) {
	var polygon;
	if(geom != "") {
		var idx = geom.indexOf("$$");
		var geomArr = [];
		var k=0;
			
		while(idx != -1) {
			var part = geom.substring(0, idx);
			geom = geom.substring(idx+2);
			idx = geom.indexOf("$$");
			geomArr[k++] = part;
		}
		geomArr[k++] = geom;
		var i =0;			
		var latlons = [];
		var j=0;	
		for(i=0; i<k; i++) {
			var linePoints = GX_getPointsOnLine(geomArr[i]);
			var latlonsInner = [];
			for(var t=0; t<linePoints.length; t++) {
				//latlons[j] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
				latlonsInner[t] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
				j++;
			}
			//alert("Polyline: " + latlonsInner);
			var linecolor="#FF0000";
			var lineweight=4;
			var lineopacity=1;
			var fillcolor="#FF0000";
			var fillopacity=0.3;
			polygon = new GPolygon(latlonsInner,linecolor,lineweight,lineopacity,fillcolor,fillopacity);
			//GX_polyline = GX_createPolyLine(latlonsInner, "#ff0000", 4);
			polygon.hide();
     		//iconMgr.addMarker(polygon, minZoom);
			map.addOverlay(polygon);
		}
	}
	return polygon;
}

function GX_showPolyline(geom, color, thickness, clickText) {	
	if(geom != "") {
		var idx = geom.indexOf("$$");
		var geomArr = [];
		var k=0;
			
		while(idx != -1) {
			var part = geom.substring(0, idx);
			geom = geom.substring(idx+2);
			idx = geom.indexOf("$$");
			geomArr[k++] = part;
		}
		geomArr[k++] = geom;
		var i =0;			
		var latlons = [];
		var j=0;	
		for(i=0; i<k; i++) {
			var linePoints = GX_getPointsOnLine(geomArr[i]);
			var latlonsInner = [];
			for(var t=0; t<linePoints.length; t++) {
				//latlons[j] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
				latlonsInner[t] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
				j++;
			}
			GX_showLine(latlonsInner, color, thickness, clickText);
		}
	}
}

function GX_toggleParcels() {
	if(document.getElementById('chkParcel').checked == true) {
		for(var i=0; i<GX_parcels.length; i++) {
			var parcel = GX_parcels[i];
			if(parcel.marker)
				iconMgr.addMarker(parcel.marker, minZoom);
		}
	} else {
		for(var i=0; i<GX_parcels.length; i++) {
			var parcel = GX_parcels[i];

			if(parcel.marker)
				iconMgr.removeMarker(parcel.marker);
		}
	}
}
		
function GX_showGazetteerAndDocs(tileID, idx) {
	GX_showGazetteer(tileID, idx, 0);
	GX_drawDocs(tileID, idx, 0);
}		

function GX_getGazetteersForTile(tilex, tiley, zoom) {
	var tilesx = [];
	var tilesy = [];

	if(zoom < minZoom) {
		return;
	}
	
	if(zoom == defaultZoom) {
		tilesx.push(tilex);
		tilesy.push(tiley);
	} else if(zoom > defaultZoom) {
		var diff = Math.pow(2, zoom - defaultZoom);
		tilex = Math.floor(tilex / diff);
		tiley = Math.floor(tiley / diff);
		tilesx.push(tilex);
		tilesy.push(tiley);
	} else if(zoom < defaultZoom) {
		var diff = Math.pow(2, defaultZoom - zoom);
		tilex = Math.floor(tilex * diff);
		tiley = Math.floor(tiley * diff);
		
		for(var x=tilex; x<tilex+diff; x++) {
			tilesx.push(x);
		}
		for(var y=tiley; y<tiley+diff; y++) {
			tilesy.push(y);
		}
	}

	var numStarted = 0;
	for(var i=0; i<tilesx.length; i++) {
		tilex = tilesx[i];
		
		for(var j=0; j<tilesy.length; j++) {
			tiley = tilesy[j];
		
			var tileID = tilex + "_" + tiley + "_" + defaultZoom;
			if(GX_gazetteer_tile_cache[tileID]) {
				continue;
			}
			if(GX_gazetteer_tile_status[tileID]) {
				continue;
			}		
			numStarted++;
			var service = getServer() + "/getGazetteers?" + 
						"appName=" + getAppName() + 
						"&format=jason&sort=geom" +
						"&tilex=" + tilex + 
						"&tiley=" + tiley + 
						"&zoom=" + defaultZoom;
			var params = [];
			params[0] = tilex; params[1] = tiley; params[2] = defaultZoom;
			numTiles++;
		
			if(numStarted == 1) {
				showStatus("Getting Features..");
			}
	
			GX_gazetteer_tile_status[tileID] = "started";
			HttpGetRequest(service, "/getGazetteers", GX_gazetteerCallback, params);
			
		}
	}
	
	
		
}

function loadBoundaries() {
	var service = getServer() + "/getGazetteers?" + 
						"appName=" + getAppName() + 
						"&format=jason&sort=geom" +
						"&action=getBoundaries&minlat=-1&minlon=-1&maxlat=-1&maxlon=-1";
	var params = [];
	
	HttpGetRequest(service, "/getGazetteers", 
		function(JSON_output, params1) {
			
			if(JSON_output.length < 1) return;
			var output =  eval(JSON_output);
			for(var i=0; i<output.length; i++) {
				var point = output[i].GeneralGazetteer;
				GX_showPolyline(point.geom, getBoundaryColor(point.featureName), 8, point.featureName);
			}
		}, params);
}

var GX_GazetterSortState = "gazetteer";		
function GX_refreshVisibleGazListDefault() {	
	GX_refreshVisibleGazList(GX_getDefaultGazetteerSortState(), false);
}

function GX_getDefaultGazetteerSortState() {
	var sortByNews = false;
	if(GX_GazetterSortState == "news") 
		sortByNews = true;
	return sortByNews;
}

function GX_refreshVisibleGazList(sortByNews, forceGetNews) {
	//alert(sortByNews + ":" + forceGetNews);

	if(map.getZoom() < minZoom) {		
		document.getElementById('divLeftNumResults').innerHTML = "Please zoom in to view points of interest and related area news";
		document.getElementById('divLeftResults').innerHTML = "";
		map.closeInfoWindow();
		if(displayAreaNews == true)
			GX_getCityNews();
		return;
	}
	
	if(sortByNews == true)
		GX_GazetterSortState = "news";
	else 
		GX_GazetterSortState = "gazetteer";
	//gbTimeProfiler.start();
	
	var bounds = map.getBounds();
	var southWest = bounds.getSouthWest();
	var northEast = bounds.getNorthEast();
	var latNE = northEast.lat();
	var latSW = southWest.lat();
	var lonSW = southWest.lng();
	var lonNE = northEast.lng();
	var minlat, maxlat;
	if(latNE > latSW) {
		minlat = latSW;
		maxlat = latNE;
	} else {
		minlat = latNE;
		maxlat = latSW;
	}
	var minlon, maxlon;
	if(lonSW > lonNE) {
		minlon = lonNE;
		maxlon = lonSW;
	} else {
		minlon = lonSW;
		maxlon = lonNE;
	}
			
	var zoom = defaultZoom;
	var tileSW = TileUtil.getTileCoords( latSW, lonSW,  zoom, false);  			
	var tileNE = TileUtil.getTileCoords( latNE, lonNE, zoom, true );
	 		
	//var point1 = gbTimeProfiler.getExecTime();
	 			
	
		
	var msg = new StringBuffer();
	//msg.append("<UL class=\"locationslist\">");
	var numGaz = 0;
	var gazs = [];
	//alert(tileSW.x + " -> " + tileNE.x + "\n" + tileNE.y + " -> " + tileSW.y);
	delayRefreshVisibleGazList = false;	
	
	var sortByNewsGazs_nonews = [];
	var sortByNewsGazs_news = [];
	
	for(var tilex=tileSW.x; tilex<=tileNE.x; tilex++) {
		for(var tiley=tileNE.y; tiley<=tileSW.y; tiley++) {
			var tileID = tilex + "_" + tiley + "_" + zoom;
			
			if(GX_gazetteer_tile_cache[tileID]) {
			} else {
				delayRefreshVisibleGazList = true;
				continue;
			}
			
			for(var numGaz=0; numGaz<GX_gazetteer_tile_cache[tileID].length; numGaz++) {
				var gp = GX_gazetteer_tile_cache[tileID][numGaz];
				
				if(!GX_withinBounds(gp.centerPoint, minlat, minlon, maxlat, maxlon))
					continue;
							
				if(GX_isFeatureChecked(gp.gaz.featureType) && !(gp.isRoad)) {
					
					if(sortByNews) {
						if(gp.news.length > 0 || gp.docs.length > 0) {
							sortByNewsGazs_news.push(gp);
						} else {
							sortByNewsGazs_nonews.push(gp);
						}
					} else {
						gazs.push(gp);
					}
				}			
				
				//GX_allGazs += gp.gaz.featureName + " " + gp.gaz.featureType + "    ";
			}
			
		}
	}
	
	//var point2 = gbTimeProfiler.getExecTime();
	if(sortByNews == true) {
		GX_SortGazetteers(sortByNewsGazs_news);
		GX_SortGazetteers(sortByNewsGazs_nonews);
		gazs = sortByNewsGazs_news;
		for(var i=0; i<sortByNewsGazs_nonews.length;i++)
			gazs.push(sortByNewsGazs_nonews[i]);
	} else {
		GX_SortGazetteers(gazs);
	}
	var numGazWithNews = 0;
	var numGazWithDocs = 0;
	var allGazs = new StringBuffer();
	for(var i=0; i<gazs.length; i++) {
		var gp = gazs[i];
		msg.append("<LI><a href=\"javascript:GX_showGazetteer('").append(gp.tileID).append("',").append(gp.gazNum).append(", 0);\">").append(gp.gaz.featureName).append("</a>");
		if(gp.news.length > 0) {												
			msg.append("&nbsp;&nbsp;&nbsp;<a href=\"javascript:GX_showGazetteer('").append(gp.tileID).append("',").append(gp.gazNum).append(");\"><img src=\"images/icons/news.png\" border='0'/></a>");
			numGazWithNews++;
		}
		if(gp.docs.length > 0) {
			msg.append("&nbsp;&nbsp;&nbsp;<a href=\"javascript:GX_showGazetteerAndDocs('").append(gp.tileID).append("',").append(gp.gazNum).append(");\"><img src=\"images/icons/docs.png\" border='0'/></a>");
			numGazWithDocs++;
		}
		if(adsEnabled == true) {
			allGazs.append(gp.gaz.featureName).append(" ").append(gp.gaz.featureType).append(" ");
		}
		msg.append("</LI>");		
	}
	
	msg.append("</UL>");
	var listClass = "locationslist";
	var numNewsTxt  = "";
	if(numGazWithNews > 0 || forceGetNews == true) {
		numNewsTxt = ", " + numGazWithNews + " made news <img src=\"images/icons/news.png\" border=\"0\">";		
		listClass = "locationslistSmall";
	}	
	if(numGazWithDocs > 0) {		
		numNewsTxt += "<BR>" + numGazWithDocs + " have documents<img src=\"images/icons/docs.png\" border=\"0\">";
		listClass = "locationslistSmall2"	
	}	
	if(numGazWithNews > 0 || numGazWithDocs > 0  || forceGetNews == true) {
		if(sortByNews == true) {
			numNewsTxt += "<BR><B>Sort By News</B> | <a class=\"leftHeadingLink\" href=\"javascript:GX_refreshVisibleGazList(false, false)\">Sort By Name</a>";
		} else {
			numNewsTxt += "<BR><a class=\"leftHeadingLink\" href=\"javascript:GX_refreshVisibleGazList(true, false)\">Sort By News</a> | <B>Sort By Name</B>";
		}
	}
	document.getElementById('divLeftNumResults').innerHTML = gazs.length + " locations found" + numNewsTxt;
	document.getElementById('divLeftResults').innerHTML = "<UL class=\"" + listClass + "\">" + msg.toString();
	
	//alert("point1:" + point1 + " msec, point2:" + point2 + " msec, end:" + gbTimeProfiler.getExecTime() + 
	//		" msec\n");
	if(adsEnabled == true) {
		window.setTimeout(GX_refreshAd, 2000, allGazs.toString());
	}
	
	
	//Set timer to check no MOVE activity for 2 seconds	
	window.clearTimeout(GX_moveEndTimer);
  	GX_prevNorthEastBounds = map.getBounds().getNorthEast();
  	GX_moveEndTimer = window.setTimeout(
  			function() {
  				var bounds = map.getBounds();
  				var neBounds = bounds.getNorthEast();
				if(GX_prevNorthEastBounds.lat() == neBounds.lat() &&
					GX_prevNorthEastBounds.lng() == neBounds.lng()) {
					//alert("Stationary for 2 seconds! ");
					//window.clearTimeout(GX_moveEndTimer);
					GX_getNewsForVisibleTiles(bounds);
				}
  			}, 
  			GX_getNewsTimeout);
  	if(displayAreaNews == true)
	  	//window.setTimeout(function() {
	  		GX_displayAreaNews(gazs);
	  	//}, 500);
}

function GX_redrawMarkers() {	
	//var timeAll = 0;
	//var profiler1 = new TimeProfiler();
	for(var tileID in GX_gazetteer_tile_cache) {		
		
		for(var i=0; i<GX_gazetteer_tile_cache[tileID].length; i++) {
			var gp = GX_gazetteer_tile_cache[tileID][i];
			if(gp) {
				if(gp.marker !=  null) {
					
					if(GX_isFeatureChecked(gp.gaz.featureType)) {
						//var profiler = new TimeProfiler();
						iconMgr.addMarker(gp.marker, minZoom);
						//timeAll += profiler.getExecTime();
					}
				}
			}
		}
	}
	//alert(profiler1.getExecTime() + "  " + timeAll);
}
		
function GX_gazetteerCallback(JSON_output, params) {
	var profiler = new TimeProfiler();
	
	var tilex = params[0];
	var tiley = params[1];
	var zoom = params[2];
	var tileID = tilex + "_" + tiley + "_" + zoom;
	
	if(JSON_output.length > 1) {
		var output =  eval(JSON_output);

		GX_gazetteer_tile_cache[tileID] = new Array();
		var numGaz = 0;	
								
		for(var i=0; i<output.length; i++) {
			var point = output[i].GeneralGazetteer;
			
			var gp = new GX_Gazetteer(tileID, numGaz, point);						
			GX_gazetteer_tile_cache[tileID][numGaz] = gp;							
			numGaz++;
		}
		
		
		//var	point1 = profiler.getExecTime();
	
		var gazGeoMap = GX_getGazetteerGeomMap(tileID);
		GX_gazGeomMap[tileID] = gazGeoMap;
		
		if(iconMgr) {
		} else {
			initIconManager();
		}
		
		for(var i=0; i<numGaz; i++) {
			var gp = GX_gazetteer_tile_cache[tileID][i];
			GX_createGazetteer(tileID, i, gazGeoMap);
	
			if(GX_isFeatureChecked(gp.gaz.featureType) && !(gp.isRoad)) {							
				if(gp.numRoadMarker > 0) {
					for(var t=0; t<gp.numRoadMarker; t++) {
						iconMgr.addMarker(gp.roadMarker[t], minZoom);
					}						
				}
				iconMgr.addMarker(gp.marker, minZoom);
			}
		}
	}
	
	//var point2 = profiler.getExecTime();
			
	numTiles--;
	if(numTiles < 0) numTiles = 0;
	
	GX_gazetteer_tile_status[tileID] = "completed";
	
	if(numTiles == 0) {		
		//alert("Progress bar display: " + gbTimeProfiler.getExecTime() + " msec\n" + gbProfilerMsg);
		if(delayRefreshVisibleGazList == true) {
		//	alert("after tiles");
			GX_refreshVisibleGazList(GX_getDefaultGazetteerSortState(), false);
		}
		hideStatus();
	}
	GX_systemState = "gazetteers";
	//GX_log += "got gazetteers for " + tileID + "\n";
	//gbProfilerMsg += tileID + ", Gaz:"+ numGaz + ", point1:" + point1 + " msec, point2:" + point2 + " msec, end:" + profiler.getExecTime() + " msec\n"				
	
	if(GX_tile_active_feature[tileID]) {
		var feature = GX_tile_active_feature[tileID];
		if(feature != "") {
			//alert("GX_showGazetteer " + tileID + "," + feature + ":" + GX_getGazetteerIndex(tileID, feature));
			GX_showGazetteer(tileID, GX_getGazetteerIndex(tileID, feature), 0);
			GX_tile_active_feature[tileID] = "";
		}
		
	}
}
			
				

		
function GX_getGazetteerGeomMap(tileID) {
	var output = [];
	
	var tileGazs = GX_gazetteer_tile_cache[tileID];
	var numGaz = tileGazs.length;
	
	for(var i=0; i<numGaz; i++ ) {
		var gp = tileGazs[i];
		var x = output[gp.gaz.geom];
		if(x == null) {
			x = [];
		}
		x.push(gp);
		output[gp.gaz.geom] = x;
	}	
	return output;
}

function GX_createGazetteer(tileID, gazNum, gazGeomMap) {
	var tileGazs = GX_gazetteer_tile_cache[tileID];
	var gp = tileGazs[gazNum];
				
	if(gp.gaz.geom.indexOf("POINT (") != -1) {		
		var marker = GX_createGazetteerMarker(gp);
		gp.marker = marker;		
	} else {
		if(gp.isRoad == false) {
			var geom = gp.gaz.geom;
			var idx = geom.indexOf("$$");
			var geomArr = [];
			var k=0;
		
			while(idx != -1) {
				var part = geom.substring(0, idx);
				geom = geom.substring(idx+2);
				idx = geom.indexOf("$$");
				geomArr[k++] = part;
			}
			geomArr[k++] = geom;
			var i =0;			
			var latlons = [];
			var j=0;	
			for(i=0; i<k; i++) {
				var linePoints = GX_getPointsOnLine(geomArr[i]);
				var latlonsInner = [];
				for(var t=0; t<linePoints.length; t++) {
					latlons[j] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
					latlonsInner[t] = new GLatLng(linePoints[t].GX_lat, linePoints[t].GX_lon);
					j++;
				}
				var polyline = new GPolyline(latlonsInner, "#FF0000", 4);
				gp.roadMarker[gp.numRoadMarker++] = polyline;
				
				
				var idMid = parseInt("" + latlonsInner.length/2);
				var gazText3 = gp.gazText;
				var marker3 = GX_createGazetteerMarker(latlonsInner[idMid], tileID, gazNum, gp.featureType);
				gp.roadPointMarker[gp.numRoadMarker-1] = marker3;					
			}
			
			var idMid = parseInt("" + latlons.length/2);
			var gazText2 = gp.gazText;
					
			if(gp.marker) iconMgr.removeMarker(gp.marker);
			var marker2 = GX_createGazetteerMarker(latlons[idMid], tileID, gazNum, gp.featureType, gp.gaz.featureName);
			gp.marker = marker2;			
		}
	} 
	GX_gazetteer_tile_cache[tileID][gazNum] = gp;
}




		
function GX_drawGazetteer(tileID, gazNum, isSelected, showStreetView) {
	var gp = GX_gazetteer_tile_cache[tileID][gazNum];
	var marker = gp.marker;
	var markerInfoWindowText = gp.getMarkerWindowText();
	
	GX_showMarker(marker, gp.getMarkerWindowText(), showStreetView);
}
		
function GX_showGazetteer(tileID, idx) {
	GX_drawGazetteer(tileID, idx, true, false);
	document.getElementById('divRightResults').innerHTML = "";
	document.getElementById('divRightHeading').innerHTML = "";
	document.getElementById('divNewsSort').innerHTML = "";
	if(GX_gazetteer_tile_cache[tileID][idx].news.length > 0) {
		GX_drawNews(tileID,  idx, 0);
	}
}


function GX_getGazetteer(tileID, featureName) {
	if(GX_gazetteer_tile_cache[tileID]) {
		for(var i=0; i<GX_gazetteer_tile_cache[tileID].length; i++) {
			var gp = GX_gazetteer_tile_cache[tileID][i];
			var temp = gp.gaz.featureName;
			if(temp == featureName) {
				return gp;
			}		
		}
	}
	return null;
}

function GX_getGazetteerFromTiles(tileNE, tileSW, zoom, featureName) {
	for(var tilex=tileSW.x; tilex<=tileNE.x; tilex++) {
		for(var tiley=tileNE.y; tiley<=tileSW.y; tiley++) {
			var tileID = tilex + "_" + tiley + "_" + zoom;
			gp = GX_getGazetteer(tileID, featureName);
			if(gp != null) 
				return gp;
		}
	}
	return null;
}

function GX_getGazetteerIndex(tileID, featureName) {
	if(GX_gazetteer_tile_cache[tileID]) {
		for(var i=0; i<GX_gazetteer_tile_cache[tileID].length; i++) {
			var gp = GX_gazetteer_tile_cache[tileID][i];
			var temp = gp.gaz.featureName;
			if(temp == featureName) {
				return i;
			}
		}
	}	
	return -1;
}
	
	
function GX_isGazetteerTileLoaded(tileID) {
	var tileLoaded = false;
	if(GX_gazetteer_tile_status[tileID]) {
		if(GX_gazetteer_tile_status[tileID] == "completed") {
			tileLoaded = true;
		}
	}
	return tileLoaded;
}
