angular.module('MobileWebLogistics')
	.service('layerEvent', function () {
		var layerEventServ = this;
		this.parcelClick = function ($scope, evt) {
			if ($("#openSelectByGraphic").hasClass("active") || $("#GSButton").hasClass("selected") || $("#pictoButton").hasClass("selected") || $("#textTool").hasClass("selected") || $("#pointTool").hasClass("selected") || $("#lineTool").hasClass("selected") || $("#polygonTool").hasClass("selected") || $("#identifyButton").hasClass("selected")) {
				return false;
			} else {

				$scope.searchTarget = 'parcels';
				$scope.selObject = 'pl';
				if (window.innerWidth < 651) {
					$scope.map.infoWindow.resize(100, 30);
					$scope.map.infoWindow.hide();
				}

				$scope.selectedParcel = evt.graphic.attributes;
				$scope.selectedParcel['geometry'] = evt.graphic.geometry;
				$scope.adjoinerList = [];
				for (var key in $scope.selectedParcel) {
					thisKey = $scope.selectedParcel[key.toString()];
					$scope.selectedParcel[key.toString()] = $scope.formatParcelData(key, thisKey, $scope.selectedParcel[key.toString()]);
				}

				if (window.innerWidth < 651) { //in case if user enlarges windows more than 651
					$scope.queryObjectId($scope.selectedParcel[$scope.parcelUid], $scope.selectedParcel[$scope.parcelOID], 'detail', 'pl');
				}

				$scope.$apply();
				$scope.bufferLayer.clear();
				$scope.selectedLayer.clear();
				$scope.bmLayer.clear();
				$scope.immediateAdjoiners = true;

				// The data source is a MapServer and has an identify endpoint
				if (!$scope.isFeatureService) {
					$("#identifyPreloaderContainer").addClass("active");
					$scope.identifyTask = new $scope.IdentifyTask($scope.featureServUrl);
					$scope.identifyParams = new $scope.IdentifyParameters();
					$scope.identifyParams.tolerance = 0;
					$scope.identifyParams.returnGeometry = true;
					$scope.identifyParams.layerIds = [$scope.searchParcelLyrId];
					$scope.identifyParams.layerOption = $scope.IdentifyParameters.LAYER_OPTION_ALL;
					$scope.identifyParams.width = $scope.map.width;
					$scope.identifyParams.height = $scope.map.height;
					$scope.identifyParams.geometry = event.mapPoint;
					$scope.identifyParams.mapExtent = $scope.map.extent;
				}
				layerEventServ.executeIdentifyTask($scope, evt);
			}
		}

		this.executeIdentifyTask = function ($scope, event) {
			// 4 different identify functions need to be setup
			// MapServer against a parcel or against the identify others
			// FeatureServer against a parcel or against the identify others
			$scope.identifyResultArray = [];
			if ($("#identifyButton").hasClass("selected")) {
				$scope.identifyParams.geometry = event.mapPoint;
				$scope.identifyParams.mapExtent = $scope.map.extent;
				$scope.identifyParams.tolerance = 3;
				$scope.identifyParams.layerIds = [];

				//create layerlist to identify
				for (var i = 0; i < $scope.checkboxList.length; i++) { //[i][0]=lname; [i][1]=lid; [i][2]=minS; [i][3]=maxS;             
					if (($scope.checkboxList[i][2] != 0 && $scope.currentScale > $scope.checkboxList[i][2]) || ($scope.checkboxList[i][3] != 0 && $scope.currentScale < $scope.checkboxList[i][3])) {
						//if scale is out of layer scale
					} else { //visible scale					
						if (!($scope.noIdentifyLayers.contains($scope.checkboxList[i][0]))) {
							if (document.getElementById($scope.checkboxList[i][0] + "Check").checked) { //checked	
								$scope.identifyParams.layerIds.push($scope.checkboxList[i][1]);
							}
						}
					}
				}
				//in case if scope.identifyParams.layerIds is empty even if there are scope.noIdentifyLayers
				if ($scope.noIdentifyLayers.length > 0 && $scope.identifyParams.layerIds.length < 1) {
					$scope.identifyParams.layerIds.push($scope.gisServNumLayers + 10); //last layer id +10 and then add to scope.identifyParams.layerIds, so make identify result empty 
				}
			}

			$scope.showPanel2 = false;
			$scope.stackedFeature = false;
			$scope.map.infoWindow.hide();
			var deferred, multiDeferred;
			if ($scope.isFeatureService) {
				if ($("#identifyButton").hasClass("selected")) {
					var multiDeferred = [];
					for (var i = 0; i < $scope.identifyParams.layerIds.length; i++) {
						var query = $scope.Query();
						query.geometry = event.mapPoint;
						query.outFields = ["*"];
						query.returnGeometry = true;
						query.distance = 3;
						$scope.queryTask = $scope.QueryTask($scope.featureServUrl + $scope.identifyParams.layerIds[i]);
						multiDeferred.push($scope.queryTask.execute(query));
					}
					deferred = $scope.dojoAll(multiDeferred);
				} else {
					var query = $scope.Query();
					query.geometry = event.mapPoint;
					query.outFields = $scope.queryParcelFields;
					query.returnGeometry = true;
					query.distance = 3;
					$scope.queryTask = $scope.QueryTask($scope.parcelLayer.url);
					deferred = $scope.queryTask.execute(query);
				}
			} else {
				deferred = $scope.identifyTask.execute($scope.identifyParams);
			}
			deferred.then(function (response) {
				// setup same object structure for IdentifyTask and QueryTask
				if ($scope.isFeatureService) {
					if ($("#identifyButton").hasClass("selected")) {
						response = response;
					} else {
						response = response.features;
					}
				}
				$scope.identifyFeatures = [];
				$("#identifyPreloaderContainer").removeClass("active");
				if ($scope.multipleParcelIdentify == "false") {
					response.splice(1, response.length - 1); //remove stacked parcel and keep the first result
				}
				if (window.innerWidth < 651) {
					$scope.map.infoWindow.hide();
					$scope.showDetail();
				} else {
					$scope.map.infoWindow.show(event.mapPoint);
				}

				if (window.innerWidth < 651 && response.length > 1) {
					$scope.stackedFeature = true; //for show or hide #stackedFeatureList
					$scope.stackedFeatureStatus = true; //for going back to #stackedFeatureList
					setTimeout(function () {
						$scope.$apply();
						$scope.refreshIscroll();
					}, 100);
				} else if (window.innerWidth < 651 && response.length == 1) {
					$scope.showPanel2 = false;
					$scope.stackedFeatureStatus = false;
					setTimeout(function () {
						$scope.$apply();
						$scope.refreshIscroll();
					}, 100);
				} else {
					$scope.stackedFeatureStatus = false;
					$scope.map.infoWindow.resize(300, 200);
				}

				response.map(function (result, index) {
					// setup same object structure for IdentifyTask (MapServer) and QueryTask (FeatureServer)
					// handle response and identify box creation for parcel or other identifies
					var feature, layerName, identifyOthers;
					var identifySet = false;
					if ($("#identifyButton").hasClass("selected")) {
						identifyOthers = true;
					}
					// response.features from a feature service returns the field names
					// create a lookup to set the field aliases to display in the info template
					var aliasLookup = {}
					if ($scope.isFeatureService) {
						if (identifyOthers) {
							if (result.features.length == 1) {
								feature = result.features[0];
							}
							else if (result.features.length > 1) {
								feature = result.features;
							}
							if (feature) {
								for (i = 0; i < result.fields.length; i++) {
									aliasLookup[result.fields[i].name] = result.fields[i].alias;
								}
							}
							var layerId = $scope.identifyParams.layerIds[index];
							for (var i = 0; i < $scope.mapLayers.length; i++) {
								if ($scope.mapLayers[i].id == layerId) {
									layerName = $scope.mapLayers[i].name;
									break;
								}
							}
						} else {
							feature = result;
							layerName = $scope.parcelLyrName;
						}
					} else {
						feature = result.feature;
						layerName = result.layerName;
					}
					if (!feature) {
						return;
					}
					if (identifyOthers) {
						if ($scope.isFeatureService && Array.isArray(feature)) {
							for (var i = 0; i < feature.length; i++) {
								t = layerEventServ.createIdentifyOtherHTML($scope, feature[i], aliasLookup);
								var taxParcelTemplate = new $scope.InfoTemplate(layerName, t);
								feature[i].setInfoTemplate(taxParcelTemplate);
								feature[i].setSymbol($scope.selParcelSymbol);
								for (var key in feature.attributes) {
									thisKey = feature.attributes[key.toString()];
									feature.attributes[key.toString()] = $scope.formatParcelData(key, thisKey, feature.attributes[key.toString()]);
								}
								$scope.identifyFeatures.push(feature[i]);
							}
							identifySet = true;
						}
						else if ($scope.isFeatureService) {
							for (var key in feature.attributes) {
								thisKey = feature.attributes[key.toString()];
								feature.attributes[key.toString()] = $scope.formatParcelData(key, thisKey, feature.attributes[key.toString()]);
							}
							t = layerEventServ.createIdentifyOtherHTML($scope, feature, aliasLookup);
						}
						else {
							for (var key in feature.attributes) {
								thisKey = feature.attributes[key.toString()];
								feature.attributes[key.toString()] = $scope.formatParcelData(key, thisKey, feature.attributes[key.toString()]);
							}
							t = layerEventServ.createIdentifyOtherHTML($scope, feature);
						}
					} else {
						for (var key in feature.attributes) {
							thisKey = feature.attributes[key.toString()];
							feature.attributes[key.toString()] = $scope.formatParcelData(key, thisKey, feature.attributes[key.toString()]);
						}
						feature.attributes['geometry'] = feature.geometry;
						$scope.identifyResultArray.push(feature.attributes);

						//bubble contentPane
						var t = '<b>${' + $scope.bubbleInfoField[0][2] + '}</b><hr>';
						for (var i = 1; i < $scope.bubbleInfoField.length - 1; i++) {
							t += '<b>' + $scope.bubbleInfoField[i][0] + ': </b>${' + $scope.bubbleInfoField[i][2] + '} <br />';
						}
						if ($scope.noReport == 'true') {
							t += '<div id="openAdjoiners" onClick="queryObjectId(\'${' + $scope.parcelUid + '}\',\'${' + $scope.parcelOID + '}\',\'adjoiner\')" class="tooltipButton">' + $scope.bubbleBtnTxt[0] + '</div>' +
								'<div id="openListView" onClick="gotoCounty(\'${' + $scope.reportId + '}\')" class="tooltipButton">' + $scope.bubbleBtnTxt[1] + '</div>';

						} else {
							t += '<div id="openAdjoiners" onClick="queryObjectId(\'${' + $scope.parcelUid + '}\',\'${' + $scope.parcelOID + '}\',\'adjoiner\',\'pl\')" class="tooltipButton">' + $scope.bubbleBtnTxt[0] + '</div>' +
								'<div id="openListView" onClick="queryObjectId(\'${' + $scope.parcelUid + '}\',\'${' + $scope.parcelOID + '}\',\'detail\',\'pl\')" class="tooltipButton">' + $scope.bubbleBtnTxt[1] + '</div>';
						}

						window.queryObjectId = function (uniqueID, OBJECTID, selBtn) {
							$scope.queryObjectId(uniqueID, OBJECTID, selBtn);
						}
						window.gotoCounty = function (parcelid) {
							$scope.localCustom.gotoCounty($scope, parcelid);
						}

						$('#zoomImage').on("click touchend", function () {
							$scope.zoomToParcel();
						});
						$('#openAdjoiners').on("click touchstart", function () {
							$scope.showAdjoiner = true;
							$scope.switchParcelDetails('adjoiner');
							$("#detailPanels").addClass("active");
							setTimeout($scope.myScroll2.refresh(), 300);
							setTimeout($scope.myScroll3.refresh(), 300);
						});
						$('#openListView').on("click touchstart", function () {
							$("#parcelPreloaderContainer").addClass("active");
							$scope.switchParcelDetails('detail');
							$("#detailPanels").addClass("active");
							$("#panel1").addClass("active");
							$("#panel1").removeClass("inactive");
							setTimeout($scope.myScroll2.refresh(), 300);
							setTimeout($scope.myScroll3.refresh(), 300);
						});
					}
					if ($scope.setIdentifyGeomToSelectedParcel == "true") {
						// For Spotsylvania, the geom from the identify response didn't match the selected parcel when it should
						// There appears to be a slight datum shift that cannot be resolved through SR or projection updates
						feature.attributes['geometry'] = $scope.selectedParcel.geometry;
						feature.geometry = $scope.selectedParcel.geometry;
					}
					if (!identifySet) {
						var taxParcelTemplate = new $scope.InfoTemplate(layerName, t);
						feature.setInfoTemplate(taxParcelTemplate);
						feature.setSymbol($scope.selParcelSymbol);
						$scope.identifyFeatures.push(feature);
					}
				});
				// set the info pane here after either the single promise is resolved or all promises
				// construct a global $scope.identifyFeatures and push each result into it
				if ($scope.identifyFeatures.length > 0) {
					$scope.map.infoWindow.fillSymbol = $scope.selParcelSymbol;
					$scope.map.infoWindow.setFeatures($scope.identifyFeatures);
				}
				else {
					$scope.map.graphics.clear();
					$scope.map.infoWindow.setTitle("Identify Results");
					$scope.map.infoWindow.setContent("No features found.")
				}
			});
		}

		this.createIdentifyOtherHTML = function ($scope, feature, aliasLookup = null) {
			var fieldCount = Object.keys(feature.attributes).length;
			var t = '<table class="popupTable">';
			for (var i = 0; i < fieldCount; i++) {
				var fieldName = Object.keys(feature.attributes)[i];
				if (aliasLookup) {
					var aliasName = aliasLookup[fieldName];
				}
				else {
					var aliasName = fieldName;
				}
				var fieldValue = feature.attributes[fieldName];
				if (!($scope.noIdentifyFields.contains(fieldName)) && String(fieldValue).substring(0, 4) == 'http') {
					t += '<tr><td>' + aliasName + ': </td><td><b><a href="' + fieldValue + '" target="_blank">' + "Open Link" + '</a></b></td></tr>';
				} else if (!($scope.noIdentifyFields.contains(fieldName))) {
					t += '<tr><td>' + aliasName + ': </td><td>' + fieldValue + '</td></tr>';
				}
			}
			t += '</table>';
			return t;
		}

		this.drawLayerOnClick = function ($scope, drawing) {
			if ($("#eraseTool").hasClass("selected")) {
				if (drawing.graphic.attributes && drawing.graphic.attributes.hasOwnProperty('gId')) {
					for (var i = 0; i < $scope.drawLayer.graphics.length; i++) {
						if ($scope.drawLayer.graphics[i].attributes.gId == drawing.graphic.attributes.gId) {
							var thisGid = drawing.graphic.attributes.gId;
							$scope.drawLayer.remove($scope.drawLayer.graphics[i]);
							for (var j = 0; j < $scope.labelLayer.graphics.length; j++) {
								if ($scope.labelLayer.graphics[j].attributes.gId == thisGid) {
									$scope.labelLayer.remove($scope.labelLayer.graphics[j]);
								}
							}
						}
					}
				}
			}
		}

		this.drawLayerOnMouseOver = function (evt) {
			if ($("#eraseTool").hasClass("selected")) {
				$(evt.target).attr("stroke-width-old", $(evt.target).attr("stroke-width"));
				$(evt.target).attr("stroke-width", "3px");
				$(evt.target).attr("stroke-old", $(evt.target).attr("stroke"));
				$(evt.target).attr("stroke", "rgb(255,0,0)");
				$(evt.target).attr("fill-old", $(evt.target).attr("fill"));
				$(evt.target).attr("fill", "rgba(0,0,0,0.5)");
				$(evt.target).css("cursor", "pointer");
			}
		}

		this.drawLayerOnMouseOut = function (evt) {
			if ($("#eraseTool").hasClass("selected")) {
				$(evt.target).attr("stroke-width", $(evt.target).attr("stroke-width-old"));
				$(evt.target).attr("stroke", $(evt.target).attr("stroke-old"));
				$(evt.target).attr("fill", $(evt.target).attr("fill-old"));
				$(evt.target).css("cursor", "default");
			}
		}

		this.drawLayerOnGraphicAdd = function ($scope, event) {
			if (event.graphic.symbol.hasOwnProperty('type')) {
				if ($("#map_layers").find('.graphic' + $scope.graphicId).length > 0) {
					$(event.graphic._shape.rawNode).attr("class", "graphic" + $scope.graphicId);
				} else {
					$(event.graphic._shape.rawNode).attr("class", "graphic" + ($scope.graphicId + 1));
				}
			}
			//select parcels by graphics
			if ($("#openSelectByGraphic").hasClass("active")) {
				$scope.selectParcelByGraphics();
			}
		}

		this.labelLayerOnClick = function ($scope, label) {
			if ($("#eraseTool").hasClass("selected")) {
				if (label.graphic.attributes.hasOwnProperty('gId')) {
					for (var i = 0; i < $scope.labelLayer.graphics.length; i++) {
						if ($scope.labelLayer.graphics[i].attributes.gId == label.graphic.attributes.gId) {
							var thisGid = label.graphic.attributes.gId;
							$scope.labelLayer.remove($scope.labelLayer.graphics[i]);
							for (var j = 0; j < $scope.drawLayer.graphics.length; j++) {
								if ($scope.drawLayer.graphics[j].attributes.gId == thisGid) {
									$scope.drawLayer.remove($scope.drawLayer.graphics[j]);
								}
							}
						}
					}
				}
			}
		}

		this.labelLayerOnGraphicAdd = function ($scope, event) {
			if (event.graphic.symbol.hasOwnProperty('type')) {
				if ($("#map_layers").find('.graphic' + $scope.graphicId).length > 0) {
					$(event.graphic._shape.rawNode).attr("class", "graphic" + $scope.graphicId);
				} else {
					$(event.graphic._shape.rawNode).attr("class", "graphic" + ($scope.graphicId + 1));
				}
			}
		}
	});