//
//  MPSuperMenu.h
//  MPServices
//
//  Created by Kirill Kovalenko on 6/9/16.
//  Copyright © 2016 MacPhun. All rights reserved.
//

#import <Cocoa/Cocoa.h>

#import "MPSuperMenuItem.h"
#import "MPSuperMenuSettings.h"
@class MPSuperMenuContentController;

extern NSString * _Nonnull const kMPSuperMenuAddLocalMonitorNotification;
extern NSString * _Nonnull const kMPSuperMenuRemoveLocalMonitorNotification;
extern NSString * _Nonnull const kMPSuperMenuItemDidPressNotification;
extern NSString * _Nonnull const kMPSuperMenuItemControlDidPressNotification;

@interface MPSuperMenu : NSObject

#pragma mark -
#pragma mark Properties

/* Returns an array containing the receiver's menu items. */
@property (readonly, copy, nullable) NSMutableArray<MPSuperMenuItem *> *items;

/* Returns the number of menu items in the menu. */
@property (readonly) NSInteger numberOfItems;

/* Getter: Returns the menu containing the item that has the receiver as a submenu, or nil if this menu is not the submenu of an item in a menu.
 Setter: If a menu item has the receiver as a submenu, then this method will be called when the menu containing that item changes.  You should never call this, but you may override it to take some action when the supermenu changes. */
@property (nullable, weak) MPSuperMenu *supermenu;

/* Custom setting for menu. */
@property (nonatomic, strong, nullable) MPSuperMenuSettings *settings;

/* Callback did close SuperMenu. */
@property (nonatomic, copy, nullable) void (^closeCallback)();
@property (nonatomic, copy, nullable) void (^applyCallback)();
@property (nonatomic, copy, nullable) void (^showCallback)();
/* Custom setting for menu. */
@property (nonatomic, assign, readonly) BOOL isOpen;

@property (nonatomic, strong, nonnull, readonly) MPSuperMenuContentController *contentController;


#pragma mark -
#pragma mark Methods

/* Designated initializer.  If this menu is used as a submenu of an item in the application's main menu, then the window is where menu show. Do not pass nil. */
- (nonnull instancetype)initWithParentWindow:(NSWindow * _Nonnull)aWindow __attribute__((deprecated("Use defaul init.")));

/* Inserts a menu item at the given index, which must be at least zero and no more than the receiver's item count.  If newItem is nil, this raises an exception. */
- (void)insertItem:(MPSuperMenuItem * _Nonnull)newItem atIndex:(NSInteger)index;

/* Appends an item to the end of the menu.  A nil item will raise an exception. */
- (void)addItem:(MPSuperMenuItem * _Nonnull)newItem;

/* Removes the item at the given index, which must be at least zero and less than the number of items.  All subsequent items will shift down one index. */
- (void)removeItemAtIndex:(NSInteger)index;

/* Removes the item from the menu.  If the item is nil, or is not present in the receiver, an exception will be raised. */
- (void)removeItem:(MPSuperMenuItem * _Nonnull)item;

/* Same as [anItem setSubmenu:aMenu].  anItem may not be nil. */
- (void)setSubmenu:(nullable MPSuperMenu *)aMenu forItem:(MPSuperMenuItem * _Nonnull)anItem;

/* Removes all items.  This is more efficient than removing items one by one.  This does not post NSMenuDidRemoveItemNotification, for efficiency. */
- (void)removeAllItems;

/* Returns the item at the given index, which must be at least zero and less than the number of items. */
- (nullable MPSuperMenuItem *)itemAtIndex:(NSInteger)index;

/* Returns the index of the item in the menu, or -1 if the item is not present in the menu */
- (NSInteger)indexOfItem:(MPSuperMenuItem * _Nonnull)item;

/* Returns the first item in the menu with the given property, or nil if no item in the menu matches. */
- (nullable MPSuperMenuItem *)itemWithTitle:(NSString * _Nonnull)aTitle;
- (nullable MPSuperMenuItem *)itemWithTag:(NSInteger)tag;

@property (readonly, copy, nullable) NSArray<MPSuperMenuItem *> *itemArray;

/* Methods for visable menu. */
- (void)show:(id _Nonnull)sender withEvent:(NSEvent * _Nullable)event;
- (void)show:(id _Nonnull)sender;
- (void)hideAll;
- (void)hide;
- (void)hideSubmenuForItem:(MPSuperMenuItem * _Nonnull)item;

- (id _Nullable)mouseMoveMonitor;

- (void)updateLayout;

@end
