package {
    import flash.display.DisplayObject;
    import flash.display.StageScaleMode;
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
        
    import flash.text.TextField;
    import flash.text.TextFormat;

    import flash.filters.GlowFilter;
    
    import flash.geom.Rectangle;
    import flash.geom.Point;
    import flash.geom.Matrix;

    import flash.media.Sound;

    import flash.events.Event;
    import flash.events.MouseEvent;
    
    import net.sakri.graphics.Bat;
    import net.sakri.graphics.PerlinNoiseBg;
    
    import com.adobe.viewsource.ViewSource;
    
    [SWF(width="1200", height="500", backgroundColor="#CCCC00")]
    public class BatmanTextEffect extends Sprite{
    
        [Embed(source="assets/batmantas.mp3")]
        private var BatSound:Class;
        
        private var _bat_holder:Sprite;
        private var _tfield:TextField;
        
        private var _text_color:uint=0x000000;
        private var _pix_grab_bg_color:uint=0xFFFFFF;
        
        private var _scale_amount:Number=.1;
        private var _bg:Bitmap;
        private var complete_bats:uint=0;
        
        public function BatmanTextEffect(){
            stage.scaleMode=StageScaleMode.NO_SCALE;
            stage.frameRate = 31;
            ViewSource.addMenuItem(this, "srcview/index.html");
            createBG();
            init();
        }
        
        private function init():void{
            createTextField();
            addGlow();
            addBats();
            _tfield.x=_bat_holder.x=130;
            _tfield.y=_bat_holder.y=150;
            stage.addEventListener(MouseEvent.CLICK,releaseTheBats);
        }
        private function createBG():void{
            if(_bg!=null)removeChild(_bg);
            var _bg:Bitmap=PerlinNoiseBg.getBatmanBG(1200,500);
            addChildAt(_bg,0);
        }
        
        public function releaseTheBats(e:Event=null):void{
            stage.removeEventListener(MouseEvent.CLICK,releaseTheBats);//make sure no kl3v4r git will click during the animation and cry bug ;)
            _tfield.visible=false;
            var b:Bat;
            for(var i:uint=0;i<_bat_holder.numChildren;i++){
                b=Bat(_bat_holder.getChildAt(i));
                b.addEventListener(Bat.FLIGHT_COMPLETE,handleBatFlightComplete);
                b.flyOff();
                b.visible=true;
            }
            var bs:*=new BatSound();
            bs.play();
        }

        public function handleBatFlightComplete(e:Event):void{
            _bat_holder.removeChild(Bat(e.target));
            complete_bats++;
            if(_bat_holder.numChildren==0)init();
        }
        
        private function addBats():void{
            if(_bat_holder!=null)removeChild(_bat_holder);
            _bat_holder=new Sprite();
            addChild(_bat_holder);
            var letter_lib:Object=new Object();
            var bd:BitmapData;
            var x:Number=100;
            var y:Number=300;
            var cur_char:String;
            var bounds:Rectangle;
            var bat:Bat;
            var tot:uint=0;
            for(var i:uint=0;i<_tfield.text.length;i++){
                cur_char=_tfield.text.charAt(i);
                if(letter_lib[cur_char]==null && cur_char!=" "){
                    bd=grabImageOfLetter(_tfield,i,_scale_amount,false,_pix_grab_bg_color);
                    letter_lib[cur_char]=getColoredPointsFromBitmapData(bd,_pix_grab_bg_color,_scale_amount);
                    tot+=letter_lib[cur_char].length;
                }
                bounds=_tfield.getCharBoundaries(i);
                var xtrans:int=-1;
                var ytrans:uint;
                for each(var p:Point in letter_lib[cur_char]){
                    bat=new Bat(.1);
                    if(xtrans==-1){
                        xtrans=uint(bat.width/2);
                        ytrans=uint(bat.height/2);
                    }
                    bat.x=bounds.x+p.x-xtrans;
                    bat.y=bounds.y+p.y;
                    _bat_holder.addChild(bat);
                    bat.visible=false;
                }
            }
        }
        
        //THE NEXT THREE FUNCTIONS "DO THE MAGIC"  SHOULD PROBABLY BE EXPORTED INTO A CLASS WITH A (STATIC?) METHOD WHICH RETURNS THE ARRAY
        
        private function grabImageOfLetter(tf:TextField,index:Number,scale:Number=1,transparent:Boolean=false,bg_color:uint=0x000000):BitmapData{
            var bounds:Rectangle=tf.getCharBoundaries(index);
            var og_bd:BitmapData=new BitmapData(bounds.width,bounds.height,transparent,bg_color);
            og_bd.draw(tf,new Matrix(1,0,0,1,-bounds.x,-bounds.y));
            var bd:BitmapData=new BitmapData(Math.ceil(bounds.width*scale),Math.ceil(bounds.height*scale),transparent,bg_color);
            bd.draw(og_bd,new Matrix(scale,0,0,scale,0,0));
            return bd;
        }
        
        private function getPointsFromTextField():Array{
            var bounds:Rectangle=getBounds(_tfield);
            _scale_amount=.12;
            var bd:BitmapData=new BitmapData(bounds.width*_scale_amount,bounds.height*_scale_amount,false,_pix_grab_bg_color);
            bd.draw(_tfield,new Matrix(_scale_amount,0,0,_scale_amount,-bounds.x,-bounds.y));
            var found:uint;
            var found_points:Array=getColoredPointsFromBitmapData(bd,_pix_grab_bg_color,_scale_amount);
            return found_points;
        }
        
        private var _min_xoffset:Number=-1;
        private var _max_xoffset:Number=2;
        private var _min_yoffset:Number=-2;
        private var _max_yoffset:Number=4;
        private function getColoredPointsFromBitmapData(bd:BitmapData,color_to_exclude:uint,scale_translate:Number=1):Array{
            var points:Array=new Array();
            var found:uint;
            for(var i:uint=0;i<bd.height;i++){
                for(var j:uint=0;j<bd.width;j++){
                    found=bd.getPixel(j,i);
                    if(found!=color_to_exclude){
                        points.push(new Point(j/scale_translate+_min_xoffset+Math.random()*_max_xoffset,i/scale_translate+_min_yoffset+Math.random()*_max_yoffset));
                    }
                }
            }
            return points;
        }
        
        
                
        private function addGlow():void{
            _tfield.filters=[new GlowFilter(0xCCCC00,.6,20,20)];
        }
        
        private function createTextField():void{
            if(_tfield!=null)removeChild(_tfield);
            _tfield=new TextField();
            _tfield.autoSize="left";
            _tfield.wordWrap=false;
            _tfield.multiline=false;
            _tfield.text="BAT MAN!";
            _tfield.selectable=false;
            
            var tformat:TextFormat=new TextFormat();
            //tformat.font="Garamond";
            tformat.font="Arial Black";
            tformat.size="120";
            tformat.letterSpacing=30;
            tformat.bold=true;
            tformat.color=_text_color;
            _tfield.setTextFormat(tformat);
            addChild(_tfield);
        }
    }
}