package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.text.*;
    import caurina.transitions.Tweener;

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

    public class DotProduct extends Sprite
    {
        //リソースクラス
        [Embed(source='dotp_bg.png')]
        private var Image0:Class;

        private var sp:Shape;   ///< 画面上の円
        private var up:Boolean; ///< 円の位置。trueなら上。falseなら下。
        private var dx:Number;  ///< X座標の移動量。スピード。

        static public const
            SCREEN_W:int = 400,    ///< 画面の幅
            SCREEN_H:int = 300;    ///< 画面の高さ

        /// コンストラクタ
        public function DotProduct()
        {
            var bg:DisplayObject = new Image0();
            addChild(bg);

            // filter作成
            var filters:Array = new Array;
            filters.push( new DropShadowFilter(2, 45, 0x000000, 1.0, 5, 5, 1, BitmapFilterQuality.HIGH, false, false, false));

            // 円の作成
            sp = new Shape();
            sp.x = SCREEN_W/2;
            sp.y = SCREEN_H/2;
            sp.graphics.beginFill(0xff0000);         //塗り潰し色
            sp.graphics.lineStyle(5, 0x000000);
            sp.graphics.drawCircle(0, 0, 20);
            sp.graphics.endFill();                //塗り潰し終了
            sp.filters = filters;
            addChild(sp);

            dx = 10;
            setSpPos(true);

            // メインループの追加       
            this.addEventListener(Event.ENTER_FRAME, mainLoop);
        }

        /**
         * ボールの高さ位置決定
         * @param true なら上に。falseなら下に。
         */
        private function setSpPos( param:Boolean ):void{

            var descY:Number;
            if(param == true){
                descY = SCREEN_H/4;
            }else{
                descY = SCREEN_H*3/4;
            }

            Tweener.addTween( sp, { y:descY, time:0.7, transition:"easeoutback" });
            up = param;
        }

        /**
         * ある点を通過したかどうかを判定する関数。
         * @param prevx 移動前のX座標
         * @param nowx 移動後のX座標
         * @param throughx 通過したか判定したいX座標の点
         * @return 通過していたらtrue。通過していないならfalse。
         */
        private function throughPoint(prevx:Number, nowx:Number, throughx:Number):Boolean {

            /// (throughx - prevx) = 0 と、(throughx - sp.x) = 0の両方で判定してしまうと2点で反応して使い勝手が悪いので
            if( (throughx - prevx) == 0 ){
                return false;
            }

            /// 一次元ベクトルの内積として考える。通り過ぎたなら2つのベクトルのなす角は180度。
            /// だから内積はcos180となり、かならず0以下になるはず
            if( (throughx - prevx)*(throughx - sp.x) <= 0 ){
                return true;
            }

            return false;
        }

        /**
         * メインループ
         * @param event
         */
        private function mainLoop( event:Event ):void {

            /// ボールの移動前の位置を保存
            var prevx:Number = sp.x;
            /// ボールを移動させる
            sp.x += dx;

            /// 画面の真ん中を通り過ぎたらを判定。
            if( throughPoint(prevx, sp.x, 200) == true ){
                setSpPos( up == true ? false : true );
            }

            /// 画面の端にきたら、移動方向を反転させる。
            if( throughPoint(prevx, sp.x, 0) == true    ||
                throughPoint(prevx, sp.x, SCREEN_W) == true ){
                dx *= -1;
            }
        }

    }
}