<?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: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:components="com.flexcapacitor.components.*"
		 xmlns:c="com.flexcapacitor.controls.*"
		 xmlns:local="*"
		 
		 width="400" height="300"
		 show="group1_showHandler(event)"
		 creationComplete="creationComplete()"
		 implements="com.flexcapacitor.components.IDocumentContainer" 
		 >

	<!-- 
		WE SHOULD REFACTOR THIS
		
		Sometimes the generated MXML document is blank. I think it's because if we open
	multiple documents the application never gets completely loaded or rendered in it's tab and the
	user closes the document and reopens it. I think it has to do with the activate event in Flex
	So we need to wait before opening new documents until application complete on the current document.
	We might need to add an event listener in the Document or Project class to make sure each application
	completely loads before opening the next. 
	-->
	
	<fx:Script>
		<![CDATA[
			import com.flexcapacitor.controller.Radiate;
			import com.flexcapacitor.events.RadiateEvent;
			import com.flexcapacitor.model.IDocument;
			import com.flexcapacitor.utils.supportClasses.ComponentDescription;
			
			import mx.core.IVisualElement;
			import mx.core.IVisualElementContainer;
			import mx.events.FlexEvent;
			import mx.events.ResizeEvent;
			import mx.managers.SystemManager;
			import mx.utils.NameUtil;
			
			import spark.components.Application;
			
			import org.as3commons.lang.ArrayUtils;
			
			
			
			/**
			 * STEP 1. 
			 * 
			 * When this is added to the display list then we
			 * load in a blank application.
			 * 
			 * We do this so that at some point we can sandbox 
			 * the application.
			 * We also do this so we can load in remote applications.
			 * */
			private function creationComplete():void {
				radiate = Radiate.getInstance();
				toolLayer = toolLayerInstance;
				canvasBorder = canvasBorderInstance;
				canvasBackground = canvasBackgroundInstance;
				canvasScroller = canvasScrollerInstance;
				//radiate.setCanvas(canvasBorder, canvasBackground, canvasScroller);				
				
				
				
				systemManager.allowDomain("*");
				
				var context:LoaderContext = new LoaderContext();
				
				/* Specify the current application's security domain. */
				context.securityDomain = SecurityDomain.currentDomain;
				
				/* Specify a new ApplicationDomain, which loads the sub-app into a 
				peer ApplicationDomain. */
				context.applicationDomain = new ApplicationDomain();
				
				projectLoader.trustContent = trustContent;
				projectLoader.loadForCompatibility = loadForCompatibility;
				projectLoader.maintainAspectRatio = maintainAspectRatio;
				projectLoader.scaleContent = scaleContent;
				
				// if not on server context throws errors
				if (Security.sandboxType == Security.REMOTE) {
					//projectLoader.loaderContext = context;
					projectLoader.trustContent = !trustContent;
				}
				
				projectLoader.source = url;//URL.text; // "http://yourdomain.com/SubApp3.swf";
				
				//projectLoader.autoLoad = autoLoad;
				//load();
				
				//stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			}
			
			/**
			 * STEP 2. 
			 * 
			 * SWF is Loaded now listen for Application Complete
			 * */
			protected function project_completeHandler(event:Event):void {
				//var loader:SWFLoader = event.currentTarget as SWFLoader;
				/*
				SecurityDomain 'http://www.radii8.com/demo2/RadiateExample.html?debug=true' 
				tried to access incompatible context 'http://www.flexcapacitor.com/apps/aboutyou/AboutYou.swf'
				SecurityError: Error #2121: Security sandbox violation: Loader.content: 
				http://www.radii8.com/demo2/RadiateExample.swf/[[DYNAMIC]]/3 cannot access 
				http://www.flexcapacitor.com/apps/urlcodec/URLCodec.swf. This may be worked around by 
				calling Security.allowDomain.

				*/
				projectLoader.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
				
				var loaderClassName:String = NameUtil.getUnqualifiedClassName(projectLoader.content);
				
				
				if (projectLoader.content is DisplayObject) {
					//parentAllowsChild.selected = b.parentAllowsChild;
					//childAllowsParent.selected = b.childAllowsParent;
					targetSystemManager = projectLoader.content as SystemManager;
					
					targetSystemManager.addEventListener(FlexEvent.APPLICATION_COMPLETE, applicationComplete);
					//LoaderInfo(targetApplication.loaderInfo).uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
				}
				
				hideBusyIndicators();
				
				
				//Radiate.log.info("SWF Loaded");
			}
			
			/**
			 * STEP 3.
			 * 
			 * Blank application loaded. Import the document. 
			 * */
			protected function applicationComplete(event:Event):void {
				var loader:Object = event.currentTarget;
				var radiate:Radiate = Radiate.instance;
				//parentAllowsChild.selected = b.parentAllowsChild;
				//childAllowsParent.selected = b.childAllowsParent;
				
				
				targetSystemManager = loader as SystemManager;
				targetApplication = loader.application;
				
				
				// 8.5 x 11 at 72dpi is 612x792
				targetApplication.width = Radiate.DEFAULT_DOCUMENT_WIDTH;
				targetApplication.height = Radiate.DEFAULT_DOCUMENT_HEIGHT;
				
				updateBackgroundSize();
				
				iDocument.instance = targetApplication;
				
				//radiate.setDocument(iDocument);
				//radiate.setTarget(targetApplication);
				
				//codeAvailable = true;
				//Radiate.log.info("Document container app complete");
				if (iDocument.source) {
					validateNow();
					iDocument.parseSource();
					iDocument.resetSaveStatus();
					updateBackgroundSize();
					//parseDocument(codeToLoad);
					//codeAvailable = false;
					
					// we should dispatch an event when parsing is complete
				}
				
				
				radiate.addEventListener(RadiateEvent.SCALE_CHANGE, scaleChange, false, 0, true);
				//radiate.addEventListener(RadiateEvent.DOCUMENT_SIZE_CHANGE, scaleChange, false, 0, true);
				radiate.addEventListener(RadiateEvent.PROPERTY_CHANGED, propertyChange, false, 0, true);
				
				radiate.setDocument(iDocument);
				radiate.setTarget(targetApplication);
				//updateAppScrollPosition();
				
				//setTimeout(updateAppScrollPosition, 10);
				//setTimeout(updateAppScrollPosition, 100);
				//setTimeout(updateAppScrollPosition, 500);
				
				hideBusyIndicators();
				
				applicationReady = true;
				
				radiate.centerApplication(true);
				
				//Radiate.log.info("Application Complete");
				
			}
			
			/**
			 * The document / application
			 * */
			public var targetApplication:Object;
			
			/*[Embed(source="assets/460/application.swf")]
			public var embeddedApplication:Class*/
			
			private var _url:String = "application.swf";
			
			public var autoLoad:Boolean = true;
			
			private var radiate:Radiate;
			
			/**
			 * Set to false. 
			 * */
			private var loadForCompatibility:Boolean;
			
			/**
			 * Maintains the aspect ratio
			 * */
			private var maintainAspectRatio:Boolean = true;
			
			/**
			 * Set to false to prevent application from scaling to fit (vs resizing)
			 * */
			private var scaleContent:Boolean;
			
			/**
			 * Set to false for loading local file? And true for loading remote swf.
			 * */
			private var trustContent:Boolean;
			
			/**
			 * System manager of the target application
			 * */
			private var targetSystemManager:SystemManager;
			
			/**
			 * Padding to add around the document if it is too large to 
			 * fit in the available space. 
			 * */
			public var documentPadding:int = 25;
			
			/**
			 * True when updating the document and background size
			 * */
			public var inUpdateBackgroundSize:Boolean = true;
			
			/**
			 * Application ready
			 * */
			public var applicationReady:Boolean;
			
			/**
			 * 
			 * */
			public var codeAvailable:Boolean;
			
			/**
			 * 
			 * */
			public var codeToLoad:String;
			
			
			private var _componentDescription:ComponentDescription;

			/**
			 * Root component description
			 * */
			public function get componentDescription():ComponentDescription {
				return _componentDescription;
			}

			/**
			 * @private
			 */
			[Bindable]
			public function set componentDescription(value:ComponentDescription):void {
				_componentDescription = value;
			}
			
			private var _documentDescription:IDocument;

			public function get iDocument():IDocument {
				return _documentDescription;
			}

			/**
			 * Reference to document description
			 * */
			[Bindable]
			public function set iDocument(value:IDocument):void {
				if (_documentDescription == value) return;
				_documentDescription = value;
				
				//load();
			}
			
			private var _toolLayer:IVisualElementContainer;

			public function get toolLayer():IVisualElementContainer {
				return _toolLayer;
			}

			/**
			 * Reference to the tool layer
			 * */
			[Bindable]
			public function set toolLayer(value:IVisualElementContainer):void {
				_toolLayer = value;
			}

			private var _canvasBorder:IVisualElementContainer;

			public function get canvasBorder():IVisualElementContainer {
				return _canvasBorder;
			}

			/**
			 * Canvas border
			 * */
			[Bindable]
			public function set canvasBorder(value:IVisualElementContainer):void {
				_canvasBorder = value;
			}

			private var _canvasBackground:IVisualElementContainer;

			/**
			 * Reference to the canvas background
			 * */
			public function get canvasBackground():IVisualElementContainer {
				return _canvasBackground;
			}

			public function set canvasBackground(value:IVisualElementContainer):void {
				_canvasBackground = value;
			}

			private var _canvasScroller:Scroller;

			public function get canvasScroller():Scroller {
				return _canvasScroller;
			}

			/**
			 * Canvas scroller
			 * */
			[Bindable]
			public function set canvasScroller(value:Scroller):void {
				_canvasScroller = value;
			}

			/**
			 * 
			 * */
			public function importDocument(code:String):Boolean {
				load();
				codeToLoad = code;
				codeAvailable = true;
				return true;
			}
			
			/**
			 * 
			 * */
			[Bindable]
			public function get url():String {
				return _url;
			}

			public function set url(value:String):void {
				_url = value;
				load();
			}

			
			
			/**
			 * Load blank Spark Application SWF
			 * */
			public function load():void {
				
				removeErrorMessages();
				
				showBusyIndicators();
				
				if (url) {
					try {
						//projectLoader.trustContent = trustContent;
						projectLoader.loaderContext = null;
						projectLoader.source = "";
						projectLoader.source = url;
						projectLoader.load();
					}
					catch (error:Error) {
						Radiate.log.error(error.message);
						hideBusyIndicators();
					}
				}
				else {
					hideBusyIndicators();
				}
			}
			
			/**
			 * Load URL
			 * */
			public function loadRemote(url:String, trustContent:Boolean = true, loadForCompatibility:Boolean = false):void {
				
				systemManager.allowDomain("*");
				showBusyIndicators();
				
				if (url) {
					try {
						// if not on server context throws errors
						//if (Security.sandboxType == Security.REMOTE) {
							//projectLoader.loaderContext = context;
						projectLoader.trustContent = trustContent;
						//}
							
						var context:LoaderContext = new LoaderContext();
							
						/* Specify the current application's security domain. */
						//context.securityDomain = SecurityDomain.currentDomain;
						//projectLoader.loaderContext = context;
						projectLoader.loadForCompatibility = loadForCompatibility;
						projectLoader.source = "";
						projectLoader.source = url;
						projectLoader.load();
					}
					catch (error:Error) {
						Radiate.log.error(error.message);
						hideBusyIndicators();
					}
				}
				else {
					hideBusyIndicators();
				}
			}
			
			protected function allowDomainHandler(event:MouseEvent):void {
				systemManager.allowDomain("*");
			}
			
			private function uncaughtErrorHandler(event:UncaughtErrorEvent):void {
				event.preventDefault();
				
				//to capture the error message
				var errorMessage:String = new String();
				
				if (event.error is Error) {
					errorMessage = Error( event.error ).message;
				}
				else if (event.error is ErrorEvent) {
					errorMessage = ErrorEvent( event.error ).text;
				}
				else {
					errorMessage = event.error.toString();
				}
				
				//Radiate.logTarget.logEvent(new LogEvent("Uncaught Error", LogEventLevel.ERROR));
				Radiate.log.error(errorMessage);
				//trace("Uncaught error", event);
				
				hideBusyIndicators();
			}
			
			/**
			 * 
			 * */
			protected function project_ioErrorHandler(event:IOErrorEvent):void {
				//trace("ioerror");
				Radiate.log.error(event.text);
				hideBusyIndicators();
			}
			
			/**
			 * 
			 * */
			protected function project_securityErrorHandler(event:SecurityErrorEvent):void
			{
				//trace("security error");
				Radiate.log.error(event.text);
				hideBusyIndicators();
			}
			
			/**
			 * 
			 * */
			protected function project_initHandler(event:Event):void
			{
				//trace("init");
			}
			
			/**
			 * 
			 * */
			protected function project_progressHandler(event:ProgressEvent):void
			{
				//trace("PROGRESS");
			}
			
			/**
			 * 
			 * */
			protected function project_unloadHandler(event:Event):void
			{
				//trace("unload");
				Radiate.log.info("SWF unloaded");
				hideBusyIndicators();
			}
			
			/**
			 * 
			 * */
			protected function project_openHandler(event:Event):void
			{
				//trace("open");
				showBusyIndicators();
			}
			
			/**
			 * 
			 * */
			protected function project_httpStatusHandler(event:HTTPStatusEvent):void {
				//trace("http status");				
			}
			
			/**
			 * Show busy indicatos
			 * */
			public function showBusyIndicators():void {
				//fadeOutBusy.end();
				//fadeInBusy.play();
				
				if (!loadingLabel || !toolLayer || !canvasBorder) return;
				loadingLabel.visible =  true;
				IVisualElement(toolLayer).visible = false;
				canvasBorderInstance.visible = false;
			}
			
			/**
			 * Hide busy indicators
			 * */
			public function hideBusyIndicators():void {
				
				if (!loadingLabel || !toolLayer || !canvasBorder) return;
				loadingLabel.visible =  false;
				toolLayerInstance.visible = true;
				canvasBorderInstance.visible = true;
			}
			
			/**
			 * Make sure we are showing the correct document
			 * */
			protected function group1_showHandler(event:FlexEvent):void {
				if (radiate.selectedDocument!=iDocument) {
					radiate.setDocument(radiate.selectedDocument, true);// maybe call update document here???
				}
				
				Radiate.log.info("Document SHOW event");
			}
			
			/**
			 * Reload blank app
			 * */
			public function reload():void {
				creationComplete();
			}
			
			/**
			 * 
			 * */
			private function removeErrorMessages():void {
				
				if (projectLoader && projectLoader.loaderInfo) {
					projectLoader.loaderInfo.uncaughtErrorEvents.removeEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
				}
				
				if (targetSystemManager) {
					//parentAllowsChild.selected = b.parentAllowsChild;
					//childAllowsParent.selected = b.childAllowsParent;
					
					targetSystemManager.removeEventListener(FlexEvent.APPLICATION_COMPLETE, applicationComplete);
				}
			}
			
			
			/**
			 * 
			 * */
			private function canvasBorder_resizeHandler(event:ResizeEvent):void {
				if (targetApplication) {
					updateBackgroundSize();
				}
			}
			
			/**
			 * Update the size of the target application
			 * */
			private function updateAppScrollPosition():void {
				
				if (targetApplication is DisplayObject) {
					radiate.centerApplication();
				}
			}
			
			/**
			 * Handles the clipping, scaling and sizing of the target application. 
			 * Could be moved to update display list???
			 * */
			public function updateBackgroundSize():void {
				//if (inUpdateBackgroundSize) return;
				inUpdateBackgroundSize = true;
				
				// size canvas background to be the minimum size of the scroller
				// or the size of the target application + 50
				var scaledDocumentWidth:int = targetApplication.width * targetApplication.scaleX;
				var scaledDocumentHeight:int = targetApplication.height * targetApplication.scaleY;
				/*var aspectRatio:String = scaledDocumentWidth/scaledDocumentHeight>1?"portrait":"landscape";
				if (aspectRatio!=canvasBorder.skin.currentState) {
					canvasBorder.skin.currentState = aspectRatio;
				}*/
				
				var scaledPaddedDocumentWidth:int = documentPadding + (targetApplication.width * targetApplication.scaleX);
				var scaledPaddedDocumentHeight:int = documentPadding + (targetApplication.height * targetApplication.scaleY);
				
				var scrollerWidth:int = canvasScroller.width;
				var scrollerHeight:int = canvasScroller.height;
				
				var scrollerPaddedWidth:int = canvasScroller.width + documentPadding;
				var scrollerPaddedHeight:int = canvasScroller.height + documentPadding;
				
				var visiblePaddedWidth:int = canvasScroller.width - documentPadding;
				var visiblePaddedHeight:int = canvasScroller.height - documentPadding;
				
				var minimumWidth:int;
				var minimumHeight:int;
				
				// if content width is more than available width plus padding then 
				// set minimum width to show scrollbars and add padding
				if (scaledPaddedDocumentWidth >= visiblePaddedWidth+10) {
					minimumWidth = Math.max(scrollerWidth, scaledPaddedDocumentWidth);
				}
				else {
					minimumWidth = scrollerWidth;
				}
				
				// if content height is more than available height plus padding then 
				// set minimum height to show scrollbars and add padding
				if (scaledPaddedDocumentHeight >=visiblePaddedHeight+10) {
					minimumHeight = Math.max(scrollerPaddedHeight, scaledPaddedDocumentHeight);
				}
				else {
					minimumHeight = scrollerHeight;
				}
				
				canvasBackgroundParent.percentWidth = 100;
				canvasBackgroundParent.percentHeight = 100;
				
				canvasBackgroundInstance.width = minimumWidth;//Math.max(canvasScroller.width, minimumWidth);
				canvasBackgroundInstance.height = minimumHeight;//Math.max(canvasScroller.height, minimumHeight);
				
				canvasBorderInstance.width = scaledDocumentWidth;
				canvasBorderInstance.height = scaledDocumentHeight;
				
				projectLoader.width = scaledDocumentWidth;
				projectLoader.height = scaledDocumentHeight;
				
				// we do this because when we scale the application the 
				// system manager mask is not updated and the content gets clipped
				targetSystemManager.setActualSize(scaledDocumentWidth, scaledDocumentHeight);
				
				validateNow();
				
				inUpdateBackgroundSize = false;
			}
			
			/**
			 * Update the position of the document
			 * */
			protected function scaleChange(event:RadiateEvent):void {
				
				//if (!inUpdateBackgroundSize) {
					updateBackgroundSize();
				//}
			}
			
			public var importantProperties:Array = ["width", "explicitWidth", "height", "explicitHeight","scaleX","scaleY"];
			
			/**
			 * Update the size of the document
			 * */
			protected function propertyChange(event:RadiateEvent):void {
				var sizeChange:Boolean;
				
				if (event.selectedItem is Application) {
					sizeChange = ArrayUtils.containsAny(event.properties, importantProperties);
					
					if (sizeChange) {
						updateBackgroundSize();
					}
				}
			}
			
			protected function canvasBackground_resizeHandler(event:ResizeEvent):void {
				
			}
			
			protected function canvasBackgroundParent_resizeHandler(event:ResizeEvent):void {
				
			}
			
			protected function projectLoader_resizeHandler(event:ResizeEvent):void {
				//Radiate.log.info("Project loader resize");
			}
			
			
			/**
			 * 
			 * */
			private function updateScrollBarPosition(center:Point=null):void {
				/*if (canvasBackground.contentHeight > canvasBackground.height) {
					//canvasBackground.verticalScrollPosition = int((canvasBackground.contentHeight-canvasBackground.height)/2)
				}
				else {
					//canvasBackground.verticalScrollPosition = 0;
				}*/
				/*if (borderContainer.contentHeight > borderContainer.height) {
					borderContainer.verticalScrollPosition = int((borderContainer.contentHeight-borderContainer.height)/2);
				}
				else {
						borderContainer.verticalScrollPosition = 0;
				}
				
				if (borderContainer.contentWidth > borderContainer.width) {
					borderContainer.horizontalScrollPosition = int((borderContainer.contentWidth-borderContainer.width)/2);
				}
				else {
					borderContainer.horizontalScrollPosition = 0;
				}*/
			}
			
			/**
			 * Not used but probably should be
			 * */
			override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
				super.updateDisplayList(unscaledWidth, unscaledHeight);
				
				return;
				
			}
			
			private var _showBorders:Boolean;

			/**
			 * 
			 * */
			public function get showBorders():Boolean {
				return _showBorders;
			}

			/**
			 * Show borders for debugging layout of application
			 * */
			public function set showBorders(value:Boolean):void {
				if (_showBorders == value) return;
				_showBorders = value;
				
				if (_showBorders) {
					canvasBackgroundParent.setStyle("backgroundColor", 0xF00000);
					canvasBackgroundInstance.setStyle("backgroundColor", 0xFF0000);
					canvasBorderInstance.setStyle("backgroundColor", 0xFFF000);
					toolLayerInstance.setStyle("backgroundColor", 0xFFFF00);
					canvasBackgroundParent.setStyle("backgroundAlpha", 1);
					canvasBackgroundInstance.setStyle("backgroundAlpha", 1);
					canvasBorderInstance.setStyle("backgroundAlpha", 1);
					toolLayerInstance.setStyle("backgroundAlpha", 1);
				}
				else {
					canvasBackgroundParent.setStyle("backgroundAlpha", 0);
					canvasBackgroundInstance.setStyle("backgroundAlpha", 0);
					canvasBorderInstance.setStyle("backgroundAlpha", 0);
					toolLayerInstance.setStyle("backgroundAlpha", 0);
				}
			}

			/**
			 * 
			 * */
			protected function scrollerCornerButton_clickHandler(event:MouseEvent):void {
				//showBorders = !showBorders;
				
				//if (!inUpdateBackgroundSize) { 
					radiate.centerApplication();
				//}
			}
			
			/**
			 * 
			 * */
			protected function scroller_resizeHandler(event:ResizeEvent):void {
				if (!targetApplication) return;
				
				//if (!inUpdateBackgroundSize) {
					updateBackgroundSize();
				//}
			}
			
			
			protected function canvasScrollerInstance_creationCompleteHandler(event:FlexEvent):void {
				var enableMouseSupport:Boolean = false;
				
				if (enableMouseSupport) {
       				canvasScrollerInstance.addEventListener(MouseEvent.MOUSE_WHEEL, list_mouseWheel, true);
				}
			}
			
			protected function list_mouseWheel(e:MouseEvent):void {
				e.preventDefault();
				e.stopImmediatePropagation();
				canvasScrollerInstance.viewport.verticalScrollPosition  -= e.delta * 5;
			}
			
			protected function drawGrid(sprite:Sprite):void {
                var x:int = 0;
                var y:int = 0;
                
                sprite.graphics.clear();
                
                // draw the background
                sprite.graphics.beginFill(0xFFFFFF);
                sprite.graphics.drawRect(0, 0, sprite.width, sprite.height);
                sprite.graphics.endFill();
                
                sprite.graphics.lineStyle(0.5, 0x000000, 0.2);
                
                // draw the vertical lines
                while (x <= sprite.width) {
                    sprite.graphics.moveTo(x, 0);
                    sprite.graphics.lineTo(x, sprite.height);
                    x = x + 20;
                }
                
                // draw the horizontal lines
                while (y <= sprite.height) {
                    sprite.graphics.moveTo(0, y);
                    sprite.graphics.lineTo(sprite.width, y);
                    y = y + 20;
                }
            }
		]]>
	</fx:Script>
	
	<fx:Declarations>
		<!--<s:Fade id="fadeInBusy" 
				alphaTo="1" 
				target="{busyIndicator}"
				effectStart="busyIndicator.visible=true"
				effectEnd="busyIndicator.visible=true"/>
		<s:Fade id="fadeOutBusy" 
				alphaTo="0" 
				target="{busyIndicator}" 
				effectStart="busyIndicator.visible=true"
				effectEnd="busyIndicator.visible=false"/>-->
		
		<fx:XML id="testModel" xmlns="">
			<mx:MXML >
				<s:Group x="15" y="50">
				<s:Button label="Hello World" x="20" y="20" color="#ff0000"/>
				</s:Group >
			</mx:MXML>
		</fx:XML>
	</fx:Declarations>
	
	
	
	<s:Rect id="backgroundRect" width="100%" height="100%">
		<s:fill>
			<s:SolidColor color="#666666"/>
		</s:fill>
	</s:Rect>
	
	<s:Rect width="20" height="20">
		<s:fill>
			<s:SolidColor color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
	
	
	<s:Scroller id="canvasScrollerInstance" 
				left="20" 
				right="0" 
				top="20" 
				bottom="0" 
				width="100%"
				height="100%"
				resize="scroller_resizeHandler(event)"
				interactionMode="mouse"
				creationComplete="canvasScrollerInstance_creationCompleteHandler(event)"
				>
		
		<!--- why two containers around this? reasons below -->
		<!--
		
			// clicked on background area
			if (target==canvasBackground || target==canvasBackgroundParent) {
				radiate.setTarget(targetApplication, true);
		-->
		
		<!--- 
		This first group is sized by the Scroller. 
		The scroller automatically sets this group, the viewport, to 100%
		-->
		<s:Group id="canvasBackgroundParent"
				 width="100%"
				 height="100%" >
			
			
			<!---
			This second group is to provide padding to the top and bottom of the document 
			and to receive any mouse events such as zoom in and out.
			
			It gets sized to the canvas size plus the padding value. 
			
			It may also be used for skinning with different devices. 
			-->
			<s:BorderContainer id="canvasBackgroundInstance"
							   borderVisible="false"
							   backgroundAlpha="0"
							   >
				
			
				<!--- 
				This third group is to mask application content.
				Without it the application or the application's system manager
				may bleed over. 
				-->
				<s:BorderContainer id="canvasBorderInstance" 
						 verticalCenter="0"
						 horizontalCenter="0"
						 backgroundAlpha="0"
						 borderVisible="false"
						 visible="false"
						 resize="canvasBorder_resizeHandler(event)">
				
				<!--<s:SkinnableContainer id="canvasBorder"
									  verticalCenter="0"
									  horizontalCenter="0"
									  visible="false"
									  backgroundAlpha="1"
									  skinClass="com.flexcapacitor.skins.DeviceSkin"
									  >-->
					
				
					<!--- 
					This group contains the system manager and the blank application
					-->
					<s:SWFLoader id="projectLoader" 
								 resize="projectLoader_resizeHandler(event)"
								 complete="project_completeHandler(event)"
								 httpStatus="project_httpStatusHandler(event)"
								 init="project_initHandler(event)"
								 ioError="project_ioErrorHandler(event)"
								 open="project_openHandler(event)"
								 progress="project_progressHandler(event)"
								 securityError="project_securityErrorHandler(event)"
								 unload="project_unloadHandler(event)"/>
				
					<!--- 
					This group is used to add visual elements above the application.
					For example, selection and resizing borders. 
					-->
					<s:Group id="toolLayerInstance" 
							 mouseChildren="false" 
							 mouseEnabled="false">
						
					</s:Group>
				
				</s:BorderContainer>
				<!--</s:SkinnableContainer>-->
			</s:BorderContainer>
		</s:Group>
	</s:Scroller>
	
	<s:Label id="loadingLabel" color="#ffffff" text="Loading. Please wait..." 
			 fontWeight="bold" horizontalCenter="0" verticalCenter="0"/>
	
	<s:Group id="scrollerCornerButton" 
			 width="16" height="16" right="0" bottom="0"
			 click="scrollerCornerButton_clickHandler(event)">
		<s:Rect width="100%"
				height="100%"
				alpha="0"
				visible="{canvasScroller.verticalScrollBar.visible &amp;&amp; canvasScroller.horizontalScrollBar.visible}"
				>
			<s:fill>
				<s:SolidColor color="#000000"/>
			</s:fill>
		</s:Rect>
	</s:Group>
	
	
	<!-- alternatives to ruler component -->
	<s:Rect left="20" width="100%" height="20">
		<s:fill>
			<s:SolidColor color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
	
	<s:Rect top="20" width="20" height="100%">
		<s:fill>
			<s:SolidColor color="#FFFFFF"/>
		</s:fill>
	</s:Rect>
	<!--<components:Ruler left="20" width="100%" height="20"/>
	
	<components:Ruler top="20" width="20" height="100%" direction="vertical"/>-->
	
	<!--<s:BusyIndicator id="busyIndicator" right="20" top="10" symbolColor="white"/>-->
	
	
</s:Group>
