<?xml version="1.0" encoding="utf-8"?>
<mx:HDividedBox width="100%" height="100%"
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	xmlns:components="components.*" initialize="{init()}">
	
	<mx:Script>
		<![CDATA[
			import mx.events.StateChangeEvent;
			import mx.events.FlexEvent;
			import mx.controls.listClasses.IListItemRenderer;
			import mx.events.DragEvent;
			import data.DataSource;
			import components.AuthorDataDescriptor;		
			import mx.collections.XMLListCollection;
			import mx.events.CollectionEventKind;
			import mx.events.CollectionEvent;	
			import mx.controls.Alert;
			import mx.binding.utils.BindingUtils;
			import mx.managers.DragManager;
			
			public var initExpandDepth:int = 4;
			
			[Bindable]
			public var treeDragEnabled:Boolean = true;
			
			[Bindable]
			public var treeDropEnabled:Boolean = true;
			
			private var openItems:XMLList = new XMLList();
			
			private function expandItem(item:XML, depth:int):void {
				if(item.children().length() > 0) {
					//tree.expandItem(item, true);
					openItems += item;
					if(depth > 0) {
						for each(var subItem:XML in item.children()) {
							expandItem(subItem, depth - 1);
						}
					}
				}
			}
			
			private function collectionListener(event:CollectionEvent) : void {
				if(event.kind == "add") {
					openItems = new XMLList();
					for each(var item:Object in event.items) {
						expandItem(XML(item), initExpandDepth);
					}
					tree.openItems = openItems;
				}
			}
			
			[Bindable]
			public function set currentTree(collection:XMLListCollection):void {
				if(_currentTree != null) {
					_currentTree.removeEventListener(CollectionEvent.COLLECTION_CHANGE, collectionListener);
				}
				_currentTree = collection;
				if(_currentTree != null) {
					_currentTree.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionListener);
				}
				
				openItems = new XMLList();
				for each(var item:XML in _currentTree) {
					callLater(expandItem, [item, initExpandDepth]);
				}
				callLater(function():void {
					tree.openItems = openItems;
				});
			}
			
			public function get currentTree():XMLListCollection {
				return _currentTree;
			}
			
			private var _currentTree:XMLListCollection;
			
			[Bindable]
			public var dataSource:DataSource;
			
			[Bindable]
            [Embed("assets/server.png")]
            private var serverIcon:Class;	
            
            [Bindable]
            [Embed("assets/server_delete.png")]
            private var serverDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/server_add.png")]
            private var serverNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/server_edit.png")]
            private var serverChangedIcon:Class;
            
            [Bindable]
            [Embed("assets/folder_delete.png")]
            private var contextDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/folder_add.png")]
            private var contextNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_edit.png")]
            private var contextChangedIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_table.png")]
            private var contextOpenBranchIcon:Class;	
            
            [Bindable]
            [Embed("assets/folder_picture.png")]
            private var mapOpenBranchIcon:Class;	
			
            [Bindable]
            [Embed("assets/picture.png")]
            private var mapIcon:Class;	
            
            [Bindable]
            [Embed("assets/picture_delete.png")]
            private var mapDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/picture_add.png")]
            private var mapNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/picture_edit.png")]
            private var mapChangedIcon:Class;
			
			[Bindable]
            [Embed("assets/folder_image.png")]
            private var layersOpenBranchIcon:Class;	
			
			[Bindable]
            [Embed("assets/map.png")]
            private var layerIcon:Class;	
            
            [Bindable]
            [Embed("assets/map_delete.png")]
            private var layerDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/map_add.png")]
            private var layerNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/map_edit.png")]
            private var layerChangedIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_magnify.png")]
            private var openQueryAspectsIcon:Class;	
            
            [Bindable]
            [Embed("assets/magnifier.png")]
            private var queryAspectIcon:Class;	
            
            [Bindable]
            [Embed("assets/magnifier_delete.png")]
            private var queryAspectDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/magnifier_add.png")]
            private var queryAspectNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/magnifier_edit.png")]
            private var queryAspectChangedIcon:Class;	
            
            [Bindable]
            [Embed("assets/folder_table.png")]
            private var openTemplatesIcon:Class;	
            
            [Bindable]
            [Embed("assets/layout.png")]
            private var templateIcon:Class;	
            
            [Bindable]
            [Embed("assets/layout_delete.png")]
            private var templateDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/layout_add.png")]
            private var templateNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/layout_edit.png")]
            private var templateChangedIcon:Class;	
            
            [Bindable]
            [Embed("assets/folder_table.png")]
            private var openReportsIcon:Class;	
            
            [Bindable]
            [Embed("assets/report.png")]
            private var reportIcon:Class;	
            
            [Bindable]
            [Embed("assets/report_delete.png")]
            private var reportDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/report_add.png")]
            private var reportNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/report_edit.png")]
            private var reportChangedIcon:Class;	
            
			[Bindable]
            [Embed("assets/folder.png")]
            private var closedBranchIcon:Class;
			
			[Bindable]
            [Embed("assets/folder_page_white.png")]
            private var openBranchIcon:Class;
			 
            [Bindable]
            [Embed("assets/folder_add.png")]
            private var newBranchIcon:Class;

            [Bindable]
            [Embed("assets/folder_delete.png")]
            private var deletedBranchIcon:Class;
			
			[Bindable]
            [Embed("assets/folder_edit.png")]
            private var changedBranchIcon:Class;
			
			[Bindable("propertiesChanged")]
			
			[Bindable]
            [Embed("assets/folder_delete.png")]
            private var configDeletedIcon:Class;			
            				
            [Bindable]
            [Embed("assets/folder_add.png")]
            private var configNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_edit.png")]
            private var configChangedIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_table.png")]
            private var configOpenBranchIcon:Class;	
			
			[Bindable]
            [Embed("assets/color_swatch.png")]
            private var colorsIcon:Class;	
			
			[Bindable]
            [Embed("assets/color_swatch_changed.png")]
            private var colorsChangedIcon:Class;	
			
            [Bindable]
            [Embed("assets/folder_wrench.png")]
            private var buttonBarsOpenBranchIcon:Class
            
            [Bindable]
            [Embed("assets/cog.png")]
            private var buttonBarIcon:Class;	
            
            [Bindable]
            [Embed("assets/cog_edit.png")]
            private var buttonBarChangedIcon:Class;	
            
             [Bindable]
            [Embed("assets/cog_delete.png")]
            private var buttonBarDeletedIcon:Class;	
            
            [Bindable]
            [Embed("assets/cog_add.png")]
            private var buttonBarNewIcon:Class;	
			
			[Bindable]
            [Embed("assets/folder_brick.png")]
            private var buttonsOpenBranchIcon:Class;	
            
			[Bindable]
            [Embed("assets/brick.png")]
            private var buttonIcon:Class;	
			
			[Bindable]
            [Embed("assets/brick_edit.png")]
            private var buttonChangedIcon:Class;	
           
           [Bindable]
            [Embed("assets/folder_table.png")]
            private var panesOpenBranchIcon:Class;	
            
            [Bindable]
            [Embed("assets/application_form.png")]
            private var paneIcon:Class;	
			
			[Bindable]
            [Embed("assets/application_form_edit.png")]
            private var paneChangedIcon:Class;	
            
			
			private function treeLabel(item:Object):String
			{
				var parentItem:XML = XML(item).parent();
				if(parentItem != null) {
					if(parentItem.localName() == "Panes") {
						return item.@title;
					}				
				}
				
				var type:String = item.localName();
				switch(type)
				{
					case "Context":
						return dataSource.getProps(XML(item)).Name;
					case "Map":		
					case "Layer":
					case "Template":
					case "QueryAspect":
					case "Report":
						//return dataSource.getProps(XML(item)).Name;
						return dataSource.getProps(XML(item)).Titles.Title.(Language == String(resourceManager.localeChain[0]).substr(0, 2)).Title						
					case "Server":
						return dataSource.getProps(XML(item)).Title;	
					case "Configs":
						return resourceManager.getString('language', 'Tree_Configs');	
					case "Geoide_Client_Config":
						return item.@name;	
					case "Colors":
						return 	resourceManager.getString('language', 'Tree_Colors');		
					case "ButtonBars":
						return 	resourceManager.getString('language', 'Tree_ButtonBars');	
					case "ButtonBar":
						 return item.Name;
					case "ActionButtons":
						return 	resourceManager.getString('language', 'Tree_ActionButtons');		 
					case "ActionButton":
						return item.Name;
					case "MapViewerButtons":
						return 	resourceManager.getString('language', 'Tree_MapViewerButtons');
					case "MapViewerButton":
						return item.Name;	
					case "PaneButtons":
						return 	resourceManager.getString('language', 'Tree_PaneButtons');
					case "PaneButton":
						return item.Name;	
					case "SinglePaneComponents":
						return 	resourceManager.getString('language', 'Tree_SinglePaneComponents');	
					case "SinglePaneComponent":
						return item.Name;
				}
				
				return type;
			}
			
			private function treeIcon(item:Object):Class
			{
				var itemStatus:String = item.@status;
				
				switch(item.localName()) {
					case "Layers":
						if(tree.isItemOpen(item)){
							return layersOpenBranchIcon;
						} else {
							return closedBranchIcon;
						}
					case "Maps":
						if(tree.isItemOpen(item)){
							return mapOpenBranchIcon;
						} else {
							return closedBranchIcon;
						}
					case "Map":
						if(itemStatus == "deleted")	{
					    	return mapDeletedIcon;	
					    } else {
					    	if (itemStatus == "changed"){
					    		return mapChangedIcon;	
					    	} else  
					    	if (itemStatus == "new"){
					    		return mapNewIcon
					    	}  	
					    	else {
					    		return mapIcon
					    	}
					    }
						
					case "Servers":
						if(tree.isItemOpen(item)){
							return openBranchIcon;
						} else {
							return closedBranchIcon;
						}
					case "Server":
					    if(itemStatus == "deleted")	{
					    	return serverDeletedIcon;	
					    } else {
					    	if (itemStatus == "changed"){
					    		return serverChangedIcon;	
					    	} else  
					    	if (itemStatus == "new"){
					    		return serverNewIcon
					    	}  	
					    	else {
					    		return serverIcon
					    	}
					    }
					case "Contexts":
						if(tree.isItemOpen(item)){
							return openBranchIcon;
						} else {
							return closedBranchIcon;
						}
					case "Context": 
						if(itemStatus == "deleted")	{
					    		return contextDeletedIcon;	
					    	} else {
					    		if (itemStatus == "changed"){
					    			return contextChangedIcon;	
					    		} else
					    		if (itemStatus == "new"){
					    			return contextNewIcon
					    		}  else {
					    			if(tree.isItemOpen(item)){
										return contextOpenBranchIcon;
									} else {
										return closedBranchIcon;
									}
					    		}	
					    	}	
					case "QueryAspects":
						if(tree.isItemOpen(item)){
							return openQueryAspectsIcon;
						} else {
							return closedBranchIcon;
						}
					case "QueryAspect":
						if(itemStatus == "deleted")	{
					    		return queryAspectDeletedIcon;	
					    	} else {
					    		if (itemStatus == "changed"){
					    			return queryAspectChangedIcon;	
					    		} else
					    		if (itemStatus == "new"){
					    			return queryAspectNewIcon
					    		}  else {
					    			return queryAspectIcon
					    		}	
					    	}
					case "Templates":
						if(tree.isItemOpen(item)){
							return openTemplatesIcon;
						} else {
							return closedBranchIcon;
						}
					case "Template":
						if(itemStatus == "deleted")	{
					    		return templateDeletedIcon;	
					    	} else {
					    		if (itemStatus == "changed"){
					    			return templateChangedIcon;	
					    		} else
					    		if (itemStatus == "new"){
					    			return templateNewIcon
					    		}  else {
					    			return templateIcon
					    		}	
					    	}    	
					    	
					case "Reports":
						if(tree.isItemOpen(item)){
							return openReportsIcon;
						} else {
							return closedBranchIcon;
						}
					case "Report":
						if(itemStatus == "deleted")	{
					    		return reportDeletedIcon;	
					    	} else {
					    		if (itemStatus == "changed"){
					    			return reportChangedIcon;	
					    		} else
					    		if (itemStatus == "new"){
					    			return reportNewIcon
					    		}  else {
					    			return reportIcon
					    		}	
					    	}    	    	
						
					case "Layer":
						if(itemStatus == "deleted")	{
							if(dataSource.getProps(XML(item)).Type == "Group"){
								return contextDeletedIcon;								
							} else {
					    		return layerDeletedIcon;
					  		}	
					    }
					
						if(tree.dataDescriptor.isBranch(item)){
							if(tree.isItemOpen(item)){
								return layersOpenBranchIcon;
							} else {
								return closedBranchIcon;
							}
						} else { 							
				    		if (itemStatus == "changed"){
				    			return layerChangedIcon;	
				    		} else
				    		if (itemStatus == "new"){
				    			return layerNewIcon
				    		}  else {
				    			return layerIcon
				    		}
						}		
					case "Configs":
						if(tree.isItemOpen(item)){
							return openBranchIcon;
						} else {
							return closedBranchIcon;
						}
					case "Geoide_Client_Config":
						if(itemStatus == "deleted")	{
					    		return configDeletedIcon;	
					    } else {
				    		if (itemStatus== "changed"){
				    			return configChangedIcon;	
				    		} else
				    		if (itemStatus == "new"){
				    			return configNewIcon
				    		}  else {
				    			if(tree.isItemOpen(item)){
									return configOpenBranchIcon;
								} else {
									return closedBranchIcon;
								}
				    		}	
					    }			
					 case "Colors":
						if(itemStatus == "changed"){	
				    		return colorsChangedIcon;	
				    	} else {
							return colorsIcon;
				    	}   
				     case "ButtonBars":
						if(itemStatus == "deleted")	{
					    		return configDeletedIcon;	
					    } else {
				    		if (itemStatus == "changed"){
				    			return configChangedIcon;	
				    		} else
				    		if (itemStatus == "new"){
				    			return configNewIcon
				    		}  else {
				    			if(tree.isItemOpen(item)){
									return buttonBarsOpenBranchIcon;
								} else {
									return closedBranchIcon;
								}
				    		}	
					    }
					case "ButtonBar":
						if(itemStatus == "changed"){
				    		return buttonBarChangedIcon;	
				    	} else {
							return buttonBarIcon;
				    	}   
				    case "ActionButtons":		
					case "MapViewerButtons":
					case "PaneButtons":
			    		if (itemStatus == "changed"){
				    			return configChangedIcon;	
				    	} else {
			    			if(tree.isItemOpen(item)){
								return buttonsOpenBranchIcon;
							} else {
								return closedBranchIcon;
							}
					    }
					case "ActionButton":
					case "MapViewerButton":
					case "PaneButton":
						if(itemStatus == "changed"){
				    		return buttonChangedIcon;	
				    	} else {
							return buttonIcon;
				    	} 
					case "SinglePaneComponents": 	
					case "MultiPaneComponents":  
						if (itemStatus == "changed"){
				    			return configChangedIcon;	
				    	} else {
			    			if(tree.isItemOpen(item)){
								return panesOpenBranchIcon;
							} else {
								return closedBranchIcon;
							}
					    }
					case "SinglePaneComponent": 	
					case "MultiPaneComponent":
						  if(itemStatus == "changed"){
				    		 return paneChangedIcon;	
				    	 } else {
							return paneIcon;
				    	} 
					    
				}	
				
				return layerIcon;
			}
			
			private function getSelectedItem(selectedItem:Object):Object
			{
				if(selectedItem.@status != 'deleted')
				{
					return selectedItem;
				}
				else
				{
					return null;
				}
			}

			private function treeInit():void
			{   
	            tree.addEventListener(DragEvent.DRAG_ENTER,
	            	treeDragEnter);
	            tree.addEventListener(DragEvent.DRAG_OVER,
	            	treeDragOver);	            	
	            tree.addEventListener(DragEvent.DRAG_COMPLETE,
	            	treeDragComplete);
	            tree.addEventListener(DragEvent.DRAG_DROP,
	            	treeDragDrop);
			}
			
			private function treeDragComplete(event:DragEvent):void {												
				/*var parent:Object = event.target.getDropParent();
				if(parent != null) {				
					this.callLater(dataSource.updateEntity, [XML(parent)]);
				}*/
				dataSource.treeToProps(XML(currentTree.getItemAt(0)), true);
				tree.hideDropFeedback(event);												
			}
			
			private function treeDragDrop(event:DragEvent):void {
				/*var item:XML = XML(event.dragSource.dataForFormat("treeItems")[0]);
				this.callLater(dataSource.updateEntity, [item.parent(), true]);*/
			}
			
			private function treeDragEnter(event:DragEvent):void {				
				event.preventDefault();
				
				if(event.dragInitiator != event.target) {			
					return;
				}
				
				var item:XML = XML(event.dragSource.dataForFormat("treeItems")[0]);
				switch(item.localName()) {
					case "Layers":
					case "Maps":
					case "Servers":
					case "Contexts":
					case "Templates":
					case "QueryAspects":
					case "Reports":
						tree.hideDropFeedback(event);	
						return;	
				}
				
				/*if(!dataSource.isOwner(item)) {
					tree.hideDropFeedback(event);	
					return;
				}*/
				
				tree.showDropFeedback(event);
				DragManager.acceptDragDrop(tree);
			}
			
			private function treeDragOver(event:DragEvent):void {				
				event.preventDefault();
				tree.hideDropFeedback(event);
				
				var index:Number = tree.calculateDropIndex(event);
				
				if(index == 0) {					
					DragManager.showFeedback(DragManager.NONE);
					return;
				}
				
				var itemRenderer:IListItemRenderer = tree.indexToItemRenderer(index);
				if(itemRenderer == null) {
					itemRenderer = tree.indexToItemRenderer(index - 1)					 
					
					if(itemRenderer == null) {
						DragManager.showFeedback(DragManager.NONE);
						return;
					}
				}
				
				var dropItem:Object = itemRenderer.data;
				var item:XML = event.dragSource.dataForFormat("treeItems")[0];
				var itemName:String = item.localName();				
				var parent:XML = XML(tree.getDropParent());				
			
				if(parent == null || parent.localName() == null || (parent.localName() == "Layer" && !dataSource.isOwner(parent))) {					
					DragManager.showFeedback(DragManager.NONE);
					return;
				}
												
				var parentName:String = parent.localName().toString();
				
				if(itemName == "Layer") {
					if(parentName != "Layers" && !(parentName == "Layer" && dataSource.isGroupLayer(parent))) {						
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					} else {
						var currentParent:XML = parent;
						while(currentParent.localName() != "Layers") {
							currentParent = currentParent.parent();
						}
						var itemParent:XML = item.parent();
						while(itemParent.localName() != "Layers") {
							itemParent = itemParent.parent();
						}
						var layers:XMLList = currentParent..Layer.(@id == item.@id);
						/*if(itemParent != currentParent && layers.length() > 0
							|| itemParent.parent().parent() != currentParent.parent().parent() 
								&& itemParent.parent().@id == currentParent.parent().@id) {
							DragManager.showFeedback(DragManager.NONE);
							tree.hideDropFeedback(event);
							return;
						}*/
						
						// TODO: only public sublayers in public group layers
						/*if(dataSource.getProps(item).Scope == "private") {
							currentParent = parent;
							if(currentParent.localName() == "Layers") {
								currentParent = currentParent.parent();
							if(dataSource.getProps(currentParent)[0].Scope == "public") {
								DragManager.showFeedback(DragManager.NONE);
								tree.hideDropFeedback(event);
								return;
							} 
						}
						}*/
					}					
				} else if(itemName == "Map") {					
					if(parentName != "Maps") {
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					} 
				} else if(itemName == "Context") {
					if(parentName != "Contexts") {
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					}
				} else if(itemName == "QueryAspect") {
					if(parentName != "QueryAspects" || parent.QueryAspect.(@id == item.@id).length() > 0) {
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					}
				} else if(itemName == "Template") {
					if(parentName != "Templates" || parent.Template.(@id == item.@id).length() > 0) {
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					}
				} else if(itemName == "Report") {
					if(parentName != "Reports" || parent.Template.(@id == item.@id).length() > 0) {
						DragManager.showFeedback(DragManager.NONE);
						tree.hideDropFeedback(event);
						return;
					}
				}
								
				tree.showDropFeedback(event);
				DragManager.showFeedback(DragManager.MOVE);
			}
			
			private function init():void {
				navigator.addEventListener(FlexEvent.INVALID,
	            	function():void {
	            		tree.selectable = false;
	            	});
	            	
	            navigator.addEventListener(FlexEvent.VALID,
	            	function():void {
	            		tree.selectable = true;
	            	});
			}
		]]>		
	</mx:Script>

	<mx:VBox height="100%" minWidth="200">
		<components:ExtendedTree id="tree" width="100%" height="100%"
			dataProvider="{currentTree}"
			labelFunction="{treeLabel}"
			iconFunction="{treeIcon}"
			showRoot="true"
			dragEnabled="{treeDragEnabled}"
            dragMoveEnabled="{treeDropEnabled}"                        
            dropEnabled="true"            
            dataDescriptor="{new AuthorDataDescriptor(dataSource)}"
            initialize="treeInit()"/>        
		<components:ButtonBar id="buttonBar" item="{getSelectedItem(tree.selectedItem)}" 
			width="100%" dataSource="{dataSource}"/>
	</mx:VBox>
	<components:PropsNavigator id="navigator" item="{XML(getSelectedItem(tree.selectedItem))}"
		width="100%" height="100%"		
		dataSource="{dataSource}"/>
</mx:HDividedBox>