using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.Ytl;
using Yanesdk.Draw;

namespace Kyojin.Component.Ending
{
    /** なんらかのアクションを行う動作定義するインターフェース */
    public interface Moment
    {
        /** 移動処理 */
        YanesdkResult Act(DrawInfo drawInfo);

        /** 初期状態に戻す */
        void Reset();

        /** リバースモードか？ */
        bool IsReverse
        {
            set;
            get;
        }
    }

    /** 拡縮・回転モーメントクラス */
    public class RateRadMoment : Moment
    {
        /** 移動処理 */
        public YanesdkResult Act(DrawInfo drawInfo)
        {
            if (!IsReverse)
            {
                drawInfo.X = drawInfo.X + AddX;
                drawInfo.Y = drawInfo.Y + AddY;
                drawInfo.Rad = drawInfo.Rad + AddRad;
                drawInfo.Rate = drawInfo.Rate + AddRate;
            }
            else
            {
                drawInfo.X = drawInfo.X - AddX;
                drawInfo.Y = drawInfo.Y - AddY;
                drawInfo.Rad = drawInfo.Rad - AddRad;
                drawInfo.Rate = drawInfo.Rate - AddRate;
            }

            return YanesdkResult.NoError;
        }


        /** 初期状態に戻す */
        public void Reset()
        {
            // とくになんもせんでよし
        }

        private float addAlpha = 1.0f;

        public float AddAlpha
        {
            get { return addAlpha; }
            set { addAlpha = value; }
        }
        private float m_addX = 0.0f;

        public float AddX
        {
            get { return m_addX; }
            set { m_addX = value; }
        }
        private float m_addY = 0.0f;

        public float AddY
        {
            get { return m_addY; }
            set { m_addY = value; }
        }
        private float m_addRad = 0.0f;

        public float AddRad
        {
            get { return m_addRad; }
            set { m_addRad = value; }
        }
        private float m_addRate = 0.0f;

        public float AddRate
        {
            get { return m_addRate; }
            set { m_addRate = value; }
        }
        private bool m_reverse = false;

        public bool IsReverse
        {
            get { return m_reverse; }
            set { m_reverse = value; }
        }


    }

    /** 描画するときの情報 */
    public class DrawInfo
    {
        public Color4ub? Color
        {
            get { return m_color; }
            set { m_color = value; }
        }

        public float X
        {
            get { return m_x; }
            set { m_x = value; }
        }

        public float Y
        {
            get { return m_y; }
            set { m_y = value; }
        }

        public float Rate
        {
            get { return m_rate; }
            set { m_rate = value; }
        }

        public float Rad
        {
            get { return m_rad; }
            set { m_rad = value; }
        }


        public int DrawOffset
        {
            get { return m_drawOffset; }
            set { m_drawOffset = value; }
        }

        /** 初期状態に戻す */
        public void Reset()
        {
            X = 0;	// 描画位置
            Y = 0;
            Rate = 1.0f;	// 拡大率
            Rad = 0;	// 回転角度
            DrawOffset = 0;
        }

        private Color4ub? m_color;	// 描画色
        private float m_x = 0;	// 描画位置
        private float m_y = 0;
        private float m_rate = 1.0f;	// 拡大率
        private float m_rad = 0;	// 回転角度
        private int m_drawOffset = 0;

    }

    public class FloatageTexture
    {

        #region メンバフィールド

        private ITexture m_texture;

        private readonly DrawInfo m_drawInfo;	// 瞬間の描画設定値を保存
        private Moment[] m_moments;

        #endregion


        /** コンストラクタ */
        public FloatageTexture()
        {
            m_drawInfo = new DrawInfo();
        }

        /** テクスチャの設定/取得 */
        public ITexture Texture
        {
            get { return m_texture; }
            set { m_texture = value; }
        }

        public DrawInfo DrawInfo
        {
            get { return m_drawInfo; }
        }

        /** モーメントの設定/取得 */
        public Moment[] Moments
        {
            get { return m_moments; }
            set { m_moments = value; }
        }

        /** オブジェクトプールに対応させる */
        public void Reset()
        {
            foreach (Moment moment in Moments)
            {
                moment.Reset();
            }
            DrawInfo.Reset();
        }

        /** 移動処理を行います */
        public YanesdkResult OnMove(IScreen screen)
        {
            // モーメントによって動作させる
            foreach (Moment moment in Moments)
            {
                moment.Act(DrawInfo);
            }

            return YanesdkResult.NoError;
        }


        /** 描画処理を行います */
        public YanesdkResult OnDraw(IScreen screen)
        {
            if (screen == null || Texture == null)
            {
                return YanesdkResult.InvalidParameter;
            }
            Draw(screen, Texture, DrawInfo);
            return YanesdkResult.NoError;
        }

        /** 指定した情報で描画する */
        private static YanesdkResult Draw(IScreen screen, ITexture texture, DrawInfo drawInfo)
        {
            // 変なのよこすな...
            if (screen == null || texture == null || drawInfo == null)
            {
                return YanesdkResult.InvalidParameter;
            }

            // ScreenColorのバックアップはしないよ...
            if (drawInfo.Color != null)
            {
                screen.SetColor(drawInfo.Color.Value);
            }
            else
            {
                screen.SetColor(255, 255, 255, 255);
            }

            if (drawInfo.Rad != 0 || drawInfo.Rate != 0.0f)
            {
                screen.BltRotate(texture, (int)drawInfo.X, (int)drawInfo.Y,
                        (int)drawInfo.Rad, drawInfo.Rate, drawInfo.DrawOffset);
            }
            else
            {
                screen.Blt(texture, (int)drawInfo.X, (int)drawInfo.Y);
            }
            return YanesdkResult.NoError;
        }
    }
}
