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

namespace Yamalib.Draw
{
    public static class DrawAssist
    {
        public class Context
        {

            #region メンバフィールド

            private Size m_originalSize;
            private int m_rad = 0;
            private int m_radBaseX;
            private int m_radBaseY;
            private bool m_enableRad = false;
            private float m_rate = 1.0f;
            private bool m_enableRate = false;
            private int m_offsetType;
            private Rect m_srcRect;
            private bool m_enableSrcRect = false;
            private Rect m_dstRect;
            private bool m_enableDstRect = false;

            #endregion

            /// コンストラクタ
            // OriginalSize は想定するオリジナルのサイズ
            // このサイズが本来のサイズと想定して、その他の描画オプションを実行する
            public Context(Size originalSize)
            {
                this.m_originalSize = originalSize;
            }

            /// サイズから、Rate 換算を行う（縦横比は維持されているものとし、x方向を基準にサイズを割り出します。
            public float GetSizeToRate(ITexture texture)
            {
                return this.m_originalSize.Cx / texture.Width;
            }

            /// 取得のみ(この参照を変更したりしないこと
            public Size OriginalSize()
            {
                return this.m_originalSize;
            }

            /// 拡大縮小
            public float Rate()
            {
                return this.m_rate;
            }
            public float Rate(float r)
            {
                return this.m_rate = r;
            }
            public bool EnableRate()
            {
                return this.m_enableRate;
            }
            public bool EnableRate(bool b)
            {
                return this.m_enableRate = b;
            }

            /// 拡大縮小で描画するときの、位置のオフセットタイプ
            /**
             * 
             * baseは転送元画像どの点が(x,y)に来るかを指定します。<BR>
             *	0	 : 左上。		1 : 上辺の中点　2:右上<BR>
             *	3	 : 左辺の中点	4 : 画像中心	5:右辺の中点<BR>
             *	6	 : 左下。　	7 : 下辺の中点	8:右下<BR>
             */
            public int OffsetType()
            {
                return m_offsetType;
            }
            public int OffsetType(int type)
            {
                return m_offsetType = type;
            }

            /// 回転
            public int Rad()
            {
                return m_rad;
            }
            public int RadBx()
            {
                return this.m_radBaseX;
            }
            public int RadBy()
            {
                return this.m_radBaseY;
            }
            public void SetRad(int rad_, int bx_, int by_)
            {
                m_rad = rad_;
                m_radBaseX = bx_;
                m_radBaseY = by_;
            }
            /// 回転を有効にする、転送元、転送先矩形は無視されます
            public bool EnableRad()
            {
                return this.m_enableRad;
            }
            public bool EnableRad(bool b)
            {
                return this.m_enableRad = b;
            }

            /// 転送先矩形の設定
            public Rect SrcRect()
            {
                return this.m_srcRect;
            }
            public Rect SrcRect(Rect rect)
            {
                return this.m_srcRect = rect;
            }
            public bool EnableSrcRect()
            {
                return this.m_enableSrcRect;
            }
            public bool EnableSrcRect(bool b)
            {
                return this.m_enableSrcRect = b;
            }

            /// 転送元矩形の設定
            public Rect DstRect()
            {
                return this.m_dstRect;
            }
            public Rect DstRect(Rect rect)
            {
                return this.m_dstRect = rect;
            }
            public bool EnableDstRect()
            {
                return this.m_enableDstRect;
            }
            public bool EnableDstRect(bool b)
            {
                return this.m_enableDstRect = b;
            }


        }

        public static Context SCREEN_SIZE;	// とりあえず背景用 640 * 480

        /// 静的コンストラクタ
        static DrawAssist()
        {
            Size size = new Size(640, 480);
            SCREEN_SIZE = new Context(size);
        }

        /// コンテクストにしたがって描画を行う
        public static void Blt(IScreen screen, ITexture texture, int x, int y, Context context)
        {
            Size size = new Size(0,0);
            Rect srcRect = new Rect();
            Rect dstRect = new Rect();

            if (context.EnableSrcRect())
            {
                Rect orgRect = context.SrcRect();
                if (!(orgRect == null))
                {
                    float xRate = (texture.Width / (float)context.OriginalSize().Cx);
                    float yRate = (texture.Height / (float)context.OriginalSize().Cy);
                    srcRect.Left = orgRect.Left * xRate;
                    srcRect.Right = orgRect.Right * xRate;
                    srcRect.Top = orgRect.Top * yRate;
                    srcRect.Bottom = orgRect.Bottom * yRate;
                    size.SetSize(
                        (int)(srcRect.Width * xRate),
                        (int)(srcRect.Height * yRate));
                }
            }

            if (context.EnableRad())
            {
                //-- 回転
                float rate = 1.0f;
                // 拡大率の換算
                if (context.EnableRate())
                {
                    rate = (context.OriginalSize().Cx * context.Rate())
                            / texture.Width;
                }
                else
                {
                    rate = context.GetSizeToRate(texture);
                }
                screen.BltRotate(texture, x, y, context.Rad(), rate, context.OffsetType());
            }
            else if (context.EnableRate())
            {
                //-- 拡大縮小
                if (context.EnableSrcRect() && !(context.SrcRect() == null))
                {
                    size.Cx = (int)(context.SrcRect().Width * context.Rate());
                    size.Cy = (int)(context.SrcRect().Height * context.Rate());

                }
                else
                {
                    size.SetSize((int)(context.OriginalSize().Cx * context.Rate()),
                          (int)(context.OriginalSize().Cy * context.Rate()));
                }

                screen.Blt(texture, x, y,
                        context.EnableSrcRect() ? srcRect : null, size);

            }
            else
            {
                if (context.EnableSrcRect())
                {
                    screen.Blt(texture, x, y, srcRect, size);
                }
                else
                {
                    // 通常描画
                    screen.Blt(texture, x, y, null, context.OriginalSize());
                }
            }
        }
    }
}
