﻿/*
Primary class for the application. Contains all the methods needed by other classes.
*/
cadastral.base = {

	zoomIn: function () {
		var currentLevel = cadastral.map.getLevel();
		if (currentLevel < cadastral.minLevel) {
			cadastral.map.setLevel(currentLevel + 1);
		}
	},

	zoomOut: function () {
		var currentLevel = cadastral.map.getLevel();
		if (currentLevel > cadastral.maxLevel) {
			cadastral.map.setLevel(currentLevel - 1);
		}
	},

	/*
	Initializes the dynamic layers of the map. Sets visibility and opacity of the layer and set the checkboxes.
	*/
	initDynamicLayer: function (url, id, isVisible, opacity) {
		var imageParameters = new esri.layers.ImageParameters();
		var layer = new esri.layers.ArcGISDynamicMapServiceLayer(url, { id: id, visible: isVisible, "imageParameters": imageParameters, "opacity": opacity });

		switch (layer.id) {
			case "street":
				layer.setVisibleLayers([0, 7, 10, 24, 29, 30, 31, 32, 33, 34, 35, 36, 37]);
				if (isVisible) {
					dojo.addClass("street2", "street2Active");
				}
				break;
			case "satellite":
				layer.setVisibleLayers([0, 17]);
				if (isVisible) {
					dojo.addClass("satellite", "satellite2Active");
				}
				break;
			case "topo":
				layer.setVisibleLayers([0, 17]);
				if (isVisible) {
					dojo.addClass("topo", "topo2Active");
				}
				break;
			default:
				break;
		}

		cadastral.map.addLayer(layer);

		return layer;
	},

	initImageServiceLayer: function (url, id, isVisible, checkBoxId) {
		var layer = new esri.layers.ArcGISImageServiceLayer(url, { id: id, visible: isVisible });
		cadastral.map.addLayer(layer);

		if (isVisible) {
			var checkBox = dojo.byId(checkBoxId);
			if (checkBox) {
				checkBox.checked = true;
			}
		}
		return layer;
	},

	initTiledLayer: function (url, id, isVisible, opacity, checkBoxId) {
		var layer = new esri.layers.ArcGISTiledMapServiceLayer(url, { id: id, visible: isVisible, "opacity": opacity });
		cadastral.map.addLayer(layer);
		if (isVisible) {
			var checkBox = dojo.byId(checkBoxId);
			if (checkBox) {
				checkBox.checked = true;
			}
		}

		return layer;
	},

	/*
	Handles click event for base layer radio buttons. Toggles base layers on and off.
	*/
	changeMap: function (layerId) {
		var layers = [];
		switch (layerId) {
			case "street":
				layers[0] = cadastral.street;
				dojo.addClass("street2", "street2Active");
				dojo.removeClass("satellite2", "satellite2Active");
				dojo.removeClass("topo2", "topo2Active");
				break;
			case "satellite":
				layers[0] = cadastral.satellite;
				dojo.addClass("satellite2", "satellite2Active");
				dojo.removeClass("street2", "street2Active");
				dojo.removeClass("topo2", "topo2Active");
				break;
			case "topo":
				layers[0] = cadastral.topo;
				dojo.addClass("topo2", "topo2Active");
				dojo.removeClass("street2", "street2Active");
				dojo.removeClass("satellite2", "satellite2Active");
				break;
			default:
				break;
		}

		cadastral.base.showLoading();
		cadastral.base.hideBaseLayers(layers);
		for (var i = 0; i < layers.length; i++) {
			if (layers[i].id == "street") {
				layers[i].setVisibleLayers([0, 7, 10, 24, 29, 30, 31, 32, 33, 34, 35, 36, 37]);
			}
			else {
				layers[i].show();
			}
		}
	},

	hideBaseLayers: function (layers) {
		for (var j = 0, jl = cadastral.baseLayerArray.length; j < jl; j++) {
			var layer = cadastral.map.getLayer(cadastral.baseLayerArray[j].id);
			if (dojo.indexOf(layers, layer) == -1) {
				if (layer.id == "street") {
					layer.setVisibleLayers([0, 17]);
				}
				else {
					layer.hide();
				}
			}
		}
	},

	/*
	Sets map back to initial extent which is the full state extent
	*/
	zoomToInitialExtent: function () {
		this.map.setExtent(this.initialExtent, true);
	},

	/*
	Used to show a graphic on the map
	*/
	addGraphicToMap: function (geometry) {
		var symbol;
		switch (geometry.type) {
			case "polyline":
				symbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 128, 255]), 2);
				break;
			case "polygon":
				symbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 128, 255]), 2);
				break;
			default:
				break;
		}

		var graphic = new esri.Graphic(geometry, symbol);
		cadastral.map.graphics.add(graphic);

		return graphic;
	},

	// Show identify error
	showError: function (error, evt) {
		alert(error.description);
	},

	toggleButtonPosition: function () {
		var w1 = parseInt(dojo.style("propertyCard", "width"));
		var w2 = parseInt(dojo.style("searchPane", "width"));
		var w3 = 0;
		if (dojo.style("propertyCard", "visibility") == "hidden") {
			if (parseInt(dojo.style("legendPane", "width")) > 0 || parseInt(dojo.style("helpPane", "width")) > 0 || parseInt(dojo.style("toolsPane", "width"))) {
				w3 = parseInt(dojo.style("legendPane", "width")) + parseInt(dojo.style("helpPane", "width")) + parseInt(dojo.style("toolsPane", "width")) + 20;
			}
		}
		var w4 = parseInt(dojo.style("leftControlPane", "width"));
		return w1 + w2 + w3 + w4;
	},

	setToggleButtonPosition: function () {
		if (dojo.style("togglePropertyCard", "visibility") == "visible" || dojo.style("propertyCard", "visibility") == "visible") {
			var w = cadastral.base.toggleButtonPosition();
			dojo.style("togglePropertyCard", { "position": "absolute", "top": "35px", "left": w + "px", "visibility": "visible", "width": "28px" });
		}
	},

	/*
	Sets the width and visibility on the property card pane then calls resize on the parent bordercontainer to resize all children appropriately.
	*/
	showPropertyCard: function (geocode) {
		if (dojo.style("propertyCard", "visibility") != "visible") {
			// Show the propertyCard widget
			dojo.style("propertyCard", { "width": "560px", "visibility": "visible" });

			// Resize the mainWindow dijit to get all children to resize appopriately
			var mainWindow = dijit.byId("mainWindow");
			if (mainWindow) {
				mainWindow.resize();
			}
		}
		cadastral.base.setToggleButtonPosition();

		// Gecode will be passed in from the search options links
		if (geocode) {
			dojo.style("geocodeParcelMessage", "display", "none");
			// Disconnect the upMapUpdateEnd listener so that we show the loading symbol uninterrupted until the final map displays
			// We connect it again when we run the queryTask to get the parcel geometry.
			dojo.disconnect(cadastral.onMapUpdateEndConnection);
			cadastral.map.graphics.clear();
			geocode = geocode.split("-").join("");
			cadastral.geocode = geocode;

			var queryTask = new esri.tasks.QueryTask(cadastral.parcelQueryUrl);
			var query = new esri.tasks.Query();
			query.returnGeometry = true;
			query.where = "PARCELID = '" + cadastral.geocode + "'";
			dojo.connect(queryTask, "onError", function (error) {
				cadastral.onMapUpdateEndConnection = dojo.connect(cadastral.map, "onUpdateEnd", cadastral.base.hideLoading);
				cadastral.base.hideLoading();
			});
			dojo.connect(queryTask, "onComplete", cadastral.base.drawGraphic);
			queryTask.execute(query);
			cadastral.base.updatePropertyCard();
		}

		cadastral.base.getTaxYearData();
		cadastral.base.setPrintPane();

	},

	drawGraphic: function (featureSet) {
		setTimeout(function () {
			// reconnect the onUpdateEnd listener so the loading div is hidden when the parcel is displayed
			cadastral.onMapUpdateEndConnection = dojo.connect(cadastral.map, "onUpdateEnd", cadastral.base.hideLoading);
			var extent = cadastral.base.getExtent(featureSet);
			if (typeof extent !== "undefined") {
				cadastral.map.setExtent(extent, true);
				var symbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 128, 255]), 2);
				var feature = featureSet.features[0];
				feature.setSymbol(symbol);
				cadastral.map.graphics.add(feature);
				dojo.byId("parcelMapMessage").innerHTML = "&nbsp;";
			}
			else {
				cadastral.base.hideLoading();
				dojo.style("geocodeParcelMessage", "display", "block");
				dojo.byId("parcelMapMessage").innerHTML = "NOTE: The parcel for this owner cannot be mapped.";
			}
		}, 1000);
	},

	/*
	Closes the property card pane and calls resize on the parent bordercontainer to adjust the size of all the viewable panes.
	*/
	closePropertyCard: function () {
		dojo.style("propertyCard", "width", "0px");
		dojo.style("propertyCard", "visibility", "hidden");
		dojo.style("togglePropertyCard", { "position": "absolute", "top": "0px", "visibility": "hidden", "width": "28px" });
		// Resize the mainWindow dijit to get all children to resize appopriately
		var mainWindow = dijit.byId("mainWindow");
		if (mainWindow) {
			mainWindow.resize();
		}
		// clear off the parcel boundary symbol
		cadastral.map.graphics.clear();
		// resize the map because the mapDiv has changed size
		cadastral.base.resizeMap();
	},

	togglePropertyCard: function () {
		var visibility = dojo.style("propertyCard", "visibility");
		if (visibility == "visible") {
			dojo.style("propertyCard", { "width": "0px", "visibility": "hidden" });
			cadastral.base.setToggleButtonPosition();
			dojo.attr("propertyCardToggle", "src", "Content/images/expand.png");
			dojo.attr("propertyCardToggle", "alt", "Show");
			dojo.attr("propertyCardToggle", "title", "Show Property Record Card");
		}
		else {
			dojo.style("propertyCard", { "width": "560px", "visibility": "visible" });
			cadastral.base.setToggleButtonPosition();
			dojo.attr("propertyCardToggle", "src", "Content/images/collapse.png");
			dojo.attr("propertyCardToggle", "alt", "Hide");
			dojo.attr("propertyCardToggle", "title", "Hide Property Record Card");
		}

		var mainWindow = dijit.byId("mainWindow");
		if (mainWindow) {
			mainWindow.resize();
		}
	},

	/*
	Called anytime we need to update the property record card and we may or may not be on the summary pane.
	*/
	updatePropertyCard: function () {
		switch (cadastral.activePane) {
			case "summaryPane":
				cadastral.identify.getSummaryData();
				break;
			case "ownersPane":
				cadastral.identify.getOwnerData();
				break;
			case "commercialBuildingsPane":
				cadastral.identify.getCommercialData();
				break;
			case "appraisalsPane":
				cadastral.identify.getAppraisalData();
				break;
			case "marketLandPane":
				cadastral.identify.getMarketLandData();
				break;
			case "otherBuildingsPane":
				cadastral.identify.getOtherBuildingData();
				break;
			case "dwellingPane":
				cadastral.identify.getDwellingData();
				break;
			case "agForestPane":
				cadastral.identify.getAgForestData();
				break;
			default:
				cadastral.identify.getSummaryData();
				break;
		}
	},

	/*
	Handles onchange event for tax year select list
	*/
	setTaxYear: function (taxYear) {
		if (cadastral.geocode !== null && cadastral.geocode !== "") {
			var control = dojo.byId("taxYearDropDown");
			if (control) {
				cadastral.taxYear = control.options[control.selectedIndex].value;
				cadastral.base.updatePropertyCard();
			}
		}
	},

	/*
	Resizes map div when browser window resizes
	*/
	resizeMap: function () {
		var resizeTimer;
		clearTimeout(resizeTimer);
		resizeTimer = setTimeout(function () {
			cadastral.map.resize();
			cadastral.map.reposition();
		}, 800);
	},

	/*
	Used to show results in the appropriate pane in the property record card. 
	results - json result set
	pane - target pane to inject the results into
	*/
	showData: function (results, pane) {
		dojo.byId(pane).innerHTML = results;
		dojo.style("certificateWait", "display", "none");
		dojo.style("bufferWait", "display", "none");
		dojo.style("ownerWait", "display", "none");
		dojo.style("geocodeWait", "display", "none");
		dojo.style("assessmentWait", "display", "none");
	},

	fillCountySelect: function (id, countyList) {
		var options = '';
		var selectList = dojo.byId(id);
		selectList.options.length = 0;
		var i = 1;
		selectList.options[0] = new Option("-- Choose a County --", "", false, true);
		for (var key in countyList) {
			i = selectList.options.length++;
			selectList.options[i] = new Option(countyList[i - 1].Name, countyList[i - 1].Id, false, false);
		}
	},

	/*
	Uses dojo.addClass to set the image for the currently active tool.
	*/
	setActiveTool: function (active) {
		var returnNow = false;
		if (cadastral.activeTool != active) {
			switch (active) {
				case "searchButton":
					dojo.xhrGet({
						url: "./Search/GetCountyList",
						handleAs: "json",
						load: function (rdata) {
							cadastral.base.fillCountySelect('countySelect', rdata);
							cadastral.base.fillCountySelect('countyAssessmentSelect', rdata);
							cadastral.base.fillCountySelect('countyCertSelect', rdata);
						}
					});
					dojo.addClass("searchButton", "searchButtonActive");
					dojo.style("searchPane", "width", "287px");
					dojo.style("searchPane", "visibility", "visible");
					// Resize the mainWindow dijit to get all children to resize appopriately
					var mainWindow = dijit.byId("mainWindow");
					if (mainWindow) {
						mainWindow.resize();
					}
					cadastral.base.resizeMap();
					break;
				case "legendButton":
					dojo.addClass("legendButton", "legendButtonActive");
					dojo.removeClass("legendPane", "paneHidden");
					dojo.addClass("legendPane", "paneVisible");
					break;
				case "dataButton":
					dojo.addClass("dataButton", "dataButtonActive");
					dojo.removeClass("dataPane", "paneHidden");
					dojo.addClass("dataPane", "dataPaneVisible");
					var dataHtml = "<iframe src=\"ftp://anonymous:anonymous@ftp.gis.mt.gov/CadastralFramework/\" width=\"100%\" height=\"95%\" scrolling=\"auto\" frameborder=\"0\" id=\"download\"><p>Your browser does not support iframes.</p></iframe>";
					dojo.byId("dataPaneContents").innerHTML = dataHtml;
					break;
				case "helpButton":
					dojo.addClass("helpButton", "helpButtonActive");
					dojo.removeClass("helpPane", "paneHidden");
					dojo.addClass("helpPane", "paneVisible");
					break;
				case "toolsButton":
					dojo.addClass("toolsButton", "toolsButtonActive");
					dojo.removeClass("toolsPane", "paneHidden");
					dojo.addClass("toolsPane", "paneVisible");
					cadastral.mapOnClickListeners.push(dojo.connect(cadastral.map, "onClick", cadastral.identify.identifyIt));
					break;
				default:
					break;
			}
		}

		if (returnNow) {
			return;
		}

		switch (cadastral.activeTool) {
			case "searchButton":
				dojo.removeClass("searchButton", "searchButtonActive");
				dojo.style("searchPane", "width", "0px");
				dojo.style("searchPane", "visibility", "hidden");
				// Resize the mainWindow dijit to get all children to resize appopriately
				var mainWindow = dijit.byId("mainWindow");
				if (mainWindow) {
					mainWindow.resize();
				}
				cadastral.base.resizeMap();
				break;
			case "legendButton":
				dojo.removeClass("legendButton", "legendButtonActive");
				dojo.removeClass("legendPane", "paneVisible");
				dojo.addClass("legendPane", "paneHidden");
				break;
			case "dataButton":
				dojo.removeClass("dataButton", "dataButtonActive");
				dojo.removeClass("dataPane", "dataPaneVisible");
				dojo.addClass("dataPane", "paneHidden");
				break;
			case "helpButton":
				dojo.removeClass("helpButton", "helpButtonActive");
				dojo.removeClass("helpPane", "paneVisible");
				dojo.addClass("helpPane", "paneHidden");
				break;
			case "toolsButton":
				dojo.removeClass("toolsButton", "toolsButtonActive");
				dojo.removeClass("toolsPane", "paneVisible");
				dojo.addClass("toolsPane", "paneHidden");
				dojo.byId("identifyButton").checked = "checked";
				cadastral.tools.displayTool('identifyButton');
				cadastral.tools.prevTool = "";
				cadastral.tools.prevSelectType = "";
				if (cadastral.map.graphics !== null) {
					if (dojo.style("togglePropertyCard", "visibility") != "visible") {
						cadastral.map.graphics.clear();
					}
				}
				break;
			default:
				break;
		}
		cadastral.base.setToggleButtonPosition();
		if (cadastral.activeTool == active) {
			cadastral.activeTool = "";
		}
		else {
			cadastral.activeTool = active;
		}
	},

	/*
	This function is used anytime we need to get an extent to zoom the map to.
	*/
	getExtent: function (featureSet) {
		if (featureSet.features.length > 0) {
			var maxX;
			var maxY;
			var minX;
			var minY;
			var extent = esri.graphicsExtent(featureSet.features);
			if (extent === null) {
				if (featureSet.features.length == 1 && featureSet.features[0].geometry.type == "point") {
					maxX = featureSet.features[0].geometry.x + 100;
					minX = featureSet.features[0].geometry.x - 100;
					maxY = featureSet.features[0].geometry.y + 100;
					minY = featureSet.features[0].geometry.y - 100;
				}
			}
			else {
				if (featureSet.features.length == 1 && featureSet.features[0].geometry.type == "polygon") {
					maxX = extent.xmax + 100;
					maxY = extent.ymax + 100;
					minX = extent.xmin - 100;
					minY = extent.ymin - 100;
				}
				else {
					for (i = 0; i < featureSet.features.length; i++) {
						var extent = esri.graphicsExtent([featureSet.features[i]]);

						if (featureSet.features[i].geometry.type == "point") {
							if (i === 0) {
								maxX = featureSet.features[i].geometry.x;
								minX = featureSet.features[i].geometry.x;
								maxY = featureSet.features[i].geometry.y;
								minY = featureSet.features[i].geometry.y;
							}
							else {
								if (maxX < featureSet.features[i].geometry.x) {
									maxX = featureSet.features[i].geometry.x;
								}
								if (maxY < featureSet.features[i].geometry.y) {
									maxY = featureSet.features[i].geometry.y;
								}
								if (minX > featureSet.features[i].geometry.x) {
									minX = featureSet.features[i].geometry.x;
								}
								if (minY > featureSet.features[i].geometry.y) {
									minY = featureSet.features[i].geometry.y;
								}
							}
						}
						else if (featureSet.features[i].geometry.type == "polygon") {
							if (i === 0) {
								maxX = extent.xmax;
								maxY = extent.ymax;
								minX = extent.xmin;
								minY = extent.ymin;
							}
							else {
								if (maxX < extent.xmax) {
									maxX = extent.xmax;
								}
								if (maxY < extent.ymax) {
									maxY = extent.ymax;
								}
								if (minX > extent.xmin) {
									minX = extent.xmin;
								}
								if (minY > extent.ymin) {
									minY = extent.ymin;
								}
							}
						}
					}
				}
			}

			var extent = new esri.geometry.Extent(minX, minY, maxX, maxY, new esri.SpatialReference({ wkid: 102100 }));
			return extent;
		}
	},

	/*
	This function is used anytime we need to get an extent to zoom the map to.
	*/
	getExtentFromIdentify: function (feature) {
		var maxX;
		var maxY;
		var minX;
		var minY;
		var features = [feature];
		var extent = esri.graphicsExtent(features);

		if (feature.geometry.type == "polygon") {
			maxX = extent.xmax + 100;
			maxY = extent.ymax + 100;
			minX = extent.xmin - 100;
			minY = extent.ymin - 100;
		}

		var projectExtent = new esri.geometry.Extent(minX, minY, maxX, maxY, new esri.SpatialReference({ wkid: 102100 }));
		return projectExtent;
	},

	/*
	Handles showing the loading div anytime the map is refreshing
	*/
	showLoading: function () {
		var top = (parseInt(Math.round(dojo.style("mapDiv", "height")) / 2 - 75)) + 'px';
		var left = (parseInt(Math.round(dojo.style("mapDiv", "width")) / 2 - 100)) + 'px';
		dojo.style("loadingDiv", "top", top);
		dojo.style("loadingDiv", "left", left);
		dojo.style("loadingDiv", "width", "200px");
		dojo.style("loadingDiv", "visibility", "visible");
	},

	/*
	Handles hiding the loading div when the map is done refreshing
	*/
	hideLoading: function () {
		dojo.style("loadingDiv", "visibility", "hidden");
	},

	onZoomEnd: function () {
		cadastral.base.checkZoomLevel();
	},

	checkZoomLevel: function () {
		// The code below is what is used to limit topo from rendering at small scales.
		// We basically just limit the use of the button until we are in the scale range we want.
		var currentLevel = cadastral.map.getLevel();
		if (currentLevel >= 0 && currentLevel <= 4) {
			var layer = cadastral.map.getLayer("topo");
			if (layer.visible) {
				cadastral.base.changeMap("street");
			}
			dojo.attr("topo2", "disabled", true);
			dojo.removeClass("topo2", "topo2Active");
			dojo.removeClass("topo2", "topo2");
			dojo.addClass("topo2", "topo2Disabled");
		}
		else {
			var layer = cadastral.map.getLayer("topo");
			if (layer.visible) {
				dojo.addClass("topo2", "topo2Active");
			}
			else {
				dojo.addClass("topo2", "topo2");
			}
			dojo.attr("topo2", "disabled", false);
			dojo.removeClass("topo2", "topo2Disabled");
		}
	},

	onMapUpdateEnd: function () {
		if (cadastral.identify.identifyPoint !== null) {
			cadastral.map.centerAt(cadastral.identify.identifyPoint);
			cadastral.identify.identifyPoint = null;
		} else {
			cadastral.base.hideLoading();
		}
		cadastral.base.checkZoomLevel();
	},

	/*
	Gets all available tax years in the database for the given geocode
	*/
	getTaxYearData: function () {
		dojo.xhrGet({
			url: "./Common/GetTaxYearData",
			content: { geocode: cadastral.geocode },
			handleAs: "json",
			load: function (rdata) {
				dojo.byId('taxYearPane').innerHTML = rdata;
				var control = dojo.byId("taxYearDropDown");
				var yearIndex;
				if (control && cadastral.taxYear != "") {
					for (i = 0; i < control.length; i++) {
						if (control.options[i].value == cadastral.taxYear) {
							yearIndex = i;
						}
					}
					control.selectedIndex = yearIndex;
				}
			}
		});
	},

	setPrintPane: function () {
		dojo.xhrGet({
			url: "./Common/SetGeocode",
			content: { geocode: cadastral.geocode },
			handleAs: "json",
			load: function (rdata) {
				cadastral.base.showData(rdata, 'printPane');
			}
		});
	}
};
