//
//  PTTViewController.m
//  GMEDemoAudio
//
//  Created by RoonieChen on 2020/12/1.
//  Copyright © 2020 tobinchen. All rights reserved.
//

#import "PTTViewController.h"
#import "PTTLabel.h"
#import "PTTFlipView.h"
#import "GMESDK/TMGEngine.h"
#import "DispatchCenter.h"
@interface PTTViewController ()<ITMGDelegate>

@property (nonatomic, strong) NSScrollView *mainScrollView;

@property (nonatomic, strong) NSView *documentView;

@property (nonatomic, strong) PTTLabel *localTitleLabel;

@property (nonatomic, strong) PTTLabel *localContentLabel;

@property (nonatomic, strong) PTTLabel *downloadTitleLabel;

@property (nonatomic, strong) PTTLabel *downloadContentLabel;

@property (nonatomic, strong) PTTLabel *downloadPathLabel;

@property (nonatomic, strong) PTTLabel *downloadPathContentLabel;

@property (nonatomic, strong) PTTLabel *voiceTextLabel;

@property (nonatomic, strong) PTTLabel *voiceTextContentLabel;

@property (nonatomic, strong) PTTLabel *downloadedDurationLabel;

@property (nonatomic, strong) PTTLabel *downloadedDurationContentLabel;

@property (nonatomic, strong) PTTLabel *micVolLabel;

@property (nonatomic, strong) NSSlider *micSlider;

@property (nonatomic, strong) PTTLabel *spkVolLabel;

@property (nonatomic, strong) NSSlider *spkVolSlider;

@property (nonatomic, strong) PTTLabel *levelLabel;

@property (nonatomic, strong) PTTFlipView *contentView;

@property (nonatomic, strong) NSButton *clearBtn;

@property (nonatomic, strong) PTTLabel *statusLabel;

@property (nonatomic, copy) NSString *downloadPath;

@property (nonatomic, copy) NSString *currentStatus;

@property (nonatomic, strong) NSTimer *timerMonitor;

@property (nonatomic, strong) NSButton *recordAudioCodecTypeButton;

@property (nonatomic, strong) NSString *recordAudioCodecType;
@end

@implementation PTTViewController

- (void)viewDidLoad {
    _recordAudioCodecType = @"ogg";
    [super viewDidLoad];
    [self createSubView];
}

- (void)createSubView {
    self.mainScrollView = [[NSScrollView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.height, self.view.frame.size.height)];
    self.documentView = [[PTTFlipView alloc]initWithFrame:NSMakeRect(0, 0, self.mainScrollView.frame.size.width, 0)];
    [self.view addSubview:self.mainScrollView];
    CGFloat left = 10;
    CGFloat maxW = self.view.frame.size.width - left * 2;
    CGFloat height = 30;
    CGFloat totalHeight = 0;
    CGFloat margin = 5;
    self.localTitleLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, 20, maxW, height)];
    self.localTitleLabel.stringValue = @"本地音频文件：";
    self.localTitleLabel.alignment = NSTextAlignmentCenter;
    [self.documentView addSubview:self.localTitleLabel];
    
    self.localContentLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.localTitleLabel.frame) + margin, maxW, height)];
    self.localContentLabel.stringValue = @"空";
    self.localContentLabel.textEditable = YES;
    [self.documentView addSubview:self.localContentLabel];
    
    self.downloadTitleLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.localContentLabel.frame) + margin, maxW, height)];
    self.downloadTitleLabel.alignment = NSTextAlignmentCenter;
    self.downloadTitleLabel.stringValue = @"下载链接：";
    [self.documentView addSubview:self.downloadTitleLabel];
    
    self.downloadContentLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadTitleLabel.frame) + margin, maxW, height)];
    self.downloadContentLabel.stringValue = @"空";
    self.downloadContentLabel.textEditable = YES;
   [self.documentView addSubview:self.downloadContentLabel];
    
    self.downloadPathLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadContentLabel.frame) + margin, maxW, height)];
    self.downloadPathLabel.alignment = NSTextAlignmentCenter;
    self.downloadPathLabel.stringValue = @"下载地址：";
    [self.documentView addSubview:self.downloadPathLabel];
    
    self.downloadPathContentLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadPathLabel.frame) + margin, maxW, height)];
    self.downloadPathContentLabel.stringValue = @"空";
    self.downloadPathContentLabel.textEditable = YES;
    [self.documentView addSubview:self.downloadPathContentLabel];
    
    self.voiceTextLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadPathContentLabel.frame) + margin, maxW, height)];
    self.voiceTextLabel.alignment = NSTextAlignmentCenter;
    self.voiceTextLabel.stringValue = @"语音转文本结果：";
    [self.documentView addSubview:self.voiceTextLabel];
    
    self.voiceTextContentLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.voiceTextLabel.frame) + margin, maxW, height)];
    self.voiceTextContentLabel.stringValue = @"空";
    [self.documentView addSubview:self.voiceTextContentLabel];
    if (@available(macOS 10.14, *)) {
    } else {
        self.voiceTextContentLabel.maxSize = CGSizeMake(maxW, height + 20);
    }
    
    self.downloadedDurationLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.voiceTextContentLabel.frame) + margin, maxW, height)];
    self.downloadedDurationLabel.stringValue = @"下载音频时长：";
    self.downloadedDurationLabel.alignment = NSTextAlignmentCenter;
    [self.documentView addSubview:self.downloadedDurationLabel];
    
    self.downloadedDurationContentLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadedDurationLabel.frame) + margin, maxW, height)];
    self.downloadedDurationContentLabel.stringValue = @"空";
    [self.documentView addSubview:self.downloadedDurationContentLabel];
    
    self.micVolLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.downloadedDurationContentLabel.frame) + margin, 70, height)];
    self.micVolLabel.stringValue = @"mic音量：";
    [self.documentView addSubview:self.micVolLabel];
    
    self.micSlider = [[NSSlider alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.micVolLabel.frame) + 2, self.micVolLabel.frame.origin.y - 5, 100, 30)];
    self.micSlider.target = self;
    self.micSlider.action = @selector(micSliderSlide:);
    self.micSlider.minValue = 0.f;
    self.micSlider.maxValue = 200.f;
    self.micSlider.intValue = [[[ITMGContext GetInstance] GetAudioCtrl] GetMicVolume];
    
    [self.documentView addSubview:self.micSlider];
    
    self.spkVolLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.micSlider.frame) + margin, 70, height)];
    self.spkVolLabel.stringValue = @"语音音量：";
    [self.documentView addSubview:self.spkVolLabel];
    
    self.spkVolSlider = [[NSSlider alloc]initWithFrame:CGRectMake(CGRectGetMaxX(self.spkVolLabel.frame) + 2, self.spkVolLabel.frame.origin.y - 5, 100, 30)];
    [self.documentView addSubview:self.spkVolSlider];
    self.spkVolSlider.target = self;
    self.spkVolSlider.action = @selector(spkSliderSlide:);
    self.spkVolSlider.minValue = 0.f;
    self.spkVolSlider.maxValue = 200.f;
    self.spkVolSlider.intValue = [[[ITMGContext GetInstance] GetAudioCtrl] GetSpeakerVolume];
    
    self.levelLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.spkVolSlider.frame) + margin, maxW, 30)];
    [self.documentView addSubview:self.levelLabel];

    CGFloat statusLeft = CGRectGetMaxX(self.spkVolSlider.frame) + 5;
    self.statusLabel = [[PTTLabel alloc]initWithFrame:CGRectMake(statusLeft, self.micSlider.frame.origin.y, self.view.frame.size.width - statusLeft, 70)];
    self.statusLabel.stringValue = [NSString stringWithFormat:@"当前状态:%@",self.currentStatus];
    [self.documentView addSubview:self.statusLabel];
    
    self.contentView = [[PTTFlipView alloc]initWithFrame:CGRectMake(left, CGRectGetMaxY(self.levelLabel.frame) + margin,maxW, 300)];
    [self.documentView addSubview:self.contentView];
    [self layoutContentView];
    
    self.clearBtn = [[NSButton alloc]initWithFrame:CGRectMake((self.view.frame.size.width - 100)/2, CGRectGetMaxY(self.contentView.frame) + margin, 100, 30)];
    self.clearBtn.title = @"清空";
    self.clearBtn.target = self;
    self.clearBtn.action = @selector(clearBtnClick);
    [self.documentView addSubview:self.clearBtn];
    
    self.recordAudioCodecTypeButton = [[NSButton alloc]initWithFrame:CGRectMake((self.view.frame.size.width - 100)/2 + 100, CGRectGetMaxY(self.contentView.frame) + margin - 55, 200, 50)];
    [self.recordAudioCodecTypeButton setButtonType:NSSwitchButton];
    [self.recordAudioCodecTypeButton setTitle:@"录制启用mp3编码"];
    [[self.recordAudioCodecTypeButton cell] setControlSize:NSControlSizeRegular];
    [[self.recordAudioCodecTypeButton cell] setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeRegular]]];
    [[self.recordAudioCodecTypeButton cell] setState:NSControlStateValueOff];
    [[self.recordAudioCodecTypeButton cell] setEnabled:YES];
    [self.recordAudioCodecTypeButton setTarget:self];
    [self.recordAudioCodecTypeButton setAction:@selector(recordAudioCodecTypeChanged:)];
    [self.documentView addSubview:self.recordAudioCodecTypeButton];
    
    totalHeight = CGRectGetMaxY(self.clearBtn.frame) + 10;
    NSRect frame = self.documentView.frame;
    frame.size.height = totalHeight;
    self.documentView.frame = frame;
    self.mainScrollView.documentView = self.documentView;
    [[DispatchCenter getInstance] addDelegate:self];
    [self addObserver:self forKeyPath:@"currentStatus" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)recordAudioCodecTypeChanged:(NSButton *)sender {
    if ([sender state] == NSControlStateValueOn) {
        _recordAudioCodecType = @"mp3";
    } else {
        _recordAudioCodecType = @"ogg";
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"currentStatus"]) {
        NSLog(@"%@",self.currentStatus);
        self.statusLabel.stringValue = [NSString stringWithFormat:@"当前状态:%@",self.currentStatus];
    }
}

- (void)clearBtnClick {
    [self.voiceTextContentLabel clearContent];
    [self.downloadPathContentLabel clearContent];
    [self.downloadContentLabel clearContent];
    [self.localContentLabel clearContent];
    [self.downloadedDurationContentLabel clearContent];
    
    self.voiceTextContentLabel.stringValue =
    self.downloadPathContentLabel.stringValue =
    self.downloadContentLabel.stringValue =
    self.localContentLabel.stringValue =
    self.downloadedDurationContentLabel.stringValue = @"空";
    self.downloadPath = nil;
}

- (void)layoutContentView {
    NSArray *titleArr = @[@"开始录音",@"停止录音",@"上传",@"下载",@"开始播放",@"停止播放",@"转文本",@"时长",@"流式",@"播本地",@"取消"];
    NSInteger colNum = 3;
    NSInteger marginH = 30;
    NSInteger marginV = 10;
    NSInteger w = (self.contentView.frame.size.width - marginH * (colNum + 1))/colNum;
    NSInteger h = 30;
    for (int i = 0; i < titleArr.count; i++) {
        NSInteger rowIdx = i / colNum;
        NSInteger colIdx = i % colNum;
        NSInteger x = marginH * (colIdx + 1) + w * colIdx;
        NSInteger y = marginV * rowIdx + h * rowIdx;
        NSButton *btn = [[NSButton alloc]initWithFrame:CGRectMake(x, y, w, h)];
        btn.target = self;
        btn.action = @selector(contentBtnClick:);
        btn.tag = i;
        btn.title = titleArr[i];
        [self.contentView addSubview:btn];
        if (i == titleArr.count - 1) {
            CGRect frame = self.contentView.frame;
            frame.size.height = CGRectGetMaxY(btn.frame) + marginV;
            self.contentView.frame = frame;
        }
    }
}

- (void)contentBtnClick:(NSButton *)btn {
    static int recordIndex = 0;
    static int downloadIndex = 0;
    if (btn.tag == 0) {//开始录音
        QAVResult ret = [[[ITMGContext GetInstance] GetPTT] StartRecording:[self pttTestPath:recordIndex++]];
        if (ret == 0) {
            self.currentStatus = @"开始录音";
        } else {
            self.currentStatus = [NSString stringWithFormat:@"录音失败:%@",@(ret)];
        }
    } else if (btn.tag == 1) {//停止录音
         QAVResult ret =  [[[ITMGContext GetInstance] GetPTT] StopRecording];
          if (ret == 0) {
              self.currentStatus = @"停止录音";
          } else {
               self.currentStatus = @"停止录音失败";
          }
      } else if (btn.tag == 2) {//上传
          QAVResult ret = [[[ITMGContext GetInstance] GetPTT] UploadRecordedFile:self.localContentLabel.stringValue];
          if (ret == 0) {
              self.currentStatus = [NSString stringWithFormat:@"开始上传%@",self.localContentLabel.stringValue];
          } else {
              self.currentStatus = @"开始上传失败";
          }
      } else if (btn.tag == 3) {//下载
          self.downloadPath = [self pttdownloadPath:downloadIndex++ fileId:self.downloadContentLabel.stringValue];
          QAVResult ret = [[[ITMGContext GetInstance] GetPTT] DownloadRecordedFile:self.downloadContentLabel.stringValue filePath:self.downloadPath];
          if (ret == 0) {
              self.currentStatus = [NSString stringWithFormat:@"开始下载%@",self.downloadContentLabel.stringValue];
          } else {
              self.currentStatus = [NSString stringWithFormat:@"开始下载失败%@",self.downloadContentLabel.stringValue];
          }
      } else if (btn.tag == 4) {//开始播放
          QAVResult ret = [[[ITMGContext GetInstance] GetPTT] PlayRecordedFile:self.downloadPath];
          if (ret == 0) {
              self.currentStatus = @"播放成功";
              NSLog(@"播放成功");
          } else {
              NSLog(@"播放失败~~~%ld",ret);
              self.currentStatus = @"播放失败";
          }
      } else if (btn.tag == 5) {//停止播放
          QAVResult ret = [[[ITMGContext GetInstance] GetPTT] StopPlayFile];
          if (ret == 0) {
              NSLog(@"停止播放成功");
          } else {
              NSLog(@"停止播放失败~~~%ld",ret);
          }
      } else if (btn.tag == 6) {//转文本
          if ([self.downloadContentLabel.stringValue isEqualToString:@"空"]) {
              self.currentStatus = @"需上传下载后方可转换文本";
              return;
          }
          [[[ITMGContext GetInstance] GetPTT] SpeechToText:self.downloadContentLabel.stringValue];
      } else if (btn.tag == 7) {//时长
          self.downloadedDurationContentLabel.stringValue = [NSString stringWithFormat:@"文件时长:%f", [[[ITMGContext GetInstance] GetPTT] GetVoiceFileDuration:self.downloadPath]/1000.0f] ;
      } else if (btn.tag == 8) {//流式
          QAVResult ret = [[[ITMGContext GetInstance] GetPTT] StartRecordingWithStreamingRecognition:[self pttTestPath:recordIndex++] speechLanguage:@"cmn-Hans-CN"];
          if (ret == 0) {
              self.currentStatus = @"开始流式录音";
          } else {
              self.currentStatus = @"开始流式录音失败";
          }
      } else if (btn.tag == 9) {//播放本地
        QAVResult ret = [[[ITMGContext GetInstance] GetPTT] PlayRecordedFile:self.localContentLabel.stringValue];
        if (ret == 0) {
            self.currentStatus = @"播放（本地文件）成功";
        } else {
            self.currentStatus = @"播放（本地文件）失败";
        }
    }else if (btn.tag == 10) {//取消
        QAVResult ret = [[[ITMGContext GetInstance] GetPTT] CancelRecording];
        if (ret == 0) {
            self.currentStatus = @"取消录音";
        } else {
            self.currentStatus = @"取消录音失败";
        }
    }
}

- (NSString *)getFileExtension:(NSString *)fileName {
    if (!fileName) {
        return @"";
    }
    
    NSArray *components = [fileName componentsSeparatedByString:@"."];
    if (components.count > 1) {
        NSString* format =  components.lastObject;
        
        if([format isEqualToString: @"ogg"] || [format isEqualToString: @"ogg-opus"] ) {
            return @"ogg";
        } else if([format isEqualToString: @"mp3"]) {
            return @"mp3";
        }
    }
    
    components = [fileName componentsSeparatedByString:@"-"];
    if (components.count > 1) {
        NSString* format =  components.lastObject;
        if([format isEqualToString: @"ogg"] || [format isEqualToString: @"opus"] ) {
            return @"ogg";
        } else if([format isEqualToString: @"mp3"]) {
            return @"mp3";
        }
    }
    
    return @"";
}

- (NSString *)pttTestPath:(int)index{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (documentsDirectory.length) {
        
        documentsDirectory = [documentsDirectory stringByAppendingFormat:@"/test_%d.%@", index, _recordAudioCodecType];
        return documentsDirectory;
    }
    return @"";
}

- (NSString *)pttdownloadPath:(int)index fileId:(NSString *)fileId {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (documentsDirectory.length) {
        NSString *extension = [self getFileExtension:fileId];
        documentsDirectory = [documentsDirectory stringByAppendingFormat:@"/download_%d.%@", index, extension];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if([fileManager fileExistsAtPath:documentsDirectory]) {
            [fileManager removeItemAtPath:documentsDirectory error:nil];
        }
        return documentsDirectory;
    }
    return @"";
}

- (void)micSliderSlide:(NSSlider *)slider {
    NSLog(@"%d",slider.intValue);
    [[[ITMGContext GetInstance] GetAudioCtrl] SetMicVolume:slider.intValue];
}

- (void)spkSliderSlide:(NSSlider *)slider {
    NSLog(@"%d",slider.intValue);
    [[[ITMGContext GetInstance] GetAudioCtrl] SetSpeakerVolume:slider.intValue];
}

- (void)OnEvent:(ITMG_MAIN_EVENT_TYPE)eventType data:(NSDictionary*)data
{
    NSNumber *number = [data objectForKey:@"result"];
    int result = -1;
    if (number != nil) {
        result = [number intValue];
    }
    if (result != 0 && eventType != ITMG_MAIN_EVENT_TYPE_USER_VOLUMES &&
        eventType != ITMG_MAIN_EVENT_TYPE_CHANGE_ROOM_QUALITY &&
        eventType != ITMG_MAIN_EVENT_TYPE_USER_UPDATE &&
        eventType != ITMG_MAIN_EVENT_TYPE_NUMBER_OF_USERS_UPDATE &&
        eventType != ITMG_MAIN_EVENT_TYPE_NUMBER_OF_AUDIOSTREAMS_UPDATE &&
        eventType != ITMG_MAIN_EVENT_TYPE_NETWORK_QUALITY &&
        eventType != ITMG_MAIN_EVENT_TYPE_PTT_STREAMINGRECOGNITION_IS_RUNNING) {
        NSLog(@"%@",[NSString stringWithFormat:@"操作失败:eventType %d error code ,%@",(int)eventType,number]);
        self.currentStatus = [NSString stringWithFormat:@"操作失败:eventType %d error code ,%@",(int)eventType,number];
    }

    switch (eventType)
    {
        case ITMG_MAIN_EVENT_TYPE_PTT_RECORD_FIRST_FRAME:
        {
            self.currentStatus = @"收到第一帧音频数据";
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_RECORD_COMPLETE:
        {
            if (result == 0)
            {
                NSString *recordfilePath = [data objectForKey:@"file_path"];
                self.localContentLabel.stringValue = recordfilePath;
                self.currentStatus = @"录制完成";
            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_UPLOAD_COMPLETE:
        {
            if (result == 0)
            {
                self.downloadContentLabel.stringValue = [data objectForKey:@"file_id"] ;
                self.currentStatus = [NSString stringWithFormat:@"上传完成%@",self.downloadContentLabel.stringValue];
            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_DOWNLOAD_COMPLETE:
        {
            if (result == 0)
            {
                self.downloadPathContentLabel.stringValue = [data objectForKey:@"file_path"] ;
                self.currentStatus = [NSString stringWithFormat:@"下载完成%@",self.downloadPathContentLabel.stringValue];
            }
        }
            break;
        
        case ITMG_MAIN_EVENT_TYPE_PTT_STREAMINGRECOGNITION_COMPLETE:
        {
            if (result == 0)
            {
                self.downloadContentLabel.stringValue = data[@"file_id"];
                self.localContentLabel.stringValue = [data objectForKey:@"file_path"];
                self.voiceTextContentLabel.stringValue = [data objectForKey:@"text"] ;
                self.currentStatus = @"流式转换完成";
            }
            
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_STREAMINGRECOGNITION_IS_RUNNING: {
            self.downloadContentLabel.stringValue = @"";
            self.localContentLabel.stringValue = @"";
            self.voiceTextContentLabel.stringValue = [data objectForKey:@"text"];
            self.currentStatus = @"流式正在运行";
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_SPEECH2TEXT_COMPLETE:
        {
            if (result == 0)
            {
                self.voiceTextContentLabel.stringValue = [data objectForKey:@"text"];
                self.currentStatus = @"转换文字成功";
            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_PLAY_COMPLETE:
        {
            if (result == 0) {
                self.currentStatus = @"播放完成";
            }
        }
            break;
        default:
            break;
    }
}

- (void)windowShouldClose {
    [[DispatchCenter getInstance] removeDelegate:self];
    [self removeObserver:self forKeyPath:@"currentStatus"];
}

@end
