//
//  MPOutlineView.h
//  Aurora HDR
//
//  Created by Oleksiy Buhantsov on 1/18/16.
//  Copyright © 2016 MacPhun LLC. All rights reserved.
//

#import <Cocoa/Cocoa.h>

#import "MPSFlippedView.h"
#import "MPSOutlineViewChild.h"

@class MPScrollView;
@class MPSOutlineView;

extern NSString * _Nonnull const kMPSOutlineViewDidChangeStateScrollNotification;

@protocol MPSOutlineViewDataSource <NSObject>

@required
- (NSInteger)outlineView:(nonnull MPSOutlineView *)outlineView numberOfChildrenOfItem:(nullable id)item;
- (nullable id)outlineView:(nonnull MPSOutlineView *)outlineView child:(NSInteger)index ofItem:(nullable id)item;

@optional
// optimization
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView isViewHiddenForItem:(nonnull id)item;
- (NSUInteger)outlineView:(nonnull MPSOutlineView *)outlineView numberOfPreloadChildsForItem:(nullable id)item;
- (void)outlineView:(nonnull MPSOutlineView *)outlineView reconfigureItem:(nullable id)item atIndex:(NSInteger)idx;
// ------------

- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView isItemExpandable:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView isItemDragable:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView passDragEventsToSuperview:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView isItemStretchable:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView shouldItem:(nullable id)item acceptDropAtIndex:(NSUInteger)childIndex;

- (NSColor * _Nonnull)outlineView:(nonnull MPSOutlineView *)outlineView backgroundColorForItem:(nullable id)item;
- (NSShadow * _Nonnull)outlineView:(nonnull MPSOutlineView *)outlineView shadowForItem:(nullable id)item;
- (CGFloat)outlineView:(nonnull MPSOutlineView *)outlineView cornerRadiusForItem:(nullable id)item;
- (CGFloat)outlineView:(nonnull MPSOutlineView *)outlineView bottomOffsetForItem:(nullable id)item;

- (NSNumber *)outlineView:(nonnull MPSOutlineView *)outlineView indexOfFirstNonDraggableItemForItem:(nonnull id)item;

@end

@protocol MPSOutlineViewDelegate <NSObject>

@required
- (nullable NSView *)outlineView:(nonnull MPSOutlineView *)outlineView viewForItem:(nullable id)item;

@optional
- (nullable NSView *)placeholderForOutlineView:(nonnull MPSOutlineView *)outlineView;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView shouldExpandItem:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView isItemExpanded:(nullable id)item;
- (BOOL)outlineView:(nonnull MPSOutlineView *)outlineView shouldCollapseItem:(nullable id)item;

- (void)outlineView:(nonnull MPSOutlineView *)outlineView didDropItemFromIndex:(NSUInteger)fromIndex inParent:(nullable id)parentItem toIndex:(NSUInteger)toIndex;
- (void)outlineView:(nonnull MPSOutlineView *)outlineView didSelectChild:(nonnull id)item ofItem:(nullable id)parentItem;
- (void)outlineView:(nonnull MPSOutlineView *)outlineView didSelectItemAtIndex:(NSUInteger)index;
- (void)outlineView:(nonnull MPSOutlineView *)outlineView didSelectItemAtIndex:(NSUInteger)index withEvent:(nonnull NSEvent *)event;

@end

@interface MPSOutlineView : MPSFlippedView <MPSOutlineViewChildDataSource, MPSOutlineViewChildDelegate>

@property (strong, nonatomic, nonnull) MPSOutlineViewChild *rootContainer;
@property (weak, nonatomic) _Nullable id<MPSOutlineViewDataSource> dataSource;
@property (weak, nonatomic) _Nullable id<MPSOutlineViewDelegate> delegate;

@property (strong, nonatomic, readonly) MPScrollView * _Nonnull scrollView;
@property (assign, nonatomic) BOOL scrollEnabled;

@property (nonatomic, assign) IBInspectable BOOL resizeToFitContents;

- (void)reloadData;
- (void)reconfigureItems;
- (void)expandItem:(nonnull id)item expandChildren:(BOOL)expandChildren animated:(BOOL)animated;
- (void)collapseItem:(nonnull id)item collapseChildren:(BOOL)collapseChildren animated:(BOOL)animated;
- (void)expandItem:(nonnull id)item animated:(BOOL)animated;
- (void)collapseItem:(nonnull id)item animated:(BOOL)animated;
- (void)toggleItem:(nonnull id)item animated:(BOOL)animated;
- (void)disable:(BOOL)disable forItem:(nonnull id)item animated:(BOOL)animated;
- (void)reloadItem:(nullable id)item;
- (void)reloadItem:(nullable id)item reloadChildren:(BOOL)reloadChildren;
- (void)disableItem:(nullable id)item;
- (void)moveItemAtIndex:(NSInteger)fromIndex inParent:(nullable id)parent toIndex:(NSInteger)toIndex animated:(BOOL)animated;
- (void)insertItemsAtIndexes:(nonnull NSIndexSet *)indexes inParent:(nullable id)parent animated:(BOOL)animated;
- (void)removeItemsAtIndexes:(nonnull NSIndexSet *)indexes inParent:(nullable id)parent animated:(BOOL)animated;

@end
