/*!
 * Ext JS Library 3.1.0
 * Copyright(c) 2006-2009 Ext JS, LLC
 * licensing@extjs.com
 * http://www.extjs.com/license
 */
var tree;
var destinationTree;
/*combobox for paikannimihaku*/
var placenameCombo;

Ext.onReady(function(){

    tree = new Ext.tree.TreePanel({
        renderTo:'tree-div',
        useArrows:false,
        autoScroll:false,
        animate:false,
        enableDD:true,
        containerScroll: true,
        rootVisible: false,
        frame: false,
        /*styling*/
        baseCls: 'x-plain',
        root: {
            nodeType: 'async',
            children: initTreeViewJson(),
            draggable: false,
            allowDrop: false
        },
    	listeners: {
	        checkchange: function(node, checked) {
	        	//09.03.2010 - ph - wfsfilter update
	        	if (node.attributes.wfsFilterIds) {
	        		//wfs_layer.mergeNewParams({'FILTER':generatePointsWfsFilter()});
	        		updatePois(node);
	        	}
	        	else if (node.attributes.layer) {
	        		toggleLayer(node, checked);
					syncMapLayersWithTree(node);
	        	} else if (node.attributes.category) {
	        		toggleCategory(node, checked);
	        	}
	        },
	        expandnode: function(node,deep,anim){
//	        	if (node.attributes.slider && !node.attributes.slider.rendered) {
				
				Ext.each(node.childNodes, function(node) {
					if (node.attributes.slider) {
						if (!node.attributes.slider.rendered) {
							var opacitySlider = node.attributes.slider;
							//reference to the parentNode -> access to layer.
				        	opacitySlider.node = node;
				        	var sliderDiv = generateOpacitySlider(opacitySlider);
		//		        	sliderDiv = sliderDiv.firstChild;

				        	sliderDiv.firstChild.style.wrap = 'no-wrap';
				        	sliderDiv.firstChild.style.display = 'inline-block';
				        	sliderDiv.firstChild.style.verticalAlign = 'bottom';
		
				        	sliderDiv.style.wrap = 'no-wrap';
//				        	sliderDiv.style.display = 'inline-block';
				        	sliderDiv.style.display = 'inline';
				        	sliderDiv.style.verticalAlign = 'bottom';
		
				        	node.getUI().anchor.firstChild.appendChild(sliderDiv);
				        	//determines half of the width of the slider -> correct positioning on the bar.
				        	//gotta do this manually, doesn't calculate correctly for some reason...
				        	opacitySlider.halfThumb = 7;
				        	opacitySlider.moveThumb(
				        		opacitySlider.translateValue(opacitySlider.value), false, false);
				        	}
			        	}
		        });
	        },
	        
	        startdrag: function(panel, node, event) {
	        	//in the beginning all folders default to false. 
	        	//Enable this.parent for reordering within a folder..
	        	node.parentNode.allowDrop = true;
	        	node.parentNode.allowChildren = true;
	        },
	        enddrag: function(panel, node, dd, event) {
	        	//reset the parent node.
	        	node.parentNode.allowDrop = false;
	        	node.parentNode.allowChildren = false;
	        },
	        dragdrop: function(panel, node, dd, event) {
//	        	syncMapLayersWithTree(panel, node, dd, event);
	        	syncMapLayersWithTree(node);
	        },
	        nodedragover: function(params) {
	        	//DON'T allow drop above "retkeily" in layer tree. Would be confusing, 'cos the poi-layer
	        	//always remains on top on the map anyway.
	        	//TODO: notify the user of why the drop isn't allowed? 
//	        	if (params.target.isFirst() && params.point == "above") {
	        	if (params.target.attributes &&
	        		params.target.attributes.category &&
	        		params.target.attributes.category.wfsCategory && 
	        		params.point == "above") {
	        			return false;
	        	}
	        }
	        ,
	        click: function(node, e) {
	        	if (!node.leaf) {
	        		node.toggle();
	        		return;
	        	} else if (node.attributes.wfsFilterIds) {
        			node.ui.checkbox.checked = true;
        			node.ui.onCheckChange();
	        		return;
	        	}
	        }
		}
    });
    
//    tree.getRootNode().expand(true);
    
    
    destinationTree = new Ext.tree.TreePanel({
        renderTo:'destinationMenuDiv',
        useArrows:false,
        autoScroll:false,
        animate:false,
        enableDD:false,
        containerScroll: true,
        rootVisible: false,
        frame: false,
        /*styling*/
        baseCls: 'x-plain',
        root: {
            nodeType: 'async',
            children: destinationJson,
            draggable: false,
            allowDrop: false
        },
        listeners: {
        
        	'click': function(node) {
				if (!node.attributes.leaf) {
					node.toggle();
					return;	
				}
				
				
				//09.03.2010 - ph - Wfs-leafnode
				if (node.attributes.wfsFilterIds) {
					//Maybe something something...
				
				}
        		else if (node.attributes.type == 'point') {
					//alert(node.attributes.x+' - '+node.attributes.y+' - '+node.attributes.zoom);
        			//map.setCenter()
        			if (node.attributes.x && node.attributes.y && node.attributes.zoom) {
	        			
        				/*04.10.2010 - ph - reverse the zoom*/
        				var actualZoom = parseInt(map.getNumZoomLevels()) - parseInt(node.attributes.zoom) - parseInt(1);
//        				map.setCenter(new OpenLayers.LonLat(node.attributes.x,node.attributes.y), node.attributes.zoom);
        				map.setCenter(new OpenLayers.LonLat(node.attributes.x,node.attributes.y), actualZoom);
	        			//Ehk�...ehk� ei...
//	        			addMarker(new OpenLayers.LonLat(node.attributes.x,node.attributes.y));
					}		
        		
        		}
        		else if (node.attributes.type == 'area' || node.attributes.type == 'route') {
        			//left,bottom,right,top
        			if (node.attributes.minx && node.attributes.miny && node.attributes.maxx && node.attributes.maxy) {
	        			map.zoomToExtent(new OpenLayers.Bounds
	        				(node.attributes.minx, node.attributes.miny,
	        				 node.attributes.maxx,node.attributes.maxy), true);
					}
        		}
        		
        		//Fetch the corresponding feature on areas-layer.
        		if (node.attributes.type == 'area') {
	        		
					highlightAreaById(node.attributes.id);
					/*
					var destinationLayer = map.getLayersBy("layerId", "allareas")[0];
	        		if (destinationLayer) {
	        			//used for being able to highlight the correct feature on printable map as well. 
	        			destinationLayer.destinationId = node.attributes.id;
	        			destinationLayer.mergeNewParams({'filter':generateFilter(node.attributes.id)});
		        		destinationLayer.setVisibility(true);
	        		}
	        		*/
        		}
        		
        		//switch on the corresponding (wfs) layer
        		var key;
        		key = categoryToLayerIdMappings[node.attributes.categoryId];
        		var layerNode = tree.getNodeById(key);
        		if (layerNode) {
        			layerNode.ui.checkbox.checked = true;
        			layerNode.ui.onCheckChange();
        		}
        		
        		//check, whether some additional category should also be switched on
        		if (node.attributes.maplayer) {
					toggleMaplayerByName(node.attributes.maplayer);
        		}
        	}
        }
	});

    /*Combobox for paikannimihaku*/
// simple array store
    var store = new Ext.data.JsonStore({
        fields: ['displayfield','locationId', 'name', 'poiclass', 'kunta', 'lonlat','bounds'],
        idProperty:'id'
    });
    placenameCombo = new Ext.form.ComboBox({
		width: 300,
		//minListWidth: 200,
		//listWidth: 'auto',
		store: store,
	    displayField:'displayfield',
	    typeAhead: false,
	    mode: 'local',
	    triggerAction: 'all',
	    emptyText:'',
	    selectOnFocus:true,
		applyTo: 'searchbyplacenameInput',
		
		/*for use with the geocoding*/
		comboId: 'paikannimihaku',
		ajaxUrl: './php/ajaxRequest.php',
		mapareacheckedInputId:'placename_chkonlymaparea',
		inputId:'searchbyplacenameInput',
		categoryChkGroupName:'chkpaikannimihaku',
		listeners: {
			'select': function(combo, record, index) {
				//The value in the input textbox (=the search) shouldn't include municipality and type info
        		document.getElementById('searchbyplacenameInput').value = record.data.name;
//	        	map.zoomToExtent(record.data.bounds, true);
	        	map.setCenter(record.data.lonlat, 4);
       		}
		}
    });
    
    var nameStore = new Ext.data.JsonStore({
//        fields: ['displayfield','locationId', 'name', 'poiclass', 'kunta', 'lonlat','bounds'],
        fields: ['displayfield','locationid', 'name', 'category', 'lonlat','bounds','maplayer'],
        idProperty:'id'
    });
    nameCombo = new Ext.form.ComboBox({
		width: 300,
		//minListWidth: 200,
		//listWidth: 'auto',
		store: nameStore,
	    displayField:'displayfield',
	    typeAhead: false,
	    mode: 'local',
	    triggerAction: 'all',
	    emptyText:'',
	    selectOnFocus:true,
		applyTo: 'searchbynameInput',
		
		/*for use with the geocoding*/
		comboId: 'nimihaku',
		ajaxUrl: './php/ajaxRequest.php?service=metsamapd',
		mapareacheckedInputId:'name_chkonlymaparea',
		inputId:'searchbynameInput',
		categoryChkGroupName:'chknimihaku',

		listeners: {
			'select': function(combo, record, index) {
				//The value in the input textbox (=the search) shouldn't include municipality and type info
        		document.getElementById('searchbynameInput').value = record.data.name;
	        	
	        	
	        		if (record.data.maplayer) {
		        		var key = nimihakuLayerMappings[record.data.maplayer];
		        		if (key) {
			        		var layerNode = tree.getNodeById(key);
			        		if (layerNode) {
			        			layerNode.ui.checkbox.checked = true;
			        			layerNode.ui.onCheckChange();
			        		}
			        	} 
		        	}

		        	//check the "special layers'" list as well. 
		        	toggleMaplayerByName(record.data.maplayer);
					highlightAreaById(record.data.locationId);
					
	        	map.zoomToExtent(record.data.bounds, true);
	        }
		}
		
    });
    
    //"lazy loading", if not expanded. Gotta ewxpand (and then collapse) to be able to make use of the 
    //whole nodehash right away!
    //
    tree.expandAll(true);
    destinationTree.expandAll(true);
    tree.collapseAll(true);
    destinationTree.collapseAll(true);
    init();
});



    Ext.override(Ext.tree.TreeEventModel, {
		delegateClick : function(e, t){
            //react only to a checkbox. Otherwise -> fuck it.
			if(e.getTarget('input[type=checkbox]', 1)){
				this.onCheckboxClick(e, this.getNode(e));
			//iconclick -> expand / collapse...	
            }else if(e.getTarget('.x-tree-ec-icon', 1)){
                this.onIconClick(e, this.getNode(e));
			//nodeclick -> select
            }else if(this.getNodeTarget(e)){
                this.onNodeClick(e, this.getNode(e));
			} else {
				Event.stop(e);
			}
		}
    });
  
/*!
 * Ext JS Library 3.1.1
 * Copyright(c) 2006-2010 Ext JS, LLC
 * licensing@extjs.com
 * http://www.extjs.com/license
 */
/**
 * @class Ext.ux.SliderTip
 * @extends Ext.Tip
 * Simple plugin for using an Ext.Tip with a slider to show the slider value
 */
Ext.ux.SliderTip = Ext.extend(Ext.Tip, {
    minWidth: 10,
    offsets : [0, -10],
    init : function(slider){
        slider.on('dragstart', this.onSlide, this);
        slider.on('drag', this.onSlide, this);
        slider.on('dragend', this.hide, this);
        slider.on('destroy', this.destroy, this);
    },

    onSlide : function(slider){
        this.show();
        this.body.update(this.getText(slider));
        this.doAutoWidth();
        this.el.alignTo(slider.thumb, 'b-t?', this.offsets);
    },

    getText : function(slider){
        return String(slider.getValue());
    }
});
  
  
function highlightAreaById(id) {
	
	
	if (id) {
		//highlight the area
		var destinationLayer = map.getLayersBy("layerId", "allareas")[0];
		if (destinationLayer) {
			//used for being able to highlight the correct feature on printable map as well. 
			destinationLayer.destinationId = id;
			destinationLayer.mergeNewParams({
				'filter': generateFilter(id)
			});
			destinationLayer.setVisibility(true);
		}
	}

}  
/*
 * used with requestparam id, to toggle on the requested feature and the necessary layers.
 *	Finds the node with the given featureId from the destinationMenu, and if found, performs click on that node. 
 */
function getDestinationTreeNodeByFeatureId(featureId) {
	
	try {
		var destinationNode = destinationTree.getNodeById(featureId);
		
		if (destinationNode) {
			destinationNode.fireEvent('click', destinationNode);
			return true;
		} else {
	//		alert('pas un node');
			return false;
		
		}
	} catch (e) {
//		alert(e.message);
		return false;
	}
}
/*toggles on a wfs-group by a single categoryId*/  
function toggleNodeByWfsFilterId(wfsFilterId, startNode) {

	if (!startNode)
		startNode = tree.getRootNode();
	
	var found = false;
	if (startNode.childNodes && startNode.childNodes.length > 0) {
		for (var i = 0; i < startNode.childNodes.length; i++) {
			found = toggleNodeByWfsFilterId(wfsFilterId, startNode.childNodes[i]);
			if (found)
				break;
		}
	} else {
 		if (startNode.attributes.wfsFilterIds) {
 			for (var i=0; i < startNode.attributes.wfsFilterIds.length; i++) {
 				if (startNode.attributes.wfsFilterIds[i] == wfsFilterId) {
 					startNode.fireEvent('click',startNode);
 					found = true;
 					break;
 					
 				}
 			}
  		}
		
	}
	
	return found;
	
}
function syncMapLayersWithTree(node) {
//function syncMapLayersWithTree(panel, node, dd, event) {

	    var tree = node.getOwnerTree();
     	var checkedNodes = tree.getChecked(null, tree.rootNode);
     	//store just leafs with layers.
     	var checkedLayerNodes = [];
     	
     	var msg = '';
     	Ext.each(checkedNodes, function(nod) {
     		
     		if (nod.attributes.layer) {
      			checkedLayerNodes.push(nod.attributes.layer);
      			msg += nod.attributes.layer.name +' - '+map.layers.indexOf(nod.attributes.layer)+'\n';	
      		}
     	});
     	
	    //exclude base layers and background layers from the ordering.
	    // -1 -> indexing from zero
	    //TODO: if taustakartta can be toggled on/off as well as other layers, how to determine
	    //the correct calculations...?
	    var noOfBackgroundMaps = map.layers.length - checkedLayerNodes.length;
		checkedLayerNodes.reverse();
		var i = 0;	
		for (i = 0; i < checkedLayerNodes.length; i++) {
			map.setLayerIndex(checkedLayerNodes[i], noOfBackgroundMaps + i);
		}
		//poilayer,destinations' layer and restrictions' layer on top!!!
		map.setLayerIndex(destinationsLayer, noOfBackgroundMaps + i + 1);
		//poilayer and destinations layer on top!!!
		map.setLayerIndex(restrictionsLayer, noOfBackgroundMaps + i + 2);
		map.setLayerIndex(poiLayer, noOfBackgroundMaps + i + 3);
		
}

function generateOpacitySlider(slider) {
	var sliderContainer = document.createElement("div");
	sliderContainer.id = 'sliderContainer';
	sliderContainer.style.visibility = 'visible';
	sliderContainer.style.display = 'inline';
	sliderContainer.style.verticalAlign="baseline";
	sliderContainer.style.width = '1px';
	sliderContainer.title = Language.get("adjusttransparency");
	
	
	slider.render(sliderContainer);
	return sliderContainer;
}

/*
helper function. Takes a navici style maplayer_name and maps that to a layerid / group, and 
toggles on the corresponding layer(s)
*/
function toggleMaplayerByName(name) {
        		//check, whether some additional category should also be switched on
        		if (name) {
					//Might be several layers / layergroups
	        		var additionalLayers = SPECIAL_LAYERS[name];
	        		if (additionalLayers) {
	        			for (var i = 0; i < additionalLayers.length; i++) {
			        		var catNode = tree.getNodeById(additionalLayers[i]);
			        		if (catNode) {
			        			catNode.ui.checkbox.checked = true;
			        			catNode.ui.onCheckChange();
			        		}
		        		}
	        		}
        		}

}

