//
//  LFLivenessDetetorManager.h
//  LFLivenessSDK
//
//  Created by linkface on 2019/6/20.
//  Copyright © 2019 linkface. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import "LFLivenessEnumType.h"


NS_ASSUME_NONNULL_BEGIN

@protocol LFLivenessDetetorManagerDelegate <NSObject>


/**
 *  活体检测成功回调
 *
 *  @param data        回传加密后的二进制数据
 *  @param arrLFImage  根据指定输出方案回传 LFImage 数组 , LFImage属性见 LFImage.h
 *  @param lfVideoData 传 NSData hack接口数据
 
 */
- (void)livenessDidSuccessfulGetData:(nullable NSData *)data
                            lfImages:(nullable NSArray *)arrLFImage
                         lfVideoData:(nullable NSData *)lfVideoData;
/**
 *  活体检测失败回调
 *
 *  @param iErrorType      失败的类型
 *  @param iDetectionType  失败时的检测模块类型
 *  @param iDetectionIndex 失败时的检测模块在动作序列中的位置, 从0开始
 *  @param data            回传加密后的二进制数据
 *  @param arrLFImage      根据指定输出方案回传 LFImage 数组 , LFImage属性见 LFImage.h
 *  @param lfVideoData     根据指定输出方案回传 NSData 视频数据
 */
- (void)livenessDidFailWithErrorType:(LivefaceErrorType)iErrorType
                       detectionType:(LivefaceDetectionType)iDetectionType
                      detectionIndex:(int)iDetectionIndex
                                data:(nullable NSData *)data
                            lfImages:(nullable NSArray *)arrLFImage
                         lfVideoData:(nullable NSData *)lfVideoData;
/**
 *  活体检测被取消的回调
 *
 *  @param iDetectionType  检测被取消时的检测模块类型
 *  @param iDetectionIndex 检测被取消时的检测模块在动作序列中的位置, 从0开始
 */
- (void)livenessDidCancelWithDetectionType:(LivefaceDetectionType)iDetectionType
                            detectionIndex:(int)iDetectionIndex;


/**
 返回人脸数据是否符合要求和人脸对应的屏幕面积
 
 @param faceChange 人脸光线亮度相关
 @param faceArea 人脸面积
 */
- (void)livenessDidFaceChange:(LivefaceChangeValue)faceChange faceArea:(int)faceArea facePose:(LivefaceChangeValue)facePose;

/**
 loading 动画是调用该方法;
 
 @param image 动作图片用于高斯模糊使用
 */
- (void)livenessLoadingViewAnimation:(UIImage *)image;

@optional
/**
 *  每个检测模块开始的回调方法
 *
 *  @param iDetectionType  当前开始检测的模块类型
 *  @param iDetectionIndex 当前开始检测的模块在动作序列中的位置, 从0开始.
 */
- (void)livenessDidStartDetectionWithDetectionType:(LivefaceDetectionType)iDetectionType
                                    detectionIndex:(int)iDetectionIndex;
/**
 *  每一帧数据回调一次,回调当前模块已用时间及当前模块允许的最大处理时间.
 *
 *  @param dPast             当前模块检测已用时间
 *  @param dDurationPerModel 当前模块检测总时间
 */
- (void)livenessTimeDidPast:(double)dPast
           durationPerModel:(double)dDurationPerModel;

/** 帧率 */
- (void)videoFrameRate:(int)rate;

- (void)lfLivenessDetetorManagerX:(float)xNum yNum:(float)yNum arrM:(NSMutableArray*)arrM;

- (void)lfLivenessDetetorTop3:(NSMutableArray*)arrM;


@end

typedef void(^LFLivenessDetetorResultBlock)(NSString *token, NSDictionary *result);

@interface LFLivenessDetetorManager : NSObject


@property(nonatomic,weak)id <LFLivenessDetetorManagerDelegate>delegate;

/**
 Debug
 */
@property(nonatomic,assign) BOOL bDebug;

/// 张嘴阈值
@property (nonatomic, assign) float LFMouth;
/// 点头阈值
@property (nonatomic, assign) float LFLowAndUpPitch;
/// 摇头阈值
@property (nonatomic, assign) float LFYaw;
/// 眨眼阈值
@property (nonatomic, assign) float LFOpenEye;

/**
 *  初始化方法 使用默认model名称
 *
 *
 *  @param dDurationPerModel    每个模块允许的最大检测时间,小于等于0时为不设置超时时间.
 *  @param strBundlePath        资源路径 可nil
 *
 *  @return 活体检测器实例
 */
- (instancetype)initWithDuration:(double)dDurationPerModel
          resourcesBundlePath:( NSString * _Nullable )strBundlePath;

/**
 *  校验Token
 *  由于 token 的唯一性,每一次调用 startDetection 检测方法都需要重新初始化该 Manager.
 *
 *  @param token       token 必传 时效性5分钟
 *  @param callback    返回校验结果
 *
 */
- (void)checkToken:(NSString * _Nullable )token
          callback:(LFLivenessDetetorResultBlock)callback;

/**
 *  对连续输入帧进行人脸跟踪及活体检测
 *
 *  @param sampleBuffer    每一帧的图像数据
 */
- (void)trackAndDetectWithCMSampleBuffer:(CMSampleBufferRef)sampleBuffer;


/**
 *  活体检测器配置方法
 *  @param delegate     回调代理
 *  @param queue        回调线程
 *  @param arrDetection 动作序列, 如 @[ @(LIVE_MOUTH) ,@(LIVE_NOD) ,@(LIVE_YAW)] , 参照 LFLivenessEnumType.h
 */
- (void)setDelegate:(id <LFLivenessDetetorManagerDelegate>)delegate
      callBackQueue:(dispatch_queue_t)queue
  detectionSequence:(NSArray *)arrDetection;

/**
 *  设置活体检测器默认输出方案及难易度, 可根据需求在 startDetection 之前调用使生效 , 且需要在调用setDelegate:callBackQueue:detectionSequence:之后调用.
 *
 *  @param iOutputType 活体检测成功后的输出方案, 默认为 LIVE_OUTPUT_SINGLE_IMAGE
 *  @param iComplexity 活体检测的复杂度, 默认为 LIVE_COMPLEXITY_NORMAL
 */
- (void)setOutputType:(LivefaceOutputType)iOutputType
           complexity:(LivefaceComplexity)iComplexity;
/**
 *  设置活体检测器是否输出视频 可根据需求在 startDetection 之前调用使生效 , 且需要在调用setDelegate:callBackQueue:detectionSequence:之后调用.
 *
 *  @param outVideo 活体检测器是否输出视频, 默认为YES
 *  @param videoQuality 活体检测器视频质量, 默认为低质量 LIVE_LOW_QUALITY_VIDEO
 */
- (void)setOutVideo:(BOOL)outVideo videoQuality:(LivefaceVideoQualityType)videoQuality;

/**
 识别结果等待loading
 
 @param loadingView 要执行的等待动画视图
 @param complete 等待完成回调
 */
- (void)loadingViewBlock:(void(^)(void))loadingView complete:(void(^)(void))complete;
/**
 *  开始检测, 检测的输出方案以及难易程度为之前最近一次调用 setOutputType:complexity: 所指定方案及难易程度.
 */
- (void)startDetection;
/**
 *  取消检测
 */
- (void)cancelDetection;
/**
 *  获取SDK版本
 *
 *  @return SDK版本字符串信息
 */
+ (NSString *)getSDKVersion;

@end

NS_ASSUME_NONNULL_END