using System;
using Chernobyl.Collections.Generic.Event;
using Chernobyl.Input.Controls;
using Microsoft.Xna.Framework.Input;
namespace Chernobyl.Input.Xna.Controls.Mouse
{
    /// 
    /// The base class to all XNA Mouse buttons.
    ///  
    public abstract class XnaMouseButton : ButtonControl
    {
        /// 
        /// Initializes a new instance of the   class.
        ///  
        ///  The services class to use retrieve 
        /// dependencies from.
        ///  The mouse that this mouse button belongs to.
        protected XnaMouseButton(IEventCollection services, IMouse mouse) : base(services)
        {
            Mouse = mouse;
        }
        /// 
        /// An event that is raised when this button 
        /// is pushed down or turned on.
        ///  
        public override event EventHandler OnDown
        {
            add
            {
                // ensure we get updated by making ourself the mouses child.
                Control.MakeParentChild(Mouse, this);
                base.OnDownMethod += value;
            }
            remove
            {
                base.OnDownMethod -= value;
                if (base.OnDownMethod == null)
                    Control.SeparateParentChild(Mouse, this);
            }
        }
        /// 
        /// An event that is raised when this button
        /// has stopped being pushed down or is off.
        ///  
        public override event EventHandler OnUp
        {
            add
            {
                // ensure we get updated by making ourself the mouses child.
                Control.MakeParentChild(Mouse, this);
                base.OnUpMethod += value;
            }
            remove
            {
                base.OnUpMethod -= value;
                if (base.OnUpMethod == null)
                    Control.SeparateParentChild(Mouse, this);
            }
        }
        /// 
        /// An event that is raised when this button's
        /// state has changed.
        ///  
        public override event EventHandler OnChange
        {
            add
            {
                // ensure we get updated by making ourself the mouses child.
                Control.MakeParentChild(Mouse, this);
                base.OnChangeMethod += value;
            }
            remove
            {
                base.OnChangeMethod -= value;
                if (base.OnChangeMethod == null)
                    Control.SeparateParentChild(Mouse, this);
            }
        }
        /// 
        /// The mouse that this mouse button belongs to.
        ///  
        IMouse Mouse { get; set; }
    }
    /// 
    /// The left mouse button on a mouse.
    ///  
    public class LeftMouseButton : XnaMouseButton
    {
        /// 
        /// Constructor.
        ///  
        ///  The services class to use retrieve dependencies from.
        ///  The mouse that this mouse button belongs to.
        public LeftMouseButton(IEventCollection services, IMouse mouse) : base(services, mouse)
        {
            Name = "Mouse Left Button";
        }
        /// 
        /// True if the button is down, false
        /// if otherwise.
        ///  
        public override bool IsDown
        {
            get { return Microsoft.Xna.Framework.Input.Mouse.GetState().LeftButton == ButtonState.Pressed; }
            protected set { throw new NotImplementedException("You cannot set the state of a button."); }
        }
    }
    /// 
    /// The right mouse button on a mouse.
    ///  
    public class RightMouseButton : XnaMouseButton
    {
        /// 
        /// Constructor.
        ///  
        ///  The services class to use retrieve dependencies from.
        ///  The mouse that this mouse button belongs to.
        public RightMouseButton(IEventCollection services, IMouse mouse) : base(services, mouse)
        {
            Name = "Mouse Right Button";
        }
        /// 
        /// True if the button is down, false
        /// if otherwise.
        ///  
        public override bool IsDown
        {
            get { return Microsoft.Xna.Framework.Input.Mouse.GetState().RightButton == ButtonState.Pressed; }
            protected set { throw new NotImplementedException("You cannot set the state of a button."); }
        }
    }
    /// 
    /// The middle mouse button on a mouse.
    ///  
    public class MiddleMouseButton : XnaMouseButton
    {
        /// 
        /// Constructor.
        ///  
        ///  The services class to use retrieve dependencies from.
        ///  The mouse that this mouse button belongs to.
        public MiddleMouseButton(IEventCollection services, IMouse mouse) : base(services, mouse)
        {
            Name = "Mouse Middle Button";
        }
        /// 
        /// True if the button is down, false
        /// if otherwise.
        ///  
        public override bool IsDown
        {
            get { return Microsoft.Xna.Framework.Input.Mouse.GetState().MiddleButton == ButtonState.Pressed; }
            protected set { throw new NotImplementedException("You cannot set the state of a button."); }
        }
    }
    /// 
    /// The 1st extra mouse button on a mouse.
    ///  
    public class ExtraMouseButton1 : XnaMouseButton
    {
        /// 
        /// Constructor.
        ///  
        ///  The services class to use retrieve dependencies from.
        ///  The mouse that this mouse button belongs to.
        public ExtraMouseButton1(IEventCollection services, IMouse mouse) : base(services, mouse)
        {
            Name = "Mouse Extra Button 1";
        }
        /// 
        /// True if the button is down, false
        /// if otherwise.
        ///  
        public override bool IsDown
        {
            get { return Microsoft.Xna.Framework.Input.Mouse.GetState().XButton1 == ButtonState.Pressed; }
            protected set { throw new NotImplementedException("You cannot set the state of a button."); }
        }
    }
    /// 
    /// The 2nd extra mouse button on a mouse.
    ///  
    public class ExtraMouseButton2 : XnaMouseButton
    {
        /// 
        /// Constructor.
        ///  
        ///  The services class to use retrieve dependencies from.
        ///  The mouse that this mouse button belongs to.
        public ExtraMouseButton2(IEventCollection services, IMouse mouse) : base(services, mouse)
        {
            Name = "Mouse Extra Button 2";
        }
        /// 
        /// True if the button is down, false
        /// if otherwise.
        ///  
        public override bool IsDown
        {
            get { return Microsoft.Xna.Framework.Input.Mouse.GetState().XButton2 == ButtonState.Pressed; }
            protected set { throw new NotImplementedException("You cannot set the state of a button."); }
        }
    }
}