OpenLayers.Control.MyLayerSwitcher = OpenLayers.Class(OpenLayers.Control.LayerSwitcher, 
{
	isLoadedDataLayers: false,
	
	layersTreeDiv: null,
	layersTree: null,
	expandedCategory: null,
		
	loadDataLayers: function(styleMap)
	{
    		var callback = 
    		{        
       		success: function(oResponse)
        		{
        			//alert(oResponse.responseText);
        			var dl = eval("(" + oResponse.responseText + ")");
        			//alert(oResponse.argument);

        			userlayers = [];
        			for(i = 0; i < dl.length; i++)
        			{        	
					var ul = new OpenLayers.Layer.Vector(dl[i].name, 
        				{
        					DataLayerCategory: (dl[i].public ? "Пользовательские слои" : "Мои слои"),  
        					isExpandedDataLayerCategory: false,
        					
        					visibility: false,
        					styleMap: oResponse.argument.style,
        					displayInLayerSwitcher: true, 
        					isBaseLayer: false,
        					projection:	new OpenLayers.Projection("EPSG:32637"),
        					//projection:	new OpenLayers.Projection("EPSG:4326"),
        					strategies: [new OpenLayers.Strategy.BBOX()],
        					protocol:	new OpenLayers.Protocol.WFS({
        						version:        "1.0.0",
        						srsName:		"EPSG:4326",
        						//srsName:		"EPSG:32637",
        						url:			"/wms/scripts/proxy.php",        						
        						//url:			"/cgi-bin/mapserv?map=/home/alkis/LipetskMap/lipetsk.map",
        						featureType: 	["userlayer_photo", "userlayer_other"],
        						//featureType: 	["userlayer_photo"],
        						featurePrefix:	"ms",
        						geometryName: 	"msGeometry"
        					}),
        					filter: new OpenLayers.Filter.Comparison({
                            		type: OpenLayers.Filter.Comparison.EQUAL_TO,
                            		property: "datalayer_id",
                            		value: dl[i].id
						})
        				});
        		        			
        				        				
        				userlayers.push(ul);
        				map.addLayer(ul);
        				ul.setZIndex(414);        		
        				//ul.setZIndex(300);
        				//ul.setVisibility(true);     		
        			}        			                	
              
        			var sf;
        		
        			map.addControl(sf = new OpenLayers.Control.SelectFeature(userlayers, 
       	 		{
        				onSelect: function (feature) 
        				{        				
        					//alert("e");
        					if (feature.popup == null)
        					{
        						var content = "<img src='" +feature.attributes.picture + 
        							"' width='300' vspace='30' hspace='30' alt='' /><br>" + feature.attributes.ad_descrdatalayer;
        						feature.lonlat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
        						feature.popup = new OpenLayers.Popup.AnchoredBubble(
        							"InfoUserLayerObject",
        							feature.lonlat,
        							new OpenLayers.Size(300,200),
        							content,
        							//{size: new OpenLayers.Size(30,30), offset: new OpenLayers.Pixel(0,0)},
        							null,
        							true,
        							function(e) 
        							{
        								this.hide(); 
        								popupInfo = null;        						
        							}        				
        						);
        				
        						feature.popup.setBackgroundColor("#EEEDFF");	      				
        						feature.popup.autoSize = true;
        						map.addPopup(feature.popup);
        					}
        					else
        						feature.popup.show();
        				
        					popupInfo = feature.popup;
        					this.unselectAll();        				        				
        				},
        			
        				toggle: true        		        			        			
        			}));
        		
        			sf.activate();
        		
        		
        			map.addControl(sf = new OpenLayers.Control.SelectFeature(userlayers, 
       	 		{
        				onSelect: function (feature) 
        				{
        					var popup_info = "<div style='font-size:10px'>";
        					if (feature.attributes.ad_namedatalayer.length)
        						popup_info += "<strong>" + feature.attributes.ad_descrdatalayer + " - " + feature.layer.name + "</strong><br>";
        					else
        						popup_info += "<strong>" + feature.layer.name + "</strong><br>";
        					
        					popup_info = popup_info + "<p>" + feature.attributes.ad_descrdatalayer + "</p>";
        					popup_info += "</div";
        				
						feature.lonlat = new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y);
        					feature.popupHover = new OpenLayers.Popup.AnchoredBubble("SDVegetationInfo",
                                        feature.lonlat,
                                        new OpenLayers.Size(20,5),
                                        popup_info,
                                        {size: new OpenLayers.Size(16,16), offset: new OpenLayers.Pixel(-8,0)},
                                        false);

        					feature.popupHover.setBackgroundColor("#EEEDFF");
	      				feature.popupHover.autoSize = true;
        					map.addPopup(feature.popupHover);

        		      		if (!feature.handlerClick)
        		      		{
        		      			feature.handlerClick = new OpenLayers.Handler.Click
        		      			(
                        				this,
                        				{click: function(e)
                        					{
                        						if (this.openFeature && this.openFeature.popup)
                        						{
                        							this.openFeature.popup.destroy();
                        							this.openFeature.popup = null;
                        						}
                        					
                        						this.openFeature = this.currentFeature;
                        						showFeatureInfo(this.currentFeature);
                        					}
                        				},
                        				{single: true, stopSingle: true}
                    			);                    		
                    		}
                    	
                    		this.currentFeature = feature;
                    		feature.handlerClick.activate();
        				},        			        			
        			
        				onUnselect: function (feature) 
        				{
        					feature.popupHover.destroy();
        					feature.popupHover = null;
        					feature.handlerClick.deactivate();
        				},
        			
        				hover: true        		        			        			
        			}));
        		
        			sf.activate();        			        			        			                	
        			
        			oResponse.argument.obj.isLoadedDataLayers = true;
        			oResponse.argument.obj.redraw();
      		},
                
            
       		failure: function(oResponse) 
       		{         	       			
        		},

        		argument: 
        		{
        			style: styleMap,
        			obj: this
        		},
                            
        		timeout: 15000
		};
		
    		YAHOO.util.Connect.asyncRequest('GET', "/wms/scripts/datalayers.php", callback);    	
	},
	
	clearLayersArray: function(layersType) 
	{
        var layers = this[layersType + "Layers"];
        if (layers) {
            for(var i=0, len=layers.length; i<len ; i++) {
                var layer = layers[i];
                OpenLayers.Event.stopObservingElement(layer.inputElem);
                OpenLayers.Event.stopObservingElement(layer.labelSpan);
            }
        }
        
        if (layersType == "data" && this.layersTree)
        	this.layersTree.removeChildren(this.layersTree.getRoot());	
        else
        	this[layersType + "LayersDiv"].innerHTML = "";
        	
        this[layersType + "Layers"] = [];
    },


	initialize: function(options) 
	{
     	OpenLayers.Control.LayerSwitcher.prototype.initialize.apply(this, arguments);
     	
     	this.expandedCategory = {};     	     	     	
    	},
    	
    	drawTree: function()
    	{
    		this.layersTreeDiv 		= document.createElement("div");
        	this.layersTreeDiv.id 	= this.id + "_layersTree";
        	OpenLayers.Element.addClass(this.layersTreeDiv, "ygtv-checkbox layersTree");        	
        	this.dataLayersDiv.appendChild(this.layersTreeDiv);
        	
        	this.layersTree = new YAHOO.widget.TreeView(this.layersTreeDiv.id);  
        		
        	this.layersTree.subscribe("highlightEvent", function(node)
        	{        		        		
        		if (node.children.length > 0)
        		{
        			for(var i = 0; i < node.children.length; i++)
        			{
        				var indexLayer = node.children[i].data.layer.map.getLayerIndex(node.children[i].data.layer);        		        				        				
        				node.children[i].data.switcher.layerStates[indexLayer].visibility = node.children[i].highlightState > 0;        				        				
        				node.children[i].data.layer.setVisibility(node.children[i].data.switcher.layerStates[indexLayer].visibility);
        			}
        		}
        		else
        		{        			
        			var indexLayer = node.data.layer.map.getLayerIndex(node.data.layer);        		
        			node.data.switcher.layerStates[indexLayer].visibility = node.highlightState > 0;
        			node.data.layer.setVisibility(node.data.switcher.layerStates[indexLayer].visibility);        	
        		}
        	});
        	
          //alert("layer count=" + this.layersTree.getNodeCount());

        	
		this.layersTree.draw(); 
		//this.layersTree.render();

    	},
    	
    	draw: function()
    	{    		
    		OpenLayers.Control.prototype.draw.apply(this);

        	// create layout divs
        	this.loadContents();

        	// set mode to minimize
        	if(!this.outsideViewport) {
         		this.minimizeControl();
        	}
        	
        	this.drawTree();

        	// populate div with current info
        	this.redraw();
        	
        	
        	
        	var defaultStyle = new OpenLayers.Style(
    	   	{
  			pointRadius: 10,
  			externalGraphic: '/wms/icon/znak-foto.png',  			
  			graphicZIndex: 91000,
  			graphicWidth: 10,
            graphicHeight: 10,
            graphicXOffset: -8,
            graphicYOffset: -8,
            fillOpacity: 1,
            cursor: "pointer",
            pointerEvents: "visiblePainted" 
		});

		
		var selectStyle = new OpenLayers.Style({
  			pointRadius: 20
		});

		var	styleMap = new OpenLayers.StyleMap({'default': defaultStyle,
                         'select': selectStyle});
        
		if (!this.isLoadedDataLayers)
			this.loadDataLayers(styleMap);                         
		this.isLoadedDataLayers = true;								        	
        	

        	return this.div;
    	},
    	
    	redraw: function() 
    	{     	        			
        	//if the state hasn't changed since last redraw, no need
        	// to do anything. Just return the existing div.
        	if (!this.checkRedraw())
            return this.div;
            
            
        	//clear out previous layers
        	this.clearLayersArray("base");
        	this.clearLayersArray("data");
        	
        	//this.drawTree();
        	this.layersTree.draw(); 
        	var layersCategory = {};
        	
        	var containsOverlays = false;
        	var containsBaseLayers = false;

        	// Save state -- for checking layer if the map state changed.
        	// We save this before redrawing, because in the process of redrawing
        	// we will trigger more visibility changes, and we want to not redraw
        	// and enter an infinite loop.
        	var len = this.map.layers.length;
        	this.layerStates = new Array(len);
        	for (var i=0; i <len; i++) 
        	{
            var layer = this.map.layers[i];
            this.layerStates[i] = {
                'name': layer.name,
                'visibility': layer.visibility,
                'inRange': layer.inRange,
                'id': layer.id
            };
        	}

        	var layers = this.map.layers.slice();
        	if (!this.ascending) { layers.reverse(); }
        	
        	for(var i=0, len=layers.length; i<len; i++) 
        	{
            var layer = layers[i];
            var baseLayer = layer.isBaseLayer;                        

            if (layer.displayInLayerSwitcher) 
            {
                if (baseLayer) {
                    containsBaseLayers = true;
                } else {
                    containsOverlays = true;
                }
                

                // only check a baselayer if it is *the* baselayer, check data
                //  layers if they are visible
                var checked = (baseLayer) ? (layer == this.map.baseLayer)
                                          : layer.getVisibility();
			   // create input element
                var inputElem = document.createElement("input");
                inputElem.id = this.id + "_input_" + layer.name;
                inputElem.name = (baseLayer) ? this.id + "_baseLayers" : layer.name;
                inputElem.type = (baseLayer) ? "radio" : "checkbox";
                inputElem.value = layer.name;
                inputElem.checked = checked;
                inputElem.defaultChecked = checked;

                if (!baseLayer && !layer.inRange) 
                {
                    inputElem.disabled = true;
                }
                
                var context = {
                    'inputElem': inputElem,
                    'layer': layer,
                    'layerSwitcher': this
                };
                OpenLayers.Event.observe(inputElem, "mouseup",
                    OpenLayers.Function.bindAsEventListener(this.onInputClick,
                                                            context)
                );
                
                // create span
                var labelSpan = document.createElement("span");
                OpenLayers.Element.addClass(labelSpan, "labelSpan")
                if (!baseLayer && !layer.inRange) {
                    labelSpan.style.color = "gray";
                }
                labelSpan.innerHTML = layer.name;
                labelSpan.style.verticalAlign = (baseLayer) ? "bottom"
                                                            : "baseline";
                OpenLayers.Event.observe(labelSpan, "click",
                    OpenLayers.Function.bindAsEventListener(this.onInputClick,
                                                            context)
                );
                // create line break
                var br = document.createElement("br");


                var groupArray = (baseLayer) ? this.baseLayers
                                             : this.dataLayers;
                groupArray.push({
                    'layer': layer,
                    'inputElem': inputElem,
                    'labelSpan': labelSpan
                });


                var groupDiv = (baseLayer) ? this.baseLayersDiv
                                           : this.dataLayersDiv;
                                           
			 if (baseLayer)                                           
			 {
                	groupDiv.appendChild(inputElem);
               	groupDiv.appendChild(labelSpan);
                	groupDiv.appendChild(br);
                }
                else
                {                	
                	var tmpNode;
                	if (layer.DataLayerCategory)
                	{
                		var cat 		= layersCategory[layer.DataLayerCategory];
                		var isExpanded = this.expandedCategory[layer.DataLayerCategory];
                		var layerNode;
                		                 		
                		if (!cat)
                		{
                			//if (isExpanded)
                			//alert("list=" + this.expandedCategory + " is_expand=" + isExpanded + " cat=" + layer.DataLayerCategory);                			
                				
                			cat = new YAHOO.widget.TextNode(layer.DataLayerCategory, this.layersTree.getRoot(), isExpanded); 
                			layersCategory[layer.DataLayerCategory] = cat;                	
                			cat.data = {layer: layer, switcher: this};
                		}
                	
                		layerNode 	= new YAHOO.widget.TextNode(layer.name, cat, false);                	
                	}
                	else
                		layerNode = new YAHOO.widget.TextNode(layer.name, this.layersTree.getRoot(), false);                	
                
                	layerNode.data	= {layer: layer, disabled: !layer.inRange, switcher: this};
                
                	if (layerNode.data.disabled)
                	{
              			layerNode.className = "disabledLayer";
              	 	}
                                
                	
                	if(checked)
                	{
                		layerNode.propagateHighlightUp = true;
                		layerNode.highlight();
                	}
                }
            }
        	}

		// if no overlays, dont display the overlay label
        	this.dataLbl.style.display = (containsOverlays) ? "" : "none";

        	// if no baselayers, dont display the baselayer label
        	this.baseLbl.style.display = (containsBaseLayers) ? "" : "none";

        	
        	this.layersTree.setNodesProperty('propagateHighlightUp',true);
		this.layersTree.setNodesProperty('propagateHighlightDown',true);
		//this.layersTree.subscribe('clickEvent', this.layersTree.onEventToggleHighlight);
		
		this.layersTree.subscribe('clickEvent', function(oArgs)
		{
			//alert(oArgs.node.data);			
			if (oArgs.node.data.disabled)
				return false;
				
			//this.layersTree.onEventToggleHighlight(oArgs);
			oArgs.node.toggleHighlight();
			
			return false;
		});		
		
		this.layersTree.subscribe('expandComplete', function(node)
		{
			var old = node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory];
			//if (!old)
			//	alert("try expanded=" + node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory]);
			
			node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory] = true;
			
			//if (old!=node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory])
			//	alert("expanded=" + node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory]);
			
			//alert(node.data.switcher.expandedCategory);
		});
		
		this.layersTree.subscribe('collapseComplete', function(node)
		{			
			if (!this.isClearTree)
			{
				//node.data.switcher.expandedCategory[node.data.layer.DataLayerCategory] = false;
				//alert("collapsed");
			}
		});
		
		this.layersTree.render();

                         
        	return this.div;

    	},
    
	CLASS_NAME: "OpenLayers.Control.MyLayerSwitcher"
});
