//
//  MPSOutlineViewChild.h
//  Outline
//
//  Created by Oleksiy Buhantsov on 1/20/16.
//  Copyright © 2016 Oleksiy Buhantsov. All rights reserved.
//

#import <Cocoa/Cocoa.h>

#import "MPSFlippedView.h"


@class MPSOutlineView;
@class MPSOutlineViewChild;


@protocol MPSOutlineViewChildDataSource <NSObject>

@required
- (NSUInteger)numberOfPreloadChildrensForItem:(nonnull id)item;
- (BOOL)viewIsHiddenForItem:(nullable id)item;
- (void)reconfigureItem:(nullable id)item atIndex:(NSInteger)idx;

- (NSInteger)numberOfChildrenOfItem:(nullable id)item;
- (nullable id)child:(NSInteger)index ofItem:(nullable id)item;

- (BOOL)isItemExpandable:(nonnull id)item;
- (BOOL)isItemDraggable:(nonnull id)item;
- (BOOL)isItemStretchable:(nonnull id)item;
- (BOOL)shouldItem:(nonnull id)item acceptDropAtIndex:(NSUInteger)childIndex;

@optional
- (NSShadow *_Nonnull)shadowForItem:(nonnull id)item;
- (NSColor * _Nonnull)backgroundColorForItem:(nonnull id)item;
- (CGFloat)cornerRadiusForItem:(nonnull id)item;
- (CGFloat)bottomOffsetForItem:(nonnull id)item;

- (BOOL)passDragEventsToSuperview:(nonnull id)item;

- (NSNumber *_Nonnull)indexOfFirstNonDraggableItemForItem:(nonnull id)item;

@end

@protocol MPSOutlineViewChildDelegate <NSObject>

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

- (nullable NSView *)placeholderView;
- (BOOL)shouldExpandItem:(nullable id)item;
- (BOOL)isItemExpanded:(nullable id)item;
- (BOOL)shouldCollapseItem:(nullable id)item;
- (void)layoutAllIfNeeded;
- (void)scrollIfNeededForLocation:(NSPoint)location inView:(nonnull NSView *)view;
- (void)didDropItemFromIndex:(NSUInteger)fromIndex inParent:(nullable id)parentItem toIndex:(NSUInteger)toIndex;
- (void)didSelectItemAtIndex:(NSUInteger)childIndex inParent:(nullable id)parentItem withEvent:(nullable NSEvent *)event;
- (BOOL)isDisabled;
- (void)makeParentStretchable:(BOOL)stretchable;
- (nullable NSMutableArray *)childViews;

@optional
- (void)dragChild:(nonnull MPSOutlineViewChild *)child withEvent:(nonnull NSEvent *)event;
- (void)dropChild:(nonnull MPSOutlineViewChild *)child withEvent:(nonnull NSEvent *)event;
- (void)selectChild:(nonnull MPSOutlineViewChild *)child withEvent:(nullable NSEvent *)event;
@end


@interface MPSOutlineViewChild : MPSFlippedView <MPSOutlineViewChildDataSource, MPSOutlineViewChildDelegate>

@property (strong, nonatomic) _Nullable id item;
@property (strong, nonatomic)  NSLayoutConstraint * _Nullable heightConstraint;
@property (weak, nonatomic) id <MPSOutlineViewChildDataSource> _Nullable dataSource;
@property (weak, nonatomic) id <MPSOutlineViewChildDelegate> _Nullable delegate;
@property (assign, nonatomic, getter = isExpanded) BOOL expanded;
@property (assign, nonatomic, getter = isExpandable) BOOL expandable;
@property (assign, nonatomic, getter = isDraggable) BOOL draggable;
@property (assign, nonatomic, getter = isDisabled) BOOL disabled;
@property (assign, nonatomic) CGFloat height;
@property (strong, nonatomic, readonly) NSView * _Nullable childHeaderView;
@property (assign, nonatomic, getter = isStretchable) BOOL stretchable;
@property (strong, nonatomic, readonly) MPSFlippedView * _Nullable childrenContainerView;

- (void)reconfigureItems;
- (void)expandWithChildren:(BOOL)expandChildren animated:(BOOL)animated;
- (void)expandItem:(nonnull id)item expandChildren:(BOOL)expandChildren animated:(BOOL)animated;
- (void)collapseWithChildren:(BOOL)collapseChildren animated:(BOOL)animated;
- (void)collapseItem:(nonnull id)item collapseChildren:(BOOL)collapseChildren animated:(BOOL)animated;
- (void)disable:(BOOL)disable animated:(BOOL)animated;
- (void)disable:(BOOL)disable forItem:(nonnull id)item animated:(BOOL)animated;
- (void)toggleAnimated:(BOOL)animated;
- (void)toggleItem:(nonnull id)item animated:(BOOL)animated;
- (void)reloadItem:(nullable id)item reloadChildren:(BOOL)reloadChildren;
- (void)disableItem:(nullable)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
