//
//  CustomCameraViewController.m
//  RNImagePicker
//
//  Created by 左建军 on 2017/7/3.
//  Copyright © 2017年 Marc Shilling. All rights reserved.
//

#import "CustomCameraViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>

#define ScreenWidth    [[UIScreen mainScreen] bounds].size.width  // 屏幕宽度
#define ScreenHeight   [[UIScreen mainScreen] bounds].size.height // 屏幕高度

@interface CustomCameraViewController ()<UIGestureRecognizerDelegate>

@property (nonatomic, strong) UIView *cameraView;
@property (nonatomic, strong) UIImageView *coverImageView;
@property (nonatomic, strong) UIView *usePhoneBar;

@property (nonatomic, strong) NSData *phoneData;
@property (nonatomic) CMSampleBufferRef phoneImageDataSampleBuffer;

@property (nonatomic) dispatch_queue_t sessionQueue;

@property (nonatomic, strong) AVCaptureSession* session;
@property (nonatomic, strong) AVCaptureDeviceInput* videoInput;
@property (nonatomic, strong) AVCaptureStillImageOutput* stillImageOutput;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer* previewLayer;

@end

@implementation CustomCameraViewController


// 横向
- (BOOL)shouldAutorotate {
    return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:YES];
    
    // 拍照栏
    [self createTakePhotoBar];
    
    // 使用栏
    [self createUsePhoneBar];
    
    // 照相机页面
    self.cameraView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth - 64, ScreenHeight)];
    self.cameraView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.cameraView];
    
    [self initAVCaptureSession];
    
    if (self.session) {
        [self.session startRunning];
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] setStatusBarHidden:NO];
}

- (void)viewDidDisappear:(BOOL)animated{
    
    [super viewDidDisappear:YES];
    
    if (self.session) {
        
        [self.session stopRunning];
    }
}

#pragma mark private method

- (void)createTakePhotoBar {
    UIView *actionBar = [[UIView alloc] initWithFrame:CGRectMake(ScreenWidth - 64, 0, 64, ScreenHeight)];
    actionBar.backgroundColor = [UIColor blackColor];
    
    UIButton *takePhoneButton = [UIButton buttonWithType:UIButtonTypeSystem];
    takePhoneButton.frame = CGRectMake(0, ScreenHeight / 2 -32, 64, 64);
    NSBundle *rnBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"RNImage" ofType: @"bundle"]];
    NSString *imgPath = [rnBundle pathForResource:@"takePhone" ofType:@"png" inDirectory:@"images"];
    [takePhoneButton setImage:[UIImage imageWithContentsOfFile:imgPath] forState:UIControlStateNormal];
    [takePhoneButton setTintColor:[UIColor whiteColor]];
    [takePhoneButton addTarget:self action:@selector(takePhotoAction:) forControlEvents:UIControlEventTouchUpInside];
    [actionBar addSubview:takePhoneButton];
    
    UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
    cancelButton.frame = CGRectMake(12, ScreenHeight / 2 + (ScreenHeight / 4 - 15), 40, 30);
    [cancelButton setTitle:@"取消" forState:UIControlStateNormal];
    [cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [cancelButton.titleLabel setFont:[UIFont systemFontOfSize:17]];
    [cancelButton addTarget:self action:@selector(cancelAction:) forControlEvents:UIControlEventTouchUpInside];
    [actionBar addSubview:cancelButton];
    
    [self.view addSubview:actionBar];
}

- (void)createUsePhoneBar {
    self.usePhoneBar = [[UIView alloc] initWithFrame:CGRectMake(ScreenWidth - 64, 0, 64, ScreenHeight)];
    self.usePhoneBar.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.usePhoneBar];
    
    UIButton *useButton = [UIButton buttonWithType:UIButtonTypeSystem];
    useButton.frame = CGRectMake(12, ScreenHeight / 2 - (ScreenHeight / 4 - 15), 40, 30);
    [useButton setTitle:@"使用" forState:UIControlStateNormal];
    [useButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [useButton.titleLabel setFont:[UIFont systemFontOfSize:17]];
    [useButton addTarget:self action:@selector(usePhoneAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.usePhoneBar addSubview:useButton];
    
    UIButton *cancelButton = [UIButton buttonWithType:UIButtonTypeSystem];
    cancelButton.frame = CGRectMake(12, ScreenHeight / 2 + (ScreenHeight / 4 - 15), 40, 30);
    [cancelButton setTitle:@"重拍" forState:UIControlStateNormal];
    [cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [cancelButton.titleLabel setFont:[UIFont systemFontOfSize:17]];
    [cancelButton addTarget:self action:@selector(takePhoneAgainAction:) forControlEvents:UIControlEventTouchUpInside];
    [self.usePhoneBar addSubview:cancelButton];
    self.usePhoneBar.hidden = YES;
}

//
- (void)initAVCaptureSession {
    
    self.session = [[AVCaptureSession alloc] init];
    
    NSError *error;
    
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
    //更改这个设置的时候必须先锁定设备，修改完后再解锁，否则崩溃
    [device lockForConfiguration:nil];
    //设置闪光灯为自动
    if ([device isFlashModeSupported:AVCaptureFlashModeAuto]) {
        [device setFlashMode:AVCaptureFlashModeAuto];
    }
    [device unlockForConfiguration];
    
    self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:device error:&error];
    if (error) {
        NSLog(@"%@",error);
    }
    self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
    //输出设置。AVVideoCodecJPEG   输出jpeg格式图片
    NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
    [self.stillImageOutput setOutputSettings:outputSettings];
    
    if ([self.session canAddInput:self.videoInput]) {
        [self.session addInput:self.videoInput];
    }
    if ([self.session canAddOutput:self.stillImageOutput]) {
        [self.session addOutput:self.stillImageOutput];
    }
    
    //初始化预览图层
    self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspect];
    self.previewLayer.transform = CATransform3DMakeRotation(-M_PI/2, 0, 0, 1);
    self.previewLayer.frame = self.cameraView.bounds;
    self.cameraView.layer.masksToBounds = YES;
    [self.cameraView.layer addSublayer:self.previewLayer];
    
    // 引导图片
    NSBundle *rnBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"RNImage" ofType: @"bundle"]];
    NSString *imgPath = [rnBundle pathForResource:[[self.options objectForKey:@"customCamera"] objectForKey:@"path"] ofType:@"png" inDirectory:@"images"];
    self.coverImageView = [[UIImageView alloc] init];
    self.coverImageView.image = [UIImage imageWithContentsOfFile:imgPath];
    self.coverImageView.layer.transform = CATransform3DMakeRotation(-M_PI/2, 0, 0, 1);
    self.coverImageView.frame = CGRectMake(0, 0, 517 * ScreenWidth / 736, 327 * ScreenHeight / 414);
    self.coverImageView.center = self.cameraView.center;
    [self.cameraView addSubview: self.coverImageView];
}

- (AVCaptureVideoOrientation)avOrientationForDeviceOrientation:(UIDeviceOrientation)deviceOrientation {
    AVCaptureVideoOrientation result = (AVCaptureVideoOrientation)deviceOrientation;
    if ( deviceOrientation == UIDeviceOrientationLandscapeLeft )
        result = AVCaptureVideoOrientationLandscapeRight;
    else if ( deviceOrientation == UIDeviceOrientationLandscapeRight )
        result = AVCaptureVideoOrientationLandscapeLeft;
    return result;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
            
            interfaceOrientation == UIInterfaceOrientationLandscapeRight );
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

#pragma mark -按钮方法-

// 拍照
- (void)takePhotoAction:(id)sender {
    AVCaptureConnection *stillImageConnection = [self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo];
    UIDeviceOrientation curDeviceOrientation = [[UIDevice currentDevice] orientation];
    AVCaptureVideoOrientation avcaptureOrientation = [self avOrientationForDeviceOrientation:curDeviceOrientation];
    [stillImageConnection setVideoOrientation:avcaptureOrientation];
    
    [stillImageConnection setVideoScaleAndCropFactor:1.f];
    
    __weak typeof(*&self) weakSelf = self;
    if (stillImageConnection.enabled) {
        [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:stillImageConnection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {
            
            // 照片信息
            weakSelf.phoneImageDataSampleBuffer = imageDataSampleBuffer;
            weakSelf.phoneData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            
            if (weakSelf.session) {
                [weakSelf.session stopRunning];
                weakSelf.usePhoneBar.hidden = NO;
                weakSelf.coverImageView.hidden = YES;
            }
        }];
    }
}

// 使用
- (void)usePhoneAction:(id)barButton {
    // 创建图片路径
    NSString *path = [self creatImgPathWithFileName:[[[self.options objectForKey:@"customCamera"] objectForKey:@"path"] stringByAppendingString:@".jpg"]];
    if (!path) {
        return;  // 路径出错
    }
    
    // 将图片信息写入文件中
    [UIImagePNGRepresentation([UIImage imageWithCGImage:[[UIImage imageWithData: self.phoneData] CGImage] scale:1 orientation:UIImageOrientationUp]) writeToFile:path atomically:YES];
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    
    // 创建返回对象
    NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
    
    NSString *filePath = [fileURL absoluteString];
    [response setObject:filePath forKey:@"uri"];
    NSMutableArray *results = [NSMutableArray arrayWithCapacity:0];
    [results addObject:response];
    
    // 照片保存到相册
    if ([[self.options objectForKey:@"saveAlbum"] boolValue]) {
        UIImageWriteToSavedPhotosAlbum([UIImage imageWithData: self.phoneData], self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
    }
    
    __weak typeof(*&self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf dismissViewControllerAnimated:YES completion:^{
            weakSelf.callback(@[@{@"numOfSelect": @(1), @"results": results}]);
        }];
    });
}

//  取消拍照
- (void)cancelAction:(id)barButton {
    __weak typeof(*&self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf dismissViewControllerAnimated:YES completion:^{
            weakSelf.callback(@[@{@"didCancel": @YES}]);
        }];
    });
}

// 重拍
- (void)takePhoneAgainAction: (id)barButton {
    if (self.session) {
        [self.session startRunning];
        self.usePhoneBar.hidden = YES;
        self.coverImageView.hidden = NO;
    }
}

- (NSString *)creatImgPathWithFileName:(NSString *)fileName {
    // 默认保存tmp文件夹
    NSString *path = [[NSTemporaryDirectory()stringByStandardizingPath] stringByAppendingPathComponent:fileName];
    
    if ([self.options objectForKey:@"storageOptions"] && [[self.options objectForKey:@"storageOptions"] isKindOfClass:[NSDictionary class]]) {
        NSDictionary *storageOptions = [self.options objectForKey:@"storageOptions"];
        
        //获取cache的路径
        NSString *cache = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        
        // 对path的值进行判断， path表示在外部规定图片存储的位置
        if ([storageOptions objectForKey:@"path"]) {
            // 如果path存在，在caches中创建文件夹路径
            NSString *newPath = [cache stringByAppendingPathComponent:[storageOptions objectForKey:@"path"]];
            NSError *error;
            // 创建文件夹，如果文件夹存在，不需要创建
            if (![[NSFileManager defaultManager] fileExistsAtPath:newPath]) {
                [[NSFileManager defaultManager] createDirectoryAtPath:newPath withIntermediateDirectories:YES attributes:nil error:&error];
                if (error) {
                    // 创建错误，将错误返回
                    NSLog(@"创建cache子目录错误: %@", error);
                    self.callback(@[@{@"error": error.localizedFailureReason}]);
                    return nil;
                }
            }
            // 拼接图片路径
            path = [newPath stringByAppendingPathComponent:fileName];
        } else {
            // 如果path不存在，直接保存到caches文件夹中
            path = [cache stringByAppendingPathComponent:fileName];
        }
    }
    return path;
}

-(void)image:(UIImage*)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo {
    if(!error){
        //        NSLog(@"保存成功");
    }else{
        //        NSLog(@"保存失败");
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


/*
 #pragma mark - Navigation
 
 // In a storyboard-based application, you will often want to do a little preparation before navigation
 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
 // Get the new view controller using [segue destinationViewController].
 // Pass the selected object to the new view controller.
 }
 */

@end
