﻿/// <reference path="GISMap.js" />
/// <reference path="GISHelperClasses.js" />
/// <reference path="GISCommunicationsHandler.js" />

var g_currentlyClickedButton = null;
function input_renderButtonClick(clickedImage, prevent) {
	/// <summary>Specialized function for a specific UI.  Changes a image to it's clicked version.</summary>
	/// <param name="prevent" type="Boolean">If true, prevents the button from actually changing to the clicked version (but unclicking the current clicked button).</param>

	// Unclick any button that was clicked.
	if (g_currentlyClickedButton) {
		// It isn't.  "Unclick" the button and tell the hover controller to unhighlight it.
		g_currentlyClickedButton.setAttribute('isClicked', 'false');
		input_renderButtonHover(g_currentlyClickedButton, false);
	}

	if (prevent) {return;}

	// Unhover it.
	input_renderButtonHover(clickedImage, false);

	clickedImage.setAttribute('isClicked', 'true');
	g_currentlyClickedButton = clickedImage;

	// Change the image src to the clicked version.
	clickedImage.src = clickedImage.src.replace(/\.gif/, '_clicked.gif');
	clickedImage.src = clickedImage.src.replace(/\.png/, '_clicked.png');
}

function input_renderButtonHover(currentImage, hoverMode) {
	/// <summary>Specialized function for a specific UI.  Changes a image to it's hovered version.</summary>
	/// <param name="hoverMode" type="Boolean">Determines if this is gaining the hover effect, or loosing it.</param>

	// If the button has been clicked, and it is the just-selected button, then return.
	if (currentImage.getAttribute('isClicked') === 'true') {
		return;
	}
	
	// We are going to unhighlight no matter what (because in some rare instances, highlighting gets applied twice).
	currentImage.src = currentImage.src.replace(/_hover/,'');
	currentImage.src = currentImage.src.replace(/_clicked/,'');

	if (hoverMode) {
		// Highlight
		currentImage.src = currentImage.src.replace(/\.gif/, '_hover.gif');
		currentImage.src = currentImage.src.replace(/\.png/, '_hover.png');
	}
}

function ui_displayLayers(layerDiv) {
	/// <summary>Specialized function for a specific UI.  Reloads the div with a table containing the available layers.</summary>
	/// <param name="layerDiv" type="HTMLElement"></param>
	
	if (!layerDiv) {return;}
	
	// Remote the table from the div.
	var layerTable = layerDiv.getElementsByTagName('table')[0];
	if (layerTable) {
		layerDiv.removeChild(layerTable);
	}
	// Create a new table and add it to the div.
	layerTable = document.createElement('table');
	layerTable.className = 'compressed';
	layerDiv.appendChild(layerTable);
		
	// Clear all rows from the layer list.
	for (var i=layerTable.rows.length - 1;i>=0;i--) {
		layerTable.deleteRow(i);
	}
			
	var currLayer = null;
	var row = null;
	var isChecked = '';
			
	for (i=0;i<this.currentContext.groupCollection.groups.length;i++) {
		currLayer = this.currentContext.groupCollection.groups[i];
		row = layerTable.insertRow(layerTable.rows.length);
		isChecked = '';
		if (currLayer.visible) {isChecked = 'checked="checked"';}
				
		row.insertCell(0).innerHTML = '<label for="' + this.id + '-layerVisibility' + currLayer.id + '">' + currLayer.name + '</label>';
		row.cells[0].style.textAlign = 'left';
		row.insertCell(1).innerHTML = '<input type="checkbox" id="' + this.id + '-layerVisibility' + currLayer.id + '" ' + isChecked + ' />';
	}
}
		
function ui_reloadLayersFromLayerList(mapObj) {
	// Check the table list for each layer.  Reset the visibility on each one, then re-request the image.
	var updateMap = false;
	var currLayer = null;
	var currVisibility = null;
	var checkBoxID = '';
	var newVisibility = null;
	var groupCollection = mapObj.currentContext.groupCollection.groups;

	for (var i=0;i<groupCollection.length;i++) {
		currLayer = groupCollection[i];

		currVisibility = currLayer.visible;
		checkBoxID = mapObj.id + '-layerVisibility' + currLayer.id;
		// Get the visibility
		newVisibility = document.getElementById(checkBoxID).checked;
				
		// Compare the new to the old, if there is a change then set the updateMap flag.
		if (currVisibility !== newVisibility) {
			groupCollection[i].visible = newVisibility;
			updateMap = true;
		}
	}
			
	if (updateMap) {
		mapObj.getMapImage();
	}
}

function ui_searchByOwner(mapReference, formObj) {
	if (!mapReference) {return false;}
	if (!mapReference.infoFrame) {return false;}

	// Make sure the user entered an owner name.
	var ownerName = formObj.ownerName.value;
	if (ownerName.length === 0) {
		alert('Please enter an owner name.');
		formObj.ownerName.focus();
		return null;
	}

	mapReference.infoFrame.searchByOwner(ownerName);
	return null;
}

function ui_searchByAddress(mapReference, formObj) {
	if (!mapReference) {return false;}
	if (!mapReference.infoFrame) {return false;}

	var str_num;
	var str_num_sfx;
	var str_pfx;
	var str;
	var str_sfx;
	var str_sfx_dir;

	if (typeof(formObj.str_num) !== 'undefined') {
		str_num = formObj.str_num.value;
	}
	if (typeof(formObj.str_num_sfx) !== 'undefined') {
		str_num_sfx = formObj.str_num_sfx.value;
	}
	if (typeof(formObj.str_pfx) !== 'undefined') {
		str_pfx = formObj.str_pfx.value;
	}
	if (typeof(formObj.str) !== 'undefined') {
		str = formObj.str.value;
	}
	if (typeof(formObj.str_sfx) !== 'undefined') {
		str_sfx = formObj.str_sfx.value;
	}
	if (typeof(formObj.str_sfx_dir) !== 'undefined') {
		str_sfx_dir = formObj.str_sfx_dir.value;
	}
	
	// Make sure the user entered a street name.
	if (str.length === 0) {
		alert('Please enter a street name.');
		formObj.streetName.focus();
		return null;
	}
	
	if (str_num.length > 5) {
		alert('Please enter a shorter street number.');
		formObj.streetNumber.focus();
		return null;
	}

	mapReference.infoFrame.searchByAddress(str_num, str_num_sfx, str_pfx, str, str_sfx, str_sfx_dir);
	return null;
}

function ui_searchByParcelID(mapReference, formObj) {
	if (!mapReference) {return false;}
	if (!mapReference.infoFrame) {return false;}

	// Make sure the user entered a parcelID.
	var parcelID = formObj.parcelID.value;
	if (parcelID.length === 0) {
		alert('Please enter a Parcel ID.');
		formObj.parcelID.focus();
		return null;
	}
	
	mapReference.infoFrame.searchByParcelID(parcelID);
	return null;
}

function ui_searchBySTR(mapReference, formObj) {
	if (!mapReference) {return false;}
	if (!mapReference.infoFrame) {return false;}

	// Make sure the user entered all values.
	var section = formObj.section.value;
	var township = formObj.township.value;
	var range = formObj.range.value;

	var sectionRequired = true;
	var townshipRequired = true;
	var rangeRequired = true;
	
	if ((CountyApp) && (CountyApp.Config)) {
		if (CountyApp.Config.searchBySTR_SectionNotRequired) {sectionRequired = false;}
		if (CountyApp.Config.searchBySTR_TownshipNotRequired) {townshipRequired = false;}
		if (CountyApp.Config.searchBySTR_RangeNotRequired) {rangeRequired = false;}	
	}

	if (sectionRequired) {
		if (section.length === 0) {
			alert('Please enter a section.');
			formObj.section.focus();
			return null;
		}
	}
	
	if (townshipRequired) {
		if (township.length === 0) {
			alert('Please enter a township.');
			formObj.township.focus();
			return null;
		}
	}
	
	if (rangeRequired) {
		if (range.length === 0) {
			alert('Please enter a range.');
			formObj.range.focus();
			return null;
		}
	}

	mapReference.infoFrame.searchBySTR(section, township, range);
	return null;
}

function ui_presentBufferSearchPopup(mapObj, popupObj) {
	if (!popupObj) {
		return mapObj.setCurrentMapTool(GISMap.mapTool.NONE);
	}
	
	if (mapObj.verifyParcelIsSelected()) {
		if (!mapObj.hasCapability(GISMap.capability.ALLOW_BUFFERSEARCH)) {
			alert('The server has not returned enough data to allow buffer searches.');
			return false;
		} else {
			popupObj.show();
		}
	} else {
		alert('Please select a parcel before using buffer search.');
	}
	
	mapObj.setCurrentMapTool(GISMap.mapTool.NONE);
	return false;
}

// Makes sure the map service is allowing buffer searches.
// Parses the input to make sure it is a valid number in range, calls the handling map's retrieveBuffer function.
function input_retrieveBuffer(mapObj, bufferInputObj) {
	// Convert the input to a proper number
	if (!bufferInputObj) {
		// There is a programatic error, the input object doesn't exist.
		// Allow the box to be closed, and disable the buffer functionality.
		mapObj.removeCapability(GISMap.capability.ALLOW_BUFFERSEARCH);
		return true;
	}

	var originalValue = bufferInputObj.value;

	// Remove commas and spaces.  Also, "ft" in case someone wanted to do that.
	var radiusFeet = originalValue.replace(/,/,'').replace(/ /,'').replace(/ft/gi,'');
	
	// Make sure this is a number (just to prevent the occasional oddities).
	radiusFeet = parseInt(radiusFeet, 10);

	if (isNaN(radiusFeet)) {
		alert('The value you entered was not a number.');
		bufferInputObj.focus();
		return false;
	}

	// 2640 (1/2 mile) is the maximum buffer size.  In testing a full mile still performed acceptably.  10,000ft crashed the server (I think).
	// The old website only allowed 1000ft, so 2640 is a step up.
	if (radiusFeet > 2640) {
		alert('You cannot create a buffer larger than 2640ft (1/2 mile).\r\n\r\nPlease enter a smaller buffer radius.');
		bufferInputObj.focus();
		return false;
	}

	// Call the actual buffer function inside the mapObj. (All of the previous code was simply cleanup.)
	mapObj.retrieveBuffer(radiusFeet);

	// Returning true will make the buffer size popup box go away.
	return true;
}

// Automatically moves to the next text box once maxLength has been hit.
function autoTab(e) {
	var thisEvent = e || window.event;
	var thisInput = thisEvent.target ? thisEvent.target : thisEvent.srcElement;
	var keyCode = thisEvent.keyCode;
	var filter = [0,8,9,16,17,18,37,38,39,40,46];
	if(thisInput.value.length >= thisInput.maxLength && !containsElement(filter,keyCode)) {
		thisInput.value = thisInput.value.slice(0, thisInput.maxLength);
		thisInput.form[(getIndex(thisInput)+1) % thisInput.form.length].select();
		thisInput.form[(getIndex(thisInput)+1) % thisInput.form.length].focus();
	}

	function containsElement(filterArray, enteredCharacter) {
		var found = false, index = 0;
		while(!found && index < filterArray.length) {
			if (filterArray[index] === enteredCharacter) {
				found = true;
			} else {
				index++;
			}
		}
		return found;
	}

	function getIndex(thisInput) {
		var index = -1, i = 0, found = false;
		while (i < thisInput.form.length && index === -1) {
			if (thisInput.form[i] === thisInput) {
				index = i;
			} else {
				i++;
			}
		}
		return index;
	}
	return true;
}


function makeTabActive(clickedTab) {
	// Get the tab elements.
	if (!clickedTab) {return false;}
	var tabPanel = getParentByClassName(clickedTab,'tabPanel');
	var tabList = getParentByClassName(clickedTab,'tabList');
	var tabOptions = tabList.getElementsByTagName('li');

	// All the tabBoxes have a prefix that indicates that it is part of this panel.
	// That prefix is set as the id attribute of the <div class="tabPanel" /> element.
	var tabPanelPrefix = tabPanel.id;

	// Deactivate the current tab and tabBox.
	// Check each tab in the tabList; if the tab has a className of "current" then store its title, it is the current active tab.
	// Clear the className to deactivate it, then hide the tabBox that is associated with it.
	for (var i=0;i<tabOptions.length;i++) {
		if (tabOptions[i].className == 'current') {
			var currTabTitle = tabOptions[i].getAttribute('title');
			// Deactivate the tab header.
			tabOptions[i].className = '';

			// Hide the tab's box.
			if (document.getElementById(tabPanelPrefix + '.' + currTabTitle)) {
				document.getElementById(tabPanelPrefix + '.' + currTabTitle).style.display='none';
			}
			
			// Stop processing after we find the active tab.
			break;
		}
	}

	// Activate the new tab and tabBox.
	// The "clickedTab" is the A element inside the LI.  Get the actual tab.
	var selectedLI = clickedTab.parentNode;
	// Determine the id of the new tabBox div.
	var thisTitle = tabPanelPrefix + '.' + selectedLI.getAttribute('title');

	// Activate this tab.
	selectedLI.className='current';
	
	// If there is a tabBox, show it.
	if (document.getElementById(thisTitle)) {
		document.getElementById(thisTitle).style.display='block';
	} else {
		return false;
	}

	// Return false to prevent the page from changing to "#"
	return false;
}

// Get the parent, check it's className, if it doesn't match then call the parent as the child.
// If the parent is the document object then return null.
function getParentByClassName(childObj, className) {
	className = className.toUpperCase();

	// Set the childObj to it's parentNode and check if it 1) has a parentNode, 2) matches the tagName, 3) is the document object.
	// If the childObj's parentNode is the match then we don't even enter the loop.
	while ((childObj.parentNode) && (childObj.parentNode.className.toUpperCase() != className) && (childObj != document)) {
		childObj = childObj.parentNode;
	}

	// If the loop ended on document or null parentNode then return null.
	if ((childObj == document) || (!childObj.parentNode)) {
		return null;
	}
	
	// Return the current node.
	return childObj.parentNode;
}

// Get the parent, check it's tagName, if it doesn't match then call the parent as the child.
// If the parent is the document object then return null.
function getParentByTagName(childObj, tagName) {
	tagName = tagName.toUpperCase();

	// Set the childObj to it's parentNode and check if it 1) has a parentNode, 2) matches the tagName, 3) is the document object.
	// If the childObj's parentNode is the match then we don't even enter the loop.
	while ((childObj.parentNode) && (childObj.parentNode.tagName.toUpperCase() != tagName) && (childObj != document)) {
		childObj = childObj.parentNode;
	}

	// If the loop ended on document or null parentNode then return null.
	if ((childObj == document) || (!childObj.parentNode)) {
		return null;
	}
	
	// Return the current node.
	return childObj.parentNode;
}
