/******************************************************************************/
/*                                                                            */
/* Copyright Avaya LLC.                                                       */
/*                                                                            */
/******************************************************************************/

#import "ActiveCallViewController.h"
#import "NotificationHelper.h"
#import "SDKManager.h"
#import "ConferenceControlViewController.h"
#import "ConfigData.h"

@interface ActiveCallViewController () <NSWindowDelegate>

@property (nonatomic, weak) NSTimer *callTimer;
@property (nonatomic) BOOL viewInitialized;
@property (nonatomic, weak) MediaManager* mediaManager;

@end

@implementation ActiveCallViewController

@synthesize localVideoView;
@synthesize remoteVideoView;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.viewInitialized = NO;
    self.mediaManager = [SDKManager getInstance].mediaManager;
    // Change window background to white
    self.view.wantsLayer = YES;
    self.view.layer.backgroundColor = [NSColor whiteColor].CGColor;
    
    NSLog(@"%s Received call object from segue: [%@]", __PRETTY_FUNCTION__, self.currentCall);
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshActiveCallWindow:) name:kRefreshActiveCallWindowNotification object:nil];
    
    // Display current call status
    self.callState.stringValue = @"";
    
    if (self.currentCall.isConference) {
        
        NSLog(@"%s Call is Conference call, populate participant list", __PRETTY_FUNCTION__);
        NSArray *participantsNames = [self.currentCall.conference.participants valueForKey:@"displayName"];
        self.participantList.stringValue = [participantsNames componentsJoinedByString:@"\n"];

        self.conferenceControlBtn.hidden = !self.currentCall.conference.moderationCapability.allowed;
    } else if (self.currentCall.callerIdentityPrivate) {
        
        NSLog(@"%s Call identitiy is private", __PRETTY_FUNCTION__);
        self.participantList.stringValue = @"Restricted";
    } else {
        
        NSLog(@"%s Update caller display name", __PRETTY_FUNCTION__);
        if (self.currentCall.remoteDisplayName.length == 0) {
            
            // Display remoteNumber if remoteDisplayName is unavailable
            self.participantList.stringValue = [NSString stringWithFormat:@"%@", self.currentCall.remoteNumber];
        } else {
            
            self.participantList.stringValue = [NSString stringWithFormat:@"%@", self.currentCall.remoteDisplayName];
        }
    }
}

- (void)dealloc {
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kRefreshActiveCallWindowNotification object:nil];
}

- (void)viewDidDisappear {
    
    [super viewDidDisappear];
    // Release video resources
    [self deallocViews];
}

- (IBAction)endCallBtn:(id)sender {
    
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [self.currentCall end];
}

- (IBAction)muteCallBtn:(id)sender {
    
    if (!self.currentCall.audioMuted) {
        
        if (self.currentCall.muteCapability.allowed) {
            
            NSLog(@"%s Call audio can be muted", __PRETTY_FUNCTION__);
            
            [self.currentCall muteAudio: YES completionHandler:^(NSError *error) {
                
                if (error) {
                    
                    [NotificationHelper displayMessageToUser:[NSString stringWithFormat:@"Error while muting audio of call, callId: [%lu]", self.currentCall.callId] TAG:__PRETTY_FUNCTION__];
                } else {
                    
                    NSLog(@"%s Audio Mute succesfful for call, callId: [%lu]", __PRETTY_FUNCTION__, self.currentCall.callId);
                    self.mute.title = @"ON";
                }
            }];
        } else {
            
            NSLog(@"%s Call audio cannot be muted", __PRETTY_FUNCTION__);
        }
    } else {
        
        if (self.currentCall.unmuteCapability.allowed && self.currentCall.audioMuted) {
            
            NSLog(@"%s Call audio can be unmuted", __PRETTY_FUNCTION__);
            
            [self.currentCall muteAudio:NO completionHandler:^(NSError *error) {
                
                if (error) {
                    
                    [NotificationHelper displayMessageToUser:[NSString stringWithFormat:@"Error while muting Audio of the call, callId: [%ld]", (long)self.currentCall.callId] TAG: __PRETTY_FUNCTION__];
                } else {
                    
                    NSLog(@"%s Audio of call muted successfully, callId:[%lu]", __PRETTY_FUNCTION__, self.currentCall.callId);
                    self.mute.title = @"OFF";
                }
            }];
        } else {
            
            NSLog(@"%s Call audio cannot be unmuted", __PRETTY_FUNCTION__);
        }
    }
}

- (void)windowWillClose:(NSNotification *)notification {
    
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)refreshActiveCallWindow:(NSNotification *)notification {
    
    // Check if video channels are available for call, if Yes then display local and remote video previews
    if (self.currentCall.videoChannels.count != 0) {
        
        NSLog(@"%s call has Video", __PRETTY_FUNCTION__);
        [self initViews];
    } else {
        
        NSLog(@"%s call doesn't have Video", __PRETTY_FUNCTION__);
        [self deallocViews];
    }
    
    NSString *state = @"";
    
    // Determine current call state
    switch ([self.currentCall state]) {
        case CSCallStateIdle:
            state = @"Idle";
            break;
        case CSCallStateInitiating:
            state = @"Initiating";
            break;
        case CSCallStateAlerting:
            state = @"Alerting";
            break;
        case CSCallStateRemoteAlerting:
            state = @"Remote Alerting";
            break;
        case CSCallStateEstablished:
        {
            state = @"Established";
            [self.callTimer invalidate];
            
            self.callTimer = [NSTimer scheduledTimerWithTimeInterval:1
                                                              target:self selector:@selector(callTimer:)
                                                            userInfo:nil repeats:YES];
            break;
        }
        case CSCallStateHolding:
            state = @"Holding";
            break;
        case CSCallStateHeld:
            state = @"Held";
            break;
        case CSCallStateUnholding:
            state = @"Unholding";
            break;
        case CSCallStateVideoUpdating:
            state = @"Video Updating";
            break;
        case CSCallStateTransferring:
            state = @"Transferring";
            break;
        case CSCallStateBeingTransferred:
            state = @"Being Transferred";
            break;
        case CSCallStateIgnored:
            state = @"Ignored";
            break;
        case CSCallStateFailed:
        {
            state = @"Failed";
            // End call timer
            [self.callTimer invalidate];
            [self deallocViews];
            [self dismissController:self];
            break;
        }
        case CSCallStateEnding:
            state = @"Ending";
            break;
        case CSCallStateEnded:
        {
            state = @"Ended";
            // End call timer
            [self.callTimer invalidate];
            [self deallocViews];
            [self dismissController:self];
            break;
        }
        case CSCallStateRenegotiating:
            state = @"Renegotiating";
            break;
        case CSCallStateFarEndRenegotiating:
            state = @"Far end Renegotiating";
            break;
        default:
            state = @"Unknown";
            break;
    }
    
    // Update current call state on UI
    self.callState.stringValue = [NSString stringWithFormat:@"%@", state];
    if(self.currentCall.state != CSCallStateEnded) {
        
        // Update Participant list
        if (self.currentCall.isConference) {
            NSLog(@"%s Call is Conference call, populate participant list", __PRETTY_FUNCTION__);
            self.participantList.stringValue = @"";

            NSArray *participantsNames = [self.currentCall.conference.participants valueForKey:@"displayName"];
            self.participantList.stringValue = [participantsNames componentsJoinedByString:@"\n"];
            
            self.conferenceControlBtn.hidden = !self.currentCall.conference.moderationCapability.allowed;
        } else if (self.currentCall.callerIdentityPrivate) {
            
            NSLog(@"%s Call identitiy is private", __PRETTY_FUNCTION__);
            self.participantList.stringValue = @"Restricted";
        } else {
            
            NSLog(@"%s Update caller display name", __PRETTY_FUNCTION__);
            if (self.currentCall.remoteDisplayName.length == 0) {
                
                // Display remoteNumber if remoteDisplayName is unavailable
                self.participantList.stringValue = [NSString stringWithFormat:@"%@", self.currentCall.remoteNumber];
            } else {
                
                self.participantList.stringValue = [NSString stringWithFormat:@"%@", self.currentCall.remoteDisplayName];
            }
        }
    }
}

- (NSString *)callTimerAsFormattedString {
    
    // Get elapsed time since call was established
    NSTimeInterval interval = - [self.currentCall.establishedDate timeIntervalSinceNow];
    NSString *intervalString = [[NSDateComponentsFormatter new] stringFromTimeInterval: interval];
    
    NSString *callTimerFormat;
    
    //Set correct format to hh:mm:ss
    switch(intervalString.length){
        case 1:
            callTimerFormat = @"00:00:0%@";
            break;
            
        case 2:
            callTimerFormat = @"00:00:%@";
            break;
        
        case 4:
            callTimerFormat = @"00:0%@";
            break;
            
        case 5:
            callTimerFormat = @"00:%@";
            break;
            
        case 7:
            callTimerFormat = @"0%@";
            break;
            
        default :
            callTimerFormat = @"%@";
    }
    
    return [NSString stringWithFormat:callTimerFormat, intervalString];
}

- (void)callTimer:(NSTimer*)theTimer {
    
    self.callDuration.stringValue = [self callTimerAsFormattedString];
}

- (void)initViews {
    
    // Perform initialization only once
    if (!self.viewInitialized) {
        
        [self.mediaManager initializeVideoView:self];
        self.viewInitialized = YES;
        [self.mediaManager runLocalVideo];
        
        localVideoView.wantsLayer = YES;
        localVideoView.layer = self.mediaManager.localVideoSink;
        
        remoteVideoView.wantsLayer = YES;
        remoteVideoView.layer = self.mediaManager.remoteVideoSink;
    }
    
    // Show remote video preview when call is established
    if ([self.currentCall state] == CSCallStateEstablished) {
        
        // show remote video preview
        remoteVideoView.hidden = NO;
        [self.mediaManager.remoteVideoSink handleVideoFrame:nil];
        [self.mediaManager runRemoteVideo:self.currentCall];
    }
    
    // show labels on window
    self.remoteVideoLabel.hidden = NO;
    self.localVideoLabel.hidden = NO;
    
    // show local video preview
    localVideoView.hidden = NO;
}

- (void)deallocViews {
    
    NSLog(@"%s", __PRETTY_FUNCTION__);
    if (self.viewInitialized) {
        
        // Hide local and remote video previews
        localVideoView.hidden = YES;
        remoteVideoView.hidden = YES;
        self.remoteVideoLabel.hidden = YES;
        self.localVideoLabel.hidden = YES;
        
        // Release camera resource from OS
        [self.mediaManager stopVideoCapture];
    }
}

- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
    
    if ([segue.identifier isEqualToString:@"conferenceControlSegue"]) {
        ConferenceControlViewController *viewController = segue.destinationController;
        viewController.conferenceCall = self.currentCall.conference;
    }
}

@end
