namespace Eto.Mac.Forms.Controls
{
	public class MacEventView : NSBox, IMacControl
	{
		public MacEventView()
		{
			BoxType = NSBoxType.NSBoxCustom;
			Transparent = true;
			BorderWidth = 0;
			BorderType = NSBorderType.NoBorder;
			ContentViewMargins = CGSize.Empty;
			
			// disable clipping to bounds so buttons/etc aren't clipped, 10.9+
			this.SetClipsToBounds(false);
			(ContentView as NSView)?.SetClipsToBounds(false);
		}

		public MacEventView(IntPtr handle)
			: base(handle)
		{
		}

		public WeakReference WeakHandler { get; set; }

		public IMacViewHandler Handler
		{ 
			get { return WeakHandler?.Target as IMacViewHandler; }
			set { WeakHandler = new WeakReference(value); } 
		}

		public Control Widget
		{
			get { return Handler == null ? null : Handler.Widget; }
		}

		public static bool KeyDown(Control control, NSEvent theEvent)
		{
			var handler = control?.Handler as IMacViewHandler;
			if (handler == null)
				return false;

			var kpea = theEvent.ToEtoKeyEventArgs();
			handler.OnKeyDown(kpea);
			return kpea.Handled;
		}

		public static bool FlagsChanged(Control control, NSEvent theEvent)
		{
			var handler = control?.Handler as IMacViewHandler;
			if (handler == null)
				return false;

			Keys key;
			NSEventModifierMask requiredModifier;

			// check which key is being pressed currently and figure out correct modifier mask for that key alone
			switch (theEvent.KeyCode)
			{
				case 56:
					key = Keys.LeftShift;
					requiredModifier = (NSEventModifierMask)0x20002;
					break;
				case 60:
					key = Keys.RightShift;
					requiredModifier = (NSEventModifierMask)0x20004;
					break;
				case 59:
					key = Keys.LeftControl;
					requiredModifier = (NSEventModifierMask)0x40001;
					break;
				case 57:
					key = Keys.RightControl;
					requiredModifier = (NSEventModifierMask)0x40002; // correct?  I don't have a keyboard with right control key.
					break;
				case 58:
					key = Keys.LeftAlt;
					requiredModifier = (NSEventModifierMask)0x80020;
					break;
				case 61:
					key = Keys.RightAlt;
					requiredModifier = (NSEventModifierMask)0x80040;
					break;
				case 55:
					key = Keys.LeftApplication;
					requiredModifier = (NSEventModifierMask)0x100008;
					break;
				case 54:
					key = Keys.RightApplication;
					requiredModifier = (NSEventModifierMask)0x100010;
					break;
				default:
					Debug.WriteLine($"Unknown FlagsChanged Key: {theEvent.KeyCode}, Modifiers: {theEvent.ModifierFlags}");
					return false;
			}
			// test the modifier to see if the key was pressed or released
			var modifierFlags = theEvent.ModifierFlags;
			var type = modifierFlags.HasFlag(requiredModifier) ? KeyEventType.KeyDown : KeyEventType.KeyUp;

			key |= modifierFlags.ToEto();
			var kpea = new KeyEventArgs(key, type);
			if (type == KeyEventType.KeyDown)
				handler.OnKeyDown(kpea);
			else
				handler.OnKeyUp(kpea);
			return kpea.Handled;
		}

		public static bool KeyUp(Control control, NSEvent theEvent)
		{
			var handler = control?.Handler as IMacViewHandler;
			if (handler == null)
				return false;

			var kpea = theEvent.ToEtoKeyEventArgs();
			handler.Callback.OnKeyUp(control, kpea);
			return kpea.Handled;
		}

		public override void ResetCursorRects()
		{
			var handler = Handler;
			if (handler == null)
				return;
			var cursor = handler.CurrentCursor;
			if (cursor != null)
			{
				AddCursorRect(new CGRect(CGPoint.Empty, Frame.Size), cursor.ControlObject as NSCursor);
			}
		}

		public override bool AcceptsFirstMouse(NSEvent theEvent)
		{
			return Handler?.OnAcceptsFirstMouse(theEvent) ?? base.AcceptsFirstMouse(theEvent);
		}

	}
}

