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

-->
<!-- basic swf for subModule tests, load a subapp -->
<s:Application 
	xmlns:fx="http://ns.adobe.com/mxml/2009"
	xmlns:s="library://ns.adobe.com/flex/spark"
	xmlns:mx="library://ns.adobe.com/flex/mx"
	creationComplete="resetModuleLoader()"
	>
 
	
	<fx:Style source="../../../../Assets/Fonts/VeraFontStyles.css" />
	<fx:Style>
		@namespace mx "library://ns.adobe.com/flex/mx";
		@namespace s "library://ns.adobe.com/flex/spark";

 		s|Module,
 		mx|DataGrid{
 		    fontFamily: MyVeraHalo;
 		    fontLookup: embeddedCFF;
 		    fontAntiAliasType: normal;
 		}
 		s|Label,
 		s|TitleWindow{
 		    fontFamily: MyVeraSpark;
		    fontLookup: embeddedCFF;
 		    fontAntiAliasType: normal;
 		}
 
 		
</fx:Style>
	<s:layout> <s:VerticalLayout/> </s:layout>
	
	<fx:Script>
		<![CDATA[
			import flash.events.Event;
			
			import mx.collections.ArrayList;
			import mx.controls.Alert;
			import mx.core.IUIComponent;
			import mx.events.FlexEvent;
			import mx.events.ModuleEvent;
			import mx.managers.PopUpManager;
			import mx.managers.SystemManager;
			
			PopUpManager;
			private var moduleErrorMsg:String="";
			public var subAppRef:SystemManager;
			
			public function handleSWFLoaded(e:Event):void
			{
				e.currentTarget.removeEventListener("complete", handleSWFLoaded);
				subAppRef=(contentLoader.content as SystemManager);
				subAppRef.addEventListener(FlexEvent.APPLICATION_COMPLETE, handleSWFLoadedAndReady);
				trace("subAppRef="+subAppRef);
				
				
			}
			public function handleSWFLoadedAndReady(e:Event):void
			{
				subAppRef.removeEventListener(FlexEvent.APPLICATION_COMPLETE, handleSWFLoadedAndReady);
				dispatchEvent(new FlexEvent("SWFLoaded")); 	
			}
			
			public function handleSWFLoadedError(e:Event):void
			{
				e.currentTarget.removeEventListener("error", handleSWFLoaded);
				dispatchEvent(new FlexEvent("ErrorSWFLoad"));
				
			}
			public function handleSWFUnloaded(e:Event):void
			{
				e.currentTarget.removeEventListener("unload", handleSWFUnloaded);
				dispatchEvent(new FlexEvent("SWFUnloaded"));
			}
			public function loadContent(swfURL:String):void
			{
				
				contentLoader.addEventListener("complete",handleSWFLoaded);
				contentLoader.addEventListener("unload",handleSWFUnloaded);
				contentLoader.load(swfURL);
			}
			public function unloadContent(swfURL:String):void
			{
				contentLoader.unloadAndStop(true);
				
			}
		        private function errorModuleHandler(e:ModuleEvent):void
			{
				e.currentTarget.removeEventListener(ModuleEvent.ERROR,errorModuleHandler);
				moduleErrorMsg=e.errorText;
				Alert.show(e.errorText);
				
				
			}
			public function setModuleLoaderListeners():void
			{
				moduleLoader1.addEventListener(ModuleEvent.READY,handleModuleLoaded);
				moduleLoader1.addEventListener(ModuleEvent.ERROR,errorModuleHandler);
				moduleLoader1.addEventListener(ModuleEvent.UNLOAD,removeModuleLoaded);

			}
			public function handleModuleLoaded(e:ModuleEvent):void
			{
		    		e.currentTarget.removeEventListener(ModuleEvent.READY, handleModuleLoaded);
		    		dispatchEvent(new FlexEvent("moduleLoaded"));
			}
			public function removeModuleLoaded(e:ModuleEvent):void
			{
				e.currentTarget.removeEventListener(ModuleEvent.UNLOAD, removeModuleLoaded);
				dispatchEvent(new FlexEvent("moduleRemoved"));
			}
			public function loadModule(moduleURL:String):void
			{
				if (moduleLoader1.url==null)
					moduleLoader1.url = moduleURL;
				else moduleLoader1.loadModule();
			}

			public function unloadModule():void
			{	
				//moduleLoader1.unloadModule(); 
				moduleLoader1.unloadModule();
				moduleLoader1.url=null;

			}
			public function resetModuleLoader():void
			{
				unloadModule();
				setModuleLoaderListeners();
			}

		]]>
	</fx:Script>	
		
	<mx:Panel id="myPanel" title="load a sub app">
	    <mx:SWFLoader id="contentLoader" />     <!--  trustContent="true"  -->
     	</mx:Panel> 
	<s:ModuleLoader id="moduleLoader1" />
</s:Application>
