var widget = null;
var PAGE_ID = "w_";
var map = null;
var search = null;
// need a global session2 since it's made in template_top and that's not being added to this
var session2 = new PSession2();
function onLoad() {

	// giving subscriber user rights so all features don't need to be kluged for now
	session2.put("_userid", 2);
	// sets the parameters from the url
	session2.checkUrl();

	if (typeof index_delayed != 'undefined') index_delayed();

	var urlParams = PWebUtil.parseQuery(window.location.search);

	// change legend color ramp if in url params
	if (urlParams['rmp'] && PColorRampOptions[urlParams['rmp']])
		PColorRamp.DEFAULT = PColorRampOptions[urlParams['rmp']];

	// hide menus if parameter is set in url
	if (!urlParams['hideimenu'])
		jQuery('#ind_menu_widget').show();
	if (!urlParams['hidepmenu'])
		jQuery('#addsites_widget').show();

	// when both menus are hidden hide td that contains them so map expands, then adjust layout
	if (urlParams['nomenus']) {
		jQuery('#widgetcolumn').hide();
		jQuery('#mapcolumn').css('padding-left','10px');
		jQuery('#bc_td').css('padding-left','10px');
		jQuery('#maptitlebox').css('padding-left','0px');
		jQuery('#moretitle').css('left','70px');
		if (urlParams['i']) {
			var indid = urlParams['i'];
			jQuery('#widgetAddDataButton').click(function() {
				selectIndicators(indid);
				jQuery(this).find('.innerdiv').addClass('selected');
			});
		}
	}

	// set up click events for legend toggles
	jQuery("#legend_toggle").click(function() {
		toggleOnMapLegend();
	});

	var curZoom = urlParams["curZoom"];
	// create polycreator
	var options = new PPolyCreatorOptions();
	options.poly.weight = 1;
	options.poly.opacity = 0.5;
	polycreator = new PPolyCreator(options);

	// need to set the height for the map div before the PMap is instantiated
	if (urlParams && urlParams['height'])
		jQuery('#map').css('height',urlParams['height'] + 'px');

	// Create map
	map = new PMap(document.getElementById("map"));

	map.addControl(new PLargeMapControl());
	map.enableDoubleClickZoom();
	map.disableKeyboard();

	if (urlParams['search']) {
		jQuery('#searchboxContainer').show();
		initSearchBox();
	}

	// Check if load delay necessary
	loaddelaytotal = getMapRelatedCount(urlParams);
	if (loaddelaytotal)
		map.enableLoadDelay();

	// Handle clicks as an identify request: query pushpin for features/data
	// and display result in info bubble.
	// TODO: refactor this long algorithm into functions
	PEvent.addListener(map, 'click', function(overlay, point) {
		PMIdentificationModule.clickHandler(overlay, point);
	});

	PEvent.addListener(map, 'dblclick', function() {
		map.cancelIdentify = true;
		map.closeInfoWindow();
	});

	// sites legend
	sitelegends = new PTRFSiteLegendGroup(map);
	sitelegends.addListener('change', function() {
		// Reduce the filters into a skinny (and therefore json-able)
		// map of filters to overlay set id's
		var filters = {};

		// iterate through all groups of sets
		var groups = sitelegends.setgroups;
		var l1 = sitelegends.setgroups.length;
		for ( var i1 = 0; i1 < l1; i1++) {
			var sets = groups[i1];
			var l2 = sets.length;
			var overlaySet;
			for ( var i2 = 0; i2 < l2; i2++) {
				overlaySet = sets[i2];
				filters[overlaySet.id] = overlaySet.filtergroups;
			}
		}
		session2.put('ofilters', filters);
	});

	// overlay set events
	PEvent.addListener(map, 'addoverlayset', function(overlayset) {
		sitelegends.refresh();
		session2.put('o', POverlaySetUtil.toIdCsv(map.getOverlaySets()));
	});
	PEvent.addListener(map, 'removeoverlayset', function(overlayset) {
		sitelegends.refresh();
		session2.put('o', POverlaySetUtil.toIdCsv(map.getOverlaySets()));
	});
	// overlay set events
	PEvent.addListener(map, 'setoverlaysets', function(overlaysets) {
		sitelegends.refresh();
		// if menus are hidden then show sites with filters in the legend
		if (urlParams['hideimenu'] && urlParams['hidepmenu'] || urlParams['nomenus']) {
			var sites = createSitesHtmlForLegend();
			jQuery('.legend_container').append(sites);
		}
	});

	// Create the place containment (breadcrumbs) widget
	var breadcrumbs = new PPlaceContainmentWidget(map, document.getElementById("breadcrumbs"), 
			[ PPlaceType.STATE, PPlaceType.COUNTY, PPlaceType.COUNTY_SUBDIVISION, PPlaceType.CITY,
			  PPlaceType.ZIP, PPlaceType.CENSUSTRACT ]);

	// Request containments
	var geocoder = new PClientGeocoder();
	PEvent.addListener(map, 'moveend', function() {
		geocoder.getPlaceContainment(map.getCenter(),PPlaceTypeConfig.PPLACECONTAINMENT.getTypeByAbsoluteZoom(map.getAbsoluteZoom()), function(places) {
			breadcrumbs.refresh(places);
		});
	});

	// change current place if one of the breadcrumbs is clicked
	breadcrumbs.addListener('click', function(place) {
		mapstates.currentplace = place;
		map.closeInfoWindow();
		clearPolygons(map);
		addPolygons(map, place.getVertices());
		mapstates.add(new PMapState(map.getCenter(), map.getZoom(), map.getIndicator(), null, mapstates.currentplace));
	});

	if (urlParams['cx'] && urlParams['cy'] && urlParams['cz']) {
		if ((urlParams['p'] || urlParams['cp']) && loaddelaytotal > 1)
			loaddelaycount++;
		else if (urlParams['p'] || urlParams['cp'])
			map.disableLoadDelay();
		map.setCenter(new PLatLng(urlParams['cy'], urlParams['cx']), urlParams['cz']);
	} else {
		map.setCenter(new PLatLng(37.6902, -96.9129), 2);
	}

	// check if break number in url
	if (urlParams['nb'])
		map.getLegend().setNumberOfBreaks(parseInt(urlParams['nb']));
	else
		map.getLegend().setNumberOfBreaks(DEFAULT_NUMBREAKS);

	// check if indicator will need to load before using identify to open
	// infowindow
	if (urlParams['iwx'] && !urlParams['i'] && urlParams['iwtype'] == 'identify')
		PMIdentificationModule.showInfoWindow(urlParams);

	var transit = PMapLayer.UMTRANSIT;
	// zoom event to toggle transit points when layer turns off
	PEvent.addListener(map, 'zoomend', function() {
		if (map.getZoom() > 8 && transit.isOn() && !transit.pointDataset.isOn())
			transit.pointDataset.on();
		else if (map.getZoom() < 9 && transit.isOn())
			transit.pointDataset.off();
	});

	//mapOptionsPopulate();
	//showMapOptions();
	// adds the transit points if the transit layer got added in sessions
	if (PMapLayer.UMTRANSIT.isOn())
		map.addOverlaySet(PMapLayer.UMTRANSIT.pointDataset);

	PEvent.addListener(map, 'setindicator', function(ind) {
		var legend = map.getLegend();
		legend.clearStoredScale();
		var ind = map.getIndicator();

		document.getElementById("maptitle").innerHTML = createMapWidgetTitle(ind);
		if (document.getElementById('morelink').innerHTML.search('>close<') != -1) {
			var moretitle = document.getElementById('moretitle');
			moretitle.innerHTML = ind.getDescription();
			moretitle.innerHTML += "<a class='dataLink' target='_blank' href='/our-data-directory.html#" + ind.getDataDirectory() + "'>(see data directory)</a>";
		}
		if (urlParams['nomenus'] && urlParams['i']) {
			jQuery('#widgetAddDataButton').attr('title',ind.getLabel());
			jQuery('#widgetAddDataButton').show();
		}
		// hide the legend
		// This should only be done when the map is first loaded and urlparams are initiated, hence the map.winWidgetInitialized
		if (urlParams['hideleg'] && !map.windowWidgetInitialized) {
			toggleOnMapLegend(true);
		}
		map.windowWidgetInitialized = true;
	});
	PEvent.addListener(map, 'removeindicator', function(ind) {
		document.getElementById("maptitle").innerHTML = createTitle(new PMapState(map.getCenter(),map.getZoom(),null,null,null),true);
		jQuery('#moretitle').hide(200);
		document.getElementById('moretitle').innerHTML = "";
		document.getElementById("morelink").innerHTML = "";
		if (urlParams['nomenus'] && urlParams['i'])
			jQuery('#widgetAddDataButton').hide();
	});
/*
	PEvent.addListener(map, 'removeoverlayset', function(overlayset) {
		document.getElementById("maptitle").innerHTML = 
			createTitle(new PMapState(map.getCenter(),map.getZoom(),map.getIndicator(),null,null),true);
	});
*/
	// indicator events
	widget = new PTRFIndicatorLegend(map, map.getLegend(),{enableToggle:true, enableShade:true, enableBreaks:true});
	var indElm = $("#legend");
	var indToggle = widget.getIndicatorToggle();
	var indicatorShade = widget.getIndicatorShade();
	var indicatorBreaks = widget.getIndicatorBreaks();

	var legendContainer = new PLegendContainer(indElm);
	widget.addListener('refresh',legendContainer.show,legendContainer);

	widget.addListener('clear',legendContainer.hide,legendContainer);

	var toggleWidget = new PIndicatorToggleWidget(indElm.find('#toggle_container'));
	indToggle.addListener('refresh', toggleWidget.refresh, toggleWidget);
	indToggle.addListener('clear', toggleWidget.clear, toggleWidget);

	var breaksWidget = new PBreaksWidget(indElm.find('#breaks_container'));
	breaksWidget.removeEditRangesLinks();
	indicatorBreaks.addListener('refresh', breaksWidget.refresh, breaksWidget);
	indicatorBreaks.addListener('clear', breaksWidget.clear, breaksWidget);

	var shadeWidget = new PIndicatorShadeWidget(indElm.find("#shade_container"));
	indicatorShade.addListener('refresh',shadeWidget.update,shadeWidget);
	indicatorShade.addListener('clear',shadeWidget.clear,shadeWidget);
	shadeWidget.addListener('change', indicatorShade.changeShade, indicatorShade);

	legendContainer.init();
	//legendContainer.show();

	// Widget object that populates the map with data from the db and from the url
	var winoptions = new PWindowOptions(map, widget, urlParams);

	PEvent.addListener(map, 'zoomend', function() {
		//session2.put('curZoom', map.getZoom());
		var legend = map.getLegend();

		legend.clearStoredScale();
		if( legend.boundaryTypeIsLocked() ) {
			if( !legend.isValidBoundaryType( map.getLegend().getBoundaryType() ) ) {
				legend.unlockBoundaryType();
			}
		}
		// refreshes map layers checkboxes
		winoptions.refreshMapOptionsLayers();
		if( map.getLegend().getBoundaryType() ) {
			widget.getIndicatorShade().setOldBoundaryTypeId(map.getLegend().getBoundaryType().id);
		}
		if( widget.legend.getBoundaryType() && widget.getIndicatorShade().getOldBoundaryTypeId() != widget.legend.getBoundaryType().id ){
			widget.getIndicatorShade().setOldBoundaryTypeId(widget.legend.getBoundaryType().id);
		}

		widget.refresh();
		map.refresh();
	});
}

/************************
* Class: PWindowOptions *
************************/
PWindowOptions = function(map, widget, urlParams) {
	this.map = map;
	this.widget = widget;
	this.urlParams = urlParams;
	// the id is used to retrieve all the selected data and features to innitiate
	this.id = urlParams['id'];
	
	this.mapLayersHash = [];
	// global map layers
	var mo = MAPLAYER_OPTIONS;
	// stores all the maplayers by layer name
	// layernames are in url and used to find the PMapLayer object
	for (var i=0; i<mo.length; i++) {
		if (mo[i])
			this.mapLayersHash[mo[i].name] = mo[i];
	}

	PEvent.addListener(map.logo, 'click', function() { window.open("http://www.policymap.com","policymap"); });

	this.addOptions();
}

PWindowOptions.prototype.addOptions = function() {
	// adds place from url
	this.addPlace();

	// adds indicator from url
	this.addIndicators();

	// adds points from url
	this.addPoints();

	// adds map layer from url
	this.addMapOptionsLayers();
}

PWindowOptions.prototype.addPlace = function(urlParams) {
	var curZoom = null;
	var urlParams = this.urlParams;
	if (urlParams['p'] && (!urlParams['iwtype'] || urlParams['iwtype'] == 'place')) {
		var f = function(places) {
			loadDelayCheck();

			var place = places[places.length - 1];
			this.map.clearOverlays();

			if (place instanceof PPlace) {
				if (!urlParams['cx'] && !urlParams['cy'] && !urlParams['cz']){
					this.map.setCenterBounds(place.getBounds());
					if(curZoom)
						this.map.setZoom(curZoom);
				}
				// when url has nobounds param don't show polygon but still center map on place
				// this allows to still use the place id to center map
				// this way lat longs and zooms don't need to be set if user knows what place they want to center around
				if (urlParams['nobounds']) {
					map.setCenterBounds(place.getBounds());
				}
				else {
					var polygons = place.getVertices();
					if (polygons)
						addPolygons(this.map, polygons);
					mapstates.currentplace = place;
				}
			} else if (!urlParams['cx'] && !urlParams['cy'] && !urlParams['cz']) {
				this.map.setCenter(place, curZoom || 13);
			}
			if (urlParams['iwx'] && urlParams['iwy']) {
				var title = "<div style='font-size: 11px'>" + place.getLabel() + " (" + place.getType().getName() + ")</div>";
				point = place.getBounds().getCenter();
//				this.map.openInfoWindowHtml(point, title);
			}

			// add to map state list
			mapstates.add(new PMapState(this.map.getCenter(), this.map.getZoom(), this.map.getIndicator(), null, mapstates.currentplace));
		}
		PPlaceLoader.load( [ urlParams['p'] ], f);

		// check if address in session
	} else if (urlParams['place'] && urlParams['iwtype'] != "identify") {
		var addy = urlParams['place'];
		geocoder.getLatLng(addy, function(latlng) {
			if (latlng) {
				loadDelayCheck();
				if (urlParams['cx'] && urlParams['cy'] && urlParams['cz']) {
					this.map.setCenter(new PPoint(urlParams['cx'], urlParams['cy']), urlParams['cz']);
				} else if (urlParams['cz']) {
					this.map.setCenter(latlng, urlParams['cz'])
				} else {
					this.map.setCenter(latlng, curZoom || 13);
				}
				// add see report link
				var link = generateReportLink(null, null, addy);
				var div = document.createElement('div');
				div.innerHTML = "<div class='infoBubbleText'>" + addy + "</div><br />";
				div.appendChild(link);
				this.map.openInfoWindowHtml(latlng, div);
			}
		});
		// check if custom polygon in session
	} else if (urlParams['cp']) {
		polycreator.load(urlParams['cp'], function(places) {
			if (places[0]) {
				loadDelayCheck();
				custom_place = places[0];
				var polygon = new PPolyline(places[0].getVertices(), '#e68000');
				this.map.addOverlay(polygon);
				var html = function(){ return PMIdentificationPrinter.printCustomPolyPlaces(custom_place, polycreator.marker); };
				polycreator.addPolyMarker(places[0].getVertices()[0],html,this.map);
				
				if (!urlParams['cx'] && !urlParams['cy'] && !urlParams['cz']) {
					this.map.setCenterBounds(polygon.getBounds());
				}
				// open custom poly infowindow from saved map
				if (urlParams['iwtype'] == 'cp')
					polycreator.marker.openInfoWindow(html);
			}
		});
	}
}

PWindowOptions.prototype.addIndicators = function() {
	if (this.urlParams['i']) {
		var ind = this.urlParams['i'];
		// make sure the indicator is in this users db by seeing if it was added to the taxonomy
		if (ria[ind]) {
			var period = null;
			if (this.urlParams['period']) {
				period = this.urlParams['period'];
				session2.put('period', period);
			}
			selectIndicators(ind);
		}
	}
}

PWindowOptions.prototype.addPoints = function() {
	var urlParams = this.urlParams;
	// check if overlaysets in session
	if (urlParams['o']) {
		// only allow pointset from url if it's in the db
		if (!allowedPinsets[urlParams['o']])
			return;
		var ids = urlParams['o'].split(',');
		var l = ids.length;
		var sets = [];
		for ( var i = 0; i < l; i++) {
			// don't use transit points, they're added with transit layer, and aren't in hash
			if (!overlaySetHash[ids[i]])
				continue;

			var site = createSites(this.map, ids[i], overlaySetHash[ids[i]].name, overlaySetHash[ids[i]].icon);
			if (site != null) {
				var filters = session2.getFilters(ids[i]);
				if (filters) {
					if (filters[0] && filters[0].values[0] == "COLORCODE") {
						var ftrs = [];
						var displayfilters = site.displayfiltergroups[filters[0].name];
						var l = displayfilters.length;
						for ( var i = 0; i < l; i++) {
							if (displayfilters[i].values[0] != "COLORCODE")
								ftrs.push(displayfilters[i]);
						}
						site.setFiltersByIcons(ftrs, site.colorcodes);
						site.filtergroups[filters[0].name] = [];
						site.filtergroups[filters[0].name].push(filters[0]);
					} else
						site.setFilters(filters);
				}
				sets.push(site);
			}
		}
		this.map.setOverlaySets(sets);
	}
}

// This is similar to MapCommon.js mapOptionsPopulate version but uses a hash of the layers since it needs to get the layer by the name
// It also doesn't redraw the html elements on events, but just disables/enables checkbox
PWindowOptions.prototype.addMapOptionsLayers = function() {
	var map = this.map;
	var urlParams = this.urlParams;
	var mapLayersHash = this.mapLayersHash;

	// don't bother if not in url
	if (!urlParams['ml'])
		return;

	var layerNames = [urlParams['ml']];
	// if we need to use more than 1 layer then uncomment this line and use this to set loop, but currently only one layer is allowed
	//var layerNames = urlParams['ml'].split(",")
	
	var optsbox = document.getElementById('optsbox');
	var l = MAPLAYER_OPTIONS_ORDER.length;
	var scale = map.getScale();
	var layerDivArray = [];
	// only allow 1 map layer for now
	for (var j=0; j<1; j++) {
		if (mapLayersHash[layerNames[j]]) {
			// remove the line breaks from layer titles
			var layerTitle = mapLayersHash[layerNames[j]].title.replace(/<br>/, ' ');

			var divMain = document.createElement('div');
			divMain.className = 'widget_layerbox';
			divMain.layername = layerTitle;

			// check box
			var opt = document.createElement('input');
			opt.type = "checkbox";
			opt.layername = layerNames[j];
			opt.id = "mapOptionsLayer";
			divMain.appendChild(opt);
//			if (parseInt(MAPLAYER_OPTIONS_ON[i]) && (!MAPLAYER_OPTIONS[i].forSubscribers || isSubscriber()))
//				opt.checked = true;
			if (urlParams['mlon']) {
				var m = urlParams['mlon'].split(",");
				if (m[j]) {
					opt.checked = true;
					mapLayersHash[layerNames[j]].on();
				}
			}
			var that = this;
			PEvent.addListener(opt, 'click', function() {
				that.toggleWidgetMapOptionsLayers(this.layername);
			});

			// label
			var text = document.createElement("label");
			text.style.verticalAlign = "top";
			text.style.paddingRight = "3px";
			text.style.textTransform = "capitalize";
			jQuery(text).attr("for",layerNames[j]);
			text.innerHTML = urlParams['mltitle'] || layerTitle;
			if (opt.disabled) {
				text.title = 'Not available at this zoom level';
				text.style.color = "#ccc";
			}
			divMain.appendChild(text);
			// divs are put in array and then displaying order is done based on MAPLAYER_OPTIONS_ORDER array
			layerDivArray.push(divMain);
			optsbox.appendChild(divMain);
		}
	}
	// disables/enables checkboxes
	this.refreshMapOptionsLayers(mapLayersHash);

	// need to turn these on 
//	PMapLayer.POINTLINE.on();
//	PMapLayer.POLY.on();
}

// Similar to MapCommon.js version but again uses MAPLAYERS_HASH instead of MAPLAYER_OPTIONS array
PWindowOptions.prototype.toggleWidgetMapOptionsLayers = function(name) {
	var mapLayersHash = this.mapLayersHash;
	var layer = mapLayersHash[name];

	// add label layers for these layers
	var label = null;
	if (MAPLAYER_LABELS[layer.name])
		label = MAPLAYER_LABELS[layer.name];

	if (layer.isOn()) {
		layer.off();
		if (label)
			label.off();
		// removes transit points
		if (mapLayersHash[name].pointDataset)
			map.removeOverlaySet(mapLayersHash[name].pointDataset);
	} else {
		layer.on();
		if (label)
			label.on();
		// adds transit points
		if (mapLayersHash[name].pointDatasetId) {
			var markerset = createTransitPoints(index);
			map.addOverlaySet(markerset);
		}
	}
}

// Checks scale of map compared to what scales the layers are available for and disables/enables checkboxes
PWindowOptions.prototype.refreshMapOptionsLayers = function() {
	var mapLayersHash = this.mapLayersHash;
	var scale = map.getScale();
	var inputs = jQuery('#optsbox').find('input');
	var labels = jQuery('#optsbox').find('label');
	for (var i=0; i<inputs.length; i++) {
		if (mapLayersHash[inputs[i].layername].minScale > scale || mapLayersHash[inputs[i].layername].maxScale < scale) {
			inputs[i].disabled = true;
			labels[i].title = 'Not available at this zoom level';
			labels[i].style.color = "#ccc";
		}
		else  {
			inputs[i].disabled = false;
			labels[i].title = "";
			labels[i].style.color = "#333";
		}
	}
}

// Rewritten from createTitle in MapCommon.js and removed mapstates
function createMapWidgetTitle(indicator) {
	var text = "";
	if (indicator && indicator.getFullDisplayName()) {
		if (indicator.getDescription() != "" && indicator.getDescription().length < indicator.getFullDisplayName().length) {
			text = indicator.getDescription();
			if (document.getElementById('morelink').innerHTML.search('>close<') == -1)
				var moretext = "details";
			else
				var moretext = "close";
			document.getElementById('morelink').innerHTML = "<a class='morelink' onclick='showMore()'><span id='morespan' style='text-decoration:underline'>"
				+ moretext
				+ "</span><img class='morearrow' src='images/more_arrow.gif' /></a>";

		} else {
			text = indicator.getFullDisplayName();
			if (document.getElementById('morelink').innerHTML.search('>close<') == -1)
				var moretext = "details";
			else
				var moretext = "close";
			document.getElementById('morelink').innerHTML = "<a class='morelink' onclick='showMore()'><span id='morespan' style='text-decoration:underline'>"
				+ moretext
				+ "</span><img class='morearrow' src='images/more_arrow.gif' /></a>";
		}
	} else if (indicator) {
		text = indicator.displayName;
	}

	return text;
}

// taken from PSession2 object
function getMapRelatedCount(urlParams) {
	var retVal = 0;
	if (urlParams['i'])
		retVal++;
	// only allow one type of location
	if (urlParams['p'])
	retVal++;
	else if (urlParams['place'])
		retVal++;
	else if (urlParams['cp'])
		retVal++;
	// special case for overlays (get all)
	if (urlParams['o']) {
		var os = urlParams['o'].split(",");
		retVal = retVal + os.length;
	}

	return retVal;
}

function clearIndicatorData() {
	widget.clear();
	var urlParams = PWebUtil.parseQuery(window.location.search);
	if (urlParams['nomenus'] || urlParams['hideimenu']) {
		jQuery('#widgetAddDataButton').find('.innerdiv').removeClass('selected');
		jQuery('#widgetAddDataButton').show();
	}
}

function resetWidget() {
	clearIndicatorData();
	map.clearOverlays();
	map.clearOverlaySets();
	sitelegends.refresh();

	if (map.getInfoWindow())
		map.closeInfoWindow();

	map.setCenter(new PLatLng(37.6902, -96.9129), 2);
	document.getElementById("maptitle").innerHTML = "";
	jQuery('#moretitle').hide(200);
	document.getElementById('moretitle').innerHTML = "";
	document.getElementById('morelink').innerHTML = "";

	search.reset();

	session.clear();
	session2.removeAllRelevant();
}
