//
//  ViewController.m
//  GMEDemoAudio
//
//  Created by tobinchen on 12/06/2018.
//  Copyright © 2018 tobinchen. All rights reserved.
//

#import "ViewController.h"
#import "EnginePollHelper.h"
#import "PTTWindowViewController.h"
#import "DispatchCenter.h"
#import "APPIDKeys.h"
#import "SystemAudioLoopbackViewController.h"

static NSString *INIT_ROOM_ID = @"20210901";

@interface ViewController()

@property (weak) IBOutlet NSButton *pttBtn;

@property (nonatomic, strong) PTTWindowViewController *pttWindowVC;
@property (nonatomic, strong) NSWindowController *loopbackWindowController;

@end

@implementation ViewController

- (instancetype)initWithCoder:(NSCoder *)coder
{
    if (self = [super initWithCoder:coder]) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onApplicationWillResignActive:) name:NSApplicationWillResignActiveNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onApplicationDidBecomeActive:) name:NSApplicationDidBecomeActiveNotification object:nil];
    }
    
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [EnginePollHelper createEnginePollHelper];
    NSString *modelPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"tap_audio_enhance_model.trtc"];
    [[ITMGContext GetInstance] SetAdvanceParams:@"DisableEncryptLog" value:@"1"];
    [[ITMGContext GetInstance] SetAdvanceParams:@"AinsModelFilePath" value:modelPath];
    _sdkVersionText.stringValue = [NSString stringWithFormat:@"SDKVersion:%@", [[ITMGContext GetInstance] GetSDKVersion]];
    srand((unsigned)time(NULL));
    int openid = rand() % 10000 + 1;
    
    
    _userIdText.stringValue = [NSString stringWithFormat:@"%d", openid];
    _appIdText.stringValue = SDKAPPID3RD;
    _keyText.stringValue = AUTHKEY;
    _roomIdText.stringValue = INIT_ROOM_ID;
    _InRoomPanel.hidden = NO;
    [_InRoomPanel setWantsLayer:YES];
    _InRoomPanel.layer=[CALayer layer];
    _InRoomPanel.layer.backgroundColor = [NSColor lightGrayColor].CGColor;
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    [self logV:[NSString stringWithFormat:@"log path:%@",documentsDirectory]];
    
#if TARGET_CPU_ARM64
    const char* arch_info = "arm64";
#elif TARGET_CPU_X86_64
    const char* arch_info = "x86_64";
#endif
    [self logV:[NSString stringWithFormat:@"GMEDemoAudio arch: %s", arch_info] ];
    
    self.pttBtn.title = @"PTT";
    [self.view addSubview:self.pttBtn];
    self.pttBtn.target = self;
    self.pttBtn.action = @selector(pttBtnClick);
    
    // Add System Loopback Test Button
    NSButton *loopbackTestBtn = [[NSButton alloc] initWithFrame:NSMakeRect(350, 10, 160, 30)];
    loopbackTestBtn.title = @"System Loopback Test";
    loopbackTestBtn.bezelStyle = NSBezelStyleRounded;
    loopbackTestBtn.target = self;
    loopbackTestBtn.action = @selector(onLoopbackTestBtnClick);
    [self.view addSubview:loopbackTestBtn];
}

- (void)onLoopbackTestBtnClick {
    if (!self.loopbackWindowController) {
        SystemAudioLoopbackViewController *vc = [[SystemAudioLoopbackViewController alloc] init];
        NSWindow *window = [NSWindow windowWithContentViewController:vc];
        window.title = @"System Audio Loopback Test";
        // Set window style to allow closing and resizing
        window.styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable;
        self.loopbackWindowController = [[NSWindowController alloc] initWithWindow:window];
    }
    [self.loopbackWindowController showWindow:self];
}

- (void)pttBtnClick {
    NSData* authBuffer = [QAVAuthBuffer GenAuthBuffer:_appId.intValue roomID:nil openID:_openId key:_authKey];
    [[[ITMGContext GetInstance] GetPTT] ApplyPTTAuthbuffer:authBuffer];
    self.pttWindowVC = [[PTTWindowViewController alloc]init];
    [self.pttWindowVC.window makeKeyAndOrderFront:nil];
}

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}

-(IBAction)InitGME:(id)sender{
    _openId=_userIdText.stringValue;
    _appId=_appIdText.stringValue;
    [self logV:@"InitGME"];
    
    [[ITMGContext GetInstance] SetRecvMixStreamCount:(int)(_mixCountText.integerValue)];
    [[ITMGContext GetInstance] SetAppVersion:@"Native Demo"];    // Just for Test
    
    if (_testEvnCheckBox.state == NSControlStateValueOn) {
        [[ITMGContext GetInstance] SetRegion:@"DEFAULT_TEST"];
    }
    
    [[ITMGContext GetInstance] InitEngine:_appId openID:_openId];
    [[DispatchCenter getInstance] addDelegate:self];
    _authKey=_keyText.stringValue;
}

-(IBAction)EnterRoom:(id)sender{
    _roomId = _roomIdText.stringValue;
    _appId=_appIdText.stringValue;
    _authKey=_keyText.stringValue;
    NSData* authBuffer = [QAVAuthBuffer GenAuthBuffer:_appId.intValue roomID:_roomId openID:_openId key:_authKey];

    ITMG_ROOM_TYPE roomType = ITMG_ROOM_TYPE_FLUENCY;
    if ([_roomTypeCombo.stringValue isEqualToString:@"STANDARD"]) {
        roomType = ITMG_ROOM_TYPE_STANDARD;
    } else if ([_roomTypeCombo.stringValue isEqualToString:@"HIGHQUALITY"]) {
        roomType = ITMG_ROOM_TYPE_HIGHQUALITY;
    }

    [[ITMGContext GetInstance] EnterRoom:_roomId roomType:roomType authBuffer:authBuffer];
}

-(IBAction)ExitRoom:(id)sender{
    [[ITMGContext GetInstance] ExitRoom];
}


-(IBAction)Unint:(id)sender{
    [[ITMGContext GetInstance] Uninit];
    [_setSocket5ProxyButton setState:NSControlStateValueOff];
    
    [self.pttWindowVC close];
}

-(IBAction)ChangeRoomType:(id)sender{
    ITMG_ROOM_TYPE roomType = ITMG_ROOM_TYPE_FLUENCY;
    if([_roomTypeCombo.stringValue isEqualToString:@"STANDARD"]){
        roomType = ITMG_ROOM_TYPE_STANDARD;
    }else if([_roomTypeCombo.stringValue isEqualToString:@"HIGHQUALITY"]){
        roomType = ITMG_ROOM_TYPE_HIGHQUALITY;
    }
    [[[ITMGContext GetInstance] GetRoom] ChangeRoomType:roomType];
}

-(IBAction)EnableMic:(NSButton*)sender{
    bool enable =  sender.state == NSControlStateValueOn;
    [[[ITMGContext GetInstance] GetAudioCtrl] EnableAudioCaptureDevice:enable];
}
- (IBAction)EnableAudioSend:(NSButton*)sender {
    bool enable =  sender.state == NSControlStateValueOn;
    [[[ITMGContext GetInstance] GetAudioCtrl] EnableAudioSend:enable];
}
-(IBAction)EnableAudioRecv:(NSButton*)sender{
    bool enable =  sender.state == NSControlStateValueOn;
    [[[ITMGContext GetInstance] GetAudioCtrl] EnableAudioRecv:enable];
}

-(IBAction)EnableMixSystemHookToSend:(NSButton*)sender {
    // bool enable =  sender.state == NSControlStateValueOn;
    // [[[ITMGContext GetInstance] GetAudioCtrl] EnableMixSystemAudioToSend:enable];
}

- (IBAction)EnableSetSocket5Proxy:(NSButton*)sender {
    bool enable =  sender.state == NSControlStateValueOn;
    NSString* value = enable ?
        @"{\"enable\":true, \"host\":\"106.53.53.131\", \"port\":8899, \"username\":\"gme_test\", "
        @"\"password\":\"gme_test\", \"supportHttps\":true, \"supportTcp\":true, "
        @"\"supportUdp\":true}" :
        @"{\"enable\":false, \"host\":\"\", \"port\":0, \"username\":\"\", "
        @"\"password\":\"\", \"supportHttps\":false, \"supportTcp\":false, "
        @"\"supportUdp\":false}";
    [[ITMGContext GetInstance] SetAdvanceParams:@"setSocks5Proxy" value:value];
}

-(IBAction)EnableLoopBack:(NSButton*)sender{
    bool enable =  sender.state == NSControlStateValueOn;
    [[[ITMGContext GetInstance] GetAudioCtrl] EnableLoopBack:enable];
}

-(IBAction)showTips:(NSButton*)sender{
    
    bool enable =  sender.state == NSControlStateValueOn;

    if(!_tipsWindowController){
        _tipsWindowController = [[NSStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateControllerWithIdentifier:@"TipsWindowController"];
    }
    
    if (enable){
        NSPoint pos = NSMakePoint(0, 0);
        [_tipsWindowController.window setFrameTopLeftPoint:pos];
        
        [_tipsWindowController showWindow:self];
    }else{
        [_tipsWindowController close];
    }
}

-(IBAction)accompany:(id)sender {
    if (![[[ITMGContext GetInstance] GetAudioEffectCtrl] IsMusicPlayEnd:1]) {
        [[[ITMGContext GetInstance] GetAudioEffectCtrl] StopPlayMusic:1];
    } else {
        NSOpenPanel* panel = [NSOpenPanel openPanel];
        panel.allowedFileTypes = @[@"mp3",@"wav",@"mp4",@"aac",@"m4a",@"ogg"];
        panel.allowsMultipleSelection = NO;
        __weak typeof(self)weakSelf = self;
        [panel beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse returnCode) {
            __strong typeof(weakSelf)strongSelf = weakSelf;
            if(NSModalResponseOK == returnCode){
                NSString *pathString = [panel.URLs.firstObject path];
                int acckey = strongSelf->_acckeyText.intValue;
                [[[ITMGContext GetInstance] GetAudioEffectCtrl] SetMusicPitch:1 pitch:acckey];
                [[[ITMGContext GetInstance] GetAudioEffectCtrl] StartPlayMusic:1 filePath:pathString loopCount:1];
            }
        }];
    }
}

- (IBAction)shareRoom:(NSButton*)sender {
    bool enable =  sender.state == NSControlStateValueOn;
    NSString* roomID = _shareRoomID.stringValue;
    NSString* openID = _shareOpenID.stringValue;
    
    if (enable) {
        NSData* authBuffer = [QAVAuthBuffer GenAuthBuffer:_appId.intValue roomID:roomID openID:openID key:_authKey];
        [[[ITMGContext GetInstance]GetRoom]StartRoomSharing:roomID targetOpenID:openID authBuffer:authBuffer];
    } else {
        [[[ITMGContext GetInstance]GetRoom]StopRoomSharing];
    }
}
- (IBAction)setMixCount:(id)sender {
    NSString* _mixCount=_changeMixCountText.stringValue;
    [[ITMGContext GetInstance] SetRecvMixStreamCount:_mixCount.intValue];
}

- (IBAction)switchRoom:(id)sender {
    NSData* authBuffer = [QAVAuthBuffer GenAuthBuffer:_appId.intValue roomID:_roomIdText.stringValue openID:_openId key:_authKey];
    [[[ITMGContext GetInstance]GetRoom]SwitchRoom:_roomIdText.stringValue authBuffer:authBuffer];
}

- (IBAction)switchRoomAdd:(id)sender {
    int newRoomID = _roomIdText.intValue + 1;
    [_roomIdText setStringValue: [NSString stringWithFormat:@"%d",newRoomID]];
    NSData* authBuffer = [QAVAuthBuffer GenAuthBuffer:_appId.intValue roomID:_roomIdText.stringValue openID:_openId key:_authKey];
    [[[ITMGContext GetInstance]GetRoom]SwitchRoom:_roomIdText.stringValue authBuffer:authBuffer];
}

- (IBAction)startMicTest:(NSButton*)sender{
    bool enable = sender.state == NSControlStateValueOn;
    if(enable){
        int interval = _testMicIntervalText.intValue;
        QAVResult ret =[[[ITMGContext GetInstance] GetAudioCtrl]StartMicDeviceTest:interval];
        NSString* log= [NSString stringWithFormat:@"StartMicDeviceTest ret:%d",(int)ret];
        [self logV:log];
    }else{
        QAVResult ret =[[[ITMGContext GetInstance] GetAudioCtrl]StopMicDeviceTest];
        NSString* log= [NSString stringWithFormat:@"StopMicDeviceTest ret:%d",(int)ret];
        [self logV:log];
    }
}

- (IBAction)startSpeakerTest:(NSButton*)sender {
    bool enable =  sender.state == NSControlStateValueOn;
    if(enable){
        NSOpenPanel* panel = [NSOpenPanel openPanel];
        panel.allowedFileTypes = @[@"mp3",@"wav",@"aac",@"m4a",@"ogg"];
        panel.allowsMultipleSelection = NO;
        [panel beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse returnCode) {
            if(NSModalResponseOK == returnCode){
                NSString *pathString = [panel.URLs.firstObject path];
                QAVResult ret = [[[ITMGContext GetInstance] GetAudioCtrl]StartSpeakerDeviceTest:pathString];
                NSString* log= [NSString stringWithFormat:@"StartSpeakerDeviceTest ret:%d",(int)ret];
                [self logV:log];
            }
        }];
    }else{
        QAVResult ret = [[[ITMGContext GetInstance] GetAudioCtrl]StopSpeakerDeviceTest];
        NSString* log= [NSString stringWithFormat:@"StopSpeakerDeviceTest ret:%d",(int)ret];
        [self logV:log];
    }
}


-(void)logV:(NSString*)log{
    if([_logView.textStorage.mutableString componentsSeparatedByString:@"\n"].count>100){
        [_logView.textStorage.mutableString setString:@""];
    }

    [_logView.textStorage.mutableString appendString:[NSString stringWithFormat:@"%@\n",log]];
}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (void)OnEvent:(ITMG_MAIN_EVENT_TYPE)eventType data:(NSDictionary*)data{
    if(eventType != ITMG_MAIN_EVENT_TYPE_USER_VOLUMES ) {
        NSString* log= [NSString stringWithFormat:@"event:%d msg:%@",(int)eventType,data];
        [self logV:log];
    }

    
    switch (eventType) {
        case ITMG_MAIN_EVENT_TYPE_ENTER_ROOM:{
            // int result = ((NSNumber*)[data objectForKey:@"result"]).intValue;
            
            if (hookButton.state == NSControlStateValueOn) {
                // [[[ITMGContext GetInstance] GetAudioCtrl] EnableMixSystemAudioToSend:true];
            }
        }
            
            break;
        case ITMG_MAIN_EVENT_TYPE_ROOM_DISCONNECT:
        case ITMG_MAIN_EVENT_TYPE_EXIT_ROOM:{
            _InRoomPanel.hidden = NO;
            [_captureButton setState:NSControlStateValueOff];
            [hookButton setState:NSControlStateValueOff];
            [_playButton setState:NSControlStateValueOff];
            [_sendButton setState:NSControlStateValueOff];
            [_recvButton setState:NSControlStateValueOff];
 
            //[[[ITMGContext GetInstance] GetAudioCtrl] StopTrackingVolume];
        }
            
            break;
        case ITMG_MAIN_EVENT_TYPE_SWITCH_ROOM:{
            int result = ((NSNumber*)[data objectForKey:@"result"]).intValue;
            NSString* log = nil;
            if (result == QAV_OK) {
                log = [NSString stringWithFormat:@"switch room success."];
            } else {
                log = [NSString stringWithFormat:@"switch room failed."];
            }
            [self logV:log];
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_TEST_MIC_VOLUME: {
            int volume = ((NSNumber*)[data objectForKey:@"volume"]).intValue;
            NSString* log = [NSString stringWithFormat:@"TEST_MIC_VOLUME volume = %d",volume];
            [self logV:log];
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_TEST_SPEAKER_VOLUME: {
            int volume = ((NSNumber*)[data objectForKey:@"volume"]).intValue;
            NSString* log = [NSString stringWithFormat:@"TEST_SPEAKER_VOLUME volume = %d",volume];
            [self logV:log];
        }
            break;
//        case ITMG_MAIN_EVENT_TYPE_MIX_SYSTEM_AUDIO_TO_SEND_STOP:
//        case ITMG_MAIN_EVENT_TYPE_MIX_SYSTEM_AUDIO_TO_SEND_START: {
//            int result = ((NSNumber*)[data objectForKey:@"result"]).intValue;
//            NSString *event = (eventType == ITMG_MAIN_EVENT_TYPE_MIX_SYSTEM_AUDIO_TO_SEND_START?@"Mix System Audio To Send Start":@"Mix System Audio To Send End");
//            if (result == QAV_OK) {
//                log = [NSString stringWithFormat:@"%@ success.",event];
//            } else {
//                [hookButton setState:NSControlStateValueOff];
//                log = [NSString stringWithFormat:@"%@ failed.error code :%d",event,result];
//            }
//            [self logV:log];
//            if (ITMG_MAIN_EVENT_TYPE_MIX_SYSTEM_AUDIO_TO_SEND_START == eventType && result == QAV_ERR_SYSTEM_AUDIO_HOOK_NEED_RESTART_APP) {
//                NSAlert *alert = [[NSAlert alloc] init];
//                [alert setMessageText:@"首次安装驱动完 应用需要重启"];
//                [alert addButtonWithTitle:@"重启"];
//                [alert addButtonWithTitle:@"取消"];
//                [alert setAlertStyle:NSAlertStyleWarning];
//                NSUInteger action = [alert runModal];
//                if(action == NSAlertFirstButtonReturn) {
//                    exit(0);
//                }
//            }
//            
//            
//            break;;
//        }
        default:
            break;
    }
}
#pragma clang diagnostic pop



- (void) onApplicationWillResignActive:(NSNotification*)notification;
{
    if (_autoPauseSwitch.state == NSControlStateValueOn) {
        // Just For Test, ignore this function
        [EnginePollHelper pauseEnginePollHelper];
        [[ITMGContext GetInstance] Pause];
    }
}

- (void) onApplicationDidBecomeActive:(NSNotification*)notification;
{
    if (_autoPauseSwitch.state == NSControlStateValueOn) {
        // Just For Test, ignore this function
        [EnginePollHelper resumeEnginePollHelper];
        [[ITMGContext GetInstance] Resume];
    }
}

@end
