//
//  MVMCoreNavigationHandler.h
//  myverizon
//
//  Created by Scott Pfeil on 11/18/15.
//  Copyright © 2015 Verizon Wireless. All rights reserved.
//
//  This class should be used to handle all navigation and presentation for mvm.

#import <Foundation/Foundation.h>
#import <MVMCore/MVMCorePresentationDelegateProtocol.h>

@class MVMCoreOperation;
@class MVMCoreNavigationObject;
@class MVMCoreLoadObject;

@interface MVMCoreNavigationHandler : NSObject

// Returns the shared instance of this singleton
+ (nullable instancetype)sharedNavigationHandler;

// Can set the view controller to present on... will use MF if nil.
@property (nullable, nonatomic, weak) UIViewController *viewControllerToPresentOn;

// reference to main navigation controller
@property (nullable, weak, nonatomic) UINavigationController *navigationController;


// Will navigate appropriately based on the load style
- (void)navigateWithLoadObject:(nullable MVMCoreLoadObject *)loadObject viewController:(nonnull UIViewController *)viewController delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Perform navigation with object.
- (void)startNavigationWithNavigationObject:(nonnull MVMCoreNavigationObject *)navigationObject delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// pops or dimisses as needed
- (void)removeCurrentViewController;

#pragma mark - Navigation Simple
// Uses the default navigation controller in app delegate

// Use this to push.
- (void)pushViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to replace the top view controller.
- (void)replaceTopViewControllerWithViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to replace all the view controllers after the root with the passed in view controller.
- (void)replaceAfterRoot:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to set the navigation stack.
- (void)setViewControllers:(nonnull NSArray *)viewControllers animated:(BOOL)animated;

// Use this to pop.
- (void)popTopViewControllerAnimated:(BOOL)animated;

// Use this to pop a specific view controller.
- (void)popViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to pop to a specific view controller in the stack.
- (void)popToViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to pop to a view controller of a specific class in the stack.
- (void)popToInstanceOfClass:(nonnull Class)viewControllerClass animated:(BOOL)animated;

// Use this to pop to a view controller of a specific page type in the stack.
- (void)popToViewControllerWithPageType:(nonnull NSString *)pageType animated:(BOOL)animated;

// Use this to pop to the root of the stack.
- (void)popToRootAnimated:(BOOL)animated;

// Adds the navigation operation to the queue.
- (void)addNavigationOperation:(nonnull MVMCoreOperation *)operation;

// Removes all queued up items.
- (void)cancelNavigation;

#pragma mark - Navigation Extra

// Use this to push.
- (void)pushViewController:(nonnull UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate replaceInStack:(BOOL)replaceInStack completionHandler:(nullable void (^)(void))completionBlock;

// Use this to replace the top view controller.
- (void)replaceTopViewControllerWithViewController:(nonnull UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate replaceInStack:(BOOL)replaceInStack completionHandler:(nullable void (^)(void))completionBlock;

// Use this to replace all the view controllers after the root with the passed in view controller. If no navigation controller is provided, will use the main one in app delegate.
- (void)replaceAfterRoot:(nonnull UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate replaceInStack:(BOOL)replaceInStack completionHandler:(nullable void (^)(void))completionBlock;

// Use this to set the navigation stack. If no navigation controller is provided, will use the main one in app delegate.
- (void)setViewControllers:(nonnull NSArray *)viewControllers navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate replaceInStack:(BOOL)replaceInStack completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop. If no navigation controller is provided, will use the main one in app delegate.
- (void)popTopViewControllerAnimated:(BOOL)animated navigationController:(nullable UINavigationController *)navigationController delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop a specific view controller. If no navigation controller is provided, will use the main one in app delegate.
- (void)popViewController:(nonnull UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop to a specific view controller in the stack. If no navigation controller is provided, will use the main one in app delegate.
- (void)popToViewController:(nonnull UIViewController *)viewController navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop to a view controller of a specific class in the stack. If no navigation controller is provided, will use the main one in app delegate.
- (void)popToInstanceOfClass:(nonnull Class)viewControllerClass navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop to a view controller of a specific pageType in the stack. If no navigation controller is provided, will use the main one in app delegate.
- (void)popToViewControllerWithPageType:(nonnull NSString *)pageType navigationController:(nullable UINavigationController *)navigationController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to pop to the root of the stack. If no navigation controller is provided, will use the main one in app delegate.
- (void)popToRootAnimated:(BOOL)animated navigationController:(nullable UINavigationController *)navigationController delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

#pragma mark - Presentation Simple

// Use this to present.
- (void)presentViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to dismiss.
- (void)dismissTopViewControllerAnimated:(BOOL)animated;

// Use this to dismiss a specific view controller and any it may be presenting.
- (void)dismissViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated;

// Use this to dismiss all presented view controllers stacked on the bottom one.
- (void)dismissToBottom:(BOOL)animated;

// Removes all queued up items.
- (void)cancelPresentation;

#pragma mark - Presentation Extra

// Use this to present.
- (void)presentViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to dismiss.
- (void)dismissTopViewControllerAnimated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to dismiss a specific view controller and any it may be presenting.
- (void)dismissViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

// Use this to dismiss all presented view controllers stacked on the bottom one.
- (void)dismissToBottom:(BOOL)animated delegate:(nullable NSObject<MVMCorePresentationDelegateProtocol>*)delegate completionHandler:(nullable void (^)(void))completionBlock;

@end
