//
//  ALAR3DCaptureView.m
//  GMAlpha
//
//  Created by Q14 on 2018/11/28.
//  Copyright © 2018 Gengmei. All rights reserved.
//

#import "ALAR3DCaptureView.h"
#import "Unre3DAR3DCaptureImpl.h"
#import "HeadTranformIndexView.h"
#import <SceneKit/SceneKit.h>
#import "AudioPlayUtils.h"
#import "AL3DCaptureReminderView.h"


////////////////////////////////////////////////////////////////////
static int const TAG_CAPTURE_IMAGE_VIEW_OK = 2;
static int const TAG_CAPTURE_IMAGE_VIEW_FAIL = 3;
static int const MAX_HEADTRANFORM_COUNT = 8;
///////////////////////////////////////////////////////
static int const TAG_PANEL_SAVEPANEL = 2;
static int const TAG_PANEL_PREVIEWPANEL = 3;
static int const TAG_PANEL_CAPTUREPANEL = 4;

@interface ALAR3DCaptureView()<Unre3DAR3DCaptureImplDelegate>
//3D AR 进度
@property(nonatomic,strong) Unre3DAR3DCaptureImpl *unre3DAR3DCaptureImpl;

@property(nonatomic,strong) UIImpactFeedbackGenerator * uiImpactFeedbackGenerator;

//扫描进度
@property(nonatomic,strong) HeadTranformIndexView * scanHeadProcessBar;

// 3D 提示模型
@property(nonatomic,strong) SCNView * headscnview;

@property(nonatomic,strong) GMImageView *previewUIView;
@property(nonatomic,strong) GMImageView *captureFaceView;
@property(nonatomic,strong) UIButton *captureButton;

@property(nonatomic,assign) int panelcontrolTAG;

@property(nonatomic,assign) Unre3DAR3DScanHint lastUnre3DAR3DScanHint;
@property(nonatomic,assign) Unre3DAR3DFAILHint lastUnre3DAR3DFAILHint;
@property (nonatomic, strong) AL3DCaptureReminderView *bottomView;

@property (nonatomic, assign) BOOL isPlayVideo;
/** 当前转向 */
@property(nonatomic,assign) Unre3DAR3DScanHint hint;
@end

@implementation ALAR3DCaptureView

- (void)setup {
    [super setup];
    self.lastUnre3DAR3DFAILHint = -1;
    self.lastUnre3DAR3DScanHint = -1;
    [self setupSubView];
    _isPlayVideo = YES;
}

- (void)setupSubView {
    //创建3D相机语音提示View
    [self setupCapturePromoteView];
    //创建3D 语音View bg
    [self setup3DCameraView];
    
    //创建3D 捕获
    [self setupUnre3DAR3DCapture];
    //创建开始按钮
    [self setupStartButton];
    
    //创建是否语音提示Button
    [self setupAudioButton];
    
    [self setupRemindBottomView];
}

- (void)setupRemindBottomView {
    _bottomView = [[AL3DCaptureReminderView alloc] init];
    _bottomView.hidden = YES;
    [self addSubview:_bottomView];
    [_bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(MAINSCREEN_WIDTH);
        make.left.right.mas_equalTo(0);
        make.bottom.mas_equalTo(0);
    }];
}

//创建相机
- (void)setup3DCameraView {
    _previewUIView =[[GMImageView alloc] init];
    _previewUIView.contentMode = UIViewContentModeScaleAspectFill;
    _previewUIView.frame = CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_WIDTH);
    [self addSubview:_previewUIView];
    
    _captureFaceView = [[GMImageView alloc] init];
    _captureFaceView.frame = CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_WIDTH);
    [_previewUIView addSubview:_captureFaceView];
    [_previewUIView bringSubviewToFront:_captureFaceView];
}


- (void)setupUnre3DAR3DCapture {
    _unre3DAR3DCaptureImpl = [Unre3DAR3DCaptureImpl new];
    [_unre3DAR3DCaptureImpl setPreviewUIView:_previewUIView];
    _unre3DAR3DCaptureImpl.delegate = self;
    _unre3DAR3DCaptureImpl.unre3DAR3DCaptureImplDelegate = self;
}
- (void)closeAudio:(UIButton *)button {
    button.selected = !button.selected;
    _isPlayVideo = !button.selected;
}
//语音提示View
- (void)setupCapturePromoteView {
    self.headscnview = [[SCNView alloc] init];
    self.headscnview.backgroundColor = RGBCOLOR_HEX(0x262F3D);
    _headscnview.frame = CGRectMake(0, 0, MAINSCREEN_WIDTH, MAINSCREEN_WIDTH);
    [self addSubview:_headscnview];
}

- (void)setupStartButton {
    _captureButton = [UIButton buttonWithType:UIButtonTypeCustom];
    CGFloat centerY = (MAINSCREEN_HEIGHT - OCNavigationBar.barHeight - MAINSCREEN_WIDTH)/2.0 + _previewUIView.bottom;
    _captureButton.frame = CGRectMake(MAINSCREEN_WIDTH/2-35, centerY-35, 70, 70);
    [_captureButton setBackgroundImage:[UIImage imageNamed:@"unre_scan_start"] forState:UIControlStateNormal];
    [_captureButton addTarget:self action:@selector(onCapturePress) forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:_captureButton];
}

- (void)setupAudioButton {
    UIButton *audioButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [audioButton addTarget:self action:@selector(closeAudio:) forControlEvents:UIControlEventTouchUpInside];
    [audioButton setBackgroundImage:[UIImage imageNamed:@"3d_audio_button"] forState:UIControlStateNormal];
    [audioButton setBackgroundImage:[UIImage imageNamed:@"3d_audio_butto_cl"] forState:UIControlStateSelected];
    [self addSubview:audioButton];
    [audioButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(30);
        make.right.mas_equalTo(-15);
        make.width.mas_equalTo(45);
        make.height.mas_equalTo(27);
    }];
    
    GMLabel *label = [GMLabel labelWithTextColor:UIColor.whiteColor fontSize:12];
    label.text = @"人声引导开关";
    [self addSubview:label];
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(audioButton.mas_right);
        make.top.equalTo(audioButton.mas_bottom).offset(30);
    }];
}

- (void) signOutAll {

}

- (void) tranformpanelcontrol:(int) panel
{
    @synchronized (self) {
        if(_panelcontrolTAG != panel){
            NSLog(@"tranformpanelcontrol %@", [self tranformPANELTAGToNSString:panel]);
            [self signOutPanel:_panelcontrolTAG];
            _panelcontrolTAG = panel;
            [self signInPanel:_panelcontrolTAG];
        }
    }
}

- (void) signInPanel:(int) panel
{
    switch (panel) {
        case TAG_PANEL_SAVEPANEL:{
        }break;
        case TAG_PANEL_CAPTUREPANEL:{
            self.captureButton.hidden = YES;
            self.bottomView.hidden = NO;
            [self bringSubviewToFront:self.headscnview];
            [self loadAdminHead:YES];
        }break;
        case TAG_PANEL_PREVIEWPANEL:{
            self.previewUIView.hidden = YES;
            self.bottomView.hidden = YES;
            self.captureButton.hidden = NO;
            self.bottomView.hidden = YES;
            [self bringSubviewToFront:self.previewUIView];
        }break;
        default:
            break;
    }
}
- (void) signOutPanel:(int) panel
{
    switch (panel) {
        case TAG_PANEL_SAVEPANEL:{
//            [self signOutSavePanel];
        }break;
        case TAG_PANEL_CAPTUREPANEL:{
//            [self signOutCapturePanel];
        }break;
        case TAG_PANEL_PREVIEWPANEL:{
//            [self signOutPreviewPanel];
        }break;
        default:
            break;
    }
}

- (NSString *) tranformPANELTAGToNSString:(int) tag
{
    switch (tag) {
        case TAG_PANEL_SAVEPANEL:return @"TAG_PANEL_SAVEPANEL";
        case TAG_PANEL_CAPTUREPANEL:return @"TAG_PANEL_CAPTUREPANEL";
        case TAG_PANEL_PREVIEWPANEL:return @"TAG_PANEL_PREVIEWPANEL";
        default:
            return [NSString stringWithFormat:@"TAG_PANEL_%d", tag];
    }
}

#pragma mark - lifeCycle
/////////////////// API /////////////
- (void)viewWillAppear:(BOOL)animated
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self signInCaptureView];
//        [self.homeHelper enable:YES];
    });
}

- (void)viewDidAppear:(BOOL)animated {
    
}
- (void)viewDidDisappear:(BOOL)animated
{
//    [self.homeHelper enable:NO];
    [self signOutCaptureView];
}

- (void)viewWillDisappear:(BOOL)animated
{
    //do nothing here. for SubClass
}

- (BOOL) onCaptureFinish:(Unre3DAR3DCaptureInfo *)captureinfo
{
    if(_delegate){
        [_delegate onCaptureFinish:captureinfo];
        return YES;
    }
    return NO;
}

#pragma mark -  button and view
- (void) updateCaptureButtonAndCaptureViewByFaceType:(Unre3DAR3DFaceType) type
{
    if(type == Unre3DAR3DFacePositionReadyToScan){
        [self updateCaptureImageView:TAG_CAPTURE_IMAGE_VIEW_OK];
        [self updateCaptureButton:TAG_CAPTURE_IMAGE_VIEW_OK];
    } else {
        [self updateCaptureImageView:TAG_CAPTURE_IMAGE_VIEW_FAIL];
        [self updateCaptureButton:TAG_CAPTURE_IMAGE_VIEW_FAIL];
    }
    [self updateUnre3DAR3DFaceTypeHint:type];
}

- (void) updateCaptureImageView:(NSInteger) tagflag
{
    self.captureFaceView.contentMode = UIViewContentModeScaleAspectFill;
    if(!self.captureFaceView.hidden && self.captureFaceView.tag != tagflag){
        dispatch_async(dispatch_get_main_queue(), ^{
            switch(tagflag){
                case TAG_CAPTURE_IMAGE_VIEW_OK:
                    self.captureFaceView.userInteractionEnabled = YES;
                    self.captureFaceView.tag = TAG_CAPTURE_IMAGE_VIEW_OK;
                    self.captureFaceView.image = [UIImage imageNamed:@"scan_ok"];
                    break;
                case TAG_CAPTURE_IMAGE_VIEW_FAIL:
                    self.captureFaceView.userInteractionEnabled = NO;
                    self.captureFaceView.tag = TAG_CAPTURE_IMAGE_VIEW_FAIL;
                    self.captureFaceView.image = [UIImage imageNamed:@"scan_fail"];
                    break;
            }
        });
    }
}

- (void) updateCaptureButton:(NSInteger) tagflag
{
    if(tagflag == TAG_CAPTURE_IMAGE_VIEW_OK){
        self.captureButton.userInteractionEnabled = YES;
        [self.captureButton setBackgroundImage:[UIImage imageNamed:@"unre_scan_start"] forState:UIControlStateNormal];
        //        [self.captureButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
        //        self.captureButton.imageView.tintColor = UIColor.whiteColor;
    } else {
        self.captureButton.userInteractionEnabled = NO;
        [self.captureButton setBackgroundImage:[UIImage imageNamed:@"unre_scan_normal"] forState:UIControlStateNormal];
        
        //        [self.captureButton setTitleColor:UIColor.darkGrayColor forState:UIControlStateNormal];
        //        self.captureButton.imageView.tintColor = UIColor.darkGrayColor;
    }
}

- (void) updateUnre3DAR3DFaceTypeHint:(Unre3DAR3DFaceType) type
{
    if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_IDLE){
        NSString * facehint = @"";
        switch(type){
            case Unre3DAR3DFacePositionFaceTooFar:{
                facehint = @"近一点";
            }break;
            case Unre3DAR3DFacePositionFaceTooClose:{
                facehint = @"远一点";//NSLocalizedString(@"FaceTooClose", nil);
            }break;
            case Unre3DAR3DFacePositionFaceNotFrontal:{
                facehint = @"请保持正面";//NSLocalizedString(@"FaceNotFrontal", nil);
            }break;
            case Unre3DAR3DFacePositionFaceNotCentered:
            case Unre3DAR3DFacePositionNotAvailable:
            case Unre3DAR3DFacePositionFaceNotFound:{
                facehint = @"脸部居中";// NSLocalizedString(@"FaceNotCentered", nil);
            }break;
            case Unre3DAR3DFacePositionReadyToScan:{
                facehint = @"准备扫描";
            }break;
            default:{
                //facehint = NSLocalizedString(@"FaceNotFound", nil);
                return;//否则导致闪现提示
            }break;
        }
        self.bottomView.reminderLabel.text = facehint;
    }
}
///////////////////////////////////////////////////////////////////////////
- (BOOL)captureARKit
{
    if(self.debug){
        debugLog(@"Unre3DAR3DCaptureView captureARKit");
    }
    if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_IDLE){
        BOOL capture = [_unre3DAR3DCaptureImpl startCaptureWithComplete:^(Unre3DAR3DCaptureInfo *captureinfo){
            debugLog(@"Unre3DAR3DCaptureView capture success %@", captureinfo);
            [self notifyCaptureFinish:captureinfo];
        }];
        return capture;
    }
    return NO;
}
///////////////////////////////////////////////////////////
- (void) notifyCaptureFinish:(Unre3DAR3DCaptureInfo*)captureinfo
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self onCaptureFinish:captureinfo];
    });
   
}
////////////////////// delegate /////////////
-(void) captureStateChangeOldState:(AR3DCAPTURESTATETYPE)oldstate andNewState:(AR3DCAPTURESTATETYPE) newstate
{
    if(self.debug){
        debugLog(@"Unre3DAR3DCaptureView captureStateChangeOldState(%@,%@)"
              , [AR3DCapture tranformAR3DCAPTURESTATETYPEToNSString: oldstate]
              , [AR3DCapture tranformAR3DCAPTURESTATETYPEToNSString: newstate]);
    }
    if(newstate == AR3DCAPTURE_STATE_CAPTURE){
        [self tranformpanelcontrol:TAG_PANEL_CAPTUREPANEL];
    } else if(newstate == AR3DCAPTURE_STATE_IDLE){
       
    } else if(newstate == AR3DCAPTURE_STATE_FILESAVE){
        [self tranformpanelcontrol:TAG_PANEL_SAVEPANEL];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self startCreateOBJ];
        });
        if(_delegate){
            [_delegate onCaptureStateChangeOldState:oldstate andNewState:newstate];
        }
      
    } else if(newstate == AR3DCAPTURE_STATE_FINISH){
        
    }
    
}
#pragma mark - Unre3DAR3DCaptureImplDelegate

- (void) notifyUnre3DAR3DFaceType:(Unre3DAR3DFaceType) type
{
    if(self.debug){
        debugLog(@"notifyUnre3DAR3DFaceType %@", [Unre3DAR3DCaptureImpl tranformUnre3DAR3DFaceTypeToNSString:type]);
    }
    [self updateCaptureButtonAndCaptureViewByFaceType:type];
}

- (void) notifyHeadPosition:(float)currentHeadPosition
{
    if ((_hint == Unre3DAR3DScanHintTurnHeadLeft && currentHeadPosition < 0) || (_hint == Unre3DAR3DScanHintTurnHeadRight && currentHeadPosition > 0)) {
        self.bottomView.stepView.index = currentHeadPosition;
    }
    
    //TODO 扫描进度
    if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_CAPTURE){
        if(self.debug){
            debugLog(@"notifyHeadPosition: %f", currentHeadPosition);
        }
        if(self.headscnview){
            int index = (int)(currentHeadPosition * MAX_HEADTRANFORM_COUNT);
            if(index >0){

            }else if(index < 0){
                index *= -1;

            } else {//position == 0
                //[self.scanHeadProcessBar clearProcess];
            }
        }
    }
}

- (void) notifyCaptureFAIL:(Unre3DAR3DFAILHint) hint
{
    if(self.lastUnre3DAR3DFAILHint != hint){
        self.lastUnre3DAR3DFAILHint = hint;
        [AppDelegate.visibleController toast:@"捕获失败，请重新扫描"];
        [self.unre3DAR3DCaptureImpl notifyCapturefinishH:NO];//it will switch state.
        [self tranformpanelcontrol:TAG_PANEL_PREVIEWPANEL];
        [self.unre3DAR3DCaptureImpl startPreView];
        [self signInPanel:TAG_PANEL_PREVIEWPANEL];
        // 重置数据
        [self.bottomView.stepView resetUI];
    }
}

- (void) notifyProcessorProcessing:(float)progress
{
    if(self.debug){
        NSLog(@"notifyProcessorProcessing %f %@", progress, [AR3DCapture tranformAR3DCAPTURESTATETYPEToNSString:[_unre3DAR3DCaptureImpl getCurrentCaptureState]]);
    }
    if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_FILESAVE){
        //TODO 更新x进度
//        [self updateloadprogress:progress];
    }
}

- (void) notifyScanHint:(Unre3DAR3DScanHint) hint
{
    if(self.debug){
        NSLog(@"notifyScanHint %@", [Unre3DAR3DCaptureImpl tranformUnre3DAR3DScanHintToNSString:hint]);
    }
    if(self.lastUnre3DAR3DScanHint != hint){
        [self notifyTurnHead:hint];
        if (_isPlayVideo) {
            [self playAudio:hint];
        }
        [self animationHead:hint];
        self.lastUnre3DAR3DScanHint = hint;//update lastUnre3DAR3DScanHint.
    }
    if(self.debug){
        NSLog(@"notifyScanHint %@ over", [Unre3DAR3DCaptureImpl tranformUnre3DAR3DScanHintToNSString:hint]);
    }
}
//////////////////////////////////////////////////////////////////////////////////
- (void) startCreateOBJ
{
    if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_FILESAVE){
        if(![_unre3DAR3DCaptureImpl createOBJ]){
//            [_unre3DAR3DCaptureImpl notifyCapturefinishH:NO];//notify fail. it will call notifyCaptureFAIL.
        } else {
            // 开始创建obj
        }
    }
}
///////////////////////////////////////////////////////////////////////////////////////
- (void) notifyTurnHead:(Unre3DAR3DScanHint) hint
{
    self.hint = hint;
    NSString * facehint = @"";
    switch(hint){
        case Unre3DAR3DScanHintTurnHeadLeft:{
//            facehint = NSLocalizedString(@"FaceTurnLeft", nil);
            facehint = @"请向左慢慢转头";
        }break;
        case Unre3DAR3DScanHintTurnHeadRight:{
//            facehint = NSLocalizedString(@"FaceTurnRight", nil);
            facehint = @"请向右慢慢转头";
        }break;
        case Unre3DAR3DScanHintTurnHeadToTheMiddle:{
//            facehint = NSLocalizedString(@"FaceTurnMiddle", nil);
            facehint = @"请缓慢回正";
        }break;
        case Unre3DAR3DScanHintKeepHeadTurning:{
//            facehint = NSLocalizedString(@"FaceTrunKeeping", nil);
            facehint = @"请保持";
        }break;
        default:{
            //facehint = NSLocalizedString(@"FaceNotFound", nil);
            return;//否则导致闪现提示
        }break;
    }
    //TODO 扫描提示
    self.bottomView.reminderLabel.text = facehint;
}
- (void) playAudio:(Unre3DAR3DScanHint) hint
{
    NSString * audiofile = nil;
    switch(hint){
        case Unre3DAR3DScanHintTurnHeadLeft:{
            audiofile = @"turnleft.mp3";
        }break;
        case Unre3DAR3DScanHintTurnHeadRight:{
            audiofile = @"turnright.mp3";
        }break;
        case Unre3DAR3DScanHintTurnHeadToTheMiddle:{
            audiofile = @"turnmiddle.mp3";
        }break;
        default: break;
    }
    if(audiofile){
        [AudioPlayUtils playSoundEffect:audiofile];
    }
}
/////////////////////////////////////////////////////////////////////////////////
- (void) loadAdminHead:(BOOL) show
{
    if(self.headscnview){
        if(show){
            self.headscnview.scene = [self loadSCNScene];
            //[self AnimationFadeIn: self.headscnview.scene];
        } else {
            [self.headscnview.scene.rootNode removeAllActions];
            [self removeAllChildNodes:self.headscnview.scene.rootNode];
        }
    }
}

- (void) animationHead:(Unre3DAR3DScanHint) hint
{
    switch(hint){
        case Unre3DAR3DScanHintTurnHeadLeft:{
            [self.headscnview.scene.rootNode removeAllActions];
            [self.headscnview.scene.rootNode runAction:[SCNAction repeatAction:[SCNAction rotateByX:0 y:-0.8 z:0 duration:2.5] count:1]];
            [self vibrate];
        }break;
        case Unre3DAR3DScanHintTurnHeadRight:{
            [self.headscnview.scene.rootNode removeAllActions];
            [self.headscnview.scene.rootNode runAction:[SCNAction repeatAction:[SCNAction rotateByX:0 y:0.8 z:0 duration:2.5] count:1]];
            [self vibrate];
        }break;
        case Unre3DAR3DScanHintTurnHeadToTheMiddle:{
            if(self.lastUnre3DAR3DScanHint == Unre3DAR3DScanHintTurnHeadLeft){
                [self.headscnview.scene.rootNode removeAllActions];
                [self.headscnview.scene.rootNode runAction:[SCNAction repeatAction:[SCNAction rotateByX:0 y:0.8 z:0 duration:2.5] count:1]];
            } else if(self.lastUnre3DAR3DScanHint == Unre3DAR3DScanHintTurnHeadRight){
                [self.headscnview.scene.rootNode removeAllActions];
                [self.headscnview.scene.rootNode runAction:[SCNAction repeatAction:[SCNAction rotateByX:0 y:-0.8 z:0 duration:2.5] count:1]];
            }
            [self vibrate];
        }break;
        case Unre3DAR3DScanHintCaptureCompleted:{
            if([_unre3DAR3DCaptureImpl getCurrentCaptureState] == AR3DCAPTURE_STATE_CAPTURE){
                [self tranformpanelcontrol:TAG_PANEL_SAVEPANEL];
                //[self.headTranformIndexView reSetIndex];
            }
        }break;
        default: break;
    }
}

- (void) AnimationFadeIn:(SCNScene *) scene
{
    // Fade in the objects
    CABasicAnimation *startAnim = [CABasicAnimation animationWithKeyPath:@"opacity"];
    startAnim.duration = 0.3;
    startAnim.fromValue = @0.0;
    startAnim.toValue = @1.0;
    [scene.rootNode addAnimation:startAnim forKey:@"fadeIn"];
}

- (SCNScene *) loadSCNScene
{
    //SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/anim.scn"];
    SCNScene *scene = [SCNScene sceneNamed:@"art.scnassets/animationhead.obj"];
    SCNNode * head = scene.rootNode.childNodes[0];
    SCNVector3 position = head.position;
    head.position = SCNVector3Make(position.x , position.y + 20, position.z);
    [scene.rootNode addChildNode:[self createLightSCNNode]];
    [self scaleSCNNode:scene.rootNode byScale:0.6];
    return scene;
}

- (void) scaleSCNNode:(SCNNode *) node byScale:(float)scalevalue
{
    node.scale = SCNVector3Make(node.scale.x * scalevalue, node.scale.y * scalevalue, node.scale.z * scalevalue);
}

- (void) removeAllChildNodes:(SCNNode*)scnnode
{
    NSEnumerator * enumerateor =  [scnnode.childNodes objectEnumerator];
    SCNNode * child;
    while (child = [enumerateor nextObject]) {
        [child removeFromParentNode];
    }
}

- (SCNNode *) createLightSCNNode
{
    SCNNode *lightNode = [SCNNode node];
    //lightNode.name = SCNNODE_NAME_LIGHT;
    lightNode.light = [SCNLight light];
    lightNode.light.color = UIColor.whiteColor; // initially switched off
    lightNode.light.type = SCNLightTypeDirectional;
    return lightNode;
}

///////////////////////////////////////////////////////////////////////////
- (void)dealloc
{
    if(_unre3DAR3DCaptureImpl){
        [_unre3DAR3DCaptureImpl stopPreView];
        [_unre3DAR3DCaptureImpl stopCapture];
        _unre3DAR3DCaptureImpl = nil;
    }
}

////////////////////////////////////////////////////////////////////////////
- (UIImpactFeedbackGenerator *)uiImpactFeedbackGenerator
{
    if( !_uiImpactFeedbackGenerator ){
        _uiImpactFeedbackGenerator = [[UIImpactFeedbackGenerator alloc]initWithStyle:UIImpactFeedbackStyleLight];
    }
    return _uiImpactFeedbackGenerator;
}
- (void) vibrate
{
    [self.uiImpactFeedbackGenerator impactOccurred];
}
////////////////////////////////////////////////////////////////////////////
- (void) signInCaptureView
{
    if(_unre3DAR3DCaptureImpl){
        [_unre3DAR3DCaptureImpl startPreView];
    }
}

- (void) signOutCaptureView
{
    if(_unre3DAR3DCaptureImpl){
        [_unre3DAR3DCaptureImpl stopPreView];
        [_unre3DAR3DCaptureImpl stopCapture];
    }
}

#pragma mark - Action
- (void) onCapturePress {
    if (_delegate) {
        [_delegate onCaputreClick];
    }
    [self captureARKit];
}
@end
