//
//  NvEditViewController.m
//  SDKDemo
//
//  Created by  on 2018/5/25.
//  Copyright © 2018年 刘东旭. All rights reserved.
//

#import "NvEditViewController.h"
#import "NVHeader.h"
#import "NvLiveWindowPanelView.h"
#import "NvsVideoTrack.h"
#import "NvsVideoClip.h"
#import "NvEditCaptionViewController.h"
#import "NvFeatureItem.h"
#import "NvFeatureCollectionViewCell.h"
#import "NvCompileViewController.h"
#import "NvEditMaterialViewController.h"
#import "NvEditThemeViewController.h"
#import "NvEditFilterViewController.h"
#import "NvEditStickerViewController.h"
#import "NvTimelineData.h"
#import "NvTimelineUtils.h"
#import "NvTransitionViewController.h"
#import "NvEditMusicViewController.h"
#import "NvOriginSoundView.h"
#import "MSSysAlertUtil.h"
#import "NvsAudioClip.h"
#import "NvTipTransitionViewController.h"
#import "NvTipsView.h"
#import "NvRecordViewController.h"
#import "NvEditWatemarkVC.h"
#import "NvSDKUtils.h"

@interface NvEditViewController () <UICollectionViewDataSource, UICollectionViewDelegate, NvCompileViewControllerDelegate, NvLiveWindowPanelViewDelegate,NvEditThemeViewControllerDelegate> {
    NvsStreamingContext *_streamingContext;
    NvLiveWindowPanelView *_liveWindowPanelView;
    NvsTimeline *_timeline;
    UICollectionView *_featureCollectionView;
    NSMutableArray *_featureDataSource;
    NSString *_compileFilePath;
    NvTimelineData *timelineData;
    NvOriginSoundView *_originSoundView;
}

@end

@implementation NvEditViewController


- (void)dealloc {
    NSLog(@"%s",__func__);
    if (_isFromAlbum) {
        [timelineData clear];
        [_streamingContext stop];
        NSLog(@"%d",[_streamingContext getStreamingEngineState]);
        [_streamingContext clearCachedResources:NO];
//        [NvsStreamingContext destroyInstance];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"视频编辑";
    _streamingContext = [NvSDKUtils getSDKContext];
    UIBarButtonItem *rightButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"生成" style:UIBarButtonItemStylePlain target:self action:@selector(rightBtnClicked)];
    [rightButtonItem setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NvUtils fontWithSize:16], NSFontAttributeName, [UIColor nv_colorWithHexRGB:@"#4A90E2"], NSForegroundColorAttributeName, nil] forState:UIControlStateNormal];
    self.navigationItem.rightBarButtonItem = rightButtonItem;
    [self addSubViews];
    [self initTimeline];
    [self initTimelineData];
}

/**
 需要改动子类需要重写这个方法
 @return 需要显示的返回按钮
 */
- (UIView *)leftNavigationBarItemView {
    UIButton *backButton = [UIButton nv_buttonWithTitle:nil textColor:nil fontSize:15 image:[UIImage imageNamed:@"icon_back"]];
    backButton.frame = CGRectMake(0, 0, 30, 44);
    backButton.imageEdgeInsets = UIEdgeInsetsMake(0, -15*SCREANSCALE, 0, 0);
    __weak typeof(self)weakSelf = self;
    __weak typeof(_timeline)weakTimeline = _timeline;
    [backButton nv_BtnClickHandler:^{
        [[NvTimelineData sharedInstance] clear];
        [NvTimelineUtils removeTimeline:weakTimeline];
        if (weakSelf.isFromAlbum) {
            [weakSelf.navigationController popToRootViewControllerAnimated:YES];
        } else {
            [weakSelf.navigationController popViewControllerAnimated:YES];
        }

    }];
    return backButton;
}
- (void)initTimelineData {
    timelineData = [NvTimelineData sharedInstance];
    if (self.selectPath.count != 0) {
        NSLog(@"self.selectPath==%@",self.selectPath);
        for (NSString *path in self.selectPath) {
            NvEditDataModel *editData = NvEditDataModel.new;
            if ([path hasSuffix:@".png"]) {
                editData.isImage = YES;
                editData.trimOut = 4 * NV_TIME_BASE;
                editData.localIdentifier = path;
                editData.isPhotoAlbum = NO;
            }else{
                AVURLAsset*audioAsset=[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
                editData.trimOut = audioAsset.duration.value/(float)audioAsset.duration.timescale*NV_TIME_BASE;
                editData.isImage = NO;
                editData.videoPath = path;
            }
            editData.trimIn = 0;
            editData.duration = editData.trimOut;
            [timelineData.editDataArray addObject:editData];
            
            NvTransitionInfoModel *info = NvTransitionInfoModel.new;
            [[[NvTimelineData sharedInstance] transitionDataArray] addObject:info];
        }
    }else{
            __block BOOL isshowToast = false;
            for (NvAlbumAsset *asset in self.selectAssets) {
                if (asset.asset.mediaType == PHAssetMediaTypeVideo) {
                    PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
                    options.version = PHVideoRequestOptionsVersionOriginal;
                    options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
                    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
                    [[PHImageManager defaultManager] requestAVAssetForVideo:asset.asset
                                                                    options:options
                                                              resultHandler:^(AVAsset * avAsset, AVAudioMix * audioMix, NSDictionary * info) {
                                                                  NSLog(@"%@",[avAsset class]);
                                                                  
                                                                  if (avAsset && [avAsset isKindOfClass:[AVURLAsset class]]) {
                                                                      NvEditDataModel *editData = NvEditDataModel.new;
                                                                      editData.asset = asset.asset;
                                                                      editData.videoPath = asset.asset.localIdentifier;
                                                                      editData.isImage = NO;
                                                                      editData.trimIn = 0;
                                                                      editData.trimOut = avAsset.duration.value/(float)avAsset.duration.timescale*NV_TIME_BASE;
                                                                      editData.duration = editData.trimOut;
                                                                      [self->timelineData.editDataArray addObject:editData];
                                                                      
                                                                      NvTransitionInfoModel *info = NvTransitionInfoModel.new;
                                                                      [[[NvTimelineData sharedInstance] transitionDataArray] addObject:info];
                                                                  } else {
                                                                      isshowToast = YES;
                                                                  }
                                                                  
                                                                  dispatch_semaphore_signal(semaphore);
                                                              }];
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                } else if (asset.asset.mediaType == PHAssetMediaTypeImage) {
                    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
                    PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
                    requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
                    requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
                    requestOptions.synchronous = YES;
                    [[PHImageManager defaultManager] requestImageForAsset:asset.asset
                                                               targetSize:CGSizeMake(80, 80)
                                                              contentMode:PHImageContentModeAspectFit
                                                                  options:requestOptions
                                                            resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                                                                BOOL isIcloud =  [[info valueForKeyPath:@"PHImageResultIsInCloudKey"] boolValue];
                                                                if (isIcloud) {
                                                                    isshowToast = YES;
                                                                } else {
                                                                    NvEditDataModel *editData = NvEditDataModel.new;
                                                                    editData.localIdentifier = asset.asset.localIdentifier;
                                                                    editData.isImage = YES;
                                                                    editData.trimIn = 0;
                                                                    editData.isPhotoAlbum = YES;
                                                                    editData.trimOut = 4*NV_TIME_BASE;
                                                                    editData.duration = editData.trimOut;
                                                                    [self->timelineData.editDataArray addObject:editData];
                                                                    
                                                                    NvTransitionInfoModel *info = NvTransitionInfoModel.new;
                                                                    [[[NvTimelineData sharedInstance] transitionDataArray] addObject:info];
                                                                }
                                                                dispatch_semaphore_signal(semaphore);
                                                            }
                     ];
                    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                }
            }
            if (isshowToast) {
                [MSSysAlertUtil presentAlertViewWithTitle:@"提示" message:@"所选资源在iCloud中" confirmTitle:@"确定" handler:NULL];
            } 
    }
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [NvTimelineUtils recreateTimeline:_timeline];
    [self connectTimeline];
    [_liveWindowPanelView playAtTime:0];
    [_liveWindowPanelView showControllPanel];
}

- (void)connectLiveWindow {
    if (!_timeline) {
        return;
    }
    
    [_liveWindowPanelView connectTimeline:_timeline];
    [self seekTimeline:_liveWindowPanelView.currentTime];
}

- (void)addSubViews {
    _liveWindowPanelView = [[NvLiveWindowPanelView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.width)];
    _liveWindowPanelView.editMode = self.editMode;
    _liveWindowPanelView.delegate = self;
    [self.view addSubview:_liveWindowPanelView];
    _featureDataSource = [[NSMutableArray alloc] init];
    NSArray *featureNameArray = @[@"主题", @"编辑", @"滤镜", @"贴纸", @"字幕", @"水印", @"转场", @"音乐", @"配音"];
    NSArray *featureImageArray = @[@"NvEditTheme", @"NvEdit", @"NvEditFilter", @"NvEditSticker", @"NvEditCaption", @"NvEditWatermark", @"NvEditTransition", @"NvEditMusic", @"NvEditRecord"];
    for (int i = 0; i < featureNameArray.count; i++) {
        NvFeatureItem *item = [NvFeatureItem new];
        item.name = featureNameArray[i];
        item.image = featureImageArray[i];
        [_featureDataSource addObject:item];
    }
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    layout.itemSize = CGSizeMake(73 * SCREANSCALE, 78 * SCREANSCALE);
    layout.minimumLineSpacing = 3 * SCREANSCALE;
    layout.minimumInteritemSpacing = 0;
    //layout.sectionInset = UIEdgeInsetsMake(0, 16*SCREANSCALE, 0, 0);
    _featureCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 465 * SCREANSCALE, self.view.width, 78 * SCREANSCALE) collectionViewLayout:layout];
    _featureCollectionView.delegate = self;
    _featureCollectionView.dataSource = self;
    _featureCollectionView.backgroundColor = [UIColor clearColor];
    _featureCollectionView.showsHorizontalScrollIndicator = NO;
    [self.view addSubview:_featureCollectionView];
    [_featureCollectionView registerClass:[NvFeatureCollectionViewCell class] forCellWithReuseIdentifier:@"NvFeatureCollectionViewCell"];
    
    _originSoundView = [[NvOriginSoundView alloc] initWithFrame:CGRectMake(0, _liveWindowPanelView.bottom, _liveWindowPanelView.width, self.view.height-_liveWindowPanelView.bottom-NV_STATUSBARHEIGHT-NV_NAV_BAR_HEIGHT)];
    _originSoundView.delegate = self;
    [self.view addSubview:_originSoundView];
    float height = self.view.height-_liveWindowPanelView.bottom-NV_STATUSBARHEIGHT-NV_NAV_BAR_HEIGHT;
    [_originSoundView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.and.left.and.right.equalTo(self.view);
        make.height.equalTo(@(height));
    }];
    _originSoundView.hidden = YES;
    float origin = 1,music = 1,dubbing = 1;
    NvsVideoTrack *videoTrack = [_timeline getVideoTrackByIndex:0];
    [videoTrack getVolumeGain:&origin rightVolumeGain:&origin];
    NvsAudioTrack *audioTrack = [_timeline getAudioTrackByIndex:0];
    [audioTrack getVolumeGain:&music rightVolumeGain:&music];
    NvsAudioTrack *dubbingTrack = [_timeline getAudioTrackByIndex:NV_DUBBING_SOUND_TRACK];
    [dubbingTrack getVolumeGain:&dubbing rightVolumeGain:&dubbing];
    [_originSoundView setOriginSound:origin musicSound:music dubbing:dubbing];
}

- (void)initTimeline {
    _timeline = [NvTimelineUtils createTimeline:self.editMode];
    if (!_timeline) {
        NSLog(@"创建时间线失败！");
        return;
    }
}

- (void)connectTimeline {
    [_liveWindowPanelView connectTimeline:_timeline];
    _liveWindowPanelView.currentTime = 0;
    [self seekTimeline:0];
}

// 定位某一时间戳的图像
- (void)seekTimeline:(int64_t)postion {
    if (![_streamingContext seekTimeline:_timeline timestamp:postion videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:NvsStreamingEngineSeekFlag_ShowCaptionPoster | NvsStreamingEngineSeekFlag_ShowAnimatedStickerPoster])
        NSLog(@"定位时间线失败！");
}

- (void)rightBtnClicked {
    _compileFilePath = [VIDEO_PATH(@"Compile") stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4", [NvUtils currentDateAndTime]]];
    NvCompileViewController *compileViewController = [NvCompileViewController new];
    compileViewController.delegate = self;
    compileViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
    [self presentViewController:compileViewController animated:NO completion:nil];
    [compileViewController compileTimeline:_timeline outputPath:_compileFilePath];
}

#pragma mark - NvLiveWindowPanelViewDelegate
- (void)volumnClicked {
    _originSoundView.hidden = NO;
    
    [self.navigationController setNavigationBarHidden:YES];
}

#pragma mark - NvOriginSoundViewDelegate
- (void)applyClick:(NvOriginSoundView *)originSoundView {
    originSoundView.hidden = YES;
    [self.navigationController setNavigationBarHidden:NO];
}

- (void)originSoundView:(NvOriginSoundView *)originSoundView originSound:(float)originSound {
    //视频数据结构的修改
    NSMutableArray<NvEditDataModel *> *editDataArray = timelineData.editDataArray;
    for (int i = 0; i < editDataArray.count; i++) {
        NvEditDataModel *model = editDataArray[i];
        model.volume = originSound;
        NvsVideoClip *clip = [NvTimelineUtils getTimelineVideoClip:_timeline clipInfo:model];
        [clip setVolumeGain:originSound rightVolumeGain:originSound];
    }
}

- (void)originSoundView:(NvOriginSoundView *)originSoundView musicSound:(float)musicSound {
    //外加音乐的数据
    for (NvMusicInfoModel *musicInfo in timelineData.musicDataArray) {
        musicInfo.volume = musicSound;
    }
    
    NvThemeInfoModel *themeInfo = [[NvTimelineData sharedInstance] themeInfo];
    themeInfo.volume = musicSound;
    
    // 如果音乐存在，主题音乐音量为0，调整音乐轨道片段的音量
    // 如果音乐不存在，设置主题音乐的音量
    if (timelineData.musicDataArray.count > 0) {
        NvsAudioTrack *audioTrack = [_timeline getAudioTrackByIndex:NV_MUSIC_SOUND_TRACK];
        for (int i = 0; i < audioTrack.clipCount; i++) {
            NvsAudioClip *clip = [audioTrack getClipWithIndex:i];
            [clip setVolumeGain:musicSound rightVolumeGain:musicSound];
        }
    } else {
        [_timeline setThemeMusicVolumeGain:musicSound rightVolumeGain:musicSound];
    }
}

- (void)originSoundView:(NvOriginSoundView *)originSoundView dubbing:(float)dubbing {
    NvsAudioTrack *audioTrack = [_timeline getAudioTrackByIndex:NV_DUBBING_SOUND_TRACK];
    [audioTrack setVolumeGain:dubbing rightVolumeGain:dubbing];
    timelineData.dubbingModel.volume = dubbing;
}

#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return _featureDataSource.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    NvFeatureCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"NvFeatureCollectionViewCell" forIndexPath:indexPath];
    [cell renderCellWithItem:_featureDataSource[indexPath.row]];
    return cell;
}

#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    [_streamingContext stop];
    NvFeatureItem *item = _featureDataSource[indexPath.row];
    if ([item.name isEqualToString:@"主题"]) {
        NvEditThemeViewController *vc = [[NvEditThemeViewController alloc]init];
        vc.timeline = _timeline;
        vc.editMode = self.editMode;
        vc.delegate = self;
        vc.title = @"主题";
        [self.navigationController pushViewController:vc animated:YES];
    }else if ([item.name isEqualToString:@"编辑"]) {
        NvEditMaterialViewController *vc = [[NvEditMaterialViewController alloc]init];
//        vc.timeline = _timeline;
        vc.editMode = self.editMode;
        vc.delegate = self;
        [self.navigationController pushViewController:vc animated:YES];
    } else if ([item.name isEqualToString:@"滤镜"]) {
        NvEditFilterViewController *vc = [[NvEditFilterViewController alloc]init];
        vc.editMode = self.editMode;
        vc.title = @"滤镜";
        [self.navigationController pushViewController:vc animated:YES];
    } else if ([item.name isEqualToString:@"贴纸"]) {
        NvEditStickerViewController *vc = [[NvEditStickerViewController alloc]init];
        vc.editMode = self.editMode;
        vc.title = @"贴纸";
        [self.navigationController pushViewController:vc animated:YES];
    } else if ([item.name isEqualToString:@"字幕"]) {
        NvEditCaptionViewController *captionVC = [NvEditCaptionViewController new];
        captionVC.editMode = self.editMode;
        [self.navigationController pushViewController:captionVC animated:YES];
    } else if ([item.name isEqualToString:@"水印"]) {
        NvEditWatemarkVC *vc = [[NvEditWatemarkVC alloc]init];
        vc.editMode = self.editMode;
        vc.title = @"选择位置";
        [self.navigationController pushViewController:vc animated:YES];
    }else if ([item.name isEqualToString:@"转场"]) {
        if (timelineData.editDataArray.count>=2) {
            NvTransitionViewController *transition = [NvTransitionViewController new];
            transition.timeline = _timeline;
            transition.editMode = self.editMode;
            [self.navigationController pushViewController:transition animated:YES];
        } else {
            NvTipTransitionViewController *tip = [NvTipTransitionViewController new];
//            self.definesPresentationContext = YES;
            tip.modalPresentationStyle = UIModalPresentationOverFullScreen;
            [self presentViewController:tip animated:NO completion:NULL];
        }
    } else if ([item.name isEqualToString:@"音乐"]) {
        NvEditMusicViewController *editMusic = [NvEditMusicViewController new];
//        editMusic.timeline = _timeline;
        editMusic.editMode = self.editMode;
        [self.navigationController pushViewController:editMusic animated:YES];
    } else if ([item.name isEqualToString:@"配音"]) {
        NvRecordViewController *record = [NvRecordViewController new];
        record.editMode = self.editMode;
        [self.navigationController pushViewController:record animated:YES];
//        [self toustTipView:item.name];
//        [NvUtils alertMessage:self
//                        title:nil
//                      message:@"Demo配音界面正在开发中，敬请期待。SDK内部已支持。"
//              firstButtonText:@"确定"
//                 firstHandler:^(UIAlertAction * _Nonnull action) {
//                 }
//             secondButtonText:@"取消"
//                secondHandler:nil];
    }
}

- (void)toustTipView:(NSString *)title{
    NvTipsView *tipView = [[NvTipsView alloc]initWithFrame:CGRectMake(0, 0, SCREANWIDTH, SCREANHEIGHT) withPrompt:@"提示" describeTitle:[NSString stringWithFormat:@"Demo%@界面正在开发中，敬请期待。SDK内部已支持。",title] describeContent:nil buttonText:@"知道了" withCenter:YES];
    [tipView.clickBtn addTarget:self action:@selector(knowClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:tipView];
}

#pragma mark tipView按钮点击事件
- (void)knowClick:(UIButton *)sender{
    [sender.superview.superview removeFromSuperview];
}

//保存相册的回调
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NvTipsView *tip = [[NvTipsView alloc]initWithFrame:self.view.frame withTitle:@"保存成功！" withColor:[UIColor nv_colorWithHexRGB:@"#4D4F51"] withCenter:NO];
    [self.view addSubview:tip];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [tip removeFromSuperview];
    });
//    [MSSysAlertUtil presentAlertViewWithTitle:@"提示" message:@"视频已保存至相册" confirmTitle:@"确定" handler:NULL];

}

#pragma mark - NvCompileViewControllerDelegate
- (void)compileFinished:(BOOL)needDelete {
    [self connectLiveWindow];
    if (needDelete) {
        [[NSFileManager defaultManager] removeItemAtPath:_compileFilePath error:nil];
    } else {
        UISaveVideoAtPathToSavedPhotosAlbum(_compileFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
    }
}

- (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
