package
{    
    import com.flashartofwar.fcss.applicators.TextFieldApplicator;
    import com.flashartofwar.fcss.managers.SingletonManager;
    import com.flashartofwar.fcss.styles.Style;
    import com.flashartofwar.fcss.stylesheets.FStyleSheet;
    import com.flashartofwar.fcss.stylesheets.IStyleSheet;
    import com.flashartofwar.fcss.stylesheets.IStyleSheetCollection;
    import com.flashartofwar.fcss.stylesheets.StyleSheetCollection;
    
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;

    public class FCSSLoadingAndMerging extends Sprite
    {
        
        //Reference of singleton StyleSheetCollection
        private var styleSheetCollection:IStyleSheetCollection;
        
        private var styleSheet:IStyleSheet;

        
        // list of css files to load
        private var cssLoader:URLLoader;
        
        //switch to load single css file or multiple files
        //private var cssFiles:Array = ["css/default.css"];
        private var cssFiles:Array = ["css/default.css", "css/de_DE.css"];
        
        private var cssCount:int = 0;
        
        private var fontLoader:Loader;
        private var fonts:Array;
        private var fontCount:int = 0;
        
        public function FCSSLoadingAndMerging()
        {            
            init();
        }
        
        /**
         * Set up 
         * 
         **/
        private function init():void
        {
            stage.scaleMode  = StageScaleMode.NO_SCALE;
            stage.align         = StageAlign.TOP_LEFT;
            
            // Get a reference of the StyleSheetCollection from the StyleSheetManager
            styleSheetCollection = SingletonManager.getClassReference(StyleSheetCollection) as IStyleSheetCollection;
            
            cssLoader = new URLLoader( );
            cssLoader.addEventListener( Event.COMPLETE, onCSSFileLoaded);
            
            fontLoader = new Loader( );
            fontLoader.contentLoaderInfo.addEventListener( Event.COMPLETE, onFontFileLoaded);
            
            // Kick off loading assets
            loadCSSFile(cssFiles[cssCount]);
        }
        
        /**
         * Load css files
         * 
         **/
        private function loadCSSFile(url:String):void
        {        
            cssLoader.load(new URLRequest(url));
        }
        
        /**
         * Handle Loading of css files
         * Check if more css files need to load else
         * move on and start loading fonts
         * 
         **/
        private function onCSSFileLoaded(e : Event) : void
        {
            parseCSS( URLLoader(e.target ).data );
    
            if (++cssCount < cssFiles.length)
            {
                loadCSSFile(cssFiles[cssCount]);
            }
            else
            {
                cssLoader.removeEventListener( Event.COMPLETE, onCSSFileLoaded);
                fonts = getFontNames( true );
                
                /**
                 * Make file path to fonts.
                 * This could be implemented by checking
                 * agains a fontmapping configuration
                 **/
                fonts = fonts.map(
                    function (element:String, ...rest):String
                    {
                        return element = "fonts/" + element + ".swf";
                    }
                );
                
                trace(fonts);
                loadFontFile(fonts[fontCount]);
            }
            
        }
        /**
         * Convert raw text to styleSheets
         * 
         **/
        private function parseCSS(cssText:String) : void
        {            
            styleSheet = new FStyleSheet( );
            styleSheet.parseCSS(cssText);
                        
            // Register style sheet with the Collection.
            styleSheetCollection.addStyleSheet(styleSheet, "styleSheet"+ cssCount);
        }
        
        /**
         * Load font swf files
         * 
         **/
        private function loadFontFile(url:String):void
        {
            fontLoader.load(new URLRequest(url));
        }
        
        /**
         * Handle Loading of font swf files
         * Check if more font files need to load else
         * move on and display the application
         * 
         * 
         **/
        private function onFontFileLoaded(e : Event) : void
        {
            if (++fontCount < fonts.length)
            {
                loadFontFile(fonts[fontCount]);
            }
            else
            {
                fontLoader.contentLoaderInfo.removeEventListener( Event.COMPLETE, onFontFileLoaded);    
                
                /*
                var fontList:Array = Font.enumerateFonts();
                fontList.forEach(traceFontName);
                
                function traceFontName(element:*, ...rest):void
                {
                    trace ("fontName = " + element.fontName);
                }
                */
                draw( );
    
            }
            
        }
        
        /**
         * Get a list of fontNames
         * 
         * Get an list of all merged styles and convert them to string.
         * Use RegEx to query styles and extract any that have a font reference.
         * font, font-face, font-family, fontFace, fontFamily should all work. font*:...
         * RegEx will strip quotes "|' from font name value if they exist too.
         * Optionally filter against embedFont rule.
         * 
         **/
        private function getFontNames(embedFonts:Boolean = true):Array
        {
            var results:Array = [];
            
            // get list of all styles
            var styles:Array = [];
            var styleNames:Array = styleSheetCollection.styleNames;
            styleNames.forEach(getStyle);
            
            function getStyle(style:String, ...rest):void
            {
                styles.push(styleSheetCollection.styleLookup(style).toString());
            }
                        
            // check styles based on embedFonts rule 
            styles.forEach(checkStyles);
            function checkStyles(style:String, ...rest):void
            {
                if (!embedFonts || style.indexOf("embedFonts:true") > -1)
                {
                    var fontPattern:RegExp = /font[^:]*:["']?([^"';)]+)/g;
                    var match:Array = fontPattern.exec(style);
                    if (match)
                    {
                        results.push(match[1]);
                    }
                }
            }
            
            // remove duplicates
            results = results.filter(function(e:*, i:*, results:Array):Boolean {return results.indexOf(e) == i});
            
            return results;
        }
    
        /**
         * Test to show how to use FCSS styleSheets
         * 
         **/
        private function draw():void
        {
            
            // Use a TextFieldApplicator to apply the style to the TextField
            var tfApplicator:TextFieldApplicator = new TextFieldApplicator();
            
            var style:Style;    
            
            // Create Header TextField
            var header:TextField = new TextField();
            header.autoSize = TextFieldAutoSize.LEFT;
            addChild(header);
            style = Style(styleSheetCollection.getStyle( ".header" ));    
            tfApplicator.applyStyle(header, style);
            header.text = "F*CSS Hello World Header";
                        
            // Create title TextField
            var title:TextField = new TextField();
            title.autoSize = TextFieldAutoSize.LEFT;
            addChild(title);
            style = Style(styleSheetCollection.getStyle( ".title" ));    
            tfApplicator.applyStyle(title, style);
            title.text = "F*CSS Hello World title";
            title.y = header.y + header.height;
            
            // Create copy TextField
            var copy:TextField = new TextField();
            addChild(copy);
            style = Style(styleSheetCollection.getStyle( ".copy" ));    
            tfApplicator.applyStyle(copy, style);
            copy.text = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).";
            copy.y = title.y + title.height;;
        }
    }
}