<?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.

-->
<!---

	Creates a Regular Expression pattern that can be used in eclipse's Find in Files search dialog. 
	Usually this is all you need to find the exact element you're looking for.
	The document that the item is declared in can be used to narrow your search

	To Use: Set the target. When set it will show the document that it is in and pattern to find it. 
	Press the copy button and open Find in Files (ctrl + h). Paste the expression in the search 
	field and select RegExp match. Click Search. A list of matches will appear. If there are many 
	matches use the document info shown to narrow it down.  

-->
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx" 
		 xmlns:filters="com.flexcapacitor.filters.*" 
		 xmlns:controls="com.flexcapacitor.controls.*"
		 xmlns:inspectors="com.flexcapacitor.inspectors.*"

		 implements="com.flexcapacitor.views.Inspector" 
		 
		 creationComplete="group1_creationCompleteHandler(event)" xmlns:handlers="com.flexcapacitor.handlers.*" xmlns:clipboard="com.flexcapacitor.effects.clipboard.*" xmlns:status="com.flexcapacitor.effects.status.*" 
		 >
	
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	
	<fx:Script>
		<![CDATA[
			import com.flexcapacitor.controller.Radiate;
			import com.flexcapacitor.events.RadiateEvent;
			import com.flexcapacitor.utils.InspectorUtils;
			
			import mx.core.FlexSprite;
			import mx.core.UIComponent;
			import mx.events.FlexEvent;
			
			private var _target:DisplayObject;

			public var targetParentDocument:String;
			
			public function get target():* {
				return _target;
			}
			
			/**
			 * This is set automatically when a new target is selected
			 * This can be any type. You must disable this component if the 
			 * type is not what you can process.
			 * */
			[Bindable]
			public function set target(value:*):void {
				
				var classAndPackage:Array;
				
				// we only create patterns for MXML display objects at this time
				// would like to know how to check if the target was declared with an MXML tag
				if (!(value is DisplayObject)) {
					_target = null;
					enabled = false;
					return;
				}
				else {
					_target = DisplayObject(value);
					enabled = true;
				}
				
				searchPattern = InspectorUtils.getRegExpSearchPattern(DisplayObject(target));
				
				classAndPackage = target is UIComponent ? InspectorUtils.getClassNameAndPackage(UIComponent(target).parentDocument) : [];
				
				if (classAndPackage.length>0) {
					targetParentDocument = classAndPackage[0];
				}
				
				searchPatternText.text = searchPattern
				
			}
			
			/**
			 * Will be called by InspectorManager when window is closed
			 * */
			public function close():void {
				
			}
			
			/**
			 * Copies the search pattern to the clipboard
			 * Does not copy the parent document name
			 * */
			public function copy():void {
				if (searchPattern) {
					InspectorUtils.copyToClipboard(searchPattern);
				}
			}
			
			/**
			 * Copies the search pattern to the clipboard
			 * Does not copy the parent document name
			 * */
			public function copyDocument():void {
				if (searchPattern) {
					InspectorUtils.copyToClipboard(searchPattern);
				}
			}
			
			/**
			 * Regular Expression pattern that can be used in eclipse's Find in Files search dialog. 
			 * */
			[Bindable]
			public var searchPattern:String;
			
			public var radiate:Radiate = Radiate.instance;
			
			protected function group1_creationCompleteHandler(event:FlexEvent):void {
				radiate.addEventListener(RadiateEvent.TARGET_CHANGE, targetChangeEvent, false, 0, true);
				
				if (radiate.target) {
					target = radiate.target;
					
					updateTarget(target);
				}
			}
			
			protected function targetChangeEvent(event:RadiateEvent):void {
				target = event.selectedItem;
				
				updateTarget(target);
			}
			
			public function updateTarget(target:Object):void {
				// if null then clear the component
				if (!target) {
					searchPatternText.text = "";
				}
			}
			
		]]>
	</fx:Script>
	<fx:Declarations>
		<fx:Array id="selectFiltersOn">
			<filters:BlackAndWhiteFilter />
			<s:DropShadowFilter distance="1" blurX="3" blurY="3" strength=".8" inner="true" knockout="false"/>
		</fx:Array>
		<fx:Array id="selectFiltersOff">
			<filters:BlackAndWhiteFilter  />
		</fx:Array>
		
		
		<!-- COPY TO THE CLIPBOARD -->
		<handlers:EventHandler eventName="click" target="{copyIcon}" setTriggerEvent="true">
			
			<clipboard:CopyToClipboard data="{searchPattern}" targetAncestor="{this}" allowNullData="true">
				<clipboard:successEffect>
					<status:ShowStatusMessage message="Search pattern copied to the clipboard"/>
				</clipboard:successEffect>
				<clipboard:noDataEffect>
					<status:ShowStatusMessage message="Nothing to copy to the clipboard"/>
				</clipboard:noDataEffect>
				<clipboard:errorEffect>
					<status:ShowStatusMessage message="An error occurred while attempting to copy to the clipboard"/>
				</clipboard:errorEffect>
			</clipboard:CopyToClipboard>
			
		</handlers:EventHandler>
	</fx:Declarations>
	
	
	<s:states>
		<s:State name="document"/>
		<s:State name="package"/>
	</s:states>

	
	<s:HGroup width="100%" 
			  verticalAlign="middle" 
			  paddingRight="4" 
			  paddingLeft="4">
		
		<s:TextArea id="searchPatternText" 
					alpha=".8" 
					editable="false"
					heightInLines="2"
					borderVisible="false"
					width="100%" 
					verticalScrollPolicy="off"
					verticalAlign="middle"/>
		
		<!--<s:Spacer width="100%"/>-->
		
		<controls:ImageButton id="copyIcon" 
							  source="{Radii8LibraryAssets.copy}" 
							  filters="{selectFiltersOff}"
							  toolTip="Copy the search pattern to the Clipboard"/>
		
	</s:HGroup>
	
	<!--<s:Group width="100%">
		<inspectors:Description target="{target}" x="0" y="5" width="100%" currentState="document"
								includedItems="{['document','package']}"/>
	</s:Group>-->
</s:Group>
