package com.afi.estimator.views.preloader
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.DisplayObject;
    import flash.display.GradientType;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.events.TimerEvent;
    import flash.geom.Matrix;
    import flash.net.URLRequest;
    import flash.text.TextField;
    import flash.utils.Timer;
    import flash.utils.getTimer;
    
    import mx.events.FlexEvent;
    import mx.preloaders.IPreloaderDisplay;
    
    public class AFIPreloader
        extends Sprite
        implements IPreloaderDisplay
    {
        private static const MIN_DURATION           : Number    = 1000;
        
        private static const PROGRESS_RECT_WIDTH    : int       = 200;
        private static const PROGRESS_RECT_HEIGHT   : int       = 10;
        
        private static const BAR_COLOR_1            : int       = 0xC9EB7B;
        private static const BAR_COLOR_2            : int       = 0x588B02;
        
        private static const BORDER_COLOR           : int       = 0x88C925;
        private static const BORDER_THICKNESS       : int       = 2;
        
        private var timer               : Timer;
        
        private var initComplete        : Boolean   = false;
        private var loaded              : Number    = 0;
        private var total               : Number    = 1;
        private var percent             : Number    = 0;
        private var status              : String    = "Downloading";
        
        private var progress            : Sprite;
        private var progressBorder      : Sprite;
        
        private var logo                : flash.display.Bitmap;
        
        private var progressText        : TextField;
        private var statusText          : TextField;
        
        private static const GRAD_TYPE:String = GradientType.LINEAR;
        private static const GRAD_ROTATION:Number = Math.PI/2;
        private static const GRAD_MATRIX:Matrix = new Matrix();
        private static const GRAD_ALPHAS:Array = [100,100];
        private static const GRAD_RATIOS:Array = [0,255];
        private static const GRAD_CORNER_RADIUS:int = 6;
        
        [Embed("/com/afi/estimator/assets/images/AFI-logo.png")]
        public var logoCls:Class;
        
        
        public function AFIPreloader() {
            super();
        }
        
        public function initialize():void {
            
            logo = new logoCls();
            
            GRAD_MATRIX.createGradientBox(PROGRESS_RECT_WIDTH,
                PROGRESS_RECT_HEIGHT,
                GRAD_ROTATION);
            
            positionLogo();
            addChild(logo);
            
            progressBorder = new Sprite();
            addChild(progressBorder);
            
            progress = new Sprite();
            addChild(progress);
            
            progress.x = progressBorder.x = (1024/2) - (PROGRESS_RECT_WIDTH/2);
            progress.y = progressBorder.y = 275;
            
            /*
            progressText = createProgressText();
            addChild(progressText);
            
            statusText = createStatusText();
            addChild(statusText);
            */
            
            timer = new Timer(1);
            timer.addEventListener(TimerEvent.TIMER, timerHandler);
            timer.start();
        }
        
        
        
        private function positionLogo():void {
            logo.width  = 133;
            logo.height = 53;
            logo.x      = (1024/2) - (133/2);
            logo.y      = 210;
        }
        
        private function draw():void {
            drawProgressBorder();
            drawProgress();
            //progressText.text = (Math.round(_bytesLoaded / 1024)).toString() + 'KB of ' + (Math.round(_bytesExpected / 1024)) + 'KB downloaded';
            //statusText.text = status;
        }
        
        private function drawProgressBorder():void {
            var g:Graphics = progressBorder.graphics;
            g.clear();
            g.lineStyle(BORDER_THICKNESS, BORDER_COLOR);
            g.drawRoundRectComplex(0, 0,
                PROGRESS_RECT_WIDTH, PROGRESS_RECT_HEIGHT,
                GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS);
            g.endFill();
        }
        
        private function drawProgress():void {
            var g:Graphics = progress.graphics;
            g.clear();
            g.beginGradientFill(GRAD_TYPE,
                [BAR_COLOR_1, BAR_COLOR_2],
                GRAD_ALPHAS,
                GRAD_RATIOS,
                GRAD_MATRIX);
            
            g.drawRoundRectComplex(0, 0,
                PROGRESS_RECT_WIDTH * percent,
                PROGRESS_RECT_HEIGHT,
                GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS, GRAD_CORNER_RADIUS);
            g.endFill();
        }
        
        private function progressHandler(event:ProgressEvent):void {
            loaded = event.bytesLoaded;
            total = event.bytesTotal;
            percent = Number(loaded) / Number(total);
        }
        
        private function completeHandler(event:Event):void {
            status = 'Application Download Complete';
        }
        
        private function initProgressHandler(event:Event):void {
            if(!initComplete)
            {
                status = 'Initializing Application';
            }
        }
        
        private function initCompleteHandler(event:Event):void
        {
            status = 'Initialization Complete';
            initComplete = true;
        }
        
        private function timerHandler(event:Event):void
        {
            initComplete && minTimeComplete ? finish() :
                draw();
        }
        
        private function finish():void {
            timer.stop();
            timer.removeEventListener(TimerEvent.TIMER,timerHandler);
            dispatchEvent(new Event(Event.COMPLETE));
        }
        
        private function get minTimeComplete():Boolean {
            return getTimer() > MIN_DURATION;
        }
        
        private var _preloader:Sprite;
        public function set preloader(value:Sprite):void {
            _preloader = value;
            
            value.addEventListener(ProgressEvent.PROGRESS,  progressHandler);
            value.addEventListener(Event.COMPLETE,          completeHandler);
            value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler);
            value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler);
        }
        
        public function set backgroundAlpha(alpha:Number):void{}
        public function get backgroundAlpha():Number {return 1};
        
        private var _backgroundColor:uint = 0x000000;
        public function set backgroundColor(color:uint):void {_backgroundColor = color;};
        public function get backgroundColor():uint {return _backgroundColor};
        
        public function set backgroundImage(image:Object):void {};
        public function get backgroundImage():Object {return null};
        
        public function set backgroundSize(size:String):void {};
        public function get backgroundSize():String {return "auto"};
        
        private var _stageHeight:Number = 1;
        public function set stageHeight(height:Number):void {_stageHeight = height};
        public function get stageHeight():Number {return _stageHeight};
        
        private var _stageWidth:Number = 1;
        public function set stageWidth(width:Number):void {_stageWidth = width};
        public function get stageWidth():Number {return _stageWidth};
        
        private function createProgressText():TextField {
            var tf:TextField = new TextField(); 
            tf.x = 400;    
            tf.y = 310;
            tf.width = 200;
            tf.height = 20;
            tf.textColor = 0;
            return tf;
        }
        
        private function createStatusText():TextField {
            var tf:TextField = new TextField(); 
            tf.x = 400;    
            tf.y = 320;
            tf.width = 200;
            tf.height = 20;
            tf.textColor = 0x3ea1ee;
            return tf;
        }
    }
}