<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    xmlns:pv3d="net.borishorn.flex.pv3d.*"
    layout="absolute"
    backgroundColor="0x000000"
    backgroundGradientColors="[0x444444,0x000000]" 
    creationComplete="init()"
     viewSourceURL="srcview/index.html">

    <mx:Script>
        <![CDATA[
        
        import mx.collections.ArrayCollection;
        import be.nascom.util.MathFunctions;
        
        import be.nascom.component.FlexSimpleTraceBox;
        import be.nascom.component.FlexSimpleTraceBox;
        //import caurina.transitions.*;
        
        import org.papervision3d.cameras.*;
        import org.papervision3d.materials.*;
        import org.papervision3d.objects.*;
        import org.papervision3d.scenes.*;

        import flash.display.Sprite;
        import flash.display.Stage;
        import flash.events.*;
        import flash.geom.Point;
        import flash.geom.Rectangle;

        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.geom.Matrix;
        
        import flash.events.KeyboardEvent;
        import flash.ui.Keyboard;
            
        [Embed(source="assets/images/flex.png")]
        public static const FLEX_ICON:Class;
        
        [Embed(source="assets/images/star.png")]
        public static const STAR_ICON:Class;
        
        [Embed(source="assets/images/nascom.png")]
        public static const NASCOM_ICON:Class;
        
        [Embed(source="assets/images/pirate_smiley.png")]
        public static const PIRATE_ICON:Class;
        
        [Embed(source="assets/images/sakri_icon.png")]
        public static const SAKRI_ICON:Class;
                    
        
                    
        //from net.borishorn.flex.pv3d.utils
        public static function createBitmapMaterial(bm:Bitmap, oneSided:Boolean = true):BitmapMaterial{
            var texture:BitmapData = new BitmapData(bm.width, bm.height, true,0x00ffffff);
            texture.draw(bm, new Matrix());
            var material:BitmapMaterial = new BitmapMaterial(texture);
            material.oneSide = oneSided;
            
            return material;
        }
            
        public var _container:Sprite;
        private var _camera:Camera3D;
        private var _scene:Scene3D;
        
        private var _cam_z_angle:Number=180;
        private var _cam_rotation_radius:uint=1000;
        
        private var _cam_y_height:Number=0;
        
        private var _cam_min_y:uint=200;        
        private var _cam_max_y:uint=200;        

        private var _planes:Array;
        private var _generated_text_field:TextField;

        [Bindable]
        public var fonts:ArrayCollection=new ArrayCollection([{name:"Times New Roman",font:"embedded_times"},{name:"Comic Sans",font:"embedded_comic"},{name:"Arial Black",font:"embedded_arial_black"}]);
        
        [Bindable]
        public var icons:ArrayCollection=new ArrayCollection([    {name:"Sakri favicon",_class:SAKRI_ICON},
                                                                {name:"Nascom Logo",_class:NASCOM_ICON},
                                                                {name:"Star",_class:STAR_ICON},
                                                                {name:"Flex Logo",_class:FLEX_ICON},
                                                                {name:"Pirate Smiley",_class:PIRATE_ICON}]);

        [Bindable]
        public var intro_text:String="Enter some text, keep it short or crash your browser, then render as many times as you like! Use <b>UP, DOWN, LEFT and RIGHT</b> keys to change camera angle! Choose font and 'render icon' from dropdowns.";
    
        public function init():void{
            FlexSimpleTraceBox.setTextArea(output);
            _planes=new Array();
            _container = new Sprite();
            papergrid.addChild(_container);
            _scene = new Scene3D(_container);
            _camera=new Camera3D();
            _camera.zoom = 5;
        }

        public function handleKeyDown(e:KeyboardEvent=null):void{
            if(!_planes.length)return;
            switch(e.keyCode){
                case Keyboard.LEFT:
                    rotateCameraZ(-5);
                    break;
                case Keyboard.RIGHT:
                    rotateCameraZ(5);                    
                    break;
                case Keyboard.UP:
                    rotateCameraY(-20);
                    break;
                case Keyboard.DOWN:
                    rotateCameraY(20);
                    break;
            }
        }

        private function render(e:Event=null):void{
            if(!_planes.length)return;
            _scene.renderCamera(_camera);
        }

        private function removePreviousText():void{
            while(_planes.length){
                _scene.removeChild(Plane(_planes.pop()));
            }
            _planes=new Array();
        }


        private function renderText():void{
            stage.removeEventListener(KeyboardEvent.KEY_DOWN,handleKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_DOWN,handleKeyDown);
            removePreviousText();
            
            //CREATE SAMPLE TEXT FIELD, TAKE A SNAPSHOT OF IT
            _generated_text_field=createSampleTextField();
            temp_uic.addChild(_generated_text_field);
            var bounds:Rectangle=temp_uic.getBounds(_generated_text_field);
            var bmd:BitmapData=new BitmapData(bounds.width,bounds.height,true,0);
            bmd.draw(temp_uic);
            
            _cam_rotation_radius=bmd.width*20;//20 is ARBITRARY...A GUESS
            var xoffset:uint=Math.round((bmd.width/2)*50);
            var yoffset:uint=Math.round((bmd.height/2)*50);
            var i:uint=0, j:uint=0, k:int;
            var pixel:uint;
            var p:Plane;
            var cm:BitmapMaterial;
            var num_depth_items:uint;
            
            var num_depth_divider:uint=70;
            var max_num_depth_items:Number=255/num_depth_divider;
            var double_mndi:Number=max_num_depth_items*2;
            var offset:Number;
            
            //run through all pixels, see which ones are not fully transparent, and place "Planes" in appropriate positions
            for(i=0;i<bmd.width;i++){
                for(j=0;j<bmd.height;j++){
                    pixel=bmd.getPixel32(i,j);
                    if(pixel!=0x00000000){
                        num_depth_items=Math.ceil( ( (pixel>>24) & 0xFF ) / num_depth_divider ); // BASED ON ALPHA OF PIXEL
                        offset=max_num_depth_items-num_depth_items;
                        for(k=-num_depth_items;k<=num_depth_items;k++){
                            cm = createBitmapMaterial(getCurrentMaterial( ((offset+k+num_depth_items)/double_mndi) ));
                            cm.oneSide = false;
                            p = new Plane(cm, 50, 50);
                            p.x=i*50-xoffset;
                            p.y=(bmd.height- j) * 50-yoffset;
                            p.z-=k*30;
                            _scene.addChild(p);
                            _planes.push(p);                            
                        }
                    }
                }
            }
            temp_uic.removeChild(_generated_text_field);
            rotateCameraZ(0);
        }

        private function getCurrentMaterial(color_offset:Number):Bitmap{
            var icon_class:Class=Class(icons_list.selectedItem._class);
            var bm:Bitmap=Bitmap(new icon_class());
            var ct:ColorTransform=new ColorTransform(color_offset,color_offset,color_offset);
            bm.bitmapData.colorTransform(bm.bitmapData.rect,ct);
            return bm;
        }
        
        private function createSampleTextField():TextField{
            var tf:TextField=new TextField();
            tf.autoSize="left";
            tf.text=text_to_create.text;
            tf.selectable=false;
            tf.embedFonts=true;
            var tformat:TextFormat=new TextFormat();
            tformat.bold=true;
            tformat.size=20;
            tformat.font=fonts_list.selectedItem.font;
            tf.setTextFormat(tformat);
            return tf;
        }
    
    
            
        private function rotateCameraZ(num:Number):void{
            _cam_z_angle+=num;
            _cam_z_angle=_cam_z_angle%360;

            var rad:Number=MathFunctions.degreesToRadians(_cam_z_angle);
            _camera.x=Math.sin(rad)*_cam_rotation_radius;
            _camera.z=Math.cos(rad)*_cam_rotation_radius;
            render();
            
        }
        
        private function rotateCameraY(num:Number):void{
            _cam_y_height+=num;
            _camera.y=_cam_y_height;
            render();            
        }


        ]]>
    </mx:Script>
    
    <mx:Style>
        
        @font-face{
            src: local("Arial Black");
            fontFamily:"embedded_arial_black";
        }
        
        @font-face{
            src: local("Comic Sans MS");
            fontFamily:"embedded_comic";
        }
        
        @font-face{
            src: local("Times New Roman");
            fontFamily:"embedded_times";
        }
        
    </mx:Style>

        <mx:UIComponent id="temp_uic" />
        <mx:UIComponent id="papergrid" x="{width/2}" y="{height/2}" />
        
        <mx:Panel horizontalCenter="0" top="40" title="Teh Awesmoe Papervision 3d text effect toy?! Whussup?!" >
            <mx:Spacer height="5" />
            <mx:Text width="100%" htmlText="{intro_text}" paddingLeft="10" paddingRight="10"  />
            <mx:HBox paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="5">
                <mx:ComboBox id="fonts_list" dataProvider="{fonts}" labelField="name" />
                <mx:ComboBox id="icons_list" dataProvider="{icons}" labelField="name" />                
                <mx:TextInput id="text_to_create" text="SAK" width="200" fontSize="14" fontWeight="bold" />
                <mx:Button label="create hott text effect" click="renderText();" />
            </mx:HBox>
        </mx:Panel>
                

        
    <mx:VBox bottom="5" right="5" visible="false">
        <mx:TextArea id="output" width="300" height="400"  />
        <mx:Button label="clear" click="{FlexSimpleTraceBox.clear()}"  />        
    </mx:VBox>
        
</mx:Application>