using CPF.Mac.CoreGraphics;
using CPF.Mac.Foundation;
using CPF.Mac.ObjCRuntime;
using System;
using System.ComponentModel;

namespace CPF.Mac.AppKit
{
	[Register("NSStatusItem", true)]
	public class NSStatusItem : NSObject
	{
		private static readonly IntPtr selStatusBarHandle = Selector.GetHandle("statusBar");

		private static readonly IntPtr selLengthHandle = Selector.GetHandle("length");

		private static readonly IntPtr selSetLength_Handle = Selector.GetHandle("setLength:");

		private static readonly IntPtr selActionHandle = Selector.GetHandle("action");

		private static readonly IntPtr selSetAction_Handle = Selector.GetHandle("setAction:");

		private static readonly IntPtr selDoubleActionHandle = Selector.GetHandle("doubleAction");

		private static readonly IntPtr selSetDoubleAction_Handle = Selector.GetHandle("setDoubleAction:");

		private static readonly IntPtr selTargetHandle = Selector.GetHandle("target");

		private static readonly IntPtr selSetTarget_Handle = Selector.GetHandle("setTarget:");

		private static readonly IntPtr selTitleHandle = Selector.GetHandle("title");

		private static readonly IntPtr selSetTitle_Handle = Selector.GetHandle("setTitle:");

		private static readonly IntPtr selAttributedTitleHandle = Selector.GetHandle("attributedTitle");

		private static readonly IntPtr selSetAttributedTitle_Handle = Selector.GetHandle("setAttributedTitle:");

		private static readonly IntPtr selImageHandle = Selector.GetHandle("image");

		private static readonly IntPtr selSetImage_Handle = Selector.GetHandle("setImage:");

		private static readonly IntPtr selAlternateImageHandle = Selector.GetHandle("alternateImage");

		private static readonly IntPtr selSetAlternateImage_Handle = Selector.GetHandle("setAlternateImage:");

		private static readonly IntPtr selMenuHandle = Selector.GetHandle("menu");

		private static readonly IntPtr selSetMenu_Handle = Selector.GetHandle("setMenu:");

		private static readonly IntPtr selIsEnabledHandle = Selector.GetHandle("isEnabled");

		private static readonly IntPtr selSetEnabled_Handle = Selector.GetHandle("setEnabled:");

		private static readonly IntPtr selIsVisibleHandle = Selector.GetHandle("isVisible");

		private static readonly IntPtr selSetVisible_Handle = Selector.GetHandle("setVisible:");

		private static readonly IntPtr selToolTipHandle = Selector.GetHandle("toolTip");

		private static readonly IntPtr selSetToolTip_Handle = Selector.GetHandle("setToolTip:");

		private static readonly IntPtr selHighlightModeHandle = Selector.GetHandle("highlightMode");

		private static readonly IntPtr selSetHighlightMode_Handle = Selector.GetHandle("setHighlightMode:");

		private static readonly IntPtr selViewHandle = Selector.GetHandle("view");

		private static readonly IntPtr selSetView_Handle = Selector.GetHandle("setView:");

		private static readonly IntPtr selSendActionOn_Handle = Selector.GetHandle("sendActionOn:");

		private static readonly IntPtr selPopUpStatusItemMenu_Handle = Selector.GetHandle("popUpStatusItemMenu:");

		private static readonly IntPtr selDrawStatusBarBackgroundInRectWithHighlight_Handle = Selector.GetHandle("drawStatusBarBackgroundInRect:withHighlight:");

		private static readonly IntPtr class_ptr = Class.GetHandle("NSStatusItem");

		private object __mt_StatusBar_var;

		private object __mt_Target_var;

		private object __mt_AttributedTitle_var;

		private object __mt_Image_var;

		private object __mt_AlternateImage_var;

		private object __mt_Menu_var;

		private object __mt_View_var;

		public override IntPtr ClassHandle => class_ptr;

		public virtual NSStatusBar StatusBar
		{
			[Export("statusBar")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSStatusBar)(__mt_StatusBar_var = ((!IsDirectBinding) ? ((NSStatusBar)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selStatusBarHandle))) : ((NSStatusBar)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selStatusBarHandle)))));
			}
		}

		public virtual double Length
		{
			[Export("length")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return Messaging.Double_objc_msgSend(base.Handle, selLengthHandle);
				}
				return Messaging.Double_objc_msgSendSuper(base.SuperHandle, selLengthHandle);
			}
			[Export("setLength:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_Double(base.Handle, selSetLength_Handle, value);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_Double(base.SuperHandle, selSetLength_Handle, value);
				}
			}
		}

		public virtual Selector Action
		{
			[Export("action")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return Selector.FromHandle(Messaging.IntPtr_objc_msgSend(base.Handle, selActionHandle));
				}
				return Selector.FromHandle(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selActionHandle));
			}
			[Export("setAction:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetAction_Handle, (value == null) ? IntPtr.Zero : value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetAction_Handle, (value == null) ? IntPtr.Zero : value.Handle);
				}
			}
		}

		public virtual Selector DoubleAction
		{
			[Export("doubleAction")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return Selector.FromHandle(Messaging.IntPtr_objc_msgSend(base.Handle, selDoubleActionHandle));
				}
				return Selector.FromHandle(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selDoubleActionHandle));
			}
			[Export("setDoubleAction:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetDoubleAction_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetDoubleAction_Handle, value.Handle);
				}
			}
		}

		public virtual NSObject Target
		{
			[Export("target")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSObject)(__mt_Target_var = ((!IsDirectBinding) ? Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selTargetHandle)) : Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selTargetHandle))));
			}
			[Export("setTarget:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetTarget_Handle, value?.Handle ?? IntPtr.Zero);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetTarget_Handle, value?.Handle ?? IntPtr.Zero);
				}
				__mt_Target_var = value;
			}
		}

		public virtual string Title
		{
			[Export("title")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return NSString.FromHandle(Messaging.IntPtr_objc_msgSend(base.Handle, selTitleHandle));
				}
				return NSString.FromHandle(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selTitleHandle));
			}
			[Export("setTitle:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				IntPtr intPtr = NSString.CreateNative(value);
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetTitle_Handle, intPtr);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetTitle_Handle, intPtr);
				}
				NSString.ReleaseNative(intPtr);
			}
		}

		public virtual NSAttributedString AttributedTitle
		{
			[Export("attributedTitle")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSAttributedString)(__mt_AttributedTitle_var = ((!IsDirectBinding) ? ((NSAttributedString)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selAttributedTitleHandle))) : ((NSAttributedString)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selAttributedTitleHandle)))));
			}
			[Export("setAttributedTitle:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetAttributedTitle_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetAttributedTitle_Handle, value.Handle);
				}
				__mt_AttributedTitle_var = value;
			}
		}

		public virtual NSImage Image
		{
			[Export("image")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSImage)(__mt_Image_var = ((!IsDirectBinding) ? ((NSImage)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selImageHandle))) : ((NSImage)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selImageHandle)))));
			}
			[Export("setImage:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetImage_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetImage_Handle, value.Handle);
				}
				__mt_Image_var = value;
			}
		}

		public virtual NSImage AlternateImage
		{
			[Export("alternateImage")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSImage)(__mt_AlternateImage_var = ((!IsDirectBinding) ? ((NSImage)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selAlternateImageHandle))) : ((NSImage)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selAlternateImageHandle)))));
			}
			[Export("setAlternateImage:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetAlternateImage_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetAlternateImage_Handle, value.Handle);
				}
				__mt_AlternateImage_var = value;
			}
		}

		public virtual NSMenu Menu
		{
			[Export("menu")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSMenu)(__mt_Menu_var = ((!IsDirectBinding) ? ((NSMenu)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selMenuHandle))) : ((NSMenu)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selMenuHandle)))));
			}
			[Export("setMenu:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetMenu_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetMenu_Handle, value.Handle);
				}
				__mt_Menu_var = value;
			}
		}

		public virtual bool Enabled
		{
			[Export("isEnabled")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return Messaging.bool_objc_msgSend(base.Handle, selIsEnabledHandle);
				}
				return Messaging.bool_objc_msgSendSuper(base.SuperHandle, selIsEnabledHandle);
			}
			[Export("setEnabled:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_bool(base.Handle, selSetEnabled_Handle, value);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_bool(base.SuperHandle, selSetEnabled_Handle, value);
				}
			}
		}

		public virtual bool Visible
		{
			[Export("isVisible")]
			get
			{
				NSApplication.EnsureUIThread();
				bool isDirectBinding = base.IsDirectBinding;
				bool result;
				if (isDirectBinding)
				{
					result = Messaging.bool_objc_msgSend(base.Handle, NSStatusItem.selIsVisibleHandle);
				}
				else
				{
					result = Messaging.bool_objc_msgSendSuper(base.SuperHandle, NSStatusItem.selIsVisibleHandle);
				}
				return result;
			}
			[Export("setVisible:")]
			set
			{
				NSApplication.EnsureUIThread();
				bool isDirectBinding = base.IsDirectBinding;
				if (isDirectBinding)
				{
					Messaging.void_objc_msgSend_bool(base.Handle, NSStatusItem.selSetVisible_Handle, value);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_bool(base.SuperHandle, NSStatusItem.selSetVisible_Handle, value);
				}
			}
		}


		public virtual string ToolTip
		{
			[Export("toolTip")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return NSString.FromHandle(Messaging.IntPtr_objc_msgSend(base.Handle, selToolTipHandle));
				}
				return NSString.FromHandle(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selToolTipHandle));
			}
			[Export("setToolTip:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				IntPtr intPtr = NSString.CreateNative(value);
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetToolTip_Handle, intPtr);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetToolTip_Handle, intPtr);
				}
				NSString.ReleaseNative(intPtr);
			}
		}

		public virtual bool HighlightMode
		{
			[Export("highlightMode")]
			get
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					return Messaging.bool_objc_msgSend(base.Handle, selHighlightModeHandle);
				}
				return Messaging.bool_objc_msgSendSuper(base.SuperHandle, selHighlightModeHandle);
			}
			[Export("setHighlightMode:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_bool(base.Handle, selSetHighlightMode_Handle, value);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_bool(base.SuperHandle, selSetHighlightMode_Handle, value);
				}
			}
		}

		public virtual NSView View
		{
			[Export("view")]
			get
			{
				NSApplication.EnsureUIThread();
				return (NSView)(__mt_View_var = ((!IsDirectBinding) ? ((NSView)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, selViewHandle))) : ((NSView)Runtime.GetNSObject(Messaging.IntPtr_objc_msgSend(base.Handle, selViewHandle)))));
			}
			[Export("setView:")]
			set
			{
				NSApplication.EnsureUIThread();
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				if (IsDirectBinding)
				{
					Messaging.void_objc_msgSend_IntPtr(base.Handle, selSetView_Handle, value.Handle);
				}
				else
				{
					Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selSetView_Handle, value.Handle);
				}
				__mt_View_var = value;
			}
		}

		public event EventHandler DoubleClick
		{
			add
			{
				Target = ActionDispatcher.SetupDoubleAction(Target, value);
				DoubleAction = ActionDispatcher.DoubleAction;
			}
			remove
			{
				ActionDispatcher.RemoveDoubleAction(Target, value);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		[Export("init")]
		private NSStatusItem()
			: base(NSObjectFlag.Empty)
		{
			if (IsDirectBinding)
			{
				base.Handle = Messaging.IntPtr_objc_msgSend(base.Handle, Selector.Init);
			}
			else
			{
				base.Handle = Messaging.IntPtr_objc_msgSendSuper(base.SuperHandle, Selector.Init);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		[Export("initWithCoder:")]
		public NSStatusItem(NSCoder coder)
			: base(NSObjectFlag.Empty)
		{
			if (IsDirectBinding)
			{
				base.Handle = Messaging.IntPtr_objc_msgSend_IntPtr(base.Handle, Selector.InitWithCoder, coder.Handle);
			}
			else
			{
				base.Handle = Messaging.IntPtr_objc_msgSendSuper_IntPtr(base.SuperHandle, Selector.InitWithCoder, coder.Handle);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public NSStatusItem(NSObjectFlag t)
			: base(t)
		{
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public NSStatusItem(IntPtr handle)
			: base(handle)
		{
		}

		[Export("sendActionOn:")]
		public virtual long SendActionOn(NSTouchPhase mask)
		{
			NSApplication.EnsureUIThread();
			if (IsDirectBinding)
			{
				return Messaging.Int64_objc_msgSend_UInt64(base.Handle, selSendActionOn_Handle, (ulong)mask);
			}
			return Messaging.Int64_objc_msgSendSuper_UInt64(base.SuperHandle, selSendActionOn_Handle, (ulong)mask);
		}

		[Export("popUpStatusItemMenu:")]
		public virtual void PopUpStatusItemMenu(NSMenu menu)
		{
			NSApplication.EnsureUIThread();
			if (menu == null)
			{
				throw new ArgumentNullException("menu");
			}
			if (IsDirectBinding)
			{
				Messaging.void_objc_msgSend_IntPtr(base.Handle, selPopUpStatusItemMenu_Handle, menu.Handle);
			}
			else
			{
				Messaging.void_objc_msgSendSuper_IntPtr(base.SuperHandle, selPopUpStatusItemMenu_Handle, menu.Handle);
			}
		}

		[Export("drawStatusBarBackgroundInRect:withHighlight:")]
		public virtual void DrawStatusBarBackground(CGRect rect, bool highlight)
		{
			NSApplication.EnsureUIThread();
			if (IsDirectBinding)
			{
				Messaging.void_objc_msgSend_CGRect_bool(base.Handle, selDrawStatusBarBackgroundInRectWithHighlight_Handle, rect, highlight);
			}
			else
			{
				Messaging.void_objc_msgSendSuper_CGRect_bool(base.SuperHandle, selDrawStatusBarBackgroundInRectWithHighlight_Handle, rect, highlight);
			}
		}

		protected override void Dispose(bool disposing)
		{
			base.Dispose(disposing);
			if (base.Handle == IntPtr.Zero)
			{
				__mt_StatusBar_var = null;
				__mt_Target_var = null;
				__mt_AttributedTitle_var = null;
				__mt_Image_var = null;
				__mt_AlternateImage_var = null;
				__mt_Menu_var = null;
				__mt_View_var = null;
			}
		}
	}
}
