//
//  U3DHeadScanner.h
//  UnreScan
//
//  Created by Simon on 2018/10/24.
//  Copyright © 2018 Unretek. All rights reserved.
//

#ifndef U3DHeadScanner_h
#define U3DHeadScanner_h

NS_ASSUME_NONNULL_BEGIN

/**
The state of scanner
 */
typedef NS_ENUM(NSInteger, Unre3DHeadScannerState) {
    Unre3DHeadScannerStateIdle,
    Unre3DHeadScannerStatePreparing,
    Unre3DHeadScannerStateTracking,
    Unre3DHeadScannerStateScanning
} NS_SWIFT_NAME(Unre3DHeadScanner.State);


/**
The state of tracking
 */
typedef NS_ENUM(NSInteger, Unre3DHeadScannerFacePosition) {
    Unre3DHeadScannerFacePositionReadyToScan,
    Unre3DHeadScannerFacePositionFaceNotFound,
    Unre3DHeadScannerFacePositionFaceNotFrontal,
    Unre3DHeadScannerFacePositionFaceTooClose,
    Unre3DHeadScannerFacePositionFaceTooFar,
    Unre3DHeadScannerFacePositionFaceNotCentered,
    Unre3DHeadScannerFacePositionNotAvailable
} NS_SWIFT_NAME(Unre3DHeadScanner.FacePosition);

/**
 The hint when start scan
*/
 typedef NS_ENUM(NSInteger, Unre3DHeadScannerScanHint) {
    Unre3DHeadScannerScanHintNone,
    Unre3DHeadScannerScanHintHoldStill,
    Unre3DHeadScannerScanHintCountdownThree,
    Unre3DHeadScannerScanHintCountdownTwo,
    Unre3DHeadScannerScanHintCountdownOne,
    Unre3DHeadScannerScanHintTurnHeadLeft,
    Unre3DHeadScannerScanHintKeepHeadTurning,
    Unre3DHeadScannerScanHintTurnHeadRight,
    Unre3DHeadScannerScanHintTurnHeadToTheMiddle,
    Unre3DHeadScannerScanHintCaptureCompleted,
    Unre3DHeadScannerScanHintCaptureAboutToStop
} NS_SWIFT_NAME(Unre3DHeadScanner.ScanHint);

@class Unre3DHeadScannerSessionData, Unre3DHeadScannerProgressInfo, Unre3DCamera;
@protocol Unre3DHeadScannerObserver;




/**
 *    @brief  Use the depth camera to generate  head 3D model by scanning the camera stream.
              The position of the head should be determined before scanning
 */
OBJC_VISIBLE @interface Unre3DHeadScanner : NSObject




/**
 *    @brief    Initialization method
 *
 *    @param     camera     The Class of Unre3DCamera
 *    @param     sessionData     Unre3DHeadScannerSessionData The Scan rootDir data
 *
 *    @return    return  instancetype
 */
-(instancetype) initWithCamera:(Unre3DCamera *)camera sessionData:(Unre3DHeadScannerSessionData *)sessionData;





/**
 *    @brief    return ture if current device application is running on supports head scanning
 */
@property (nonatomic, readonly) BOOL isSupported;





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





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





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




/**
 *    @brief    stop scan
 */
- (void)cancel;





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






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


@end


OBJC_VISIBLE @protocol Unre3DHeadScannerObserver <NSObject>

@optional


/**
 *    @brief    Reports face position detected by scanner
 *
 *    @param     facePosition     Unre3DHeadScannerFacePosition
 */
- (void)didTrackFacePosition:(Unre3DHeadScannerFacePosition)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:(Unre3DHeadScannerProgressInfo *)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:(Unre3DHeadScannerScanHint)hint;

@end

NS_ASSUME_NONNULL_END
#endif /* U3DHeadScanner_h */
