package com.xt.hb.ui
{
	import com.xt.hb.utils.GisUtils;
	import com.xt.hb.utils.GlobalData;
	
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	
	import mx.collections.ICollectionView;
	import mx.collections.IList;
	import mx.controls.Tree;
	import mx.controls.treeClasses.ITreeDataDescriptor;
	import mx.controls.treeClasses.TreeItemRenderer;
	import mx.controls.treeClasses.TreeListData;
	import mx.events.FlexEvent;
	
	import spark.components.Image;
	
	
	/** 
	 * Alpha value for the Tree lines. 
	 * @default 1 
	 */ 
	[Style(name="lineAlpha", type="Number", format="Length", inherit="no")] 
	
	/** 
	 * Color of the Tree lines. 
	 * @default 0x808080 
	 */ 
	[Style(name="lineColor", type="uint", format="Color", inherit="no")] 
	
	/** 
	 * Thickness value for the Tree lines. 
	 * @default 1 
	 */ 
	[Style(name="lineThickness", type="Number", format="Length", inherit="no")] 
	
	/** 
	 * The Tree line style - none, dotted (default), or solid. 
	 * @default "dotted" 
	 */ 
	[Style(name="lineStyle", type="String", enumeration="solid", inherit="no")] 
	
	/** 
	 * Extends TreeItemRenderer to draw the dotted lines of the tree. 
	 * It supports 3 line styles - dotted (default), solid, or none. 
	 * And the tree line color, alpha, and thickness values are configurable styles too. 
	 * 
	 * <pre> 
	 * <ui:TreeItemLinesRenderer 
	 * <b>Styles</b> 
	 * lineAlpha="1" 
	 * lineColor="#808080" 
	 * lineThickness="1" 
	 * lineStyle="dotted" 
	 * > 
	 * ... 
	 * <i>child tags</i> 
	 * ... 
	 * </ui:TreeItemLinesRenderer> 
	 * </pre> 
	 * 
	 * @author Chris Callendar 
	 * @date April 20th, 2009 
	 */ 
	public class TreeItemIconRenderer extends TreeItemRenderer 
	{ 
		
		public static const DOTTED:String = "dotted"; // default 
		public static const SOLID:String = "solid"; 
		public static const NONE:String = "none"; 
		
		
		public function TreeItemIconRenderer() { 
			super(); 
			this.addEventListener(FlexEvent.SHOW,refreshNode);
		} 
		
		protected var img:spark.components.Image;
		
		/**
		 * 构建CheckBox
		 */  
		override protected function createChildren():void
		{
			super.createChildren();
			img = new spark.components.Image();
//			img.source = "flexResources/map/sxt.png";
//			img.width=18;
//			img.height=22;
			addChild( img );
		}
		
		/**
		 * 点击checkbox时,更新dataProvider
		 * @param event
		 */
		protected function changeHandler(item:Object):void
		{
			var id:String = item.id;
			var url:String = GlobalData.spjkUrl + id;
			navigateToURL(new URLRequest(url),"_blank");
		}
		
		/**
		 * 重置itemRenderer的宽度
		 */  
		override protected function measure():void
		{
			super.measure();
			measuredWidth += img.getExplicitOrMeasuredWidth();
		} 
		//显示刷新
		private function refreshNode(e:Event):void{
			var tree:Tree = (owner as Tree); 
			if(tree){
				tree.invalidateList();
			}
		}
		override public function set data(value:Object):void { 
			super.data = value; 
		} 
		
		override protected function updateDisplayList(w:Number, h:Number):void { 
			super.updateDisplayList(w, h); 
			var startx:Number = data ? TreeListData( listData ).indent : 0;
			if ((w > 0) && (h > 0)) { 
				// go up the hierarchy, drawing the vertical dotted lines for each node 
				var tree:Tree = (owner as Tree); 
				var desc:ITreeDataDescriptor = tree.dataDescriptor; 
				var currentNode:Object = data; 
				var parentNode:Object = tree.getParentItem(currentNode); 
				// the level is zero at this node, then increases as we go up the tree 
				var levelsUp:int = 0; 
				
				var lineStyle:String = getStyle("solid"); 
				var lineColor:uint = getColorStyle("lineColor", 0x808080); 
				var lineAlpha:Number = getNumberStyle("lineAlpha", 1); 
				var lineThickness:Number = getNumberStyle("lineThickness", 1); 
				var indentation:Number = tree.getStyle("indentation"); 
				
				// move the icon and label over to make room for the lines (less for root nodes) 
				var shift:int = (parentNode == null ? 2 : 6) + lineThickness; 
				if (icon) { 
					icon.move(icon.x + shift, icon.y); 
				}
				if(data.attr == "1") {
					img.width=18;
					img.height=22;
					if(data.online == "1") {
						img.buttonMode = true;
						img.source = "flexResources/map/sxt.png";
						if(!img.hasEventListener(MouseEvent.CLICK)) {
							img.addEventListener(MouseEvent.CLICK, function():void{
								changeHandler(data);
							});
						}
					} else {
						img.buttonMode = false;
						img.source = "flexResources/map/sxt_gray.png";
					}
				} else {
					img.width=0;
					img.height=0;
				}
				img.move(startx + img.width, ( unscaledHeight - img.height ) / 2 );
				if (label) { 
					label.move(label.x + shift + img.width, label.y); 
				} 
				
				var g:Graphics = graphics; 
				g.clear(); 
				
				if ((lineStyle != NONE) && (lineAlpha > 0) && (lineThickness > 0)) { 
					while (parentNode != null) { 
						var children:ICollectionView = desc.getChildren(parentNode); 
						if (children is IList) { 
							var itemIndex:int = (children as IList).getItemIndex(currentNode); 
							// if this node is the last child of the parent 
							var isLast:Boolean = (itemIndex == (children.length - 1)); 
							drawLines(g, w, h, lineStyle, lineColor, lineAlpha, lineThickness, isLast, levelsUp, indentation); 
							
							// go up to the parent, increasing the level 
							levelsUp++; 
							currentNode = parentNode; 
							parentNode = tree.getParentItem(parentNode); 
						} else { 
							break; 
						} 
					} 
				} 
			} 
		} 
		
		protected function drawLines(g:Graphics, w:Number, h:Number, lineStyle:String, lineColor:uint, 
									 lineAlpha:Number, lineThickness:Number, isLastItem:Boolean, levelsUp:int, indentation:Number):void { 
			var midY:Number = Math.round(h / 2); 
			var lineX:Number = 0; 
			if (disclosureIcon) { 
				lineX = disclosureIcon.x + (disclosureIcon.width / 2); 
			} else if (icon) { 
				lineX = icon.x - 8; 
			} else if (label) { 
				lineX = label.x - 8; 
			} 
			lineX = Math.floor(lineX) - int(lineThickness / 2); 
			// adjust the x position based on the indentation 
			if (levelsUp > 0) { 
				if (!isNaN(indentation) && (indentation > 0)) { 
					lineX = lineX - (levelsUp * indentation); 
				} else { 
					// Invalid indentation style value 
					return; 
				} 
			} 
			var lineY:Number = h; 
			// stop the dotted line halfway on the last item 
			if (isLastItem) { 
				lineY = midY; 
				// no lines need to be drawn for parents of the last item 
				if (levelsUp > 0) { 
					return; 
				} 
			} 
			
			g.lineStyle(0, 0, 0); 
			if (lineStyle == SOLID) { 
				g.beginFill(lineColor, lineAlpha); 
			} else { 
				var verticalDottedLine:BitmapData = createDottedLine(lineColor, lineAlpha, lineThickness, true); 
				g.beginBitmapFill(verticalDottedLine); 
			} 
			
			// draw the vertical line 
			g.drawRect(lineX, 0, lineThickness, lineY); 
			// end the fill and start it again otherwise the lines overlap and it create white squares 
			g.endFill(); 
			
			// draw the horizontal line - only needed on this node (not on any parents) 
			if (levelsUp == 0) { 
				var startX:int = lineX + 1 + int(lineThickness / 2); 
				var endX:int = startX + 11; // 5 dots 
				if (isLastItem) { 
					startX = lineX; 
				} 
				var startY:Number = midY - int(lineThickness / 2); 
				if (lineStyle == SOLID) { 
					g.beginFill(lineColor, lineAlpha); 
				} else { 
					var horizontalDottedLine:BitmapData = createDottedLine(lineColor, lineAlpha, lineThickness, false); 
					g.beginBitmapFill(horizontalDottedLine); 
				} 
				g.drawRect(startX, startY, endX - startX, lineThickness); 
				g.endFill(); 
			} 
			
		} 
		
		/** 
		 * Creates a BitmapData that is used to renderer a dotted line. 
		 * If the vertical parameter is true, then it creates a rectangle bitmap that is 
		 * twice as long as it is wide (lineThickness). Otherwise it creates a rectangle 
		 * that is twice as wide as it is long. 
		 * The first half of the rectangle is filled with the line color (and alpha value), 
		 * then second half is transparent. 
		 */ 
		private function createDottedLine(lineColor:uint, lineAlpha:Number, lineThickness:Number, 
										  vertical:Boolean = true):BitmapData { 
			var w:Number = (vertical ? lineThickness : 2 * lineThickness); 
			var h:Number = (vertical ? 2 * lineThickness : lineThickness); 
			var color32:uint = combineColorAndAlpha(lineColor, lineAlpha); 
			var dottedLine:BitmapData = new BitmapData(w, h, true, 0x00ffffff); 
			// create a dotted bitmap 
			for (var i:int = 0; i < lineThickness; i++) { 
				for (var j:int = 0; j < lineThickness; j++) { 
					dottedLine.setPixel32(i, j, color32); 
				} 
			} 
			return dottedLine; 
		} 
		
		/** 
		 * Combines the color value and the alpha value into a 32 bit uint like #AARRGGBB. 
		 */ 
		private function combineColorAndAlpha(color:uint, alpha:Number):uint { 
			// make sure the alpha is a valid number [0-1] 
			if (isNaN(alpha)) { 
				alpha = 1; 
			} else { 
				alpha = Math.max(0, Math.min(1, alpha)); 
			} 
			
			// convert the [0-1] alpha value into [0-255] 
			var alphaColor:Number = alpha * 255; 
			// bitshift it to come before the color 
			alphaColor = alphaColor << 24; 
			// combine the two values: #AARRGGBB 
			var combined:uint = alphaColor | color; 
			return combined; 
		} 
		
		private function getColorStyle(propName:String, defaultValue:uint):uint { 
			var color:uint = defaultValue; 
			if (propName != null) { 
				var n:Number = getStyle(propName); 
				if (!isNaN(n)) { 
					color = uint(n); 
				} 
			} 
			return color; 
		} 
		
		
		private function getNumberStyle(propName:String, defaultValue:Number):Number { 
			var number:Number = defaultValue; 
			if (propName != null) { 
				var n:Number = getStyle(propName); 
				if (!isNaN(n)) { 
					number = n; 
				} 
			} 
			return number; 
		} 
		
	} 
	
	
	
}