//
//  U2DHeadScanner.h
//  Unre2DScan
//
//  Created by MikeYu on 2018/11/27.
//  Copyright © 2018 unre. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "U2DCamera.h"
#import "U2DSessionData.h"
#import "U2DHeadScannerProgressInfo.h"

NS_ASSUME_NONNULL_BEGIN

@protocol Unre2DHeadScannerObserver;



/**
 The state of scanner
 */
typedef NS_ENUM(NSInteger, Unre2DHeadScannerState) {
    Unre2DHeadScannerStateIdle,
    Unre2DHeadScannerStatePreparing,
    Unre2DHeadScannerStateTracking,
    Unre2DHeadScannerStateScanning,
    Unre2DHeadScannerStateModeling
} NS_SWIFT_NAME(Unre2DHeadScanner.State);

/**
 The state of tracking
 */
typedef NS_ENUM(NSInteger, Unre2DHeadScannerFacePosition) {
    Unre2DHeadScannerFacePositionReadyToScan,
    Unre2DHeadScannerFacePositionFaceNotFound,
    Unre2DHeadScannerFacePositionFaceNotFrontal,
    Unre2DHeadScannerFacePositionFaceTooClose,
    Unre2DHeadScannerFacePositionFaceTooFar,
    Unre2DHeadScannerFacePositionFaceNotCentered,
    Unre2DHeadScannerFacePositionNotAvailable
} NS_SWIFT_NAME(Unre3DHeadScanner.FacePosition);


/**
 The hint when start scan
 */
typedef NS_ENUM(NSInteger, Unre2DHeadScannerScanHint) {
    Unre2DHeadScannerScanHintNone,
    Unre2DHeadScannerScanHintHoldStill,
    Unre2DHeadScannerScanHintCountdownThree,
    Unre2DHeadScannerScanHintCountdownTwo,
    Unre2DHeadScannerScanHintCountdownOne,
    Unre2DHeadScannerScanHintTurnHeadLeft,
    Unre2DHeadScannerScanHintKeepHeadTurning,
    Unre2DHeadScannerScanHintTurnHeadRight,
    Unre2DHeadScannerScanHintTurnHeadToTheMiddle,
    Unre2DHeadScannerScanHintCaptureCompleted,
    Unre2DHeadScannerScanHintCaptureAboutToStop
} NS_SWIFT_NAME(Unre2DHeadScanner.ScanHint);


@interface U2DHeadScanner : NSObject

+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

/**
 *    @brief    Initialization method
 *
 *    @param     camera     The Class of Unre2DCamera
 *    @param     sessionData     Unre2DSessionData The Scan rootDir data
 *
 *    @return    return  instancetype
 */
-(instancetype) initWithCamera:(U2DCamera *)camera sessionData:(U2DSessionData *)sessionData;

/**
 *    @brief    The state of scan
 */
@property (nonatomic, readonly) Unre2DHeadScannerState scanState;

/**
 *    @brief    Tracking of head positioning
 *
 *    @return   is staring
 */
- (BOOL)startTracking;

/**
 *    @brief    Has to be called while tracking state is Unre2DHeadScannerFacePositionReadyToScan.
 *
 *    @return  is starting
 */
- (BOOL)startScanning;

/**
 *    @brief    stop scan
 *
 *    @return  is stoping
 */
- (BOOL)cancelScaning;

/**
 *    @brief    add scan callback
 *
 *    @param     observer     callback
 */
- (void)addObserver:(id<Unre2DHeadScannerObserver>)observer NS_SWIFT_NAME(addObserver(_:));

/**
 *    @brief    remove scan callback
 *
 *    @param     observer     callback
 */
- (void)removeObserver:(id<Unre2DHeadScannerObserver>)observer NS_SWIFT_NAME(removeObserver(_:));


@end







OBJC_VISIBLE @protocol Unre2DHeadScannerObserver <NSObject>

@optional


/**
 *    @brief    Reports face position detected by scanner
 *
 *    @param     facePosition     Unre3DHeadScannerFacePosition
 */
- (void)didTrackFacePosition:(Unre2DHeadScannerFacePosition)facePosition;






/**
 *    @brief    Called several times before scan actually starts to enable client to give user some time to prepare for start turning head.
 *
 *    @param     countdown  The seconds of the scanning process
 */
- (void)didReportCountdown:(float)countdown;





/**
 *    @brief    Called several times during scanning reporting current head position and desired head rotation velocity
 *
 *    @param     progressInfo     Unre3DHeadScannerProgressInfo *
 */
- (void)didReportProgressInfo:(Unre2DHeadScannerProgressInfo *)progressInfo;


/// Called after cancelling scan when scan is stopping.
//- (void)headScannerWillStopScanning:(Unre3DHeadScanner *)headScanner;


/**
 *    @brief    Called when scanning is completed
 *
 *    @param     completedSuccessfully     BOOL
 */
- (void)didCompleteScanningSuccessfully:(BOOL)completedSuccessfully;




/**
 *    @brief    Called at each key point of scanning (countdown, changing of rotration direction of head, capture completion etc).to provide the appropriate point in code that may be used by client to present the corresponding UI with hint or play sound
 *
 *    @param     hint     Unre3DHeadScannerScanHint
 */
- (void)didProvideHint:(Unre2DHeadScannerScanHint)hint;

/**
 *    @brief      Called when scanning is finished to provide the address of the picture.
 *
 *    @param     NSString     imgPath
 */
- (void)didReportNetImagePath:(NSString*) imgPath;

@end


NS_ASSUME_NONNULL_END
