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

package mx.resources
{

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.FocusEvent;
import flash.events.IEventDispatcher;
import flash.events.TimerEvent;
import flash.system.ApplicationDomain;
import flash.system.Capabilities;
import flash.system.SecurityDomain;
import flash.utils.Dictionary;
import flash.utils.Timer;
import mx.core.IFlexModuleFactory;
import mx.core.mx_internal;
import mx.core.Singleton;
import mx.events.FlexEvent;
import mx.events.ModuleEvent;
import mx.events.ResourceEvent;
import mx.managers.SystemManagerGlobals;
import mx.modules.IModuleInfo;
import mx.modules.ModuleManager;
import mx.utils.StringUtil;

use namespace mx_internal;

/**
 *  @copy mx.resources.IResourceManager#change
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="change", type="flash.events.Event")]

[ExcludeClass]

/**
 *  @private
 *  This class provides an implementation of the IResourceManager interface.
 *  The IResourceManager and IResourceBundle interfaces work together
 *  to provide internationalization support for Flex applications.
 *
 *  <p>A single instance of this class manages all localized resources
 *  for a Flex application.</p>
 *  
 *  @see mx.resources.IResourceManager
 *  @see mx.resources.IResourceBundle
 */
public class ResourceManagerImpl extends EventDispatcher implements IResourceManager
{
    include "../core/Version.as";

    //--------------------------------------------------------------------------
    //
    //  Class variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  The sole instance of the ResourceManager.
     */
    private static var instance:IResourceManager;
    
    //--------------------------------------------------------------------------
    //
    //  Class methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Gets the single instance of the ResourceManagerImpl class.
     *  This object manages all localized resources for a Flex application.
     *  
     *  @return An object implementing IResourceManager.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public static function getInstance():IResourceManager
    {
        if (!instance)
            instance = new ResourceManagerImpl();

        return instance;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function ResourceManagerImpl()
    {
        super();

        if (SystemManagerGlobals.topLevelSystemManagers.length)
        {
            if (SystemManagerGlobals.topLevelSystemManagers[0].currentFrame == 1)
            {
                ignoreMissingBundles = true;
				inFrame1 = true;
                SystemManagerGlobals.topLevelSystemManagers[0].
                    addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }
        }
        
        var info:Object = SystemManagerGlobals.info;
		// Falcon injects this property and it is always false
		// We ignore missing bundles because Falcon doesn't
		// generate fallback bundles like MXMLC;
		if (!inFrame1)
			ignoreMissingBundles = info && info.hasOwnProperty("isMXMLC");
		
        if (info)
            processInfo(info, false);

        ignoreMissingBundles = info && info.hasOwnProperty("isMXMLC");
        
        if (SystemManagerGlobals.topLevelSystemManagers.length)
		    SystemManagerGlobals.topLevelSystemManagers[0].
			    addEventListener(FlexEvent.NEW_CHILD_APPLICATION, newChildApplicationHandler);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

	/**
	 *  @private
	 * 
	 *  Whether or ignoreMissingBundles was set in frame 1
	 */
	private var inFrame1:Boolean = false;
	
    /**
     *  @private
     * 
     *  Whether or not to throw an error.
     */
    private var ignoreMissingBundles:Boolean = false;
    
    /**
     *  @private
     * 
     *  The dictionary to hold all of the weak reference resource bundles.
     */
    private var bundleDictionary:Dictionary;
    
    /**
     *  @private
     *  A map whose keys are locale strings like "en_US"
     *  and whose values are "bundle maps".
     *  A bundle map is a map whose keys are bundle names
     *  like "SharedResources" and whose values are ResourceBundle instances.
     *  You can get to an individual resource value like this:
     *  localeMap["en_US"]["SharedResources"].content["currencySymbol"]
     */
    private var localeMap:Object = {};
    
    /**
     *  @private
     *  A map whose keys are URLs for resource modules that have been loaded
     *  and whose values are ResourceModuleInfo instances for those modules.
     */
    private var resourceModules:Object = {};

    /**
     *  @private
     */
    private var initializedForNonFrameworkApp:Boolean = false;
    
    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  localeChain
    //----------------------------------

    /**
     *  @private
     *  Storage for the localeChain property.
     */
    private var _localeChain:Array /* of String */;
    
    /**
     *  @copy mx.resources.IResourceManager#localeChain
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get localeChain():Array /* of String */
    {
        return _localeChain;
    }
    
    /**
     *  @private
     */
    public function set localeChain(value:Array /* of String */):void
    {
        _localeChain = value;
        
        update();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  This method is called by the SystemManager class of an Application
     *  when the application starts.
     *  It is also called by the FlexModuleFactory class of a code module
     *  when that module gets loaded.
     *
     *  The MXML compiler autogenerated code which set the
     *  "compiledLocales" and "compiledResourceBundleNames" properties
     *  of the info() Object required by the IFlexModuleFactory
     *  interface that these classes implement.
     *  These two properties together indicate which resource bundle
     *  classes the MXML compiler autogenerated and linked into the
     *  application or module.
     *
     *  The "compiledLocales" property has been set to the locales
     *  which were specified at compile time using the -locale option.
     *  For example, if you compile with -locale=en_US,ja_JP
     *  then the "compiledLocales" property is the array [ "en_US", "ja_JP" ].
     *
     *  The "compiledResourceBundleNames" property has been set
     *  to the names of the resource bundles which are used by
     *  the application or module, as determined by the compiler
     *  from [ResourceBundle] metadata and ~~Resource() directives.
     *  For example, if the classes in the application or module
     *  declare that they use resource bundles named "core" and "MyApp",
     *  then the "compiledResourceBundleNames" property is the array
     *  [ "core", "MyApp" ].
     *
     *  The compiler autogenerated a ResourceBundle subclass for each
     *  (locale, bundle name) pair.
     *  For example, with the above locales and bundle names,
     *  there would be four classes:
     *    en_US$core_properties
     *    en_US$MyApp_properties
     *    ja_JP$core_properties
     *    ja_JP$MyApp_properties
     *
     *  This method creates one instance of each such class
     *  and installs it into the ResourceManager with addResourceBundle().
     *  If a bundle for a given locale and bundle name already exists
     *  in the ResourceManager already exists, it does not get replaced.
     *  This can happen when a code module gets loaded into an application.
     * 
     *  When sub-applications and modules install their resource bundles 
     *  they set useWeakReference = true. Any new resource bundles they 
     *  create will be weak referenced by the ResourceManager. The 
     *  sub-application or module will then provide a hard reference
     *  to the returned Array of resource bundles to keep them from 
     *  being garbage collected.
     */
    public function installCompiledResourceBundles(
                                applicationDomain:ApplicationDomain,
                                locales:Array /* of String */,
                                bundleNames:Array /* of String */,
                                useWeakReference:Boolean = false):Array
    {
        //trace("locales", locales);
        //trace("bundleNames", bundleNames);
        var bundles:Array = [];
        var bundleCount:uint = 0;
        var n:int = locales ? locales.length : 0;
        var m:int = bundleNames ? bundleNames.length : 0;

        // Loop over the locales.
        for (var i:int = 0; i < n; i++)
        {
            var locale:String = locales[i];
            
            // Loop over the bundle names.
            for (var j:int = 0; j < m; j++)
            {
                var bundleName:String = bundleNames[j];
                
                var bundle:IResourceBundle = installCompiledResourceBundle(
                    applicationDomain, locale, bundleName, 
                    useWeakReference);
                
                if (bundle)
                    bundles[bundleCount++] = bundle;
            }
        }
        
        return bundles;
    }

    /**
     *  @private
     */
    private function installCompiledResourceBundle(
                                applicationDomain:ApplicationDomain,
                                locale:String, bundleName:String,
                                useWeakReference:Boolean = false):IResourceBundle
    {
        var packageName:String = null;
        var localName:String = bundleName;
        var colonIndex:int = bundleName.indexOf(":");
        if (colonIndex != -1)
        {
            packageName = bundleName.substring(0, colonIndex);
            localName = bundleName.substring(colonIndex + 1);
        }

        // If a bundle with that locale and bundle name already exists
        // in the ResourceManager, don't replace it.
        // If we want to install a  weakReferenceDictionary then don't rely on
        // a weak reference dictionary because it may go way when the 
        // application goes away.
        var resourceBundle:IResourceBundle = getResourceBundleInternal(locale,
                                                    bundleName, 
                                                    useWeakReference);
        if (resourceBundle)
            return resourceBundle;
        
        // The autogenerated resource bundle classes produced by the
        // mxmlc and compc compilers have names that incorporate
        // the locale and bundle name, such as "en_US$core_properties".
        var resourceBundleClassName:String =
            locale + "$" + localName + "_properties";
        if (packageName != null)
            resourceBundleClassName = packageName + "." + resourceBundleClassName;
                
        // Find the bundle class by its name.
        // We do a hasDefinition() check before calling getDefinition()
        // because getDefinition() will throw an RTE
        // if the class doesn't exist.
        var bundleClass:Class = null;
        if (applicationDomain.hasDefinition(resourceBundleClassName))
        {
            bundleClass = Class(applicationDomain.getDefinition(
                                    resourceBundleClassName));
        }

        if (!bundleClass)
        {
            resourceBundleClassName = bundleName;
            if (applicationDomain.hasDefinition(resourceBundleClassName))
            {
                bundleClass = Class(applicationDomain.getDefinition(
                                        resourceBundleClassName));
            }
        }
        
        // In case we linked against a Flex 2 SWC, look for the old
        // class name.
        if (!bundleClass)
        {
            resourceBundleClassName = bundleName + "_properties";
            if (applicationDomain.hasDefinition(resourceBundleClassName))
            {
                bundleClass = Class(applicationDomain.getDefinition(
                                        resourceBundleClassName));
            }
        }
        
        if (!bundleClass)
        {
            if (ignoreMissingBundles)
                return null;
            
            throw new Error(
                "Could not find compiled resource bundle '" + bundleName +
                "' for locale '" + locale + "'.");
        }
        
        // Create a proxy
        var proxy:ResourceBundleProxy = new ResourceBundleProxy();
        
		proxy.bundleClass = bundleClass;
		proxy.useWeakReference = useWeakReference;

        // In case we just created a ResourceBundle from a Flex 2 SWC,
        // set its locale and bundleName, because the old constructor
        // didn't used to do this.
        proxy.locale = locale;
        proxy.bundleName = bundleName;
                
        // Add that resource bundle instance to the ResourceManager.
        resourceBundle = proxy;
        addResourceBundle(resourceBundle, useWeakReference);
        
        return resourceBundle;
    }
    
    // FocusEvent is used just so we can add a relatedObject
	private function newChildApplicationHandler(event:FocusEvent):void
	{
		var info:Object = event.relatedObject["info"]();
        var weakReference:Boolean = false;
        if ("_resourceBundles" in event.relatedObject)
            weakReference = true;
        
        // If the application has a "_resourceBundles" object for us to put
        // the bundles into then we will. Otherwise have the ResourceManager
        // create a hard reference to the resources.
        var bundles:Array = processInfo(info, weakReference);
        if (weakReference)
            event.relatedObject["_resourceBundles"] = bundles;
    }
		
    private function processInfo(info:Object, useWeakReference:Boolean):Array
    {
		var compiledLocales:Array = info["compiledLocales"];

		ResourceBundle.locale =
			compiledLocales != null && compiledLocales.length > 0 ?
			compiledLocales[0] :
			"en_US";

		var applicationDomain:ApplicationDomain = info["currentDomain"];

		var compiledResourceBundleNames:Array /* of String */ =
			info["compiledResourceBundleNames"];
		
		var bundles:Array = installCompiledResourceBundles(
			applicationDomain, compiledLocales, compiledResourceBundleNames,
            useWeakReference);

		// If the localeChain wasn't specified in the FlashVars of the SWF's
		// HTML wrapper, or in the query parameters of the SWF URL,
		// then initialize it to the list of compiled locales,
        // sorted according to the system's preferred locales as reported by
        // Capabilities.languages or Capabilities.language.
		// For example, if the applications was compiled with, say,
		// -locale=en_US,ja_JP and Capabilities.languages reports [ "ja-JP" ],
        // set the localeChain to [ "ja_JP" "en_US" ].
		if (!localeChain)
			initializeLocaleChain(compiledLocales);

        return bundles;
	}

    /**
     *  @copy mx.resources.IResourceManager#initializeLocaleChain()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function initializeLocaleChain(compiledLocales:Array):void
    {
        localeChain = LocaleSorter.sortLocalesByPreference(
            compiledLocales, getSystemPreferredLocales(), null, true);
    }

    /**
     *  @copy mx.resources.IResourceManager#loadResourceModule()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function loadResourceModule(url:String, updateFlag:Boolean = true,
                                       applicationDomain:ApplicationDomain = null,
                                       securityDomain:SecurityDomain = null):
                                       IEventDispatcher
    {
        var moduleInfo:IModuleInfo = ModuleManager.getModule(url);

        // Create the per-load IEventDispatcher that we'll return.
        var resourceEventDispatcher:ResourceEventDispatcher =
            new ResourceEventDispatcher(moduleInfo);

        // Set up a handler for the "ready" event from the module.
        // We use a local Function rather than a method
        // so that it can access the 'update' argument.
        var readyHandler:Function = function(event:ModuleEvent):void
        {
            //trace("readyHandler");

            var resourceModule:* = // IResourceModule
                event.module.factory.create();
        
            //dumpResourceModule(resourceModule);
        
            resourceModules[event.module.url].resourceModule = resourceModule;

            if (updateFlag)
                update();
        }
        moduleInfo.addEventListener(ModuleEvent.READY, readyHandler,
                                    false, 0, true);

        // Set up a handler for the "error" event from the module.
        // We use a local Function rather than a method
        // for symmetry with the readyHandler.
        var errorHandler:Function = function(event:ModuleEvent):void
        {
            var message:String = "Unable to load resource module from " + url;

            if (resourceEventDispatcher.willTrigger(ResourceEvent.ERROR))
            {
                var resourceEvent:ResourceEvent = new ResourceEvent(
                    ResourceEvent.ERROR, event.bubbles, event.cancelable);
                resourceEvent.bytesLoaded = 0;
                resourceEvent.bytesTotal = 0;
                resourceEvent.errorText = message;
                resourceEventDispatcher.dispatchEvent(resourceEvent);
            }
            else
            {
                throw new Error(message);
            }
        }
        moduleInfo.addEventListener(ModuleEvent.ERROR, errorHandler,
                                    false, 0, true);

        resourceModules[url] =
            new ResourceModuleInfo(moduleInfo, readyHandler, errorHandler);

        // This Timer gives the loadResourceModules() caller a chance
        // to add event listeners to the return value, before the module
        // is loaded.
        // We use a local Function for the timerHandler rather than a method
        // so that it can access the 'moduleInfo' local var.
        var timer:Timer = new Timer(0);
        var timerHandler:Function = function(event:TimerEvent):void
        {
            timer.removeEventListener(TimerEvent.TIMER, timerHandler);
            timer.stop();
            
            //trace("loading");

            // Start loading the module.
            moduleInfo.load(applicationDomain, securityDomain);
        }
        timer.addEventListener(TimerEvent.TIMER, timerHandler,
                               false, 0, true);
        timer.start();
        
        return resourceEventDispatcher;
    }

    /**
     *  @copy mx.resources.IResourceManager#unloadResourceModule()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function unloadResourceModule(url:String, update:Boolean = true):void
    {
        // Get the resource module info.
        var rmi:ResourceModuleInfo = resourceModules[url];        
        if (!rmi)
            return;
        
        if (rmi.resourceModule)
        {
            // Get the bundles in this module.
            var bundles:Array = rmi.resourceModule.resourceBundles;
            if (bundles)
            {
               var n:int = bundles.length;
               for (var i:int = 0; i < n; i++)
               {
                   // Remove each bundle.
                   var locale:String = bundles[i].locale;
                   var bundleName:String = bundles[i].bundleName;
                   removeResourceBundle(locale, bundleName);
               }
            }
        }

        // Remove all links to the module.
        resourceModules[url] = null;
        delete resourceModules[url];
        
        // Unload the module.
        rmi.moduleInfo.unload();
        
        // Update if necessary.
        if (update)
            this.update();
    }
 
    /**
     *  @copy mx.resources.IResourceManager#addResourceBundle()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function addResourceBundle(resourceBundle:IResourceBundle, 
                                      useWeakReference:Boolean = false):void
    {
        var locale:String = resourceBundle.locale;
        var bundleName:String = resourceBundle.bundleName;
        
        if (!localeMap[locale])
            localeMap[locale] = {};
            
        if (useWeakReference)
        {
            if (!bundleDictionary)
            {
                bundleDictionary = new Dictionary(true);
            }
            
            bundleDictionary[resourceBundle] = locale + bundleName;
            localeMap[locale][bundleName] = bundleDictionary;
        }
        else
        {
            localeMap[locale][bundleName] = resourceBundle;
        }
    }
    
    /**
     *  @copy mx.resources.IResourceManager#getResourceBundle()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getResourceBundle(locale:String,
                                      bundleName:String):IResourceBundle
    {
        return getResourceBundleInternal(locale, bundleName, false);
    }
    
    /**
     *  @private
     *  
     *  @param ignoreWeakReferenceBundles if true, do not search weak
     *  reference bundles.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function getResourceBundleInternal(locale:String,
                                      bundleName:String,
                                      ignoreWeakReferenceBundles:Boolean):IResourceBundle
    {
        var bundleMap:Object = localeMap[locale];
        if (!bundleMap)
            return null;
           
        var bundle:IResourceBundle = null;
        var bundleObject:Object = bundleMap[bundleName];
        if (bundleObject is Dictionary)
        {
            if (ignoreWeakReferenceBundles)
                return null;
            
            var localeBundleNameString:String = locale + bundleName;
            for (var obj:Object in bundleObject)
            {
                if (bundleObject[obj] == localeBundleNameString)
                {
					if (obj is ResourceBundleProxy)
						bundle = loadResourceBundleProxy(ResourceBundleProxy(obj));
					else 
						bundle = obj as IResourceBundle;
                    break;
                }
            }
        }
        else if (bundleObject is ResourceBundleProxy)
        {
        	bundle = loadResourceBundleProxy(ResourceBundleProxy(bundleObject));
        }
        else 
        {
            bundle = bundleObject as IResourceBundle;
        }
        
        return bundle;
    }
    
    private function loadResourceBundleProxy(proxy:ResourceBundleProxy):ResourceBundle {
    	var proxyClass:Class = proxy.bundleClass;
        var resourceBundle:ResourceBundle = ResourceBundle(new proxyClass());
   		resourceBundle._locale = proxy.locale;
    	resourceBundle._bundleName = proxy.bundleName;
    	
    	addResourceBundle(resourceBundle, proxy.useWeakReference);
    	
    	return resourceBundle;
    }
    
    /**
     *  @copy mx.resources.IResourceManager#removeResourceBundle()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function removeResourceBundle(locale:String, bundleName:String):void
    {
        // Remove the specified bundle.
        delete localeMap[locale][bundleName];

        // If that leaves a locale node with no bundles,
        // delete the locale node.
        if (getBundleNamesForLocale(locale).length == 0)
            delete localeMap[locale];
    }
    
    /**
     *  @copy mx.resources.IResourceManager#removeResourceBundlesForLocale()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function removeResourceBundlesForLocale(locale:String):void
    {
        delete localeMap[locale];
    }
    
    /**
     *  @copy mx.resources.IResourceManager#update()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function update():void
    {
        dispatchEvent(new Event(Event.CHANGE));
    }

    /**
     *  @copy mx.resources.IResourceManager#getLocales()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getLocales():Array /* of String */
    {
        var locales:Array = [];
        for (var p:String in localeMap)
        {
            locales.push(p);
        }
        return locales;
    }

    /**
     *  @copy mx.resources.IResourceManager#getPreferredLocaleChain()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getPreferredLocaleChain():Array /* of String */
    {
        return LocaleSorter.sortLocalesByPreference(
            getLocales(), getSystemPreferredLocales(), null, true);
    }
    
    /**
     *  @copy mx.resources.IResourceManager#getBundleNamesForLocale()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getBundleNamesForLocale(locale:String):Array /* of String */
    {
        var bundleNames:Array = [];
        for (var p:String in localeMap[locale])
        {
            bundleNames.push(p);
        }
        return bundleNames;
    }

    /**
     *  @copy mx.resources.findResourceBundleWithResource
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function findResourceBundleWithResource(
                        bundleName:String, resourceName:String):IResourceBundle
    {
        if (!_localeChain)
            return null;
        
        var n:int = _localeChain.length;
        for (var i:int = 0; i < n; i++)
        {
            var locale:String = localeChain[i];
            
            var bundleMap:Object = localeMap[locale];
            if (!bundleMap)
                continue;
            
            var bundleObject:Object = bundleMap[bundleName];
            if (!bundleObject)
                continue;
                
            var bundle:IResourceBundle = null;
            
            if (bundleObject is Dictionary)
            {
                var localeBundleNameString:String = locale + bundleName;
                for (var obj:Object in bundleObject)
                {
                    if (bundleObject[obj] == localeBundleNameString)
                    {
						if (obj is ResourceBundleProxy)
							bundle = loadResourceBundleProxy(ResourceBundleProxy(obj));
						else 
							bundle = obj as IResourceBundle;
                        break;
                    }
                }
            }
            else if (bundleObject is ResourceBundleProxy)
            {
        		bundle = loadResourceBundleProxy(ResourceBundleProxy(bundleObject));
            }
            else 
            {
                bundle = bundleObject as IResourceBundle;
            }
                
            if (bundle && resourceName in bundle.content)
                return bundle;
        }

        return null;
    }

    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getObject()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getObject(bundleName:String, resourceName:String,
                              locale:String = null):*
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return undefined;

        return resourceBundle.content[resourceName];
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getString()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getString(bundleName:String, resourceName:String,
                              parameters:Array = null,
                              locale:String = null):String
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return null;

        var value:String = String(resourceBundle.content[resourceName]);
        
        if (parameters)
            value = StringUtil.substitute(value, parameters);
            
        return value;
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getStringArray()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getStringArray(bundleName:String,
                                   resourceName:String,
                                   locale:String = null):Array /* of String */
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return null;

        var value:* = resourceBundle.content[resourceName];
        
        var array:Array = String(value).split(",");
        
        var n:int = array.length;
        for (var i:int = 0; i < n; i++)
        {
             array[i] = StringUtil.trim(array[i]);
        }  
        
        return array;
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getNumber()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getNumber(bundleName:String, resourceName:String,
                              locale:String = null):Number
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return NaN;

        var value:* = resourceBundle.content[resourceName];
        
        return Number(value);
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getInt()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getInt(bundleName:String, resourceName:String,
                           locale:String = null):int
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return 0;

        var value:* = resourceBundle.content[resourceName];

        return int(value);
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getUint()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getUint(bundleName:String, resourceName:String,
                            locale:String = null):uint
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return 0;

        var value:* = resourceBundle.content[resourceName];

        return uint(value);
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getBoolean()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getBoolean(bundleName:String, resourceName:String,
                               locale:String = null):Boolean
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return false;

        var value:* = resourceBundle.content[resourceName];

        return String(value).toLowerCase() == "true";
    }
    
    [Bindable("change")]
    
    /**
     *  @copy mx.resources.IResourceManager#getClass()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getClass(bundleName:String, resourceName:String,
                             locale:String = null):Class
    {
        var resourceBundle:IResourceBundle =
            findBundle(bundleName, resourceName, locale);
        if (!resourceBundle)
            return null;

        var value:* = resourceBundle.content[resourceName];

        return value as Class;
    }

    /**
     *  @private.
     */
    private function findBundle(bundleName:String, resourceName:String,
                                locale:String):IResourceBundle
    {
        supportNonFrameworkApps();

        return locale != null ?
               getResourceBundle(locale, bundleName) :
               findResourceBundleWithResource(bundleName, resourceName);

    }

    /**
     *  @private.
     */
    private function supportNonFrameworkApps():void
    {
        if (initializedForNonFrameworkApp)
            return;
        initializedForNonFrameworkApp = true;

        if (getLocales().length > 0)
            return;
        
        var applicationDomain:ApplicationDomain =
            ApplicationDomain.currentDomain;
        
        if (!applicationDomain.hasDefinition("_CompiledResourceBundleInfo"))
            return;
        var c:Class = Class(applicationDomain.getDefinition(
                                "_CompiledResourceBundleInfo"));

        var locales:Array /* of String */ = c.compiledLocales;
        var bundleNames:Array /* of String */ = c.compiledResourceBundleNames;

        installCompiledResourceBundles(
            applicationDomain, locales, bundleNames);

        localeChain = locales;
    }
    
    /**
     *  @private
     */  
    private function getSystemPreferredLocales():Array /* of String */
    {
        var systemPreferences:Array;
        
        // Capabilities.languages was added in AIR 1.1,
        // so this API may not exist.
        if (Capabilities["languages"])
            systemPreferences = Capabilities["languages"];
        else
            systemPreferences = [ Capabilities.language ];

        return systemPreferences;
    }
    
    /**
     *  @private.
     */
    private function dumpResourceModule(resourceModule:*):void
    {
        for each (var bundle:ResourceBundle in resourceModule.resourceBundles)
        {
            trace(bundle.locale, bundle.bundleName);
            for (var p:String in bundle.content)
            {
                //trace(p, bundle.getObject(p));
            }
        }
    }

    /**
     *  @private
     */
    private function enterFrameHandler(event:Event):void
    {
        if (SystemManagerGlobals.topLevelSystemManagers.length)
        {
            if (SystemManagerGlobals.topLevelSystemManagers[0].currentFrame == 2)
            {
				inFrame1 = false;
                SystemManagerGlobals.topLevelSystemManagers[0].
                    removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }
            else
                return;
        }
        
        var info:Object = SystemManagerGlobals.info;
        if (info)
            processInfo(info, false);
    }
}

}

import flash.events.EventDispatcher;
import mx.events.ModuleEvent;
import mx.events.ResourceEvent;
import mx.modules.IModuleInfo;
import mx.resources.IResourceBundle;
import mx.resources.IResourceModule;

////////////////////////////////////////////////////////////////////////////////
//
//  Helper class: ResourceModuleInfo
//
////////////////////////////////////////////////////////////////////////////////

/**
 *  @private
 */
class ResourceModuleInfo
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function ResourceModuleInfo(moduleInfo:IModuleInfo,
                                       readyHandler:Function,
                                       errorHandler:Function)
    {
        super();

        this.moduleInfo = moduleInfo;
        this.readyHandler = readyHandler;
        this.errorHandler = errorHandler;
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  errorHandler
    //----------------------------------

    /**
     *  @private
     */
    public var errorHandler:Function;
    
    //----------------------------------
    //  moduleInfo
    //----------------------------------

    /**
     *  @private
     */
    public var moduleInfo:IModuleInfo
    
    //----------------------------------
    //  readyHandler
    //----------------------------------

    /**
     *  @private
     */
    public var readyHandler:Function;
    
    //----------------------------------
    //  resourceModule
    //----------------------------------

    /**
     *  @private
     */
    public var resourceModule:IResourceModule;
}

////////////////////////////////////////////////////////////////////////////////
//
//  Helper class: ResourceEventDispatcher
//
////////////////////////////////////////////////////////////////////////////////

/**
 *  @private
 */
class ResourceEventDispatcher extends EventDispatcher
{
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function ResourceEventDispatcher(moduleInfo:IModuleInfo)
    {
        super();

        moduleInfo.addEventListener(
            ModuleEvent.ERROR, moduleInfo_errorHandler, false, 0, true);

        moduleInfo.addEventListener(
            ModuleEvent.PROGRESS, moduleInfo_progressHandler, false, 0, true);
        
        moduleInfo.addEventListener(
            ModuleEvent.READY, moduleInfo_readyHandler, false, 0, true);
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    private function moduleInfo_errorHandler(event:ModuleEvent):void
    {
        var resourceEvent:ResourceEvent = new ResourceEvent(
            ResourceEvent.ERROR, event.bubbles, event.cancelable);
        resourceEvent.bytesLoaded = event.bytesLoaded;
        resourceEvent.bytesTotal = event.bytesTotal;
        resourceEvent.errorText = event.errorText;
        dispatchEvent(resourceEvent);
    }

    /**
     *  @private
     */
    private function moduleInfo_progressHandler(event:ModuleEvent):void
    {
        var resourceEvent:ResourceEvent = new ResourceEvent(
            ResourceEvent.PROGRESS, event.bubbles, event.cancelable);
        resourceEvent.bytesLoaded = event.bytesLoaded;
        resourceEvent.bytesTotal = event.bytesTotal;
        dispatchEvent(resourceEvent);
    }

    /**
     *  @private
     */
    private function moduleInfo_readyHandler(event:ModuleEvent):void
    {
        var resourceEvent:ResourceEvent =
            new ResourceEvent(ResourceEvent.COMPLETE);
        dispatchEvent(resourceEvent);
    }
}

////////////////////////////////////////////////////////////////////////////////
//
//  Helper class: ResourceBundleProxy
//
////////////////////////////////////////////////////////////////////////////////

/**
 *  @private
 */
class ResourceBundleProxy implements IResourceBundle
{
	public var bundleClass:Class;
	public var useWeakReference:Boolean;
	
	private var _bundleName:String;
	private var _locale:String;
 
    public function ResourceBundleProxy()
	{
	}
       
	public function get bundleName():String {
		return _bundleName;
	}
	
	public function set bundleName(value:String):void {
		_bundleName = value;
	}
       
    public function get content():Object {
    	return null;
    }
        
	public function get locale():String {
		return _locale;
	}
	
	public function set locale(value:String):void {
		_locale = value;
	}
}
