//
//  TMGPTTViewController.m
//  TMGDemoAudio
//
//  Created by RoonieChen on 2021/5/14.
//  Copyright © 2021 tobinchen. All rights reserved.
//

#import "TMGPTTViewController.h"
#import "GMESDK/TMGEngine.h"
#import "DispatchCenter.h"
#import "GMESDK/QAVAuthBuffer.h"
#import "APPIDKeys.h"
@interface TMGPTTViewController ()<ITMGDelegate>

@property (nonatomic, strong) UIScrollView *backScrollView;

@property (nonatomic, strong) UILabel *realTimeStreamLabel;

@property (nonatomic, strong) UISwitch *realTimeSwitch;

@property (nonatomic, strong) UIButton *startRecBtn;

@property (nonatomic, strong) UIButton *cancelRecBtn;

@property (nonatomic, strong) UIButton *stopRecBtn;

@property (nonatomic, strong) UITextField *localTF;

@property (nonatomic, strong) UIButton *localPlayBtn;

@property (nonatomic, strong) UIButton *uploadBtn;

@property (nonatomic, strong) UITextField *downloadURLTF;

@property (nonatomic, strong) UIButton *downloadBtn;

@property (nonatomic, strong) UITextField *downloadTF;

@property (nonatomic, strong) UIButton *downloadPlayBtn;

@property (nonatomic, strong) UIButton *convertBtn;

@property (nonatomic, strong) UITextField *translateTF;

@property (nonatomic, strong) UITextView *logTextView;

@property (nonatomic, strong) UIButton *clearBtn;

@property (nonatomic, copy) NSString *currentStatus;

@property (nonatomic, copy) NSString *downloadPath;

@property (nonatomic, assign) BOOL isStreamMode;

@end

@implementation TMGPTTViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupUI];
    [self configSDK];
}

- (void)setupUI {
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.backScrollView];
    [self.backScrollView addSubview:self.realTimeStreamLabel];
    [self.backScrollView addSubview:self.realTimeSwitch];
    [self.backScrollView addSubview:self.startRecBtn];
    [self.backScrollView addSubview:self.cancelRecBtn];
    [self.backScrollView addSubview:self.stopRecBtn];
    [self.backScrollView addSubview:self.localTF];
    [self.backScrollView addSubview:self.localPlayBtn];
    [self.backScrollView addSubview:self.uploadBtn];
    [self.backScrollView addSubview:self.downloadURLTF];
    [self.backScrollView addSubview:self.downloadBtn];
    [self.backScrollView addSubview:self.downloadTF];
    [self.backScrollView addSubview:self.downloadPlayBtn];
    [self.backScrollView addSubview:self.convertBtn];
    [self.backScrollView addSubview:self.translateTF];
    [self.backScrollView addSubview:self.logTextView];
    [self.backScrollView addSubview:self.clearBtn];
    [self layout];
    [self addObserver:self forKeyPath:@"currentStatus" options:NSKeyValueObservingOptionNew context:nil];
}

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

- (void)dealloc {
    [self removeObserver:self forKeyPath:@"currentStatus"];
}

- (void)configSDK {
    NSData* authBuffer =  [QAVAuthBuffer GenAuthBuffer:(unsigned int)self.appId.integerValue roomID:nil openID:self.openId key:self.authKey];
    
    // Step 1/12 apply ptt authbuffer
    //https://cloud.tencent.com/document/product/607/15221#.E9.89.B4.E6.9D.83.E5.88.9D.E5.A7.8B.E5.8C.96
    [[[ITMGContext GetInstance] GetPTT] ApplyPTTAuthbuffer:authBuffer];
    [[DispatchCenter getInstance] addDelegate:self];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [[DispatchCenter getInstance] removeDelegate:self];

}


- (NSString *)pttTestPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (documentsDirectory.length) {
        documentsDirectory = [documentsDirectory stringByAppendingFormat:@"/test.ogg"];
        return documentsDirectory;
    }
    return @"";
}

- (void)showLog:(NSString *)log {
    NSString *text = self.logTextView.text;
    log = [text stringByAppendingFormat:@"\n%@", log];
    self.logTextView.text = log;
}

- (void)layout {
    self.backScrollView.frame = CGRectMake(0, [self safeTop], self.view.frame.size.width, self.view.frame.size.height);
    CGFloat left = 30;
    CGFloat tfLeft = 100;
    CGFloat mar = 40;
    CGFloat tfW = self.backScrollView.frame.size.width - 65 - left * 2;
    self.realTimeStreamLabel.frame = CGRectMake(left, 60, 160, 30);
    self.realTimeSwitch.frame = CGRectMake(CGRectGetMaxX(self.realTimeStreamLabel.frame) + 10, self.realTimeStreamLabel.frame.origin.y, 50, 30);
    self.startRecBtn.frame = CGRectMake(left, CGRectGetMaxY(self.realTimeSwitch.frame) + 10, 65, 30);
    self.cancelRecBtn.frame = CGRectMake(CGRectGetMaxX(self.startRecBtn.frame) + mar,self.startRecBtn.frame.origin.y, 85, 30);
    self.stopRecBtn.frame = CGRectMake(CGRectGetMaxX(self.cancelRecBtn.frame) + mar, self.cancelRecBtn.frame.origin.y, 65, 30);
    self.localPlayBtn.frame = CGRectMake(left - 15, CGRectGetMaxY(self.stopRecBtn.frame) + 20, 100, 30);
    self.localTF.frame = CGRectMake(tfLeft, self.localPlayBtn.frame.origin.y, tfW, 30);

    self.uploadBtn.frame = CGRectMake(left - 5, CGRectGetMaxY(self.localPlayBtn.frame) + 10, 60, 30);
    self.downloadURLTF.frame = CGRectMake(tfLeft, self.uploadBtn.frame.origin.y, tfW, 30);
    self.downloadBtn.frame = CGRectMake(left, CGRectGetMaxY(self.downloadURLTF.frame) + 10, 70, 30);
    self.downloadTF.frame = CGRectMake(tfLeft, self.downloadBtn.frame.origin.y, tfW - 40, 30);
    self.downloadPlayBtn.frame = CGRectMake(CGRectGetMaxX(self.downloadTF.frame) + 5, self.downloadBtn.frame.origin.y, 40, 30);
    self.convertBtn.frame = CGRectMake(left, CGRectGetMaxY(self.downloadTF.frame) + 10, 60, 30);
    self.translateTF.frame = CGRectMake(tfLeft, self.convertBtn.frame.origin.y, tfW, 30);
    CGFloat ll = 30;
    self.logTextView.frame = CGRectMake(ll, CGRectGetMaxY(self.translateTF.frame) + 10, (self.backScrollView.frame.size.width - ll * 2), 400);
    CGFloat l = (self.backScrollView.frame.size.width - 100)/2;
    self.clearBtn.frame = CGRectMake(l, CGRectGetMaxY(self.logTextView.frame) + 10, 100, 30);
    self.backScrollView.contentSize = CGSizeMake(self.backScrollView.frame.size.width, CGRectGetMaxY(self.clearBtn.frame) + 10);
    self.backScrollView.contentSize = CGSizeMake(self.backScrollView.frame.size.width, CGRectGetMaxY(self.clearBtn.frame) + self.backScrollView.frame.origin.y + 10);
}

- (BOOL)isIPhoneNotchScreen {
    BOOL result = NO;
    if (UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPhone) {
        return result;
    }
    if (@available(iOS 11.0, *)) {
        UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
        if (mainWindow.safeAreaInsets.bottom > 0.0) {
            result = YES;
        }
    }
    return result;
}

- (CGFloat)safeTop {
    
    if ([self isIPhoneNotchScreen]) {
        return 88;
    }
    return 64;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:animated];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.navigationController setNavigationBarHidden:YES animated:animated];
}

#pragma mark - Action

- (void)backTap:(UITapGestureRecognizer *)tapGes {
    [self.view.window endEditing:YES];
}

- (void)startRecClick {
    if (!self.isStreamMode) {
        // Step 2/12 start recording
        //https://cloud.tencent.com/document/product/607/15221#.E5.90.AF.E5.8A.A8.E5.BD.95.E9.9F.B3
        QAVResult ret = [[[ITMGContext GetInstance] GetPTT] StartRecording:[self pttTestPath]];
        if (ret == 0) {
            self.currentStatus = @"开始录制";
        } else {
            self.currentStatus = [NSString stringWithFormat:@"录制失败:%@",@(ret)];
        }
    } else {
        QAVResult ret = [[[ITMGContext GetInstance] GetPTT] StartRecordingWithStreamingRecognition:[self pttTestPath]];
        if (ret == 0) {
            self.currentStatus = @"开始流式录音";
        } else {
            self.currentStatus = @"开始流式录音失败";
        }
    }
   
}

- (void)cancelRecClick {
    QAVResult ret = [[[ITMGContext GetInstance] GetPTT] CancelRecording];
    if (ret == 0) {
        self.currentStatus = @"取消录音";
    } else {
        self.currentStatus = @"取消录音失败";
    }
}

- (void)stopRecClick {
    // Step 3/12 stop recording,  need handle ITMG_MAIN_EVENT_TYPE_PTT_RECORD_COMPLETE event
    // https://cloud.tencent.com/document/product/607/15221#.E5.81.9C.E6.AD.A2.E5.BD.95.E9.9F.B3
    QAVResult ret =  [[[ITMGContext GetInstance] GetPTT] StopRecording];
     if (ret == 0) {
         self.currentStatus = @"停止录音";
     } else {
          self.currentStatus = @"停止录音失败";
     }
}

- (void)playLocalClick {
    QAVResult ret = [[[ITMGContext GetInstance] GetPTT] PlayRecordedFile:self.localTF.text];
    if (ret == 0) {
        self.currentStatus = @"播放成功";
    } else {
        self.currentStatus = @"播放失败";
    }
}

- (void)uploadClick {
    if (!self.localTF.text) {
        return;
    }
    // Step 5/12 upload voice file to server, need handle ITMG_MAIN_EVENT_TYPE_PTT_UPLOAD_COMPLETE event
    //https://cloud.tencent.com/document/product/607/15221#.E4.B8.8A.E4.BC.A0.E8.AF.AD.E9.9F.B3.E6.96.87.E4.BB.B6
    [[[ITMGContext GetInstance] GetPTT] UploadRecordedFile:self.localTF.text];
}

- (void)downloadClick {
    self.downloadPath = [self pttdownloadPath];
    // Step 7/12 download vocie file from server, need handle ITMG_MAIN_EVENT_TYPE_PTT_DOWNLOAD_COMPLETE event
    //https://cloud.tencent.com/document/product/607/15221#.E4.B8.8B.E8.BD.BD.E8.AF.AD.E9.9F.B3.E6.96.87.E4.BB.B6
    QAVResult ret = [[[ITMGContext GetInstance] GetPTT] DownloadRecordedFile:self.downloadURLTF.text filePath:self.downloadPath];
    if (ret == 0) {
        self.currentStatus = [NSString stringWithFormat:@"开始下载%@",self.downloadTF.text];
    } else {
        self.currentStatus = [NSString stringWithFormat:@"开始下载失败%@",self.downloadTF.text];
    }
}

- (void)downloadPlayClick {
    // Step 9/12 play record voice, need handle ITMG_MAIN_EVENT_TYPE_PTT_PLAY_COMPLETE event
    //https://cloud.tencent.com/document/product/607/15221#.E6.92.AD.E6.94.BE.E8.AF.AD.E9.9F.B3
    QAVResult ret = [[[ITMGContext GetInstance] GetPTT] PlayRecordedFile:self.downloadPath];
    if (ret == 0) {
        self.currentStatus = @"播放（下载文件）成功";
    } else {
        self.currentStatus = @"播放（下载文件）失败";
    }
}

- (void)translateClick {
    if (self.isStreamMode) {
        return;
    }
    if (!self.downloadURLTF.text || [self.downloadURLTF.text isEqualToString:@" "]) {
        return;
    }
    // Step 11/12 recognition voice, need handle ITMG_MAIN_EVENT_TYPE_PTT_SPEECH2TEXT_COMPLETE envent
    //https://cloud.tencent.com/document/product/607/15221#.E5.B0.86.E6.8C.87.E5.AE.9A.E7.9A.84.E8.AF.AD.E9.9F.B3.E6.96.87.E4.BB.B6.E8.AF.86.E5.88.AB.E6.88.90.E6.96.87.E5.AD.97
    QAVResult ret = [[[ITMGContext GetInstance] GetPTT] SpeechToText:self.downloadURLTF.text];
    if (ret == 0) {
        self.currentStatus = @"转文本成功";
    } else {
        self.currentStatus = @"转文本失败";
    }
}

- (void)clearBtnClick {
    self.downloadTF.text = self.translateTF.text = self.downloadURLTF.text = self.localTF.text = @"";
    self.logTextView.text = @"";
    self.downloadPath = nil;
}

- (void)realTimeSwitch:(UISwitch *)realTimeSwitch {
    self.isStreamMode = realTimeSwitch.on;
}

- (NSString *)pttdownloadPath {
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    if (documentsDirectory.length) {
        documentsDirectory = [documentsDirectory stringByAppendingFormat:@"/download.ogg"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if([fileManager fileExistsAtPath:documentsDirectory]) {
            [fileManager removeItemAtPath:documentsDirectory error:nil];
        }
        return documentsDirectory;
    }
    return @"";
}

- (void)OnEvent:(ITMG_MAIN_EVENT_TYPE)eventType data:(NSDictionary*)data
{
    if (eventType ==  ITMG_MAIN_EVENT_TYPE_PTT_PLAY_COMPLETE) {
        self.currentStatus = @"播放完成";
        NSLog(@"播放完成");
    }
    
    NSNumber *number = [data objectForKey:@"result"];
    if (![number isEqualToNumber:@(0)] && (int)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_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_COMPLETE:
        {
            // Step 4/12 handle ITMG_MAIN_EVENT_TYPE_PTT_RECORD_COMPLETE event
            if (data != NULL &&[[data objectForKey:@"result"] intValue]== 0)
            {
                NSString *recordfilePath = [data objectForKey:@"file_path"];
                self.localTF.text = recordfilePath;
                self.currentStatus = [NSString stringWithFormat:@"录制完成:%@",recordfilePath];
            }
            
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_UPLOAD_COMPLETE:
        {
            // Step 6/12 handle ITMG_MAIN_EVENT_TYPE_PTT_UPLOAD_COMPLETE event
            if (data != NULL &&[[data objectForKey:@"result"] intValue]== 0)
            {
                
                self.downloadURLTF.text = [data objectForKey:@"file_id"] ;
                self.currentStatus = [NSString stringWithFormat:@"上传完成%@",self.downloadURLTF.text];
            } else {
                self.currentStatus = [NSString stringWithFormat:@"上传失败:%@",data[@"result"]];
            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_DOWNLOAD_COMPLETE:
        {
            // Step 8/12 handle ITMG_MAIN_EVENT_TYPE_PTT_DOWNLOAD_COMPLETE event
            if (data != NULL &&[[data objectForKey:@"result"] intValue]== 0)
            {
                
                self.downloadTF.text = [data objectForKey:@"file_path"] ;
                self.currentStatus = [NSString stringWithFormat:@"下载完成%@",self.downloadTF.text];
            } else {
                self.currentStatus = @"下载失败";
            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_STREAMINGRECOGNITION_COMPLETE:
        {
            if (data != NULL &&[[data objectForKey:@"result"] intValue]== 0)
            {
                self.translateTF.text = [data objectForKey:@"text"] ;
                self.currentStatus = [@"Voice recognition result:" stringByAppendingString:[data objectForKey:@"text"]];
                NSString *localPath = [data objectForKey:@"file_path"];
                self.localTF.text = localPath;
                self.downloadURLTF.text = [data objectForKey:@"file_id"];
            }
            
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_STREAMINGRECOGNITION_IS_RUNNING: {
            if (data != NULL) {
                self.translateTF.text = [data objectForKey:@"text"];
                self.downloadURLTF.text = @"STREAMINGRECOGNITION_IS_RUNNING";
                self.currentStatus = [@"Voice recognition result:" stringByAppendingString:[data objectForKey:@"text"]];
                self.localTF.text = @"";
            }
        }
        case ITMG_MAIN_EVENT_TYPE_PTT_SPEECH2TEXT_COMPLETE:
        {
            // Step 12/12 handle ITMG_MAIN_EVENT_TYPE_PTT_SPEECH2TEXT_COMPLETE event
            if (data != NULL &&[[data objectForKey:@"result"] intValue]== 0)
            {
                self.translateTF.text = [data objectForKey:@"text"];
                self.currentStatus = [@"Voice recognition result:" stringByAppendingString:[data objectForKey:@"text"]];

            }
        }
            break;
        case ITMG_MAIN_EVENT_TYPE_PTT_PLAY_COMPLETE:
        {
            self.currentStatus = @"播放完成";
        }
            break;
        default:
            break;
    }
    
}

#pragma mark - Lazy Loading

- (UIScrollView *)backScrollView {
    if (!_backScrollView) {
        _backScrollView = [[UIScrollView alloc]init];
        _backScrollView.backgroundColor = [UIColor whiteColor];
        UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(backTap:)];
        [_backScrollView addGestureRecognizer:tapGes];
    }
    return _backScrollView;
}

- (UILabel *)realTimeStreamLabel {
    if (!_realTimeStreamLabel) {
        _realTimeStreamLabel = [[UILabel alloc]init];
        _realTimeStreamLabel.text = @"Real Time Stream";
    }
    return _realTimeStreamLabel;
}

- (UISwitch *)realTimeSwitch {
    if (!_realTimeSwitch) {
        _realTimeSwitch = [[UISwitch alloc]init];
        [_realTimeSwitch addTarget:self action:@selector(realTimeSwitch:) forControlEvents:UIControlEventValueChanged];
    }
    return _realTimeSwitch;
}

- (UIButton *)startRecBtn {
    if (!_startRecBtn) {
        _startRecBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_startRecBtn setTitle:@"Start Rec" forState:UIControlStateNormal];
        [_startRecBtn addTarget:self action:@selector(startRecClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _startRecBtn;
}

- (UIButton *)cancelRecBtn {
    if (!_cancelRecBtn) {
        _cancelRecBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_cancelRecBtn setTitle:@"Cancel Rec" forState:UIControlStateNormal];
        [_cancelRecBtn addTarget:self action:@selector(cancelRecClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _cancelRecBtn;
}

- (UIButton *)stopRecBtn {
    if (!_stopRecBtn) {
        _stopRecBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_stopRecBtn setTitle:@"Stop Rec" forState:UIControlStateNormal];
        [_stopRecBtn addTarget:self action:@selector(stopRecClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _stopRecBtn;
}

- (UITextField *)localTF {
    if (!_localTF) {
        _localTF = [[UITextField alloc]init];
        _localTF.borderStyle = UITextBorderStyleRoundedRect;

    }
    return _localTF;
}

- (UIButton *)localPlayBtn {
    if (!_localPlayBtn) {
        _localPlayBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_localPlayBtn setTitle:@"playLocal" forState:UIControlStateNormal];
        [_localPlayBtn addTarget:self action:@selector(playLocalClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _localPlayBtn;
}

- (UIButton *)uploadBtn {
    if (!_uploadBtn) {
        _uploadBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_uploadBtn setTitle:@"upload" forState:UIControlStateNormal];
        [_uploadBtn addTarget:self action:@selector(uploadClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _uploadBtn;
}

- (UITextField *)downloadURLTF {
    if (!_downloadURLTF) {
        _downloadURLTF = [[UITextField alloc]init];
        _downloadURLTF.borderStyle = UITextBorderStyleRoundedRect;

    }
    return _downloadURLTF;
}

- (UIButton *)downloadBtn {
    if (!_downloadBtn) {
        _downloadBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_downloadBtn setTitle:@"download" forState:UIControlStateNormal];
        [_downloadBtn addTarget:self action:@selector(downloadClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _downloadBtn;
}

- (UITextField *)downloadTF {
    if (!_downloadTF) {
        _downloadTF = [[UITextField alloc]init];
        _downloadTF.borderStyle = UITextBorderStyleRoundedRect;
    }
    return _downloadTF;
}

- (UIButton *)downloadPlayBtn {
    if (!_downloadPlayBtn) {
        _downloadPlayBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_downloadPlayBtn setTitle:@"play" forState:UIControlStateNormal];
        [_downloadPlayBtn addTarget:self action:@selector(downloadPlayClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _downloadPlayBtn;
}

- (UIButton *)convertBtn {
    if (!_convertBtn) {
        _convertBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_convertBtn setTitle:@"translate" forState:UIControlStateNormal];
        [_convertBtn addTarget:self action:@selector(translateClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _convertBtn;
}

- (UITextField *)translateTF {
    if (!_translateTF) {
        _translateTF = [[UITextField alloc]init];
        _translateTF.borderStyle = UITextBorderStyleRoundedRect;
    }
    return _translateTF;
}

- (UITextView *)logTextView {
    if (!_logTextView) {
        _logTextView = [[UITextView alloc]init];
        _logTextView.font = [UIFont systemFontOfSize:10];
        _logTextView.layer.borderColor = [UIColor lightGrayColor].CGColor;
        _logTextView.layer.borderWidth = 0.5;
        _logTextView.editable = NO;
    }
    return _logTextView;
}

- (UIButton *)clearBtn {
    if (!_clearBtn) {
        _clearBtn = [UIButton buttonWithType:UIButtonTypeSystem];
        [_clearBtn setTitle:@"clear" forState:UIControlStateNormal];
        [_clearBtn addTarget:self action:@selector(clearBtnClick) forControlEvents:UIControlEventTouchUpInside];
    }
    return _clearBtn;
}


@end
