//
//  SDKHelper.m
//  SDKDemo
//
//  Created by JasWorkSpace on 2018/10/19.
//  Copyright © 2018 JasWorkSpace. All rights reserved.
//

#import <Foundation/Foundation.h>
#include "SDKHelper.h"
#include "FileUtils.h"
#include "UnOSUtils.h"
#include <iostream>
#import <SceneKit/SceneKit.h>
#include <unreface_trans/unreface_trans.h>
#import "ALScanManager.h"
#import "ALFaceFittingAPI.h"

@interface SDKHelper()<UnreDeformationManagerDegelate>
@property(nonatomic,strong) NSString * datFile;
///////
@property(nonatomic,strong) OBJView *objView;
@property(nonatomic,strong) SliderPanel * sliderPanel;
@property(nonatomic,assign) float * faceTransRate;
@property(nonatomic,retain) UnreDeformationManager * faceUnreManager;
@property(nonatomic,retain) UnreDeformationManager * faceUnreManager1;
@property(nonatomic,retain) UnreDeformationManager * faceUnreManager2;

@property(nonatomic,retain) UnreDeformationManager *analyse3DManager;
@property(nonatomic,assign) BOOL unreFaceLoaded;
@property (nonatomic, assign) int index;
@property(nonatomic,strong) NSString *fengwei;
@end
/////////
@interface  SDKHelper()<UnreFaceAnalysManagerDegelate>
@property(nonatomic,assign) BOOL unreFaceAnalysloaded;
@property(nonatomic,retain) UnreFaceAnalysManager * faceUnreAnalysManager;
@property (nonatomic, strong) NSString *matchingObjpath;


@end
////////
@implementation SDKHelper

- (instancetype)initWithOBJFile:(NSString *)file andMesh:(NSString *) meshfile andOBJView:(OBJView*) objview andSliderPanel:(SliderPanel *)sliderPanel
{
    if(self = [super init]){
        _srcOBJFile = file;
        _index = 0;
        _srcMeshFile = meshfile;
        _objView = objview;
        _sliderPanel = sliderPanel;
        _objView.meshfilename = _srcMeshFile;
        [self testloadFileData];
        [self commitSDKHelperInit];
    }
    return self;
}

- (instancetype)initWithOBJView:(OBJView*) objview andModel:(ALMatchingModel *)model andSliderPanel:(SliderPanel *)sliderPanel
{
    if(self = [super init]){
        _srcOBJFile = model.sourceOBJFile;
        _srcMeshFile = model.sourceMeshFile;
        _goalOBJFile = model.goalOBJFile;
        _goalMeshFile = model.goalMeshFile;
        _objView = objview;
        _sliderPanel = sliderPanel;
        _objView.meshfilename = _srcMeshFile;
        [self testloadFileData];
        [self commitSDKHelperInit];
        _index = 0;
    }
    return self;
}

- (void) commitSDKHelperInit
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [AppDelegate.visibleController showLoading:@"模型数据分析中"];
    });
    
    [[[NSThread alloc] initWithTarget:self selector:@selector(initUnreFaceManager) object:nil] start];
}

-(BOOL) initUnreFaceManager
{
    NSString *objfile;
    NSString *meshfile;
    if ([self.goalOBJFile isNonEmpty]) {
        objfile = self.goalOBJFile;
        meshfile = self.goalMeshFile;
    } else {
        NSString * dir = @"art.scnassets/star";
        dir = [[NSBundle mainBundle] pathForResource:dir ofType:nil];
        objfile = [NSString stringWithFormat:@"%@/chenweiting3d.obj", dir];
        meshfile = [NSString stringWithFormat:@"%@/chenweiting3d.png", dir];
    }
  
    _faceUnreManager1 = [[UnreDeformationManager alloc]initUnreFaceFile:objfile andUVmap:meshfile];
    _faceUnreManager1.UnreDeformationManagerDelegate=self;
    
    _faceUnreManager = [[UnreDeformationManager alloc] initUnreFaceFile:self.srcOBJFile andUVmap:self.srcMeshFile];
    _faceUnreManager.UnreDeformationManagerDelegate = self;
    
    ///////
    _faceUnreAnalysManager = [[UnreFaceAnalysManager alloc] initUnreFaceAnalysManager];
    _faceUnreAnalysManager.unreFaceAnalysManagerDelegate=self;
    
    if(_faceUnreManager != nil && _faceUnreManager1 !=nil)
    {
        NSLog(@"load========done=======+++++++++");
        return YES;
    }
    return NO;
}
- (void) unreDeformationManagerLoadFinish:(BOOL)result
{
    _index++;
    if (_unreFaceLoaded) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [AppDelegate.visibleController hideLoading];
            if (self.index == 2) {
               [AppDelegate.visibleController toast:@"拟合成功，点击明星头像查看拟合结果"];
            }
            
            if (self.index == 4) {
                self.index = 0;
            }
        });
    }
    _unreFaceLoaded = result;
  
    NSLog(@"===初始化完毕");
}


- (void) testloadFileData
{
//    NSURL *fileUrl = [NSURL fileURLWithPath:self.srcOBJFile];
    if (!self.srcOBJFile) {
        return;
    }
    if (![FileUtils isFileExist:self.srcOBJFile]) {
        [AppDelegate.visibleController toast:@"正在处理建模数据"];
        return;
    }
    SCNScene * scene = [SceneKitUtils loadSCNSceneFromLocalFile:self.srcOBJFile];
    SCNNode * head = scene.rootNode.childNodes[0];
    _objView.faceheadname = head;
    
   
    
    NSLog(@"unre====444444444");
}

-(void) sliderItemNum:(int)index andRow:(int)row
{
    if(_unreFaceLoaded && _faceUnreManager2 != nil){
        
        float currentItemRate =0.0f;
        _faceTransRate = [_faceUnreManager2 getCurrentDeformationScales];
        if(index == 0){
            if(row==0)
                currentItemRate = _faceTransRate[3]*10;
            if(row==1)
                currentItemRate = _faceTransRate[4]*10;
        }else if (index == 1){
            if(row==0)
                currentItemRate=_faceTransRate[8]*10;
            if(row==1)
                currentItemRate=_faceTransRate[7]*10;
            if(row==2)
                currentItemRate=_faceTransRate[12]*10;
            if(row==3)
                currentItemRate=_faceTransRate[13]*10;
            if(row==4)
                currentItemRate=_faceTransRate[14]*10;
            if(row==5)
                currentItemRate=_faceTransRate[15]*10;
            if(row==6)
                currentItemRate=_faceTransRate[16]*10;
        }else if (index==2){
            if(row==0)
                currentItemRate=_faceTransRate[0]*10;
            if(row==1)
                currentItemRate=_faceTransRate[1]*10;
            if(row==2)
                currentItemRate=_faceTransRate[2]*10;
        }else if (index==3){
            if(row==0)
                currentItemRate=_faceTransRate[5]*10;
            if(row==1)
                currentItemRate=_faceTransRate[6]*10;
            if(row==2)
                currentItemRate=_faceTransRate[9]*10;
            if(row==3)
                currentItemRate=_faceTransRate[10]*10;
            if(row==4)
                currentItemRate=_faceTransRate[11]*10;
        }else if (index==4){
            if(row==0)
                currentItemRate=_faceTransRate[17]*10;
            if(row==1)
                currentItemRate=_faceTransRate[18]*10;
        }
        [self.sliderPanel setCurrentValue:currentItemRate];
    }
}
/*
 #define LIPS_SMILE 0
 #define LIPS_UP 1
 #define LIPS_DOWN 2
 #define NOSE_BRIDGE 3
 #define NOSE_FAT 4
 #define VFACE 5
 #define FOREHEAD 6
 #define EXTERNAL_CANTHUS 7
 #define MEDIAL_CANTHUS 8
 #define APPLE_MUSCLE 9
 #define UP_CHIN 10
 #define DOWN_CHIN 11
 #define SMOOTH_POUCH 12
 #define PARALLEL_EYELID 13
 #define FAN_EYELID 14
 #define MOON_EYELID 15
 #define WESTERN_EYELID 16
 #define WHITENING 17
 #define SMOOTH_UV 18
 */
- (void) testtranform:(int)index andRow:(int)row andValue:(float) rate
{
    
    float radio = (rate - 50) / 50. * 3;
    if(_unreFaceLoaded){
        
        int transformItem=0;
        if(index == 0){
            if(row==0)
                transformItem = NOSE_BRIDGE;
            if(row==1)
                transformItem= NOSE_FAT;
        }else if (index == 1){
            if(row==0)
                transformItem=MEDIAL_CANTHUS;
            if(row==1)
                transformItem=EXTERNAL_CANTHUS;
//           if(row==2)
//             transformItem=SMOOTH_POUCH;
//            if(row==3)
//             transformItem=PARALLEL_EYELID;
//            if(row==4)
//             transformItem=FAN_EYELID;
//            if(row==5)
//             transformItem=MOON_EYELID;
//            if(row==6)
//             transformItem=WESTERN_EYELID;
        }else if (index==2){
            if(row==0)
                transformItem =LIPS_SMILE;
            if(row==1)
                transformItem =LIPS_UP;
            if(row==2)
                transformItem=LIPS_DOWN;
        }else if (index==3){
            if(row==0)
                transformItem=VFACE;
            if(row==1)
                transformItem=FOREHEAD;
            if(row==2)
                transformItem=APPLE_MUSCLE;
            if(row==3)
                transformItem=UP_CHIN;
            if(row==4)
                transformItem=DOWN_CHIN;
        }else if (index==4){
//            if(row==0)
//                transformItem=WHITENING;
//            if(row==1)
//             transformItem= SMOOTH_UV;
            
        }
        
        unsigned long colorSize =0;
        UnreFileData_out * faceOut =[_faceUnreManager2 tranformFun:transformItem andValue:radio];
        colorSize = faceOut->color.size();
        if(colorSize>0){
            debugLog(@"color点云========形变");
            _objView.faceheadname = [FileDataUtils createColorSCNNode:faceOut];
        }else{
            _objView.faceheadname = [FileDataUtils createSCNNode:faceOut];
            debugLog(@"vt点云========形变");
            //需配合拟合后的贴图
            _objView.meshfilename = self.fengwei;
        }
        faceOut->color.clear();
        vector<UnrePoint3D>().swap(faceOut->color);
        faceOut->v.clear();
        vector<UnrePoint3D>().swap(faceOut->v);
        faceOut->vn.clear();
        vector<UnrePoint3D>().swap(faceOut->vn);
        faceOut->texcoords.clear();
        vector<UnrePoint2D>().swap(faceOut->texcoords);
        faceOut->faces.clear();
        vector<UnreFace3D>().swap(faceOut->faces);
    }
}

-(void)testfitfun
{
      SCNNode * fitNode = [FileDataUtils createColorSCNNode:[_faceUnreManager getUnreEncodingFaceData]];
      _objView.faceheadname = fitNode;
    
//       SCNNode * fitNode = [_faceUnreManager getUnreEncodingFaceData];
//      _objView.faceheadname = fitNode;
    
}

-(void)testEvlo
{
    ////两个 人脸。_faceUnreManager 初始化完毕后 调用 拟合函数。
    //拟合过程 需输入两个 编码点云。_faceUnreManager getUnreEncodingFaceData  -----_faceUnreManager1 getUnreEncodingFaceData  //begin
    if(_unreFaceLoaded){
        UnreFileData_out *outData = [_faceUnreManager1 getUnreEncodingFaceData];
        vector<UnreFileData_out> testScnnode = [UnreDeformationControlManager unreExchangeFace: outData andTo: [_faceUnreManager getUnreEncodingFaceData] andStep:10];
//        vector<UnreFileData_out> testScnnode = [UnreDeformationControlManager unreExchangeFace:[_faceUnreManager getUnreEncodingFaceData] andTo:outData andStep:10];
        _objView.faceheadname = [FileDataUtils createSCNNode:&testScnnode[4]];
        
        NSString * testdiff= [_faceUnreAnalysManager getUnreOverlyingDiffWith:[_faceUnreManager getCurrentFaceLandMarks] andLandMark:[_faceUnreManager1 getCurrentFaceLandMarks] andPc1:[_faceUnreManager getOriginalObjData] andPc2:[_faceUnreManager1 getOriginalObjData]];
        // 同一人脸的 对比数据
        NSString * testdiff1= [_faceUnreAnalysManager getUnreChangeDiffWith:[_faceUnreManager getCurrentFaceLandMarks]  andPc1:[_faceUnreManager getOriginalObjData] andPc2:[_faceUnreManager getOriginalObjData]];
        debugLog(@"打印 对比数据===00000===%@",testdiff);
        
        debugLog(@"打印 对比数据====1111====%@",testdiff1);
        debugLog(@"打印 版本信息======%@",[UnreDeformationControlManager getUnreTransSdkVersion]);
        
        
        /////保存拟合后的obj  供形变使用 begin
        Unre3DAR3DCaptureInfo *sharePath = [[Unre3DAR3DCaptureInfo alloc] initWithBasePath:[NSString stringWithFormat:@"%@/fittedFloder", [FileUtils getBasePath]]];
        ALScanManager.shareInstance.fitting3DInfo = sharePath;
        if (![FileUtils isPathExist:sharePath.basePath]) {
            [FileUtils createPath:sharePath.basePath];
        }

        sharePath.CustomFileName = @"alphaSharePath";
        _fengwei = [NSString stringWithUTF8String:testScnnode[4].uvImagePath.c_str()];
        //需配合拟合后的贴图
        _objView.meshfilename = _fengwei;
        _matchingObjpath = [sharePath getOBJFile];//@"alphaSharePath.obj";//[sharePath getOBJFile];//[sharePath. stringByAppendingPathComponent:objPath];
        BOOL saved = [UnreDeformationControlManager saveUnreEncodingFace:& testScnnode[4] andPath:@"alphaSharePath.obj"];

        if (saved) {
            //获取明星数据成功
            [[NSNotificationCenter defaultCenter] postNotificationName:kcapture3DModelAndStartModelSuccess object:nil];
            // 取出存取的拟合后的obj上传给服务端
            ALScanManager.shareInstance.lastMatchingPath = _matchingObjpath;
            ALScanManager.shareInstance.needUploadShareObj = YES;
            
            [ALFaceFittingAPI storeObjWithFilePath:sharePath.getOBJFile  key:@"raw_c3d_obj" completion:nil];
            [ALFaceFittingAPI storeObjWithFilePath:sharePath.getMtlFile key:@"mtl_url" completion:nil];
            [ALFaceFittingAPI storeObjWithFilePath:sharePath.getMeshFile key:@"uv_url" completion:nil];
        }
        
        debugLog(@"show saved========%@", @"开始初始化color点云");
        ////////////初始化 拟合后点云形变模型 begin
        [self commitColorDataInit];
    }
}

- (NSString *) copyOBJ
{
    NSString * dir = @"art.scnassets/star";
    dir = [[NSBundle mainBundle] pathForResource:dir ofType:nil];
    NSString * basepath = [NSString stringWithFormat:@"%@/star", [FileUtils getBasePath]];
    NSLog(@"basepath:%@,dir:%@",basepath,dir);
    [FileUtils copyItemAtPath:dir toPath:basepath overwrite:YES error:nil];
    return basepath;
}


- (void) commitColorDataInit
{
    [[[NSThread alloc] initWithTarget:self selector:@selector(initUnreColorFaceManager) object:nil] start];
}
-(BOOL) initUnreColorFaceManager
{
    //保存obj 路径
    _faceUnreManager2 = [[UnreDeformationManager alloc] initUnreFaceFileColor:_matchingObjpath];
    _faceUnreManager2.UnreDeformationManagerDelegate = self;
    if(_faceUnreManager2 != nil)
    {
        debugLog(@"load====color====done=======+++++++++");
        return YES;
    }
    return NO;
}

-(void) testShowCompare
{
    
}


- (void)unreFaceAnalysManagerLoadFinish:(BOOL)result {
    
    debugLog(@"分析初始化完毕");
   
//    [AppDelegate.visibleController toast:@"分析初始化完毕"];
    _unreFaceAnalysloaded = result;
}

- (SCNNode *)getMy3DNode {
    UnreFileData_out * fileData =  [_faceUnreManager getOriginalObjData];
    SCNNode *node = [FileDataUtils createSCNNode: fileData];
    return node;
}
@end
