using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.GUIParts;
using Yanesdk.Draw;
using Yanesdk.Input;
using Yamalib.Util;

namespace Yamalib.GUI
{
    public class Scrollbar : ITextureGUI
    {
        #region メンバフィールド

        private const int LC_SCROLL_MAX = 65535;

        protected int x;
        protected int y;
        protected int m_pos;	//!< 現在のスクロールバーの位置
        private int m_texSz;
        private int m_sx;
        private int m_sy;
        private int m_vsz;	//!< 全体のサイズ
        private int m_catchOy;
        private int m_catch;	//!< スクロールバーをつかんでいるか
        private ControlContext controlContext;
        private bool visible;

        #endregion

        #region ITextureGUI メンバ

        public void OnInit(ControlContext cc)
        {
            controlContext = cc;
        }

        public void OnPaint(IScreen scr, ControlContext cc, int x, int y)
        {
            OnMove(scr);
            OnDraw(scr);
        }

        public bool Visible
        {
            get
            {
                return visible;
            }
            set
            {
                visible = true;
            }
        }

        #endregion


        /// スクロールバーのサイズ
        public void SetSize(int x_, int y_)
        {
            this.m_sx = x_;
            this.m_sy = y_;
        }

        /// 位置の設定
        public void SetXY(int x_, int y_)
        {
            this.x = x_;
            this.y = y_;
        }

        /// 位置の設定
        public void GetXY(out int x_, out int y_)
        {
            x_ = this.x;
            y_ = this.y;
        }

        /// 全体のトータルの高さを設定する
        public void SetScrollSize(int sz)
        {
            m_vsz = sz;
        }

        /// スクロールポジションの取得(0 - 1.0)
        public float GetScrollPos()
        {
            if (m_sy >= m_vsz) return 0.0f;
            int height = m_pos - y;
            if (height == 0)
            {
                return 0.0f;
            }

            return height / (float)m_sy;
        }


        /// 毎回呼び出すなり
        public virtual void OnMove(IScreen screen)
        {
            if (m_pos < this.y)
            {
                m_pos = this.y;
            }

            int mx, my;
            controlContext.MouseInput.GetPos(out mx, out my);
            m_texSz = GetBarHeight();
            if (controlContext.MouseInput.IsPress(MouseInput.Button.Left))
            {
                // キャッチしていない時に、スクロールバーをキャッチした
                if (0 == m_catch && PtInRect(mx, my, x, m_pos, x + m_sx, m_pos + m_texSz))
                {
                    m_catch = 1;
                    m_catchOy = m_pos - my;
                }

                // キャッチしてないときに、自分を選択された
                else if (0 == m_catch && PtInRect(mx, my, x, y, x + m_sx, y + m_sy))
                {
                    m_catch = 2;
                    m_catchOy = 0;
                }
            }
            else
            {
                m_catch = 0;
                // ホイール対応
                if (controlContext.MouseInput.IsPress(MouseInput.Button.XButton1))
                {
                    m_catch = 1;
                    m_catchOy = (m_pos - my) - (m_texSz / 2);
                }
                else if (controlContext.MouseInput.IsPress(MouseInput.Button.XButton2))
                {
                    m_catch = 1;
                    m_catchOy = (m_pos - my) + (m_texSz / 2);
                }
            }


            // キャッチしている
            if (m_catch != 0)
            {
                m_pos = my + m_catchOy;
                if (m_pos + m_texSz > this.y + m_sy)
                {
                    m_pos = this.y + m_sy - m_texSz;
                }
                else if (m_pos < this.y)
                {
                    m_pos = this.y;
                }
            }
        }

        /// 毎回呼び出す名なり
        public virtual void OnDraw(IScreen screen)
        {
            Color4ub colorOrg = YanesdkUtil.GetNowScreenColor(screen);
            screen.SetColor(0, 255, 0);
            screen.DrawPolygon(
                x, m_pos,
                x, m_pos + m_texSz,
                x + m_sx, m_pos + m_texSz,
                x + m_sx, m_pos
            );
            // 色戻し
            screen.SetColor(colorOrg);
        }

        #region 非公開メンバ

        /// 点が矩形の内側にあるかどうか
        protected static bool PtInRect(int px, int py, int left, int top, int right, int bottom)
        {
            return px >= left && px < right && py >= top && py < bottom;
        }

        /// バーの高さを取得
        protected virtual int GetBarHeight()
        {
            return (int)((m_sy / (float)m_vsz) * m_sy);
        }

        #endregion
    }


    /// <summary>
    /// テクスチャによる実装
    /// </summary>
    public class TextureScrollbar : Scrollbar
    {
        private ITexture m_barTex;

        public ITexture BarTexture
        {
            get { return m_barTex; }
            set { m_barTex = value; }
        }

        public override void OnDraw(IScreen screen)
        {
            screen.Blt(BarTexture, x - (int)(BarTexture.Width / 2), m_pos);
        }

        protected override int GetBarHeight()
        {
            return (int)m_barTex.Height;
        }
    }

}
