/** 
 * @author Peter Goulborn
 * @modifiedby David Cordner
 *
 * Date: 03/05/2009
 * 
 * Class: Astun.iSharemaps.OLLayerPanel
 * User interface to control iShareMaps layers in extended OpenLayers maps.  
 * Instances of this class are created with the <Astun.iSharemaps.OLLayerPanel>
 * constructor.  
 */
Astun.iSharemaps.OLLayerPanel = Class.create(
{
/**
     * Constructor: Astun.iSharemaps.OLLayerPanel
     * Create a new iShareMaps layer UI object. This class interacts 
     *     with Astun.iSharemaps.OLLayerControl objects to set the displayed 
     *     layers.
     *
     * Parameters:
     * atolMap : {<Astun.iSharemaps.OLMap>} Astun wrapper object for 
     * OpenLayers map.  The layer panel watches this for a custom 
     * 'astun:sourceLoad' event and then loads the layer information from the 
     * referenced layer control
     */
	initialize: function ( atolMap , element ) {		
		this.mapWrapper = atolMap;
		this.containerElement = $(element);
		if (this.containerElement === null ) {
			return;
		}
		this.layers = $H({});
		this.groups = $H({});
		Event.observe(this.mapWrapper.mapElement, 'astun:sourceLoad', this.loadLayers.bindAsEventListener(this));
		
	}, 
	/**
	 * Method: setFindNearestLayer
	 * Sets image to indicate on which layer Find Nearest has been performed,
	 * resets image on previous Find Nearest layer (if any) and shows layer if hidden.
	 */
	setFindNearestLayer : function ( element ) {
	  
		this.resetFindNearestLayer();
		element.findNearest = true;
		element.queryIcon.update( new Element('img', {'src': 'images/atLayerNoQuery.png'}));
		if (!element.layerObject.currentlyVisible) {
			element.layerObject.toggle();
		}
		this.findNearestLayer = element;
	},
	
    /**
	 * Method: resetFindNearestLayer
	 * Resets image on previous Find Nearest layer (if any).
     */
	resetFindNearestLayer : function ( ) {
		if (!this.findNearestLayer) {
			return;
		}
		var element = this.findNearestLayer;
		this.findNearestLayer = null;
		element.findNearest = false;	
		element.queryIcon.update( new Element('img', {'src': 'images/atLayerQuery.png'}));
		
	},
    /**
   	 * Method: loadLayers 
	 * Loads layer information into the panel and sets up user interface.
	 * 
	 * Parameters:
	 * event - {event} that called this function.
     */
	loadLayers: function ( event ) {
	
		var panelFade = new Fx.Opacity(this.containerElement,{duration: 2500});
		panelFade.hide();
		
		var setFindNearestLayerEvent = function ( event ) {
			/*
			 * Wrapper for showFindNearestLayer, identifies the Find Nearest layer
			 */
			if (!(event.memo.type === 'findNearest') || !event.memo.displayname) {
				return;
			}
			var findNearestName = event.memo.displayName
			var layerElement = this.layers.find(
			function (l){
				return l.value.layerObject.displayName == findNearestName;
			}
			);
			if (layerElement) {
				this.setFindNearestLayer (layerElement.value);
			}
			else {
				alert('Layer: "' + findNearestName + '" not found.');
			}
		}
		
		
		var resetFindNearestLayerEvent = function ( event ) {
			if (!event.memo.type === 'findNearest') {
				return;
			}
			this.resetFindNearestLayer();
		}
		
		
		var showHideLayer = function ( element ) {
			
			var layerObject = element.layerObject;
			
			var showHideTemplate = new Template (
				'Click to #{action} #{layer} on the map'
			);
			
			var findMyNearestTemplate = new Template (
				'Show the nearest #{results} #{layer} within #{distance} #{measurement}'
			);
			
			var showMyTemplate = new Template (
				'Show my #{layer}'
			);
			
			var templateFields = {
				action: (layerObject.currentlyVisible) ? 'hide' : 'show',
				layer: layerObject.displayName,
				results: (layerObject.query.findNearest) ? layerObject.query.findNearest.maxResults : '',
				distance: (layerObject.query.findNearest) ? layerObject.query.findNearest.distance : '',
				measurement: 'metres'
			}
		
			if (layerObject.query.showMy) {
				var queryTemplate = showMyTemplate;
			} 
			else {
				var queryTemplate = findMyNearestTemplate;
			}
						
			var showHideTitle = showHideTemplate.evaluate(templateFields);
			
			element.textLink.setAttribute('title', showHideTitle);
			element.layerIcon.setAttribute('title', showHideTitle);
			element.queryIcon.setAttribute('title', queryTemplate.evaluate(templateFields))
			
		
			if (element.layerObject.currentlyVisible) {
				element.addClassName('atLayerShown');
			}
			else {
				element.removeClassName('atLayerShown');
			}
			
		
		}
		
		
		var updateLayerGroupEvent = function ( event ) {
			// event observer for updateLayerGroup function
			updateLayerGroup(this.groups.get(event.memo.layerGroup.layerName));				
		
		}
		
		var updateLayerGroup = function ( element ) {			
			if (element.groupObject.activeLayers.length  === element.groupObject.activeShown) {
				element.addClassName('atAllLayersShown');
				if (element.collapsed) {
					expandCollapseGroup(element);
				}
				var action = 'hide';
			} 
			else { 
				element.removeClassName('atAllLayersShown');
				var action = 'show';
			}
			element.layersIcon.writeAttribute('title', 'Click to ' + action + ' all ' + element.groupObject.displayName + ' layers on the map');
		
		}
		
		var updateLayerEvent = function ( event ) {
			// event observer for updateLayer function
			updateLayer(this.layers.get(event.memo.layer.layerName));				
		
		}
		
		var updateLayer = function ( element ) {
			showHideLayer(element);
			updateLayerGroup(element.groupElement);
		}
		
		
		var expandCollapseGroup = function (groupElement) {
		
			var collapsedClass = 'atGroupCollapsed';
			
			groupElement.groupLayers.each( function (layerElement) {
				var heightFx = new Fx.Height(layerElement,{duration: 350});
				heightFx.toggle();
			})
			
			if (groupElement.collapsed) {
				groupElement.removeClassName(collapsedClass);
				groupElement.collapsed = false;
			}
			else {
				groupElement.addClassName(collapsedClass);
				groupElement.collapsed = true;				
			}
			var openGroups = [];
			groupElement.panel.groups.each(function(group){
				if (!group.value.collapsed){
					openGroups.push(group.key);
				}				
			});

			groupElement.panel.mapWrapper.mapElement.fire('astun:saveSetting', {'setting': 'layerPanelOpenGroups', 'value': openGroups.toJSON()});
			
		}
		
		var groupClick = {};
		
		groupClick.toggleLayers = function(event) {
			// {this} is bound to the groupElement DOM object, which has a 
			// custom property referring back to the layer control's group object 
			if (this.groupObject.activeLayers.length === this.groupObject.activeShown) {
				this.groupObject.hideLayers();
			}
			else {
				this.groupObject.showLayers();
			}
			
			Event.stop(event);	
			return false;			
		}
		
		
		groupClick.expandCollapse = function(event) {
			// {this} is bound to the groupElement DOM object, which has a 
			// custom property referring back to the layer control's group object 
			expandCollapseGroup(this);
			Event.stop(event);		
			return false;	
			
		}
		
		var layerClick = {} 
		
		layerClick.toggle = function(event) {
			// {this} is bound to the layerElement DOM object, which has a 
			// custom property referring back to the layer control's layer object
			this.layerObject.toggle();
			Event.stop(event);		
			return false;	
		}
		
		layerClick.query = function(event) {
			// {this} is bound to the layerElement DOM object, which has a 
			// custom property referring back to the layer control's layer object
			this.layerObject.group.mapWrapper.mapElement.fire("astun:layerQuery", {layer: this.layerObject, reset : this.findNearest});
			Event.stop(event);		
			return false;				
		}
		
		
		var makeLayerGroup = function (parentElement, groupObject, click ) {
		
			var groupElement = new Element('dt', {'class': 'atLayerControlPanelGroup'});
			
			var action = (groupObject.activeLayers.length === groupObject.activeShown) ? 'hide' : 'show';
			
			var layersIconLink = new Element('a', {
				'href': ' ', 
				'class': 'atGroupLayersIcon'				
			});
			
			var displayIconLink = new Element('a', {'href': ' ', 'class': 'atGroupDisplayIcon'});
			var displayNameLink = new Element('a', {'href': ' ', 'class': 'atGroupLabel'});
			
			displayNameLink.update( groupObject.displayName );
			groupElement.update(layersIconLink).insert(displayNameLink).insert(displayIconLink);
			
			Event.observe(layersIconLink, 'click', click.toggleLayers.bindAsEventListener(groupElement));
			Event.observe(displayIconLink, 'click', click.expandCollapse.bindAsEventListener(groupElement));
			Event.observe(displayNameLink, 'click', click.expandCollapse.bindAsEventListener(groupElement));
			
			parentElement.appendChild(groupElement);
			groupElement.layerParent = parentElement;
			groupElement.layersIcon = layersIconLink;
			
			return groupElement;
			
		}
		
		var makeLayer = function (parentElement, layerObject, layerClick) {
			
			var layerElement = new Element('dd', {'class': 'atLayerControlPanelLayer'});
			
			var textLink = new Element('a', {'href': ' ', 'class': 'atLayerLabel'});
			textLink.update( layerObject.displayName );
			
			var layerIcon = new Element('a', {'href': ' ', 'class': 'atLayerIcon'});
			layerIcon.update(new Element('img', {'src': layerObject.icon}));
			
			Event.observe(layerIcon, 'click', layerClick.toggle.bindAsEventListener(layerElement));
			Event.observe(textLink, 'click', layerClick.toggle.bindAsEventListener(layerElement));
			
			if (layerObject.query && (layerObject.query.bufferSearch || layerObject.query.showMy || layerObject.query.findNearest)) {
				var queryIcon = new Element('a', {'href': ' ', 'class': 'atQueryIcon'});
				queryIcon.update( new Element('img', {'src': 'images/atLayerQuery.png'}));
				Event.observe(queryIcon, 'click', layerClick.query.bindAsEventListener(layerElement));
			}
			else {
				var queryIcon = new Element('img', {'src': 'images/atLayerNAQuery.png'});
			}
			
			layerElement.update(queryIcon).insert(layerIcon).insert(textLink);
			
			layerElement.queryIcon = queryIcon;
			layerElement.layerIcon = layerIcon;
			layerElement.textLink = textLink;
			
			
			
			
			parentElement.appendChild(layerElement);
			return layerElement;
			
		}
		
		
		this.layerControl = event.memo.layerControl;
		var groupParentElement = new Element('dl', {'class': 'atLayerControlPanel'});
		
		for ( var groupId = 0, groupLimit = this.layerControl.layerGroups.length; groupId < groupLimit; ++groupId ) {
			var groupObject = this.layerControl.layerGroups[groupId];
			if (groupObject.activeLayers.length) {
				var groupElement = makeLayerGroup(groupParentElement, groupObject, groupClick);
				groupElement.panel = this;
				var layerParent = groupElement.layerParent;
				groupElement.groupLayers = $A([]);
				for (var layerId = 0, layerLimit = groupObject.activeLayers.length; layerId < layerLimit; ++layerId) {
					var layerObject = groupObject.activeLayers[layerId];					
					var layerElement = makeLayer(layerParent, layerObject, layerClick);
					layerElement.groupElement = groupElement;
					layerElement.layerObject = layerObject;
					groupElement.groupLayers.push(layerElement);
					this.layers.set(layerObject.layerName, layerElement);
					showHideLayer(layerElement);
					
				}
				this.groups.set(groupObject.displayName, groupElement);
				groupElement.groupObject = groupObject;
			}
		}
		
		if (!!this.groups.size > 0) {
			var setOpenGroups = function(uncollapsedSetting){
				var groupOpen = false;
				if (!!uncollapsedSetting) {
					var uncollapsed = uncollapsedSetting.evalJSON();
					groupOpen = (uncollapsed.length === 0);
					var markUncollapsed = function(g){
						var groupElement = this.groups.get(g);
						if (groupElement) {
							groupElement.collapsed = false;
							if (!groupOpen) {
								groupOpen = true;
							}
						}
					}
					uncollapsed.each(markUncollapsed.bind(this));
				}
				if (!groupOpen) {
					this.groups.values()[0].collapsed = false;
				}
				this.groups.each(function(group){
					var groupElement = group.value;
					if (groupElement.collapsed !== false) {
						groupElement.collapsed = false;
						expandCollapseGroup(groupElement);
					}
					updateLayerGroup(groupElement);
					
				})
			}
			
			this.mapWrapper.mapElement.fire('astun:loadSetting', {
				setting: 'layerPanelOpenGroups',
				loadFunction: setOpenGroups.bind(this)
			});
			
			this.containerElement.update(groupParentElement);
			Event.observe(this.mapWrapper.mapElement, 'astun:layerShow', updateLayerEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:layerHide', updateLayerEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:showLayerGroup', updateLayerGroupEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:hideLayerGroup', updateLayerGroupEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:resultsReceived', setFindNearestLayerEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:resultsCleared', resetFindNearestLayerEvent.bindAsEventListener(this));
			panelFade.toggle();
		}
		else {
			this.containerElement.update('<p>No layers of type <strong>' + this.LAYERTYPES + '</strong> found.')
		}
	},
	LAYERTYPES: ['base']
	
 });
 
 
/**
 * Class: Astun.iSharemaps.OLLayerPanel.Thematic
 * User interface to control iShareMaps thematic layers in extended OpenLayers
 * maps.  
 * Instances of this class are created with the 
 * <Astun.iSharemaps.OLLayerPanel.Thematic> constructor.
 */
Astun.iSharemaps.OLLayerPanel.Thematic = Class.create(
{
    /**
     * Constructor: Astun.iSharemaps.OLLayerPanel.Thematic
     * Create a new iShareMaps thematic layer UI object. This class interacts 
     *     with Astun.iSharemaps.OLLayerControl objects to set the displayed 
     *     layers.
     *
     * Parameters:
     * atolMap : {<Astun.iSharemaps.OLMap>} Astun wrapper object for 
     * OpenLayers map.  The layer panel watches this for a custom 
     * 'astun:sourceLoad' event and then loads the layer information from the 
     * referenced layer control
     */
	initialize: function ( atolMap , element ) {	
	
		this.mapWrapper = atolMap;
		this.containerElement = $(element);
		if (this.containerElement === null ) {
			return;
		}
		this.layers = $H({});
		this.groups = $H({});
		Event.observe(this.mapWrapper.mapElement, 'astun:sourceLoad', this.loadLayers.bindAsEventListener(this));
		
	},
   /**
	* Method: loadLayers
	* Loads layer information into the panel and sets up user interface.
	* 
	* Parameters:
	* event - {event} that called this function.
    */
	loadLayers: function ( event ) {
	
	
		var panelFade = new Fx.Opacity(this.containerElement,{duration: 2500});
		panelFade.hide();
				
		var showHideLayer = function ( element ) {
			var containerElement = element.groupElement.parent;
			if (containerElement.currentElement && containerElement.currentElement !== element) {
				showHideLayer(containerElement.currentElement);
			}
			
			var layerObject = element.layerObject;
			
			var showHideTemplate = new Template (
				'Click to #{action} #{layer} on the map'
			);
					
			var templateFields = {
				action: (layerObject.currentlyVisible) ? 'hide' : 'show',
				layer: layerObject.displayName
			}
			
			//var heightFx = new Fx.Height(element.select('.atRanges')[0],{duration: 350});
			//heightFx.toggle();
			/*
			for (var i = 0, range = layerObject.thematic.ranges.range; i <range.length; ++i ){
				var classItem = new Element('li', {'class': 'atRange'+i});
				var legend = new Element('div', {'class': 'atLayerLegend'});
				var legendIcon = new Element('img', {'src': 'images/spacer.gif'});
				legend.update(legendIcon);
				classItem.update(legend);
				classItem.insert(range[i].label);
				classList.insert(classItem);
			}*/
			if (layerObject.currentlyVisible) {
				var ul = element.select('ul.atRanges')[0];
				for (var j = 0 ; j < ul.childNodes.length ; j++) {
					ul.childNodes[j].setStyle({'display':'none'});
				}
				for ( var i = 0 ; i< element.layerObject.thematic.ranges.range.length ; i++) {
					var classItem = element.select('li.atRange'+i)[0];
					var layerLabel = classItem.select('span.atRange'+i)[0];
					var layerLegend = classItem.select('.atLayerLegend')[0];
					var layerLegendIcon = classItem.select('img')[0];
					classItem.setStyle({'display':'block'});
					layerLegend.setStyle({'borderColor': element.layerObject.thematic.ranges.range[i].colour});
					layerLegendIcon.setStyle({'backgroundColor': element.layerObject.thematic.ranges.range[i].colour, 'opacity':0.6});
					layerLabel.update(element.layerObject.thematic.ranges.range[i].label);
				}	
				element.addClassName('atLayerShown');
				containerElement.currentElement = element;
			}	
			else {
				element.removeClassName('atLayerShown');
				containerElement.currentElement = null;
			}		
			
			
			var showHideTitle = showHideTemplate.evaluate(templateFields);
			
			element.textLink.setAttribute('title', showHideTitle);
					
		}
		
		
		var updateLayerGroupEvent = function ( event ) {
			// event observer for updateLayerGroup function
			updateLayerGroup(this.groups.get(event.memo.layerGroup.layerName));				
		
		}
		
		var updateLayerGroup = function ( element ) {			
			if (element.groupLayers.length  === element.layersShown) {
				element.addClassName('atAllLayersShown');
				if (element.collapsed) {
					expandCollapseGroup(element);
				}
				var action = 'hide';
			} 
			else { 
				element.removeClassName('atAllLayersShown');
				var action = 'show';
			}
			element.layersIcon.writeAttribute('title', 'Click to ' + action + ' all ' + element.groupObject.displayName + ' layers on the map');
		
		}
		
		var updateLayerShowEvent = function ( event ) {
			// event observer for updateLayer function
			
			var element = this.layers.get(event.memo.layer.layerName);
			if (!element) {
				return;
				}
			if (element !== element.groupElement.parent.currentElement) {
				updateLayer(element);	
			}
		
		}
		
		var updateLayerHideEvent = function ( event ) {
			// event observer for updateLayer function
			updateLayer(this.layers.get(event.memo.layer.layerName));	
		
		}
		
		var updateLayer = function ( element ) {
			showHideLayer(element);
			updateLayerGroup(element.groupElement);
		}
		
		
		var expandCollapseGroup = function (groupElement) {
		
			var collapsedClass = 'atGroupCollapsed';
			/*
			groupElement.groupLayers.each( function (layerElement) {
				var heightFx = new Fx.Height(layerElement,{duration: 350});
				heightFx.toggle();
			})*/
			
			if (groupElement.collapsed) {
				groupElement.removeClassName(collapsedClass);
				groupElement.collapsed = false;
			}
			else {
				groupElement.addClassName(collapsedClass);
				groupElement.collapsed = true;				
			}
			var openGroups = [];
			groupElement.panel.groups.each(function(group){
				if (!group.value.collapsed){
					openGroups.push(group.key);
				}				
			});

			groupElement.panel.mapWrapper.mapElement.fire('astun:saveSetting', {'setting': 'layerThematicOpenGroups', 'value': openGroups.toJSON()});
			
		}
		
		var groupClick = {};
		
		groupClick.expandCollapse = function(event) {
			// {this} is bound to the groupElement DOM object, which has a 
			// custom property referring back to the layer control's group object 
			expandCollapseGroup(this);
			Event.stop(event);		
			return false;	
			
		}
		groupClick.switchThematic = function(event) {
			// {this} is bound to the groupElement DOM object, which has a 
			// custom property referring back to the layer control's group object 
			var radioButtons = this.select('.atThematicSelector input[type="radio"]');
			var checked = radioButtons.find(function(radioButton){
				return radioButton.checked;
			})
			this.groupObject.themeFieldsIndex = checked.value || 0;
			if (this.groupObject.currentLayer) {
				var selectedLayer = this.groupObject.currentLayer;
				selectedLayer.thematic.ranges.initialised = false ;
				selectedLayer.reload();
			}
			//Event.stop(event);		
			//return false;	
			
		}
		
		var layerClick = {} 
		
		layerClick.toggle = function(evt) {
			// {this} is bound to the layerElement DOM object, which has a 
			// custom property referring back to the layer control's layer object
			this.layerObject.thematic.ranges.initialised = false ;
			this.layerObject.toggle();
			Event.stop(evt);		
			return false;	
		}
		
		layerClick.query = function(evt) {
			// {this} is bound to the layerElement DOM object, which has a 
			// custom property referring back to the layer control's layer object
			this.layerObject.group.mapWrapper.mapElement.fire("astun:layerQuery", {layer: this.layerObject, reset : this.findNearest});
			Event.stop(evt);		
			return false;				
		}
		
		
		var makeLayerGroup = function (parentElement, groupObject, click ) {
		
			var groupElement = new Element('dt', {'class': 'atLayerControlPanelGroup'});
			
			var action = (groupObject.activeLayers.length === groupObject.activeShown) ? 'hide' : 'show';
			
			var layersIconLink = new Element('a', {
				'href': ' ', 
				'class': 'atGroupLayersIcon'				
			});
			
			var displayIconLink = new Element('a', {'href': ' ', 'class': 'atGroupDisplayIcon'});
			var displayNameLink = new Element('a', {'href': ' ', 'class': 'atGroupLabel'});
			
			displayNameLink.update( groupObject.displayName );
			 
			
			//groupElement.update(layersIconLink).insert(displayNameLink).insert(displayIconLink);
			//groupElement.update(displayNameLink);
			groupElement.update(groupObject.displayName);
			
			Event.observe(displayIconLink, 'click', click.expandCollapse.bindAsEventListener(groupElement));
			Event.observe(displayNameLink, 'click', click.expandCollapse.bindAsEventListener(groupElement));
			if( groupObject.themeFields && groupObject.themeFields.length > 1) {
				var fields = groupObject.themeFields.slice(0);
				var fieldSelector = new Element('p');
				var checkedIndex = groupObject.themeFieldsIndex || 0;
				fieldSelector.addClassName('atThematicSelector');
				for (var i = 0; i < fields.length; i++) {
					var name = 'radio-' + groupObject.guid;
					var radioButton = new Element('input', {'type': 'radio', 'name': name, 'value': i});
					radioButton.addClassName('atLayerGroupRadio');
					radioButton.id = name + '-' + i;
					if (checkedIndex === i) {
						radioButton.checked = true;
						radioButton.defaultChecked = true;
					}
					var radioLabel = new Element('label',{'for': radioButton.id});
					radioLabel.update(fields[i]);
					fieldSelector.insert(radioButton).insert(radioLabel);
					Event.observe(radioButton, 'click', click.switchThematic.bindAsEventListener(groupElement));
				}			
				groupElement.appendChild(fieldSelector);	
				
			}
			parentElement.appendChild(groupElement);
			groupElement.parent = parentElement;
			groupElement.layersIcon = layersIconLink;
			
			return groupElement;
			
		}
		
		var makeLayer = function (parentElement, layerObject, layerClick) {
			
			var layerElement = new Element('dd', {'class': 'atLayerControlPanelLayer'});
			var linkPara = new Element('p');
			var textLink = new Element('a', {'href': '#', 'class': 'atLayerLabel'});
			textLink.update( layerObject.displayName );
			
			var layerIcon = new Element('a', {'href': ' ', 'class': 'atLayerIcon'});
			layerIcon.update(new Element('img', {'src': 'includes/olmaps/_assets/images/legend/thematicbdy.png'}));
			
			Event.observe(layerIcon, 'click', layerClick.toggle.bindAsEventListener(layerElement));
			Event.observe(textLink, 'click', layerClick.toggle.bindAsEventListener(layerElement));
			
			linkPara.update(layerIcon).insert(textLink);
			
			var classList = new Element('ul', {'class': 'atRanges'});
			for (var i = 0, range = layerObject.thematic.ranges.range; i < range.length; ++i ){
				var classItem = new Element('li', {'class': 'atRange'+i});
				var legend = new Element('div', {'class': 'atLayerLegend'});
				var label = new Element('span', {'class': 'atRange'+i});
				var legendIcon = new Element('img', {'src': 'includes/olmaps/_assets/images/spacer.gif'});
				legend.update(legendIcon);
				label.update(range[i].label)
				classItem.update(legend);
				//classItem.insert(range[i].label);
				classItem.insert(label);
				classList.insert(classItem);
			}
			
			layerElement.update(linkPara).insert(classList);
			layerElement.textLink = textLink;
						
			parentElement.appendChild(layerElement);
			return layerElement;
			
		}
		
		
		this.layerControl = event.memo.layerControl;
		var groupParentElement = new Element('dl', {'class': 'atLayerControlPanel'});
		
		for ( var groupId = 0, groupLimit = this.layerControl.layerGroups.length; groupId < groupLimit; ++groupId ) {
			var groupObject = this.layerControl.layerGroups[groupId];
	
			if (groupObject.thematicLayers.length) {
				var groupElement = makeLayerGroup(groupParentElement, groupObject, groupClick);
				groupElement.panel = this;
				var layerParent = groupElement.parent;
				groupElement.groupLayers = $A([]);
				for (var layerId = 0, layerLimit = groupObject.thematicLayers.length; layerId < layerLimit; ++layerId) {
					var layerObject = groupObject.thematicLayers[layerId];					
					var layerElement = makeLayer(layerParent, layerObject, layerClick);
					layerElement.addClassName('atAlt'+(layerId % 2));
					layerElement.groupElement = groupElement;
					layerElement.layerObject = layerObject;
					groupElement.groupLayers.push(layerElement);
					this.layers.set(layerObject.layerName, layerElement);
					showHideLayer(layerElement);
					
				}
				this.groups.set(groupObject.displayName, groupElement);
				groupElement.groupObject = groupObject;
			}
		}
		
		if (!!this.groups.size > 0) {
			var setOpenGroups = function(uncollapsedSetting){
				var groupOpen = false;
				if (!!uncollapsedSetting) {
					var uncollapsed = uncollapsedSetting.evalJSON();
					groupOpen = (uncollapsed.length === 0);
					var markUncollapsed = function(g){
						var groupElement = this.groups.get(g);
						if (groupElement) {
							groupElement.collapsed = false;
							if (!groupOpen) {
								groupOpen = true;
							}
						}
					}
					uncollapsed.each(markUncollapsed.bind(this));
				}
				if (!groupOpen) {
					this.groups.values()[0].collapsed = false;
				}
				this.groups.each(function(group){
					var groupElement = group.value;
					if (groupElement.collapsed !== false) {
						groupElement.collapsed = false;
						expandCollapseGroup(groupElement);
					}
					updateLayerGroup(groupElement);
					
				})
			}
			
			/*this.mapWrapper.mapElement.fire('astun:loadSetting', {
				setting: 'layerThematicOpenGroups',
				loadFunction: setOpenGroups.bind(this)
			});*/
			
			this.containerElement.update(groupParentElement);
			Event.observe(this.mapWrapper.mapElement, 'astun:thematicShow', updateLayerShowEvent.bindAsEventListener(this));
			Event.observe(this.mapWrapper.mapElement, 'astun:thematicHide', updateLayerHideEvent.bindAsEventListener(this));
			panelFade.toggle();
		}
		else {
			this.containerElement.update('<p>No layers of type <strong>' + this.LAYERTYPES + '</strong> found.')
		}
	},
	LAYERTYPES: ['thematic']
	
 });