Ext.namespace('geops');
Ext.namespace('geops.ol');

geops.ol.LayerSwitcher = function(config)
{
	Ext.apply(this, config);
	geops.ol.LayerSwitcher.superclass.constructor.call(this);
}

Ext.extend(geops.ol.LayerSwitcher, Ext.Panel, {

	baseLayers: null,
	overlays: null,
	overlayTree: null,
	overlayRoot: null,
	
	//overlayHierarchy: null,
	
	initComponent: function()
	{
		this.baseLayers = new Array();
		this.overlays = new Array();

		this.border = false;
		this.baseCls = 'ext_panel_accordion';
		
		geops.ol.LayerSwitcher.superclass.initComponent.apply(this);

		this._extractLayers();
		//this.overlayHierarchy = this._createOverlayHierarchy();
		this._renderOverlays();
		this._renderBaseLayers();
	},

	expandOverlayTree: function()
	{
		//alert('expand');
		this.overlayRoot.expand();
	},

	_extractLayers: function()
	{
		if(this.map)
		{
			// TODO: Layer aufteilen in Basis/Overlays
			for(var i=0; i<this.map.layers.length; ++i)
			{
				if(this.map.layers[i].displayInLayerSwitcher)
				{
					if(this.map.layers[i].isBaseLayer)
					{
						this.baseLayers.push(this.map.layers[i]);
					}
					else
					{
						this.overlays.push(this.map.layers[i]);
					}
				}
			}
		}
		else
		{
			// TODO: Fehler
		}
	},

	_handleModelChange: function LT__handleModelChange() 
	{
		if (!this.map)
		return;
	
		var layerNameToLayer = {};
		Ext.each(this.map.layers, function(layer) {
		layerNameToLayer[layer.name] = layer;
		});
		
		var wmsLayers = {};
	
		this.overlayTree.getRootNode().cascade(function() {
	
		var node = this;
		var checked = node.attributes.checked;
		var nodeLayerName = node.attributes.layerName;
		
		if (!nodeLayerName)
			return;
		
		if (layerNameToLayer[nodeLayerName]) {
			layerNameToLayer[nodeLayerName].setVisibility(checked, true);
			return;
		}
		
		var wmsParts = nodeLayerName.split(":");
		if (wmsParts.length != 2)
			return;
		var layerName = wmsParts[0];
		var wmsName = wmsParts[1];
		
		if (!wmsLayers[layerName])
			wmsLayers[layerName] = [];
		if (checked) {
			wmsLayers[layerName].push(wmsName);
		}
	
		});
	
		for (var layerName in wmsLayers) {
		var layer = layerNameToLayer[layerName];
		var wmsSubLayers = wmsLayers[layerName];
	
		if (wmsSubLayers.length == 0) {
			layer.setVisibility(false, true);
		} else {
			layer.params.LAYERS = wmsSubLayers;
			layer.redraw();
	
			layer.setVisibility(true, true);
		}
		}
    	},

	_extractOLModel: function() // aus mapfish
	{
		var layers = [];

		for (var i = 0; i < this.map.layers.length; i++) 
		{
			if(!this.map.layers[i].isBaseLayer && this.map.layers[i].displayInLayerSwitcher)
			{
				var l = this.map.layers[i];
				var wmsChildren = [];
			
				if (l instanceof OpenLayers.Layer.WMS ||
					l instanceof OpenLayers.Layer.WMS.Untiled) {
			
					var wmsLayers = l.params.LAYERS;
				
					if (wmsLayers instanceof Array) {
					for (var j = 0; j < wmsLayers.length; j++) {
						var w = wmsLayers[j];
						
						var iconUrl;
						if (this.showWmsLegend) {
						var params = OpenLayers.Util.extend({LAYER: w},
											getLegendParams);
						var paramsString = OpenLayers.Util.getParameterString(params);
						iconUrl = l.url + paramsString;
						}
				
						wmsChildren.push({text: w, // TODO: i18n
								checked: l.getVisibility(),
								icon: iconUrl,
								layerName: l.name + ":" + w,
								children: [],
								leaf: true,
								cls: "cf-wms-node"
								});
					}
					}
				}
				layers.push({text: l.name, // TODO: i18n
					checked: l.getVisibility(),
					layerName: (wmsChildren.length > 0 ? null : l.name),
					children: wmsChildren,
					leaf: wmsChildren.length == 0
					});
			}
        	}
	
		//alert(layers);

        	return layers;
	},

	//_switchBaseLayer: function(radio, layer)
	// TODO: Übergabe Layer als Funktionsparameter funktioniert nicht (falscher Scope bzw. immer gleicher Layer), darum vorerst Abgleich über Name
	_switchBaseLayer: function(radio, checked)	
	{
		//alert(checked);
		for(var i=0; i<this.baseLayers.length; ++i)
		{
			if(this.baseLayers[i].name == radio.boxLabel && checked)
			{
				//alert('change layer');
				this.map.setBaseLayer(this.baseLayers[i]);
				break;
			}
		}
	},

	_renderBaseLayers: function()
	{
		/*titlePanel = new Ext.Panel({
			html: '<div style="margin-bottom: 5px"><b>Basis Layer</b></div>',
			border: false,
			baseCls: 'ext_panel_accordion',
			//cls:  "x-form-field",
		});
		this.add(titlePanel);*/

		baseLayerPanel = new Ext.Panel({
			title: 'Basis-Layer',
			collapsible: true,
			bodyStyle: 'padding:5px 5px 5px 5px'
			//baseCls: 'TODO',
			//cls: 'TODO',
		});

		//var layerRefs = new Array();
		for(var i=0; i<this.baseLayers.length; ++i)
		{
			var radio = new Ext.form.Radio({
				boxLabel: this.baseLayers[i].name,
			        name: 'radio_layer',
				id: 'radio_baselayer_' + i
				//cls:  "x-form-field",
				//labelStyle:  "x-form-field",
				});

			if(this.baseLayers[i].getVisibility())
			{
				radio.checked = true;
			}

			baseLayerPanel.add(radio);
			

			// Lösung funktioniert nicht, weil Event nicht an unterschiedliche Layers gebunden wird
			//var layer = this.baseLayers[i]; // Umweg notwendig, da this im Eventhandler anderen Scope hat ... PROBLEM: in Handler-Funktio immer der letzte Layer Parameter!!!
			//layerRefs[i] = this.baseLayers[i];
			hFnSwitchBaseLayer = this._switchBaseLayer.bind(this);
			//radio.on('check', function(radio, checked){hFnSwitchBaseLayer(radio, layer);});
 			radio.on('check', hFnSwitchBaseLayer);
			//radio.onClick = function(){alert('click')};
			//radio.onClick = hFnSwitchBaseLayer;
			//radio.on('check', function(radio, checked){this._switchBaseLayer(radio, checked);});

			// Wg. Bug in ExtJs wird check-Event immer nur einmal pro Radio-Button gefeuert. 
			//Daher hier Prototype-Eventhandling verwendet:
			//el = radio.getEl();
			//alert(el);
			//Event.observe(domRadio, 'click', hFnSwitchBaseLayer); // noch nicht im DOM!
			
		}
		this.add(new Ext.Panel({
			html: "<div>&nbsp;</div>",
			border: false,
			baseCls: 'ext_panel_accordion'
			}));
		this.add(baseLayerPanel);
		//this.doLayout();

		/*for(var i=0; i<this.baseLayers.length; ++i)
		{
			radio = Ext.get('radio_baselayer_' + i);
			//alert(radio);
		}*/
	},

	_renderOverlays: function()
	{
		var Tree = Ext.tree;

		this.overlayTree = new Tree.TreePanel({
			rootVisible: true,
			animate: false,
			autoScroll: true,
			loader: new Tree.TreeLoader({}),
			enableDD: false,
			containerScroll: true,
			dropConfig: {appendOnly: true},
			lines: true
		});
		
		this.overlayTree.addListener("checkchange", function checkChange() {
			this._handleModelChange();
		}, this);
		
		// add a tree sorter in folder mode
		//new Tree.TreeSorter(tree, {folderSort:true});
		
		if (!this.model) {
			this.model = this._extractOLModel();
		}
	
		// set the root node
		this.overlayRoot = new Tree.AsyncTreeNode({
			text: 'Overlays', 
			draggable: false, // disable root node dragging
			id: 'source',
			children: this.model
		});
		this.overlayTree.setRootNode(this.overlayRoot);
		
		this.add(this.overlayTree);
		//this.overlayTree.render();
		//root.expand(false, /*no anim*/ false);	
	}
})

