// mxmlc -output ./bin/FilterPv3D.swf -benchmark=true -default-size 240 240 -default-frame-rate=60 -default-background-color=0xFFFFFF FilterPv3D.as

package
{
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.text.*;

    import org.papervision3d.scenes.*;
    import org.papervision3d.objects.*;
    import org.papervision3d.cameras.*;
    import org.papervision3d.materials.*;

    [SWF(backgroundColor=0xffffff)]

    public class FilterPv3D extends Sprite
    {
        // _______________________________________________________________________
        //                                                                  vars3D
        private var container : Sprite;
        private var scene     : MovieScene3D;
        private var camera    : Camera3D;

        private var planeObj : Plane;
        private var planeSize : int = 300;      //Planeオブジェクト1辺の長さ
        private var segment   : int = 1;        //面の分割数
        private var material  : BitmapMaterial;
        private var bmpData   : BitmapData;

        private var valx      : Number = 0;
        private var valy      : Number = 0;
        private var label     : TextField;

        private var filterState: uint = 0;
        static private const
            FL_BLUR:uint = 0,
            FL_SHADOW:uint = 1,
            FL_GLOW:uint = 2,
            FL_BEVEL:uint = 3,
            FL_BEVEL_AND_SHADOW:uint = 4,
            FL_SHADOWN_AND_BLUE:uint = 5,
            FL_NONE:uint = 6;

        static public const
            TEXTURE_W:int = 240,    ///< テクスチャの幅
            TEXTURE_H:int = 240;    ///< テクスチャの高さ

        // _______________________________________________________________________
        //                                                             Constructor
        public function FilterPv3D():void
        {
            stage.frameRate = 60;
            stage.quality   = "MEDIUM";
            stage.scaleMode = "noScale";
            stage.align = StageAlign.TOP_LEFT;
            this.addEventListener(Event.ENTER_FRAME, loop3D);
            this.stage.addEventListener(Event.RESIZE, onStageResize);
            this.stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);

            label=new TextField();
            label.autoSize=TextFieldAutoSize.LEFT;
            addChild(label);

            init3D();

            setFilter(filterState);
        }

        //マウスダウンイベントの処理
        private function mouseDownHandler(evt:MouseEvent):void {
            ++filterState;
            if (filterState > FL_NONE){
                filterState=0;
            }
            setFilter(filterState);
        }

        //フィルタの指定
        private function setFilter(type:int):void {
            //フィルタの生成
            var filters:Array=new Array();
            switch(type){
            case FL_BLUR:
                label.text="ブラーフィルタ";
                filters.push(new BlurFilter(8,8,BitmapFilterQuality.HIGH));
                break;
            case FL_SHADOW:
                label.text="ドロップシャドウフィルタ";
                filters.push(new DropShadowFilter(10, 45, 0x000000, 0.5, 5, 5, 1, BitmapFilterQuality.HIGH, false, false, false));
                break;
            case FL_GLOW:
                label.text="グローフィルタ";
                filters.push(new GlowFilter(0x00FFFF, 0.5, 20,20, 2, BitmapFilterQuality.HIGH, false, false));
                filters.push(new GlowFilter(0x00FFFF, 1, 40, 40, 2, BitmapFilterQuality.HIGH, true, false));
                break;
            case FL_BEVEL:
                label.text="ベベルフィルタ";
                filters.push(new BevelFilter(10,45,0xddddff,0.5,0x000000,0.8));
                break;
            case FL_BEVEL_AND_SHADOW:
                label.text="ベベル+ドロップシャドウ フィルタ";
                filters.push(new BevelFilter(10,45,0xddddff,0.5,0x000000,0.8));
                filters.push(new DropShadowFilter(10, 45, 0x000000, 0.5, 5, 5, 1, BitmapFilterQuality.HIGH, false, false, false));
                break;
            case FL_SHADOWN_AND_BLUE:
                label.text="シャドウ+ブラー フィルタ";
                filters.push(new DropShadowFilter(10, 45, 0x000000, 0.5, 5, 5, 1, BitmapFilterQuality.HIGH, false, false, false));
                filters.push(new BlurFilter(8,8,BitmapFilterQuality.HIGH));
                break;
            case FL_NONE:
                label.text="なし";
                break;
            }

            //フィルタの指定
            filterState = type;
            planeObj.container.filters = filters;
        }

        // _______________________________________________________________________
        //                                                                  Init3D
        private function init3D():void
        {
            //コンテナ生成
            this.container = new Sprite();
            addChild(this.container);
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;

            //シーン生成、MovieSchene3Dでないと、DisplayObject3Dのcontainerが作製されないので、これ。
            scene = new MovieScene3D( this.container );

            //カメラ設定
            camera = new Camera3D();
            camera.z = -planeSize;
            camera.focus = 500;
            camera.zoom = 1;

            //BitmapDataの作成。Bitmapに角丸矩形を描く
            bmpData = new BitmapData(TEXTURE_W,TEXTURE_H,true,0x00000000);
            var rrect:Shape = new Shape();
            rrect.graphics.lineStyle(0,0x47FF8A);
            rrect.graphics.beginFill(0x47FF8A);
            rrect.graphics.drawRoundRect(0,0,TEXTURE_W,TEXTURE_H,50);
            rrect.graphics.endFill();
            bmpData.draw(rrect);

            //マテリアル設定
            material = new BitmapMaterial(bmpData);
            material.oneSide = false;
            material.smooth = true;

            //Planeオブジェクト生成
            planeObj = new Plane( material, planeSize, planeSize, segment, segment);

            // sceneに対してaddChildする。sceneに対してaddChildしたものにaddChild(孫関係)だとcontainerが作製されない。
            scene.addChild( planeObj );
        }

        // _______________________________________________________________________
        //                                                                    Loop
        private function loop3D( event:Event ):void
        {
            //valx += 1;
            valy += 0.5;
            planeObj.rotationY = valx;
            planeObj.rotationX = valy;

            //レンダリング
            this.scene.renderCamera( camera );
        }

        // _______________________________________________________________________
        //                                                           onStageResize
        private function onStageResize(event:Event):void
        {
            this.container.x = this.stage.stageWidth  / 2;
            this.container.y = this.stage.stageHeight / 2;
        }

    }
}