using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.Input;
using Yamalib.Yanesdkext.System;

namespace Yamalib.Input
{
    public interface IMouseInput : IDisposable
    {
        ///	マウスカーソルを表示する
        void Show();

        ///	マウスカーソルを非表示にする
        void Hide();

        ///	マウスの位置取得
        /**
            マウスが画面外にあるときは最後に取得した値が返ります。
            すなわち、画面サイズが640×480ならば、xは0〜639,yは0〜479までの
            値しか返らないことが保証されます。
        */
        void GetPos(out int x, out int y);

        ///	マウスの位置を設定
        /**
            SDLのマウスの位置設定イベントが発生する。
        */
        void SetPos(int x, int y);

        ///	ボタンが押し下げられているかを判定する関数
        bool IsPress(MouseInput.Button e);
        bool IsPush(MouseInput.Button e);
        bool IsWheelUp { get;}
        bool IsWheelDown { get;}

        /// 内部状態を更新する
        void Update();

        /// <summary>
        ///  初期化
        /// </summary>
        void Reset();

        void SetLogicalPos(int x, int y);
    }

    public class MouseInputImpl : MouseInput, IMouseInput
    {
        #region IMouseInput メンバ


        public bool IsWheelUp
        {
            get
            {
                return SDLFrameEx.IsWheelUp;
            }
        }

        public bool IsWheelDown
        {
            get
            {
                return SDLFrameEx.IsWheelDown;
            }
        }

        #endregion
    }

    public class MouseInputNullDevice : IMouseInput
    {
        public void Show() { }
        public void Hide() { }
        public bool IsHide() { return false; }
        public void GetPos(out int x, out int y) { x = 0; y = 0; }
        public void SetPos(int x, int y) { }
        public bool IsPress(MouseInput.Button e) { return false; }
        public bool IsPush(MouseInput.Button e) { return false; }
        public void Reset() { }
        public void SetLogicalPos(int x, int y) { }
        public void Update() { }
        public void Dispose() { }
        public bool IsWheelUp { get { return false; } }
        public bool IsWheelDown { get { return false; } }


        /// NullDeviceを取得する
        public static MouseInputNullDevice GetInstance()
        {
            if (m_instance == null)
            {
                m_instance = new MouseInputNullDevice();
            }
            return m_instance;
        }

        /// 一枚札
        private MouseInputNullDevice()
        {
        }
        private static MouseInputNullDevice m_instance;


    }

    /**
        任意のタイミングでデバイスをNULLデバイスに切り替える仕組みを
        実装しているMouseInput
    */
    public class NullableMouseInput : IMouseInput
    {
        public void Show() { Get().Show(); }
        public void Hide() { Get().Hide(); }
        public bool IsHide() { return false; }
        public void GetPos(out int x, out int y) { Get().GetPos(out x, out y); }
        public void SetPos(int x, int y) { Get().SetPos(x, y); }
        public void SetLogicalPos(int x, int y) { }
        public void Reset() { }
        public bool IsPress(MouseInput.Button e) { return Get().IsPress(e); }
        public bool IsPush(MouseInput.Button e) { return Get().IsPush(e); }
        public void Update() { Get().Update(); }
        public void Dispose() { GetOriginal().Dispose(); }
        public bool IsWheelUp { get { return Get().IsWheelUp; } }
        public bool IsWheelDown { get { return Get().IsWheelDown; } }

        /// ヌルデバイスに切り替える
        public void Disable()
        {
            m_enable = false;
        }
        /// ノーマルデバイスに切り替える
        public void Enable()
        {
            m_enable = true;
        }
        /// デバイスが有効になっているか？
        public bool IsEnable()
        {
            return m_enable;
        }
        /// オリジナルのデバイスを取得する
        public IMouseInput GetOriginal()
        {
            return this.m_mouse;
        }
        /// コンストラクタ
        public NullableMouseInput(IMouseInput mouse)
        {
            m_mouse = mouse;
            m_enable = true;
        }


        private IMouseInput Get()
        {
            return m_enable ? m_mouse : m_nullMouse;
        }

        private static IMouseInput m_nullMouse = MouseInputNullDevice.GetInstance();
        private IMouseInput m_mouse;
        private bool m_enable;
    }


}
