using Sandbox.ModAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UIFun.Messagesv2;
using VRage.Collections;
using VRage.Input;
using VRage.Utils;
using VRageMath;
using BlendTypeEnum = VRageRender.MyBillboard.BlendTypeEnum;

namespace UIFun.Menu.Dialog
{
	public class KeybindInputDialog : DialogBox
	{
		StringBuilder EnteredText = new StringBuilder();
		ModHUDMessage Title = new ModHUDMessage();
		ModHUDMessage TextInput = new ModHUDMessage();
		ModHUDMessage CancelButton = new ModHUDMessage();
		ModHUDMessage ConfirmButton = new ModHUDMessage();
		ModBillboardHUDMessage CancelBackground = new ModBillboardHUDMessage();
		ModBillboardHUDMessage ConfirmBackground = new ModBillboardHUDMessage();
		ModBillboardHUDMessage BoxBackground = new ModBillboardHUDMessage();
		ModBillboardHUDMessage TitleBackground = new ModBillboardHUDMessage();
		static StringBuilder CancelString = new StringBuilder("<color=red>Cancel  ");
		static StringBuilder ConfirmString = new StringBuilder("  <color=green>Confirm");
		static MyStringId Background = MyStringId.GetOrCompute("Square");

		MyKeys? cachedInput = MyKeys.None;
		bool cachedShift = false;
		bool cachedAlt = false;
		bool cachedCtrl = false;

		Action<MyKeys, bool, bool, bool> SubmitAction;
		public KeybindInputDialog()
		{

			TextInput.Message = EnteredText;

			Title.Visible = true;
			TextInput.Visible = true;
			CancelButton.Visible = true;
			ConfirmButton.Visible = true;
			CancelBackground.Visible = true;
			ConfirmBackground.Visible = true;
			BoxBackground.Visible = true;
			TitleBackground.Visible = true;

			Title.Origin = Vector2D.Zero;
			TextInput.Origin = Vector2D.Zero;
			CancelButton.Origin = Vector2D.Zero;
			ConfirmButton.Origin = Vector2D.Zero;
			CancelBackground.Origin = Vector2D.Zero;
			ConfirmBackground.Origin = Vector2D.Zero;
			BoxBackground.Origin = Vector2D.Zero;
			TitleBackground.Origin = Vector2D.Zero;

			Title.Scale = 1.5d;
			TextInput.Scale = 1.5d;
			CancelButton.Scale = 1.5d;
			ConfirmButton.Scale = 1.5d;

			CancelButton.Message = CancelString;
			ConfirmButton.Message = ConfirmString;

			Title.Blend = BlendTypeEnum.PostPP;
			TextInput.Blend = BlendTypeEnum.PostPP;
			CancelButton.Blend = BlendTypeEnum.PostPP;
			ConfirmButton.Blend = BlendTypeEnum.PostPP;

			CancelBackground.BillBoardColor = Color.Black * 0.3f;
			CancelBackground.Blend = BlendTypeEnum.PostPP;
			CancelBackground.Material = Background;

			ConfirmBackground.BillBoardColor = Color.Black * 0.3f;
			ConfirmBackground.Blend = BlendTypeEnum.PostPP;
			ConfirmBackground.Material = Background;

			BoxBackground.BillBoardColor = Color.Black * 0.3f;
			BoxBackground.Blend = BlendTypeEnum.PostPP;
			BoxBackground.Material = Background;

			TitleBackground.BillBoardColor = Color.Blue * 0.3f + Color.Black * 0.5f;
			TitleBackground.Blend = BlendTypeEnum.PostPP;
			TitleBackground.Material = Background;

			CancelBackground.Options = Options.Shadowing;
			ConfirmBackground.Options = Options.Shadowing;
			BoxBackground.Options = Options.Shadowing;
			TitleBackground.Options = Options.Shadowing;

			SubmitAction = null;

			Refresh();
		}

		private void Refresh()
		{

			ConfirmButton.hasCache = false;
			CancelButton.hasCache = false;

			var ln = Title.GetLength();
			var inputln = TextInput.GetLength();
			var confirmln = ConfirmButton.GetLength();
			var cancelln = CancelButton.GetLength();
			var maxX = ln.X;
			if (inputln.X > maxX)
				maxX = inputln.X;
			if (confirmln.X + cancelln.X > maxX)
				maxX = confirmln.X + cancelln.X;
			
			Title.Offset = Vector2D.Zero;
			Title.hasCache = false;
			TextInput.Offset = new Vector2D(0, ln.Y);
			TextInput.hasCache = false;
			ConfirmButton.Offset = new Vector2D(cancelln.X, ln.Y + inputln.Y);
			ConfirmButton.hasCache = false;
			CancelButton.Offset = new Vector2D(0, ln.Y  + inputln.Y);
			CancelButton.hasCache = false;

			TitleBackground.Offset = new Vector2D(maxX / 2d, (ln / 2).Y);
			TitleBackground.Width = (float)maxX;
			TitleBackground.Height = -(float)ln.Y;

			ConfirmBackground.Offset = (confirmln / 2) + ConfirmButton.Offset;
			ConfirmBackground.Width = (float)confirmln.X;
			ConfirmBackground.Height = -(float)confirmln.Y;

			CancelBackground.Offset = (cancelln / 2) + CancelButton.Offset;
			CancelBackground.Width = (float)cancelln.X;
			CancelBackground.Height = -(float)cancelln.Y;

			BoxBackground.Offset = new Vector2D(maxX / 2f, (float)(inputln.Y + confirmln.Y) / 2f);
			BoxBackground.Width = (float)maxX;
			BoxBackground.Height = -(float)(inputln.Y + confirmln.Y);

		}

		public void Request(StringBuilder title, Action<MyKeys, bool, bool, bool> callback)
		{
			Reset();
			Active = true;
			Title.Message = title;
			SubmitAction = callback;
			EnteredText.Clear();
			Refresh();
		}
		public override void onClick(Vector2D MousePosition, bool left, bool right)
		{
			base.onClick(MousePosition, left, right);
			if (!left)
				return;
			//MyAPIGateway.Utilities.ShowMessage("OnClick", "In Input " + Position.ToString());
			var ln = CancelButton.GetLength();
			var pos = CancelButton.Origin + CancelButton.Offset;
			var pos2 = pos + ln;
			BoundingBox2D Area = new BoundingBox2D(new Vector2D(pos.X, pos2.Y), new Vector2D(pos2.X, pos.Y));
			if (Area.Contains(MousePosition) == ContainmentType.Contains)
			{
				Cancel();
			}
			ln = ConfirmButton.GetLength();
			pos = ConfirmButton.Origin + ConfirmButton.Offset;
			pos2 = pos + ln;
			Area = new BoundingBox2D(new Vector2D(pos.X, pos2.Y), new Vector2D(pos2.X, pos.Y));
			if (Area.Contains(MousePosition) == ContainmentType.Contains)
			{
				Submit();
			}
		}

		public override void Cancel()
		{

			Reset();
			
			base.Cancel();
		}

		public override void Reset()
		{

			SubmitAction = null;
			EnteredText.Clear();
			cachedInput = MyKeys.None;
			cachedShift = false;
			cachedAlt = false;
			cachedCtrl = false;
			Active = false;

		}

		public void Submit()
		{
			if (SubmitAction != null && cachedInput.HasValue)
				SubmitAction(cachedInput.Value, cachedShift, cachedCtrl, cachedAlt);
			Reset();
		}

		public override void onKeyPress(List<MyKeys> keys)
		{
			base.onKeyPress(keys);
			for (int i = 0; i < keys.Count; i++)
			{
				var firstkey = keys[i];
				if (firstkey == MyKeys.Escape || firstkey == MyKeys.Enter )
					return;//forbid escape and enter or Cancel:KEEN:
				if (firstkey == MyKeys.Shift || firstkey == MyKeys.LeftShift || firstkey == MyKeys.RightShift || firstkey == MyKeys.Cancel)
					continue;
				if (firstkey == MyKeys.LeftControl || firstkey == MyKeys.RightControl || firstkey == MyKeys.Control)
					continue;
				if (firstkey == MyKeys.Alt || firstkey == MyKeys.LeftAlt || firstkey == MyKeys.RightAlt)
					continue;
				if (firstkey == MyKeys.LeftButton || firstkey == MyKeys.RightButton)
					continue;
				cachedInput = firstkey;
				
				cachedShift = MyAPIGateway.Input.IsAnyShiftKeyPressed();
				cachedAlt = MyAPIGateway.Input.IsAnyAltKeyPressed();
				cachedCtrl = MyAPIGateway.Input.IsAnyCtrlKeyPressed();
				EnteredText.Clear();
				if(cachedShift)
					EnteredText.Append("Shift ");
				if(cachedCtrl)
					EnteredText.Append("Ctrl ");
				if (cachedAlt)
					EnteredText.Append("Alt ");
				EnteredText.Append(firstkey.ToString());
				var control = MyAPIGateway.Input.GetControl(firstkey);

				if(control != null && !cachedShift && !cachedCtrl && !cachedAlt)
				{
					EnteredText.Append("\nConflict: " + control.GetControlName().String);
				}
				Refresh();
			}
		}

		public override void Draw()
		{

			base.Draw();
			Title.Draw();
			TextInput.Draw();
			CancelButton.Draw();
			ConfirmButton.Draw();
			CancelBackground.Draw();
			ConfirmBackground.Draw();
			BoxBackground.Draw();
			TitleBackground.Draw();
		}
	}
}
