<?xml version="1.0" encoding="utf-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
				xmlns:s="library://ns.adobe.com/flex/spark"
				xmlns:mx="library://ns.adobe.com/flex/halo"
				doubleClickEnabled="true"
				doubleClick="itemrenderer1_doubleClickHandler(event)"
				autoDrawBackground="true"
				height="25">
	
	<fx:Metadata>
		[HostComponent("spark.components.List")]
	</fx:Metadata>
	
	<fx:Script>
	<![CDATA[
		import com.flexcapacitor.controller.Radiate;
		import com.flexcapacitor.model.DocumentData;
		import com.flexcapacitor.model.IDocument;
		
		import spark.components.List;
		import spark.components.supportClasses.ListBase;
		
		public var iDocument:IDocument;
		
		/**
		 * 
		 * */
		override public function set data(value:Object):void {
			super.data = value;
			
			iDocument = value ? IDocument(value) : null;
			
			if (iDocument && labelDisplay) {
				labelDisplay.text = iDocument.name;
			}
			
		}


		override public function setCurrentState(stateName:String, playTransition:Boolean=true):void {
			super.setCurrentState(stateName, playTransition);
		}
		
		protected function textInputChangeHandler():void {
			//this.data = textInput.text;
		    
		    //dispatch the data update event
		    var list:ListBase = this.owner as ListBase;
			
			if (data && iDocument) {
				var oldName:String = iDocument.name;
				var newName:String = textInput.text;
				Radiate.getInstance().renameDocument(iDocument, newName);
			    list.dataProvider.itemUpdated(iDocument, "name", oldName, newName); 
				currentState = "normal";
			}
		}
		
		protected function itemrenderer1_doubleClickHandler(event:MouseEvent):void {
			currentState = "edit";
			textInput.text = labelDisplay.text;
		}
		
		override protected function getCurrentRendererState():String {
			// if in edit state don't change unless 
			if (currentState=="edit") return "edit";
			
			return super.getCurrentRendererState();
		}
		
		protected function textInput_focusOutHandler(event:FocusEvent):void {
			textInputChangeHandler();
			currentState = "normal";
		}
		
		protected function openIcon_clickHandler(event:MouseEvent):void {
			Radiate.getInstance().openDocument(this.data as IDocument);
		}
		
	]]>
	</fx:Script>
	
	<s:states>
		<s:State name="normal" />
		<s:State name="hovered" />
		<s:State name="selected" />
		<s:State name="disabled" />
		<s:State name="edit" enterState="textInput.setFocus()"/>
	</s:states>
	
	<!--<s:Rect height="100%" width="100%">
		<s:fill>
			<s:SolidColor color="0xEEFFFF"
						  alpha="0" 
						  alpha.hovered="0.1" 
						  alpha.selected="0.4" />
		</s:fill>
	</s:Rect>-->
	
	<s:BitmapImage id="icon" 
				   source="{Radii8LibraryAssets.documentIcon}"
				   left="5"
				   top="5"
				   >
	</s:BitmapImage>
	
	
	<s:BitmapImage id="saveIcon" 
				   source="{Radii8LibraryAssets.save}"
				   right="5"
				   top="5" 
				   visible="{data &amp;&amp; (DocumentData(data).saveInProgress || DocumentData(data).openInProgress)}"
				   >
	</s:BitmapImage>
	
	<!--click event is not getting dispatched <s:Image id="openIcon" 
				   source="{Radii8LibraryAssets.openFolder}"
				   right="5"
				   top="5" 
				   visible="{data &amp;&amp; !(DocumentData(data).isOpen &amp;&amp; !DocumentData(data).openInProgress)}"
				   click="openIcon_clickHandler(event)"
				   >
	</s:Image>-->
	
	
	<s:Label id="labelDisplay" 
			 top="3"
			 left="18"
			 paddingLeft="4"
			 height="100%"
			 width="100%"
			 verticalAlign="middle"
			 itemCreationPolicy="immediate"
			 includeIn="hovered, normal, selected"/>
	
	<!--<s:Label id="isChangedLabel" 
			 top="3"
			 left="16"
			 text="*"
			 verticalAlign="middle"
			 itemCreationPolicy="immediate"
			 includeIn="hovered, normal, selected"
			 visible="{(data as DocumentData).isChanged}"/>-->
	
	<s:Label id="isChangedLabel2" 
			 bottom="0"
			 left="0"
			 text=" "
			 height="100%"
			 width="4"
			 backgroundColor="#989898"
			 backgroundAlpha="1"
			 visible="{data &amp;&amp; DocumentData(data).isChanged}"/>
	
	<s:TextInput id="textInput" 
				 left="18"
				 includeIn="edit" 
				 focusAlpha="0"
				 enter="textInputChangeHandler()" 
				 focusOut="textInput_focusOutHandler(event)"
				 width="100%" height="100%"/>
</s:ItemRenderer>
