////////////////////////////////////////////////////////////////////////////////
//
//  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;
        
        if(!(resourceName in resourceBundle.content))
            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;
	}
}
