/*
 * Initial Version of the Tree Viewer
 */

var TREEVIEW_INSTANCE = 0;
function TreeView(EventManager, TreeMap) {
	var MySelf = this;
	var TreeViewId = 'TreeView'+TREEVIEW_INSTANCE+'-';
	TREEVIEW_INSTANCE++;

	var MapBookData = null;

	var Parent;

	function hideLegend(obj) {
		if(!obj.className.match(/BLANK/)) {
			obj.className = obj.className +' BLANK';
		}
	}

	function showLegend(obj) {
		obj.src = '';
		var classNames = new String(obj.className);
		classNames = classNames.replace('BLANK','');
		obj.className = classNames;
	}

	this.removeLayer = function(id) {
		MySelf.removeObject('Map',id);
		if(document.getElementById(TreeViewId+'TitleFont-'+id)) {
			document.getElementById(TreeViewId+'TitleFont-'+id).className = 'TreeViewLayerVisible';
		}
	}

	this.removeService = function(id) {
		MySelf.removeObject('Service', id);
	}

	this.removeView = function(id) {
		MySelf.removeObject('View', id);
	}

	this.addLayer = function(id) {
		/* If it's only in the reference map *do not* add it to the layer list */
		if(id.getAttribute('reference') && id.getAttribute('reference').match(/only/i)) {
			return false;
		}
		
		MySelf.addObject('Map',id);
		var titleFont = document.getElementById(TreeViewId+'TitleFont-'+id.getAttribute('title'));
		var checkbox = document.getElementById(TreeViewId+'Map-'+id.getAttribute('title'));
		if(titleFont) {
			if(TreeMap.isLayerVisible(id.getAttribute('title'))) {
				titleFont.className = 'TreeViewLayerVisible';
			} else {
				titleFont.className = 'TreeViewLayerInvisible';
				if(TREEVIEW_CHECKBOX_RANGE_VISIBILITY) {
					checkbox.disabled = true;
				}
			}
		}
	}

	this.addService = function(id) {
		MySelf.addObject('Service', id);
	}

	this.addView = function(id) {
		MySelf.addObject('View', id);
	}

	
	this.removeObject = function(objType, id) {
		var checkBox = document.getElementById(TreeViewId+objType+'-'+id);
		if(checkBox) {
			checkBox.checked = false;
			var legendObj = document.getElementById(TreeViewId+'Legend-'+id);
			if(legendObj) {
				hideLegend(legendObj);
				legendObj.src = '';
			}
		}
	}

	this.addObject = function(objType, mapXMLObj) {
		var title = mapXMLObj.getAttribute('title');
		var checkBox = document.getElementById(TreeViewId+objType+'-'+title);
		if(checkBox) {
			checkBox.checked = true;
		}
	}

	this.clearAll = function() {
		var inputs = document.getElementsByTagName('input');
		for(var i = 0; i < inputs.length; i++) {
			inputs[i].checked = false;
		}
	}

	function makeInvisible(elm) {
		elm.style.height = '0px';
	}

	var visibilityOverride = false;

	this.setVisibilityOverride = function (v) {
		visibilityOverride = v;
	}

	function onclickLeaf(event) {
		if(window.event) { event = window.event; }
		if(getEventTarget(event) != this) { return true; }
		var childTree = this.getElementsByTagName('ul')[0];
		var vis = childTree.style.visibility;
		if(childTree.style.height != '0px') {
			height = '0px';
			var allUl = childTree.getElementsByTagName('ul');
			for(var u = 0; u < allUl.length; u++) {
				makeInvisible(allUl[u]);
			}
		} else {
			height = 'auto';
		}
		childTree.style.height = height;

		event.returnValue = false;
		if(event.preventDefault) {
			event.preventDefault();
		}
		return false;
	}

	var Branches = 0;
	
	function createBranch(xmlObj) { // Assumes the Element Has Children
		var root = document.createElement('ul');
		//root.className = 'TreeView';
		//root.style.marginLeft = '24px';
		root.setAttribute('id',TreeViewId+'Branch-'+Branches);
		root.className = 'TreeViewBranch';
		Branches++;
		for(var i = 0; i < xmlObj.childNodes.length; i++) {
			if(xmlObj.childNodes[i].tagName != null && (!xmlObj.childNodes[i].getAttribute('invisible') || !xmlObj.childNodes[i].getAttribute('invisible').match(/true/i) || visibilityOverride)) {
				if(xmlObj.childNodes[i].tagName == 'group') {
					var rootLeaf = getLeaf(xmlObj.childNodes[i]);
					var underList = createBranch(xmlObj.childNodes[i]);
					underList.style.height = '0px';
					underList.style.overflow = 'hidden';
					rootLeaf.appendChild(underList);
					root.appendChild(rootLeaf);

					/*
					 * These events are setup specifically in this fashion
					 * as to prevent the browser from "selecting" the text
					 * of the group names
					 */
					rootLeaf.onclick = onclickLeaf;
					rootLeaf.onmouseup = preventDefaultEvent;
					rootLeaf.onmousedown = preventDefaultEvent;
					rootLeaf.ondblclick = preventDefaultEvent;

					if(xmlObj.childNodes[i].getAttribute('expand') && xmlObj.childNodes[i].getAttribute('expand').match(/true/)) {
						underList.style.height = 'auto';
					}
				} else if(xmlObj.childNodes[i].tagName != null && xmlObj.childNodes[i].getAttribute('title') != null) {
					/*var newItem = getLeaf(xmlObj.childNodes[i]);	
					root.appendChild(newItem);*/
					root.appendChild(getLeaf(xmlObj.childNodes[i]));
				}
			}
		}
		return root;
	}

	function onclickLayer() {
		if(this.checked) {
			EventManager.triggerEvent('addlayer', this.selfXML);
			EventManager.triggerEvent('refreshlayer', this.selfXML.getAttribute('title'));
		} else {
			this.checked=true;
			if(EventManager.onRemoveLayer(this.selfXML.getAttribute('title'))) {
				this.checked=false;
			}
		}
	}

	function onclickService() {
		if(this.checked) {
			EventManager.triggerEvent('addservice', this.selfXML);
		} else {
			this.checked=true;
			if(EventManager.onRemoveService(this.selfXML.getAttribute('title'))) {
				this.checked=false;
			}
		}
	}

	function onclickView() {
		if(this.checked) {
			EventManager.triggerEvent('addview', this.selfXML);
		} else {
			this.checked=true;
			if(EventManager.triggerEvent('removeview',this.selfXML.getAttribute('title'))) {
				this.checked=false;
			}
		}
	}

	function updateLayerList() {
		var cbox = this.parentNode.getElementsByTagName('input');
		var activeLayers = new Array();
		for(var c = 0; c < cbox.length; c++) {
			if(cbox[c].checked) {
				activeLayers.push(cbox[c].value);
			}
		}
		TreeMap.setLayerParam(this.title, 'layers', activeLayers.join(' '));
		TreeMap.refreshLayer([this.title]);
	}

	
	function getLeaf(obj) {
		var newLi = document.createElement('li');
		var objTitle = obj.getAttribute('title');
		newLi.style.cursor = 'pointer';

		newLi.className = 'Folder';
		newLi.id = TreeViewId+'-List-'+objTitle;

		var objectTip = obj.getAttribute('tip');
		if(objectTip) {
			newLi.title = objectTip;
			newLi.alt = objectTip;
		}

		if(obj.getAttribute('icon')) {
			var iconUrl = obj.getAttribute('icon');
			newLi.style.listStyleType = 'none';
			newLi.style.listStyleImage = 'url('+iconUrl+')';
		} else if(obj.tagName.match(/map/)) {
			newLi.className = 'Map';
		} else if(obj.tagName.match(/service/)) {
			newLi.className = 'Service';
		} else if(obj.tagName.match(/view/)) {
			newLi.className = 'View';
		}
		if(obj.tagName != 'group') {
			var layerCheckBox = document.createElement('input');
			layerCheckBox.setAttribute('type','checkbox');
			layerCheckBox.id = TreeViewId+newLi.className+'-'+objTitle;
			layerCheckBox.selfXML = obj;
			newLi.appendChild(layerCheckBox);	

			if(obj.tagName.match(/map/i)) {
				layerCheckBox.onclick = onclickLayer; 
			} else if(obj.tagName.match(/service/i)) {
				layerCheckBox.onclick = onclickService;
			} else if(obj.tagName.match(/view/i)) {
				layerCheckBox.onclick = onclickView;
			}

			var titleFont = document.createElement('font');
			titleFont.className = 'TreeViewLayerVisible';
			titleFont.id = TreeViewId+'TitleFont-'+objTitle;
			newLi.appendChild(titleFont);
			titleFont.appendChild(document.createTextNode(objTitle));
		} else {
			newLi.appendChild(document.createTextNode(objTitle));
		}

		/* The overrides are passed in because the layer may have not been added to
			the map object yet. */

		if(obj.getElementsByTagName('meta')[0] && obj.getElementsByTagName('meta')[0].firstChild.nodeValue) {
			if(obj.getElementsByTagName('meta')[0].parentNode == obj) {
				var metaLink = document.createElement('a');
				newLi.appendChild(metaLink);
				metaLink.href = obj.getElementsByTagName('meta')[0].firstChild.nodeValue;
				var metaImage = document.createElement('img');
				metaImage.src = META_DEFAULT_ICON;
				metaLink.appendChild(metaImage);
				metaImage.title = 'Metadata for '+objTitle;
				metaImage.alt = 'Metadata for '+objTitle;
				metaLink.className = 'Metadata';
				metaLink.target = '_blank';
				metaImage = null;
				metaLink = null;
			}
		}
		if(obj.getElementsByTagName('help')[0] && obj.getElementsByTagName('help')[0].firstChild.nodeValue) {
			if(obj.getElementsByTagName('help')[0].parentNode == obj) {
				var helpLink = document.createElement('a');
				newLi.appendChild(helpLink);
				helpLink.href = obj.getElementsByTagName('help')[0].firstChild.nodeValue;
				var helpImage = document.createElement('img');
				helpImage.src = HELP_DEFAULT_ICON;
				helpLink.appendChild(helpImage);
				helpImage.title = 'Help for '+objTitle;
				helpImage.alt = 'Help for '+objTitle;
				helpLink.className = 'Help';
				helpLink.target = '_blank';
				helpImage = null;
				helpLink = null;
			}
		}

		if(TREEVIEW_SHOW_CONTROLS && obj.tagName == 'map') {
			var span = document.createElement('span');
			if(TREEVIEW_BREAK_FOR_CONTROLS) {
				newLi.appendChild(document.createElement('br'));
				span.className = 'TreeViewControls';
			}
			newLi.appendChild(span);

			if(TREEVIEW_CONTROLS.legendToggle) {
				span.appendChild(createIcon(EventManager, LEGEND_TOGGLE_ICON, ['togglelegend','refreshlayer'], objTitle, 'Toggle the legend for this layer.'));
			}

			if(TREEVIEW_CONTROLS.up) { span.appendChild(createIcon(EventManager, UP_ICON,'movelayerup', objTitle, 'Move this layer up in the stacking order.')); }
			if(TREEVIEW_CONTROLS.down) { span.appendChild(createIcon(EventManager, DOWN_ICON,'movelayerdown',objTitle, 'Move this layer down in the stacking order.')); }
			if(TREEVIEW_CONTROLS.fade) { span.appendChild(createIcon(EventManager, FADE_ICON,'fadelayer',objTitle, 'Fade this layer.')); }
			if(TREEVIEW_CONTROLS.unfade) { span.appendChild(createIcon(EventManager, UNFADE_ICON,'unfadelayer',objTitle, 'Unfade this layer.')); }
			if(MAP_POPUPS_ENABLED && obj.getAttribute('popups') && obj.getAttribute('popups').match(/true/i)) {
				var icon;
				if(POPUPS_TRIGGER_CHANGETOOL) {
					icon = createIcon(EventManager, POPUP_UNAVAILABLE_ICON, ['changetool','activatelayer'], objTitle, POPUP_MESSAGE['PopupsUnavailable']);
				} else {
					icon = createIcon(EventManager, POPUP_UNAVAILABLE_ICON, 'activatelayer', objTitle, POPUP_MESSAGE['PopupsUnavailable']);
				}
				icon.className = 'PopupsUnavailable';
				icon.title = POPUP_MESSAGE[icon.className];
				icon.id = TreeViewId+'Popups-'+objTitle;
				icon.eventTrigger = null;
				span.appendChild(icon);
			}
			if(TREEVIEW_CONTROLS.refresh) { span.appendChild(createIcon(EventManager, RELOAD_ICON,'refreshlayer', objTitle, 'Refresh this layer.')); }

		}

		/* See if there are layer options to control */
		var layers = obj.getElementsByTagName('layer');
		if(layers.length > 0) {
			newLi.appendChild(document.createElement('br'));
			var layersDiv = document.createElement('div');
			layersDiv.className = 'TreeViewLayersList';
			newLi.appendChild(layersDiv);
			for(var i = 0; i < layers.length; i++) {
				var layersOpt = document.createElement('input');
				layersOpt.type = 'checkbox';
				layersDiv.appendChild(layersOpt);

				layersOpt.value = layers[i].getAttribute('name');
				layersOpt.title = obj.getAttribute('title');
				layersOpt.disabled = parseBoolean(layers[i].getAttribute('locked'), false);

				layersOpt.checked = parseBoolean(layers[i].getAttribute('default'), true);
				layersDiv.appendChild(document.createTextNode(layers[i].getAttribute('title')));
				layersDiv.appendChild(document.createElement('br'));

				/* Update the parent layer's layer-param */
				layersOpt.onclick = updateLayerList;
			}
		}

		if(TREEVIEW_LEGENDS.enabled && obj.tagName == 'map') {
			var legendImage = document.createElement('img');
			legendImage.enabled = TREEVIEW_LEGENDS.visible;
			legendImage.setAttribute('id', TreeViewId+'Legend-'+objTitle);
			legendImage.className = 'TreeViewLegends';
			hideLegend(legendImage);
			newLi.appendChild(legendImage);
			legendImage = null;
		}
		return newLi;
	}

	this.onNavigate = function() {
		var layers = TreeMap.getLayersByZIndex();
		for(var i = 0; i < layers.length; i++) {
			var cName = 'TreeViewLayerInvisible';
			var checkbox = document.getElementById(TreeViewId+'Map-'+layers[i]);
			if(!TREEVIEW_CHECKBOX_RANGE_VISIBILITY) {
				checkbox = null;
			}
			if(TreeMap.isLayerVisible(layers[i])) {
				cName = 'TreeViewLayerVisible';
				if(checkbox) {
					checkbox.disabled = false;
				}
			} else {
				if(checkbox) {
					checkbox.disabled = true;
				}
			}
			var titleElm = document.getElementById(TreeViewId+'TitleFont-'+layers[i]);
			if(titleElm) {
				titleElm.className = cName;
			}

			MySelf.onLayerRefresh(layers[i]);
		}
	}

	this.onActivateLayer = function(layerTitle) {
		/* Clear out old active layer (this is a brute force approach...) */
		var tvParent = document.getElementById(Parent);
		var images = tvParent.getElementsByTagName('img');
		for(var i = 0 ; i < images.length; i++) {
			if(images[i].className.match(/PopupsActive/)) {
				images[i].className = 'PopupsAvailable';
				images[i].src = POPUP_AVAILABLE_ICON;
				images[i].title = POPUP_MESSAGE[images[i].className];
			}
		}
		/* Set new active layer */
		if(TREEVIEW_SHOW_CONTROLS) {
			var icon = document.getElementById(TreeViewId+'Popups-'+layerTitle);
			icon.src = POPUP_ACTIVE_ICON;
			icon.className = 'PopupsActive';
			icon.title = POPUP_MESSAGE[icon.className];
		}

	}

	this.onLoadData = function(layerTitle) {
		if(TREEVIEW_SHOW_CONTROLS) {
			var icon = document.getElementById(TreeViewId+'Popups-'+layerTitle);
			if(POPUPS_TRIGGER_CHANGETOOL) {
				icon.eventTrigger = ['changetool','activatelayer'];
			} else {
				icon.eventTrigger = ['activatelayer'];
			}
			icon.src = POPUP_AVAILABLE_ICON;
			icon.className = 'PopupsAvailable';
			icon.title = POPUP_MESSAGE[icon.className];
		}
	}

	this.onLayerRefresh = function(layerTitle) {
		var icon = document.getElementById(TreeViewId+'Popups-'+layerTitle);
		if(icon) {
			icon.eventTrigger = null;
			icon.src = POPUP_UNAVAILABLE_ICON;
			icon.className = 'PopupsUnavailable';
			icon.title = POPUP_MESSAGE[icon.className];
		}
	}

	this.onLoadLegend = function(legendObj) {
		var obj = document.getElementById(TreeViewId+'Legend-'+legendObj.id);
		if(obj) { /* && obj.enabled) {*/
			showLegend(obj);
			obj.src = legendObj.legend;
		}
	}

	this.getTree = function() {
		return createBranch(parentXML);
	}

	this.reloadMapbook = function(mbXML) {
		document.getElementById(Parent).removeChild(Tree);
		this.loadMapbook(mbXML);
	}

	this.loadMapbook = function(mbXML) {
		MapBookData = mbXML.getElementsByTagName('mapbook')[0];
		if(Parent) {
			document.getElementById(Parent).appendChild(createBranch(MapBookData));
		}
	}

	this.setParent = function(p) {
		Parent = p;
		if(MapBookData) {
			document.getElementById(Parent).appendChild(createBranch(MapBookData));
		}
	}

	this.toggleLegend = function(id) {
		var obj = document.getElementById(TreeViewId+'Legend-'+id);
		if(obj) {
			obj.enabled = !obj.enabled;
			if(obj.enabled) {
				showLegend(obj);
			} else {
				hideLegend(obj);
			}
		}
	}

	this.initializeEvents = function () {
		EventManager.addEventListener('removelayer', TreeViewId, MySelf.removeLayer);
		EventManager.addEventListener('addlayer', TreeViewId, MySelf.addLayer);
		EventManager.addEventListener('removeservice', TreeViewId, MySelf.removeService);
		EventManager.addEventListener('addservice', TreeViewId, MySelf.addService);
		EventManager.addEventListener('removeview', TreeViewId, MySelf.removeView);
		EventManager.addEventListener('addview', TreeViewId, MySelf.addView);
		EventManager.addEventListener('datalayer', TreeViewId, MySelf.onLoadData);
		EventManager.addEventListener('refreshlayer', TreeViewId, MySelf.onLayerRefresh);
		EventManager.addEventListener('navigate', TreeViewId, MySelf.onNavigate);
		EventManager.addEventListener('windowresize', TreeViewId, MySelf.onNavigate);
		EventManager.addEventListener('activatelayer', TreeViewId, MySelf.onActivateLayer);

		if(TREEVIEW_LEGENDS.enabled) {
			EventManager.addEventListener('legendlayer', TreeViewId, MySelf.onLoadLegend);
			EventManager.addEventListener('togglelegend', TreeViewId, MySelf.toggleLegend);
		}

	}
}
