//
//  IBTImagePicker.m
//  XFFruit
//
//  Created by Xummer on 4/17/15.
//  Copyright (c) 2015 Xummer. All rights reserved.
//

#import "IBTImagePicker.h"
#import "UIActionSheet+Blocks.h"

#define MAX_TIME_LIMIT    (60 * 1)

@import AVFoundation;

// ====== IBTImagePickerController ======

@interface IBTImagePickerController ()
{
    BOOL m_bWillDisappear;
}
@end

@implementation IBTImagePickerController

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    m_bWillDisappear = NO;
}

- (void)viewWillDisappear:(BOOL)animated {
    m_bWillDisappear = YES;
    [super viewWillDisappear:animated];
    
    if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
        [self setNeedsStatusBarAppearanceUpdate];
    }
}

#pragma mark - StatusBar

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent; // change this to match your style
}

- (BOOL)prefersStatusBarHidden {
    switch (self.sourceType) {
        case UIImagePickerControllerSourceTypeCamera:
            if (m_bWillDisappear) {
                return [self.navigationController.presentingViewController prefersStatusBarHidden];
            }
            else {
                return YES;
            }
            break;
        default:
            return NO;
            break;
    }
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return UIStatusBarAnimationNone;
}

- (UIViewController *)childViewControllerForStatusBarHidden {
    switch (self.sourceType) {
        case UIImagePickerControllerSourceTypeCamera:
            return nil;
            break;
        default:
            return [super childViewControllerForStatusBarHidden];
            break;
    }
}

@end

// ===== IBTMediaHelper ======
@interface IBTImagePicker ()
<
    UIImagePickerControllerDelegate,
    UINavigationControllerDelegate
>

@property (nonatomic, weak) UIViewController *m_vcHolder;

@end

@implementation IBTImagePicker

#pragma mark - Class Method
+ (NSString *)uniqueName {
    NSString *identifier = [[NSProcessInfo processInfo] globallyUniqueString];
    return identifier;
}

+ (NSString *)handleFileName:(NSString *)fileName {
    NSString *fileNewName;
    
    if (fileName) {
        fileNewName = [[fileName componentsSeparatedByString:@"."] firstObject];
    }
    else{
        fileNewName = @"";
    }
    return [fileNewName stringByAppendingString:[[self class] uniqueName]] ;
}

+ (NSString *)handleImageName:(NSString *)imageName {
    NSString *imgNewName = [[self class] handleFileName:imageName];
    // 所有名字后缀改为JPG
    return [[imgNewName stringByDeletingPathExtension] stringByAppendingPathExtension:@"JPG"];
}

+ (NSString *)handleVideoName:(NSString *)videoName {
    NSString *vdoNewName = [[self class] handleFileName:videoName];
    
    return [[vdoNewName stringByDeletingPathExtension] stringByAppendingPathExtension:@"MP4"];
}

+ (UIImage *)getVideoMainFrameWithUrl:(NSURL *)url
{
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
    NSParameterAssert(asset);
    AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    assetImageGenerator.appliesPreferredTrackTransform = YES;
    assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
    
    CGImageRef thumbnailImageRef = NULL;
    CFTimeInterval thumbnailImageTime = 0;
    NSError *thumbnailImageGenerationError = nil;
    thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60) actualTime:NULL error:&thumbnailImageGenerationError];
    
    if (!thumbnailImageRef)
        CLog(@"thumbnailImageGenerationError %@", thumbnailImageGenerationError);
    
    UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] : nil;
    
    
    return thumbnailImage;
}

+ (BOOL)startCameraControllerFromViewController:(UIViewController*)controller
                                      mediaType:(IBTMediaBrowserType)type
                                       editable:(BOOL)eFlag
                                  usingDelegate:(id <UIImagePickerControllerDelegate,
                                                 UINavigationControllerDelegate>)delegate {
    
    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeCamera] == NO)
        || (delegate == nil)
        || (controller == nil))
        return NO;
    
    IBTImagePickerController *cameraUI = [[IBTImagePickerController alloc] init];
    cameraUI.navigationBar.translucent = NO;
    
    cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
    
    NSMutableArray *mediaTypes = [NSMutableArray array];
    
    if (type & kIBTMediaBImage) {
        [mediaTypes addObject:(NSString *)kUTTypeImage];
    }
    
    if (type & kIBTMediaBVideo) {
        [mediaTypes addObject:(NSString *)kUTTypeMovie];
        cameraUI.videoQuality = UIImagePickerControllerQualityTypeLow;
        cameraUI.videoMaximumDuration = MAX_TIME_LIMIT;
    }
    
    
    cameraUI.mediaTypes = mediaTypes;
    
    // Hides the controls for moving & scaling pictures, or for
    // trimming movies. To instead show the controls, use YES.
    cameraUI.allowsEditing = eFlag;
    
    cameraUI.delegate = delegate;
    
    [controller presentViewController: cameraUI animated: YES completion:nil];
    return YES;
}

+ (BOOL)startMediaBrowserFromViewController:(UIViewController*)controller
                                  mediaType:(IBTMediaBrowserType)type
                                   editable:(BOOL)eFlag
                              usingDelegate:(id <UIImagePickerControllerDelegate,
                                             UINavigationControllerDelegate>)delegate {
    
    if (([UIImagePickerController isSourceTypeAvailable:
          UIImagePickerControllerSourceTypeSavedPhotosAlbum] == NO)
        || (delegate == nil)
        || (controller == nil))
        return NO;
    
    IBTImagePickerController *mediaUI = [[IBTImagePickerController alloc] init];
    
    NSMutableArray *mediaTypes = [NSMutableArray array];
    
    switch (type) {
        case kIBTMediaBImage:
        {
            [mediaTypes addObject:(NSString *)kUTTypeImage];
            
            mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        }
            break;
        case kIBTMediaBVideo:
        {
            [mediaTypes addObject:(NSString *)kUTTypeMovie];
            mediaUI.videoQuality = UIImagePickerControllerQualityTypeLow;
            mediaUI.videoMaximumDuration = 60 * 3;
            
            mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
        }
        case kIBTMediaBAll:
        {
            [mediaTypes addObjectsFromArray:@[ (NSString *)kUTTypeImage, (NSString *)kUTTypeMovie ]];
            mediaUI.videoQuality = UIImagePickerControllerQualityTypeLow;
            mediaUI.videoMaximumDuration = 60 * 3;
            
            mediaUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            
        }
            break;
        default:
            break;
    }
    
    mediaUI.mediaTypes = mediaTypes;
    mediaUI.navigationBar.translucent = NO;
    
    mediaUI.allowsEditing = eFlag;
    
    mediaUI.delegate = delegate;
    
    [controller presentViewController: mediaUI animated: YES completion:nil];
    return YES;
}

+ (void)showImagePickerTitle:(NSString *)title
                   mediaType:(IBTMediaBrowserType)type
                    editable:(BOOL)eFlag
          fromViewController:(UIViewController*)controller
               usingDelegate:(id <UIImagePickerControllerDelegate,
                              UINavigationControllerDelegate>)delegate
{
    NSString *cameraBtnName, *albumBtnName;
    switch (type) {
        case kIBTMediaBImage:
            albumBtnName = @"Choose Photo";
            cameraBtnName = @"Take Photo";
            break;
        case kIBTMediaBVideo:
            albumBtnName = @"Choose Video";
            cameraBtnName = @"Shoot Video";
            break;
            
        case kIBTMediaBAll:
            albumBtnName = @"From Album";
            cameraBtnName = @"From Camera";
            break;
        default:
            break;
    }
    
    [[self class] showImagePickerTitle:title
                          albumBtnName:[IBTCommon localizableString:albumBtnName]
                         cameraBtnName:[IBTCommon localizableString:cameraBtnName]
                         cancelBtnName:[IBTCommon localizableString:@"Cancel"]
                             mediaType:type
                              editable:eFlag
                    fromViewController:controller
                         usingDelegate:delegate];
}

+ (void)showImagePickerTitle:(NSString *)title
                albumBtnName:(NSString *)albumName
               cameraBtnName:(NSString *)cameraName
               cancelBtnName:(NSString *)cancelName
                   mediaType:(IBTMediaBrowserType)type
                    editable:(BOOL)eFlag
          fromViewController:(UIViewController*)controller
               usingDelegate:(id <UIImagePickerControllerDelegate,
                              UINavigationControllerDelegate>)delegate {
    
    RIButtonItem *cancelItem = [RIButtonItem itemWithLabel:cancelName action:NULL];
    
    RIButtonItem *albumItem = [RIButtonItem itemWithLabel:albumName action:^{
        [[self class] startMediaBrowserFromViewController:controller
                                                mediaType:type
                                                 editable:eFlag
                                            usingDelegate:delegate];
    }];
    RIButtonItem *cameraItem = [RIButtonItem itemWithLabel:cameraName action:^{
        [[self class] startCameraControllerFromViewController:controller
                                                    mediaType:type
                                                     editable:eFlag
                                                usingDelegate:delegate];
    }];
    
    UIActionSheet *actSheet =
    [[UIActionSheet alloc] initWithTitle:title
                        cancelButtonItem:cancelItem
                   destructiveButtonItem:nil
                        otherButtonItems:albumItem, cameraItem, nil];
    [actSheet showInView:controller.view.window];
}

#pragma mark - Instans Method
- (BOOL)startCameraControllerFromViewController:(UIViewController *)controller
                                      mediaType:(IBTMediaBrowserType)type
                                       editable:(BOOL)eFlag
{
    if (!self.m_delegate && [controller conformsToProtocol:@protocol(IBTImagePickerDelegate)]) {
        self.m_delegate = (id <IBTImagePickerDelegate>)controller;
    }
    
    self.m_vcHolder = controller;
    return [[self class] startCameraControllerFromViewController:controller
                                                       mediaType:type
                                                        editable:eFlag
                                                   usingDelegate:self];
}

- (BOOL)startMediaBrowserFromViewController:(UIViewController *)controller
                                  mediaType:(IBTMediaBrowserType)type
                                   editable:(BOOL)eFlag
{
    if (!self.m_delegate && [controller conformsToProtocol:@protocol(IBTImagePickerDelegate)]) {
        self.m_delegate = (id <IBTImagePickerDelegate>)controller;
    }
    
    self.m_vcHolder = controller;
    return [[self class] startMediaBrowserFromViewController:controller
                                                   mediaType:type
                                                    editable:eFlag
                                               usingDelegate:self];
}

- (void)showImagePickerTitle:(NSString *)title
                   mediaType:(IBTMediaBrowserType)type
                    editable:(BOOL)eFlag
          fromViewController:(UIViewController *)controller
{
    if (!self.m_delegate && [controller conformsToProtocol:@protocol(IBTImagePickerDelegate)]) {
        self.m_delegate = (id <IBTImagePickerDelegate>)controller;
    }
    
    self.m_vcHolder = controller;
    [[self class] showImagePickerTitle:title
                             mediaType:type
                              editable:eFlag
                    fromViewController:controller
                         usingDelegate:self];
}


- (void)showImagePickerTitle:(NSString *)title
                albumBtnName:(NSString *)albumName
               cameraBtnName:(NSString *)cameraName
               cancelBtnName:(NSString *)cancelName
                   mediaType:(IBTMediaBrowserType)type
                    editable:(BOOL)eFlag
          fromViewController:(UIViewController *)controller
{
    if (!self.m_delegate && [controller conformsToProtocol:@protocol(IBTImagePickerDelegate)]) {
        self.m_delegate = (id <IBTImagePickerDelegate>)controller;
    }
    
    self.m_vcHolder = controller;
    [[self class] showImagePickerTitle:title
                          albumBtnName:albumName
                         cameraBtnName:cameraName
                         cancelBtnName:cancelName
                             mediaType:type
                              editable:eFlag
                    fromViewController:controller
                         usingDelegate:self];
}


#pragma mark - UIImagePickerControllerDelegate

- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    
    NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
    void(^completion)(void);
    
    // Handle a still image capture
    if (CFStringCompare((CFStringRef) mediaType, kUTTypeImage, 0)
        == kCFCompareEqualTo)
    {
        UIImage *editedImage, *imageToSave;
        
        editedImage = (UIImage *) [info objectForKey:
                                   UIImagePickerControllerEditedImage];
        
        if (editedImage) {
            imageToSave = editedImage;
        } else {
            imageToSave =
            (UIImage *) [info objectForKey:
                         UIImagePickerControllerOriginalImage];
        }
        
        NSURL *refImageURL = [info objectForKey:UIImagePickerControllerReferenceURL];
        
        completion = ^(void) {
            if (imageToSave &&
                [self.m_delegate respondsToSelector:@selector(imagePicker:didImagePicked:referenceURL:)])
            {
                [self.m_delegate imagePicker:(IBTImagePickerController *)picker
                              didImagePicked:imageToSave
                                referenceURL:refImageURL];
            }
        };
    }
    
    else if ((CFStringCompare((CFStringRef) mediaType, kUTTypeMovie, 0)
              == kCFCompareEqualTo))
    {
        NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
        completion = ^(void) {
            if ([self.m_delegate respondsToSelector:@selector(imagePicker:didVideoPickedWithURL:)]) {
                [self.m_delegate imagePicker:(IBTImagePickerController *)picker
                       didVideoPickedWithURL:videoURL];
            }
        };
    }
    
    [self.m_vcHolder dismissViewControllerAnimated:YES
                                        completion:completion];
    
}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self.m_vcHolder dismissViewControllerAnimated:YES
                                        completion:NULL];
}



@end

