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.*;
    import caurina.transitions.Tweener;

    [SWF(width="400", height="400", backgroundColor="#FFFFFF", frameRate="30")]

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

        private var cubeObj : DisplayObject3D;

        private var trans:TextField;        ///< 画面に表示するテキスト
        private var transFormat:TextFormat; ///< テキストフォーマット
        private var num:int = 38;   ///< どのtransitionを使っているかをあらわす値

        /// transition一覧配列
        private var names:Array = [
          "linear",
          "easeinquad",    "easeoutquad",    "easeinoutquad",    "easeoutinquad",
          "easeincubic",   "easeoutcubic",   "easeinoutcubic",   "easeoutincubic",
          "easeinquart",   "easeoutquart",   "easeinoutquart",   "easeoutinquart",
          "easeinquint",   "easeoutquint",   "easeinoutquint",   "easeoutinquint",
          "easeinsine",    "easeoutsine",    "easeinoutsine",    "easeoutinsine",
          "easeincirc",    "easeoutcirc",    "easeinoutcirc",    "easeoutincirc",
          "easeinexpo",    "easeoutexpo",    "easeinoutexpo",    "easeoutinexpo",
          "easeinelastic", "easeoutelastic", "easeinoutelastic", "easeoutinelastic",
          "easeinback",    "easeoutback",    "easeinoutback",    "easeoutinback",
          "easeinbounce",  "easeoutbounce",  "easeinoutbounce",  "easeoutinbounce"
        ];

        static public const
            planeSize:int = 300,    ///< Planeオブジェクト1辺の長さ
            segment:int = 1,        ///< 面の分割数
            SCREEN_W:int = 400,    ///< テクスチャの幅
            SCREEN_H:int = 400;    ///< テクスチャの高さ

        // _______________________________________________________________________
        //                                                             Constructor
        public function Pv3dTweener():void
        {
            // ベーススプライト作成。マウスクリック用
            var base:Sprite=new Sprite();
            base.graphics.beginFill(0xB9CCD5);
            base.graphics.drawRect(0,0,SCREEN_W,SCREEN_H);
            base.graphics.endFill();
            addChild(base);

            stage.quality   = "MEDIUM";
            stage.scaleMode = "noScale";
            stage.align = StageAlign.TOP_LEFT;

            init3D();

            // 画面に表示するテキスト
            transFormat = TextButton.makeTextFormat(24, 0x000000);

            trans = new TextField();
            trans.text = names[num];
            trans.x = 10;
            trans.width = SCREEN_W;
            trans.mouseEnabled = false;
            trans.selectable = false;
            //trans.autoSize = TextFieldAutoSize.RIGHT;
            trans.filters = filters;
            base.addChild(trans);

            setTransition();

            var addButton:TextButton = new TextButton(80, 20, "add");
            addButton.x = 10;
            addButton.y = trans.y + trans.textHeight + 10;
            addChild(addButton);
            addButton.addEventListener( MouseEvent.CLICK, addButtonClick );

            var decButton:TextButton = new TextButton(80, 20, "dec");
            decButton.x = 10;
            decButton.y = addButton.y + addButton.height + 10;
            addChild(decButton);
            decButton.addEventListener( MouseEvent.CLICK, decButtonClick );

            this.addEventListener(Event.ENTER_FRAME, loop3D);
            this.stage.addEventListener(Event.RESIZE, onStageResize);
            base.addEventListener(MouseEvent.CLICK,mouseClickHandler);

        }

        // _______________________________________________________________________
        //                                                                  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*3;
            camera.focus = 500;
            camera.zoom = 1;

            //マテリアル設定
            var ml:MaterialsList = new MaterialsList(
            {
                all: new ColorMaterial(0xE5A800,1),
                front: new ColorMaterial(0x00E5DA,1),
                back: new ColorMaterial(0x56BFBA,1),
                right: new ColorMaterial(0x3200E5,1),
                left: new ColorMaterial(0x3200E5,1),
                top: new ColorMaterial(0xBF7956,1),
                bottom: new ColorMaterial(0xE5A800,1)
            });

            /* この書き方もOK           
            var ml:MaterialsList = new MaterialsList();
            ml.addMaterial(new ColorMaterial(0xff0000,1), 'all');
            ml.addMaterial(new ColorMaterial(0xff0000,1), 'front');
            ml.addMaterial(new ColorMaterial(0x00ff00,1), 'back');
            ml.addMaterial(new ColorMaterial(0x0000ff,1), 'right');
            ml.addMaterial(new ColorMaterial(0xff00ff,1), 'left');
            ml.addMaterial(new ColorMaterial(0x00ffff,1), 'top');
            ml.addMaterial(new ColorMaterial(0xffff00,1), 'bottom');
            */

            // オブジェクト生成            
            cubeObj = new Cube( ml, planeSize, planeSize, planeSize, 1, 1, 1 );
            scene.addChild(cubeObj);
            cubeObj.rotationX = 45;
            cubeObj.rotationY = 45;

            var filter:Array = new Array;
            filter.push( new DropShadowFilter() );

            cubeObj.container.filters = filter;
        }

        /// 現在のtransitionを画面の文字に設定
        private function setTransition():void{
            trans.text = num + ":" + names[num];
            trans.setTextFormat(transFormat);
        }

        //マウスクリックイベントの処理
        private function mouseClickHandler(evt:MouseEvent):void {
            //var rot:int = cubeObj.rotationY + 90;
            //Tweener.addTween( cubeObj , { rotationY:rot, time:1 , transition:names[num] });

            // 中心点からの距離を求めて距離に応じて速度決定
            var dec:Number = Math.sqrt(Math.pow(mouseX-SCREEN_W/2,2) + Math.pow(mouseY-SCREEN_H/2,2));
            var decmax:Number = Math.sqrt(Math.pow(SCREEN_W/2,2) + Math.pow(SCREEN_H/2,2));

            var t:Number = 6 - 6*dec/decmax + 2;

            var rotX:Number = 720*(mouseY-SCREEN_H/2)/dec + cubeObj.rotationX;
            var rotY:Number = 720*(mouseX-SCREEN_W/2)/dec + cubeObj.rotationY;

            Tweener.addTween( cubeObj , { rotationX:rotX, rotationY:rotY, time:t , transition:names[num] });
        }

        // _______________________________________________________________________
        //                                                                    Loop
        private function loop3D( event:Event ):void
        {
            //レンダリング
            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;
        }

        /// addボタンクリックの処理
        private function addButtonClick(event:MouseEvent):void
        {
            num++;
            if(num >= names.length){
                num = 0;
            }
            setTransition();
        }

        /// decボタンクリックの処理
        private function decButtonClick(event:MouseEvent):void
        {
            num--;
            if(num < 0){
                num = names.length - 1;
            }
            setTransition();
        }

    }
}