using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.Math;
using Yanesdk.Timer;
using Yanesdk.Draw;

namespace Yamalib.Draw.Effect
{
    public class MoveViewBase
    {
        #region フィールドメンバ

        protected readonly Rand rand = new Rand();
        protected readonly static SinTable st = SinTable.Instance;

        protected FixTimer timer;		//!< タイミングを計るタイマ
        protected TextureLoader tl;	//!< 画像をロードしてくる
        protected ITexture t;			//!< ごにょごにょするテクスチャ
        protected int movecounter;	//!< フレームをカウントする
        protected int posx;
        protected int posy;
        protected float rate;		//!< 拡大レート
        protected readonly Rect textrue_rc = new Rect();
        protected int elementNum;

        #endregion

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MoveViewBase()
        {
            rand.Randomize();
        }

        /// 画像をロードしてくるtextureloader
        public void SetTextureLoader(TextureLoader tl, int eleNum)
        {
            this.tl = tl;
            this.elementNum = eleNum;
            t = tl.GetTexture(GetNextRand());
        }

        /// 毎回呼び出すなり
        public virtual void OnMove(IScreen screen)
        {
        }

        /// 毎回呼び出すナリ
        public virtual void OnDraw(IScreen screen)
        {
        }

        #region 非公開メンバ

        /// <summary>
        /// テクスチャローダに設定されているファイルから次の適当なテクスチャ番号を取得します
        /// </summary>
        /// <returns></returns>
        protected int GetNextRand()
        {
            return rand.GetRand(elementNum);
        }


        #endregion
    }

    /// <summary>
    /// 背景ブレ描画クラス:手ぶれを再現する
    /// </summary>
    public class MoveView : MoveViewBase
    {
        #region フィールドメンバ

        private int rad;			//!< 角度
        private int rad_speed;		//!< 角速度

        private int rand_x;		//!< 移動量に対するさらなるランダム幅
        private int amplitude;

        private bool radiate = false;
        private int radiate_x;
        private int radiate_y;

        #endregion

        /// <summary>
        ///  角速度の設定
        /// </summary>
        public int AngleSpeed
        {
            get { return rad_speed; }
            set { rad_speed = value; }
        }

        /// <summary>
        /// ランダム幅の設定
        /// </summary>
        public int RandX
        {
            get { return rand_x; }
            set { rand_x = value; }
        }

        /// <summary>
        /// 振幅を設定する
        /// </summary>
        public int Amplitude
        {
            get { return amplitude; }
            set { amplitude = value; }
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="screen"></param>
        public override void OnDraw(IScreen screen)
        {
            if (tl == null)
            {
                return;
            }

            rad += rad_speed;
            if (rad > Y4dConst.C_RAD_MAX)
            {
                rad = 0;
            }

            if (radiate)
            {
                posx += radiate_x;
                posy += radiate_y;

                float sx = t.Width * rate;
                float sy = t.Height * rate;

                // 画像の矩形を求めていずれかの点が画面内にあれば終了
                textrue_rc.Left = posx - sx / 2;
                textrue_rc.Right = posx + sx / 2;
                textrue_rc.Top = posy - sy / 2;
                textrue_rc.Bottom = posy + sy / 2;

                if (textrue_rc.Left > 0 || textrue_rc.Top > 0
                    || textrue_rc.Right < screen.Width || textrue_rc.Bottom < screen.Height)
                {
                    radiate = false;
                    movecounter = 0;
                    posx = 320;
                    posy = 240;
                    rate = 1.5f;
                    rad = 0;
                    radiate_x = 0;
                    radiate_x = 0;

                    int no = rand.GetRand(elementNum);
                    t = tl.GetTexture(no);
                }
            }
            movecounter++;

            posx += st.Sin(rad, amplitude);
            if (rand_x != 0)
            {
                posx += rand.GetRand(rand_x) - rand_x / 2;	// ランダムのブレをいれる
            }
            posy += rand.GetRand(60) - 30;
            rate += 0.03f;

            screen.SetColor(255, 255, 255, 128);
            screen.BltRotate(t, posx, posy, 0, rate, 4);

            // 画面を放散させて次の画面に
            if (movecounter == 175)
            {
                radiate = true;
                radiate_x = rand.GetRand(50) + 15;
                radiate_y = rand.GetRand(50) + 10;

                if (rand.GetRand(2) != 0) radiate_x = -radiate_x;
                if (rand.GetRand(2) != 0) radiate_y = -radiate_y;
            }
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MoveView()
            : base()
        {

            this.timer = null;
            posx = 320;
            posy = 240;
            rad = 0;
            rad_speed = 36;
        }

    }
}
