using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System;

namespace XELF.Sphynx {

	enum ClipKind {
		Undo,
		Redo,
		Pause,
		Play,
	}

	struct Clip {
		public Clip(Texture2D Texture, Rectangle Rectangle) {
			this.Texture = Texture;
			this.Rectangle = Rectangle;
		}
		public readonly Texture2D Texture;
		public readonly Rectangle Rectangle;
	}
	class Clips : List<Clip> {
		public Clip this[ClipKind kind] {
			get { return this[(int)kind]; }
		}
	}

	class Control {
		public Clip Clip { get; set; }
		public Desktop Desktop { get; private set; }
		public Control(Desktop Desktop) {
			this.Desktop = Desktop;
			Color = DefaultColor = new Color(1.0f, 1.0f, 1.0f, 0.5f);
			HoveredColor = Color.White;
		}

		public Vector2 Location { get; set; }

		public Color Color { get; set; }
		public Color DefaultColor { get; set; }
		public Color HoveredColor { get; set; }


		public Rectangle Rectangle {
			get {
				var rectangle = Clip.Rectangle;
				rectangle.Location = new Point((int)Location.X, (int)Location.Y);
				return rectangle;
			}
		}

		public void DrawClip(Vector2 position, Color color) {
			//Desktop.GraphicsDevice.Viewport.TitleSafeArea
			Desktop.VectorGraphics.Batch.DrawSprite(Clip.Texture, Location, Clip.Rectangle, color);
		}
		public virtual bool HandleInput() {
			return false;
		}
		public virtual bool HandlePointer() {
			return false;
		}
		public virtual void Update() {
		}
		public virtual void Draw() {
			if (Clip.Texture != null) {
				DrawClip(Location, Color);
			}
		}
		public string Text;
	}

	class Button : Control {
		public Button(Desktop Desktop)
			: base(Desktop) {
		}
		public override bool HandlePointer() {
			if (Desktop.MouseInput.Current.LeftButton == ButtonState.Pressed
				&& Desktop.MouseInput.Previous.LeftButton == ButtonState.Released) {
				Desktop.MouseInput.Handled = true;
				PerformClick();
				return true;
			}
			return true;
		}
		public override bool HandleInput() {
			/*if (Desktop.KeyboardInput.Current.IsKeyDown(Keys.Space)
				&& Desktop.KeyboardInput.Previous.IsKeyUp(Keys.Space)) {
				PerformClick();
				return true;
			}*/
			return false;
		}
		public virtual void PerformClick() {
			if (Click != null)
				Click(this, EventArgs.Empty);
		}
		public override void Update() {
			base.Update();
		}
		public event EventHandler Click;
	}

	class CheckButton : Button {
		bool @checked;
		public CheckButton(Desktop Desktop)
			: base(Desktop) {
		}
		public List<Clip> Clips = new List<Clip>();
		public override void PerformClick() {
			Checked = !Checked;
			base.PerformClick();
		}
		public bool Checked {
			get { return @checked; }
			set {
				@checked = value;
				Clip = Clips[Checked ? 1 : 0];
			}
		}
	}

	class Desktop : DrawableGameComponent {

		public Button CreateButton(ClipKind Kind) {
			var item = new Button(this);
			item.Clip=Clips[Kind];
			Controls.Add(item);
			return item;
		}

		public CheckButton CreateCheckButton(ClipKind Unchecked, ClipKind Checked) {
			var item = new CheckButton(this);
			Controls.Add(item);
			item.Clips.Add(Clips[ClipKind.Pause]);
			item.Clips.Add(Clips[ClipKind.Play]);
			item.Clip = item.Clips[0];
			return item;
		}

		public VectorGraphicsComponent VectorGraphics { get; private set; }
		public PointerDisplay Pointer { get; private set; }
		public KeyboardInput KeyboardInput { get; private set; }
		public MouseInput MouseInput { get; private set; }

		public Desktop(VectorGraphicsComponent VectorGraphics, PointerDisplay pointer,
			KeyboardInput keyboardInput, MouseInput mouseInput)
			: base(VectorGraphics.Game) {

			this.VectorGraphics = VectorGraphics;
			this.Pointer = pointer;
			this.KeyboardInput = keyboardInput;
			this.MouseInput = mouseInput;
		}

		public readonly Clips Clips = new Clips();

		Texture2D texture;
		SpriteFont font;

		public readonly List<Control> Controls = new List<Control>();

		protected override void LoadContent() {
			texture = Game.Content.Load<Texture2D>("Gimmick");
			font = Game.Content.Load<SpriteFont>("Default");
			base.LoadContent();
		}

		Control hoveredItem;
		public Control HoveredItem {
			get { return hoveredItem; }
			set {
				if (hoveredItem == value) return;
				if (hoveredItem != null) {
					hoveredItem.Color = hoveredItem.DefaultColor;
				}
				hoveredItem = value;
				if (hoveredItem != null) {
					hoveredItem.Color = hoveredItem.HoveredColor;
				}
			}
		}

		Control HitTest() {
			foreach (var item in Controls) {
				if (item.Rectangle.Contains((int)MouseInput.Location.X, (int)MouseInput.Location.Y)) {
					return item;
				}
			}
			return null;
		}

		public override void Update(GameTime gameTime) {
			HoveredItem = HitTest();

			if (HoveredItem != null && !MouseInput.Handled) hoveredItem.HandlePointer();

			foreach (var item in Controls) {
				if (item.HandleInput())
					break;
			}
			base.Update(gameTime);
		}

		public override void Draw(GameTime gameTime) {
			VectorGraphics.Batch.Begin();
			foreach (var item in Controls) {
				item.Draw();
			}
			VectorGraphics.Batch.End();
			base.Draw(gameTime);
		}
	}
}
