/*
 *  Copyright (C) 2015-2016 Savoir-faire Linux Inc.
 *  Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */
#import "CurrentCallVC.h"
extern "C" {
#import "libavutil/frame.h"
#import "libavutil/display.h"
}

#import <QuartzCore/QuartzCore.h>

///Qt
#import <QMimeData>
#import <QtMacExtras/qmacfunctions.h>
#import <QtCore/qabstractitemmodel.h>
#import <QPixmap>
#import <QUrl>

///LRC
#import <video/renderer.h>
#import <api/newcallmodel.h>
#import <api/call.h>
#import <api/conversationmodel.h>
#import <api/avmodel.h>
#import <globalinstances.h>

#import "AppDelegate.h"
#import "views/ITProgressIndicator.h"
#import "views/CallView.h"
#import "views/NSColor+RingTheme.h"
#import "delegates/ImageManipulationDelegate.h"
#import "ChatVC.h"
#import "views/IconButton.h"
#import "utils.h"
#import "views/CallMTKView.h"
#import "VideoCommon.h"
#import "views/GradientView.h"
#import "views/MovableView.h"
#import "views/RenderingView.h"

@interface CurrentCallVC () <NSPopoverDelegate> {
    QString convUid_;
    QString callUid_;
    QString confUid_;
    const lrc::api::account::Info *accountInfo_;
    NSTimer* refreshDurationTimer;
}

// Main container
@property (unsafe_unretained) IBOutlet NSSplitView* splitView;
@property (unsafe_unretained) IBOutlet NSView* backgroundImage;
@property (unsafe_unretained) IBOutlet NSBox* bluerBackgroundEffect;

// Header info
@property (unsafe_unretained) IBOutlet NSView* headerContainer;
@property (unsafe_unretained) IBOutlet NSView* headerGradientView;
@property (unsafe_unretained) IBOutlet NSTextField* timeSpentLabel;

// info
@property (unsafe_unretained) IBOutlet NSStackView* infoContainer;
@property (unsafe_unretained) IBOutlet NSImageView* contactPhoto;
@property (unsafe_unretained) IBOutlet NSTextField* contactNameLabel;
@property (unsafe_unretained) IBOutlet NSTextField* callStateLabel;
@property (unsafe_unretained) IBOutlet NSTextField* contactIdLabel;
@property (unsafe_unretained) IBOutlet IconButton* cancelCallButton;
@property (unsafe_unretained) IBOutlet IconButton* pickUpButton;
@property (unsafe_unretained) IBOutlet ITProgressIndicator *loadingIndicator;

// Call Controls
@property (unsafe_unretained) IBOutlet GradientView* controlsPanel;
@property (unsafe_unretained) IBOutlet NSStackView* controlsStackView;

@property (unsafe_unretained) IBOutlet IconButton* holdOnOffButton;
@property (unsafe_unretained) IBOutlet IconButton* hangUpButton;
@property (unsafe_unretained) IBOutlet IconButton* recordOnOffButton;
@property (unsafe_unretained) IBOutlet IconButton* muteAudioButton;
@property (unsafe_unretained) IBOutlet IconButton* muteVideoButton;
@property (unsafe_unretained) IBOutlet IconButton* transferButton;
@property (unsafe_unretained) IBOutlet IconButton* addParticipantButton;
@property (unsafe_unretained) IBOutlet IconButton* chatButton;
@property (unsafe_unretained) IBOutlet IconButton* qualityButton;

// Video
@property (unsafe_unretained) IBOutlet CallView *videoView;
@property (unsafe_unretained) IBOutlet RenderingView *previewView;
@property (unsafe_unretained) IBOutlet MovableView *movableBaseForView;
@property (unsafe_unretained) IBOutlet NSView* hidePreviewBackground;
@property (unsafe_unretained) IBOutlet NSButton* hidePreviewButton;

@property (unsafe_unretained) IBOutlet RenderingView *distantView;

@property RendererConnectionsHolder* renderConnections;
@property QMetaObject::Connection videoStarted;
@property QMetaObject::Connection callStateChanged;
@property QMetaObject::Connection messageConnection;
@property QMetaObject::Connection profileUpdatedConnection;
@property QMetaObject::Connection participantsChangedConnection;

//conference
@property (unsafe_unretained) IBOutlet NSStackView *callingWidgetsContainer;

@property (strong) NSPopover* brokerPopoverVC;

@property (strong) IBOutlet ChatVC* chatVC;

@end

@implementation CurrentCallVC
lrc::api::AVModel* mediaModel;
NSMutableDictionary *connectingCalls;
NSMutableDictionary *participantsOverlays;
NSSize framesize;

NSInteger const PREVIEW_WIDTH = 185;
NSInteger const PREVIEW_HEIGHT = 130;
NSInteger const HIDE_PREVIEW_BUTTON_SIZE = 25;
NSInteger const PREVIEW_MARGIN = 20;

@synthesize holdOnOffButton, hangUpButton, recordOnOffButton, pickUpButton, chatButton, transferButton, addParticipantButton, timeSpentLabel, muteVideoButton, muteAudioButton, controlsPanel, headerContainer, videoView, previewView, splitView, loadingIndicator, backgroundImage, bluerBackgroundEffect, hidePreviewButton, hidePreviewBackground, movableBaseForView, infoContainer, contactPhoto, contactNameLabel, callStateLabel, contactIdLabel, cancelCallButton, headerGradientView, controlsStackView, callingWidgetsContainer, brokerPopoverVC;

@synthesize renderConnections;
CVPixelBufferPoolRef pixelBufferPoolDistantView;
CVPixelBufferRef pixelBufferDistantView;
CVPixelBufferPoolRef pixelBufferPoolPreview;
CVPixelBufferRef pixelBufferPreview;

/* update call and conversation info
 * set info for chat view
 * connect signals
 */
-(void) setCurrentCall:(const QString&)callUid
          conversation:(const QString&)convUid
               account:(const lrc::api::account::Info*)account
               avModel:(lrc::api::AVModel *)avModel;
{
    if(account == nil)
        return;

    mediaModel = avModel;
    auto* callModel = account->callModel.get();

    if (not callModel->hasCall(callUid)){
        callUid_.clear();
        confUid_.clear();
        return;
    }
    callUid_ = callUid;
    convUid_ = convUid;
    accountInfo_ = account;
    auto conv = accountInfo_->conversationModel->getConversationForUID(convUid_);
    if (conv.uid.isEmpty()) {
        return;
    }
    confUid_ = conv.confId;
    [self.chatVC setConversationUid:convUid model: account->conversationModel.get()];
    [self connectSignals];
}

-(void)updateConferenceOverlays:(QString)callID {
    auto* callModel = accountInfo_->callModel.get();
    auto call = callModel->getCall(callID);
    using Status = lrc::api::call::Status;
    switch (call.status) {
        case Status::ENDED:
        case Status::TERMINATING:
        case Status::INVALID:
        case Status::PEER_BUSY:
        case Status::TIMEOUT:
            if (participantsOverlays[call.peerUri.toNSString()] != nil) {
                [participantsOverlays[call.peerUri.toNSString()] removeFromSuperview];
                participantsOverlays[call.peerUri.toNSString()] = nil;
                if (![self isCurrentCall: callID]) {
                    [self updateCall];
                    [self setCurrentCall: callUid_ conversation:convUid_ account:accountInfo_ avModel:mediaModel];
                }
            }
            break;
    }
}

-(void)switchToNextConferenceCall:(QString)confId {
    auto* callModel = accountInfo_->callModel.get();
    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
    auto activeCalls = [appDelegate getActiveCalls];
    if (activeCalls.isEmpty()) {
        return;
    }
    auto subcalls = [appDelegate getConferenceSubcalls: confId];
    QString callId;
    if (subcalls.isEmpty()) {
        for(auto subcall: activeCalls) {
            if(subcall != callUid_) {
                callId = subcall;
            }
        }
    } else {
        for(auto subcall: subcalls) {
            if(subcall != callUid_) {
                callId = subcall;
            }
        }
    }
    if (!callModel->hasCall(callId)) {
        return;
    }
    auto callToSwitch = callModel->getCall(callId);
    auto convIt = getConversationFromURI(callToSwitch.peerUri, *accountInfo_->conversationModel);
    if (convIt == accountInfo_->conversationModel->allFilteredConversations().end()) {
        return;
    }
    [self.delegate chooseConversation: *convIt model:accountInfo_->conversationModel.get()];
}

-(void) connectSignals {
    auto* callModel = accountInfo_->callModel.get();
    auto* convModel = accountInfo_->conversationModel.get();
    QObject::disconnect(self.participantsChangedConnection);
    self.participantsChangedConnection = QObject::connect(callModel,
                                                          &lrc::api::NewCallModel::onParticipantsChanged,
                                                          [self](const QString& confId) {
        auto* callModel = accountInfo_->callModel.get();
        if (!callModel->hasCall(confId)) {
            return;
        }
        if ([self isCurrentCall: confId]) {
            [self updateConference: confId];
        }
    });
    //monitor for updated call state
    QObject::disconnect(self.callStateChanged);
    self.callStateChanged = QObject::connect(callModel,
                                             &lrc::api::NewCallModel::callStatusChanged,
                                             [self](const QString& callId) {
        [self updateConferenceOverlays: callId];
        if ([self isCurrentCall: callId]) {
            [self updateCall];
        }
    });
    /* monitor media for messaging text messaging */
    QObject::disconnect(self.messageConnection);
    self.messageConnection = QObject::connect(convModel,
                                              &lrc::api::ConversationModel::interactionStatusUpdated,
                                              [self] (const QString& convUid,
                                                      uint64_t msgId,
                                                      lrc::api::interaction::Info msg) {
                                                  if (msg.type == lrc::api::interaction::Type::TEXT) {
                                                      if(not [[self splitView] isSubviewCollapsed:[[[self splitView] subviews] objectAtIndex: 1]]){
                                                          return;
                                                      }
                                                      [self uncollapseRightView];
                                                  }
                                              });
    //monitor for updated profile
    QObject::disconnect(self.profileUpdatedConnection);
    self.profileUpdatedConnection =
    QObject::connect(accountInfo_->contactModel.get(),
                     &lrc::api::ContactModel::contactAdded,
                     [self](const QString &contactUri) {
        auto conv = accountInfo_->conversationModel->getConversationForUID(convUid_);
        if (conv.uid.isEmpty() || conv.participants.empty()) {
            return;
        }
        auto& contact = accountInfo_->contactModel->getContact(conv.participants[0]);
        if (contact.profileInfo.type == lrc::api::profile::Type::RING && contact.profileInfo.uri == contactUri)
            accountInfo_->conversationModel->makePermanent(convUid_);
        [contactPhoto setImage: [self getContactImageOfSize:120.0 withDefaultAvatar:YES]];
        [self.delegate conversationInfoUpdatedFor:convUid_];
        [self setBackground];
    });
    [self connectVideoSignals];
}

-(void) updatePendingCalls {
    for (NSView *view in callingWidgetsContainer.subviews) {
        view.removeFromSuperview;
    }
    NSDictionary * calls = connectingCalls[callUid_.toNSString()];
    for (NSViewController * callView in calls.allValues) {
       [self.callingWidgetsContainer addView: callView.view inGravity:NSStackViewGravityBottom];
    }
}

-(void) setUpButtons:(lrc::api::call::Info&)callInfo isRecording:(BOOL) isRecording {
    muteAudioButton.image = callInfo.audioMuted ? [NSImage imageNamed:@"ic_action_mute_audio.png"] :
    [NSImage imageNamed:@"ic_action_audio.png"];
    muteVideoButton.image = callInfo.videoMuted ? [NSImage imageNamed:@"ic_action_mute_video.png"] :
    [NSImage imageNamed:@"ic_action_video.png"];
    [muteVideoButton setHidden: callInfo.isAudioOnly ? YES: NO];
    if (isRecording) {
        [recordOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1 duration: 1.5];
    } else {
        [recordOnOffButton stopBlinkAnimation];
    }
}

- (void) setUpPreviewFrame {
    CGPoint previewOrigin = CGPointMake(self.videoView.frame.size.width - PREVIEW_WIDTH - PREVIEW_MARGIN, PREVIEW_MARGIN);
    movableBaseForView.frame = CGRectMake(previewOrigin.x, previewOrigin.y, PREVIEW_WIDTH, PREVIEW_HEIGHT);
    self.movableBaseForView.movable = true;
    previewView.frame = movableBaseForView.bounds;
    hidePreviewBackground.frame = [self frameForExpendPreviewButton];
    if ([hidePreviewButton respondsToSelector:@selector(contentTintColor)]) {
        hidePreviewButton.contentTintColor = [NSColor blackColor];
    }
}

- (void)awakeFromNib
{
    [self.view setWantsLayer:YES];

    renderConnections = [[RendererConnectionsHolder alloc] init];

    [loadingIndicator setColor:[NSColor whiteColor]];
    [loadingIndicator setNumberOfLines:200];
    [loadingIndicator setWidthOfLine:4];
    [loadingIndicator setLengthOfLine:4];
    [loadingIndicator setInnerMargin:59];

    [self.videoView setCallDelegate:self];
    [bluerBackgroundEffect setWantsLayer:YES];
    [backgroundImage setWantsLayer: YES];
    backgroundImage.layer.contentsGravity = kCAGravityResizeAspectFill;
    movableBaseForView.wantsLayer = YES;
    movableBaseForView.shadow = [[NSShadow alloc] init];
    movableBaseForView.layer.shadowOpacity = 0.6;
    movableBaseForView.layer.shadowColor = [[NSColor blackColor] CGColor];
    movableBaseForView.layer.shadowOffset = NSMakeSize(0, -3);
    movableBaseForView.layer.shadowRadius = 10;
    previewView.wantsLayer = YES;
    previewView.layer.cornerRadius = 5;
    previewView.layer.masksToBounds = true;
    hidePreviewBackground.wantsLayer = YES;
    hidePreviewBackground.layer.cornerRadius = 5;
    hidePreviewBackground.layer.maskedCorners = kCALayerMinXMinYCorner;
    hidePreviewBackground.layer.masksToBounds = true;
    movableBaseForView.hostingView = self.videoView;
    [movableBaseForView setAutoresizingMask: NSViewNotSizable | NSViewMaxXMargin | NSViewMaxYMargin | NSViewMinXMargin | NSViewMinYMargin];
    [previewView setAutoresizingMask: NSViewNotSizable | NSViewMaxXMargin | NSViewMaxYMargin | NSViewMinXMargin | NSViewMinYMargin];
    connectingCalls = [[NSMutableDictionary alloc] init];
    participantsOverlays = [[NSMutableDictionary alloc] init];
}

-(void) updateDurationLabel
{
    if (accountInfo_ != nil) {
        auto* callModel = accountInfo_->callModel.get();
        if (callModel->hasCall(callUid_)) {
            auto& callStatus = callModel->getCall(callUid_).status;
            if (callStatus != lrc::api::call::Status::ENDED &&
                callStatus != lrc::api::call::Status::TERMINATING &&
                callStatus != lrc::api::call::Status::INVALID) {
                [timeSpentLabel setStringValue:callModel->getFormattedCallDuration(callUid_).toNSString()];
                return;
            }
        }
    }

    // If call is not running anymore or accountInfo_ is not set for any reason
    // we stop the refresh loop
    [refreshDurationTimer invalidate];
    refreshDurationTimer = nil;
}

-(void)removeConferenceLayout {
    for (ConferenceOverlayView* overlay: [participantsOverlays allValues]) {
        [overlay removeFromSuperview];
    }
    participantsOverlays = [[NSMutableDictionary alloc] init];
}

-(void)updateConference:(QString)confId
{
    if (confId.isEmpty()) {
        [self removeConferenceLayout];
        return;
    }
    auto* callModel = accountInfo_->callModel.get();
    auto& call = callModel->getCall(confId);
    using Status = lrc::api::call::Status;
    auto participants = call.participantsInfos;
    if (participants.size() == 0 || call.status == Status::ENDED ||
        call.status == Status::TERMINATING || call.status == Status::INVALID) {
        [self removeConferenceLayout];
        return;
    }
    for (auto participant: participants) {
        ConferenceParticipant conferenceParticipant;
        conferenceParticipant.x = participant["x"].toFloat();
        conferenceParticipant.y = participant["y"].toFloat();
        conferenceParticipant.width = participant["w"].toFloat();
        conferenceParticipant.hight = participant["h"].toFloat();
        conferenceParticipant.uri = participant["uri"].toNSString();
        conferenceParticipant.active = participant["active"] == "true";
        conferenceParticipant.isLocal = false;
        conferenceParticipant.bestName = participant["uri"].toNSString();
        if (accountInfo_->profileInfo.uri == participant["uri"]) {
            conferenceParticipant.isLocal = true;
            conferenceParticipant.bestName = NSLocalizedString(@"Me", @"Conference name");
        } else {
            try {
                auto contact = accountInfo_->contactModel->getContact(participant["uri"]);
                conferenceParticipant.bestName = bestNameForContact(contact);
            } catch (...) {}
        }
        if (participantsOverlays[conferenceParticipant.uri] != nil) {
            ConferenceOverlayView* overlay = participantsOverlays[conferenceParticipant.uri];
            overlay.framesize = framesize;
            [overlay updateViewWithParticipant: conferenceParticipant];
        } else {
            ConferenceOverlayView* overlay = [[ConferenceOverlayView alloc] init];
            overlay.framesize = framesize;
            overlay.delegate = self;
            [overlay configureView];
            [self.distantView addSubview: overlay];
            participantsOverlays[conferenceParticipant.uri] = overlay;
            [overlay updateViewWithParticipant: conferenceParticipant];
        }
    }
}

-(void) updateCall
{
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();
    if (not callModel->hasCall(callUid_)) {
        return;
    }

    auto currentCall = callModel->getCall(callUid_);
    auto convIt = accountInfo_->conversationModel->getConversationForUID(convUid_);
    if (!convIt.uid.isEmpty()) {
        NSString* bestName = bestNameForConversation(convIt, *accountInfo_->conversationModel);
        [contactNameLabel setStringValue:bestName];
        NSString* ringID = bestIDForConversation(convIt, *accountInfo_->conversationModel);
        if([bestName isEqualToString:ringID]) {
            ringID = @"";
        }
        [contactIdLabel setStringValue:ringID];
    }
    [self setupContactInfo:contactPhoto];
    confUid_ = convIt.confId;
    [muteAudioButton setHidden:!confUid_.isEmpty()];
    [muteVideoButton setHidden:!confUid_.isEmpty()];
    [recordOnOffButton setHidden:!confUid_.isEmpty()];
    [holdOnOffButton setHidden:!confUid_.isEmpty()];
    [movableBaseForView setHidden:!confUid_.isEmpty()];
    [self updateConference: confUid_];

    [timeSpentLabel setStringValue:callModel->getFormattedCallDuration(callUid_).toNSString()];
    if (refreshDurationTimer == nil)
        refreshDurationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                                target:self
                                                              selector:@selector(updateDurationLabel)
                                                              userInfo:nil
                                                               repeats:YES];
    [self setBackground];

    using Status = lrc::api::call::Status;
    if (currentCall.status == Status::PAUSED) {
        [holdOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1.0 duration: 1.5];
    } else {
        [holdOnOffButton stopBlinkAnimation];
    }

    [self setUpButtons: currentCall isRecording: (callModel->isRecording([self getcallID]) || mediaModel->getAlwaysRecord())];

    [videoView setShouldAcceptInteractions: currentCall.status == Status::IN_PROGRESS];
    callStateLabel.stringValue = currentCall.status == Status::INCOMING_RINGING ? @"wants to talk to you" : to_string(currentCall.status).toNSString();
    loadingIndicator.hidden = (currentCall.status == Status::SEARCHING ||
                               currentCall.status == Status::CONNECTING ||
                               currentCall.status == Status::OUTGOING_RINGING) ? NO : YES;
    pickUpButton.hidden = (currentCall.status == Status::INCOMING_RINGING) ? NO : YES;
    callStateLabel.hidden = (currentCall.status == Status::IN_PROGRESS) ? YES : NO;
    cancelCallButton.hidden = (currentCall.status == Status::IN_PROGRESS ||
                             currentCall.status == Status::PAUSED) ? YES : NO;
    callingWidgetsContainer.hidden = (currentCall.status == Status::IN_PROGRESS) ? NO : YES;
    switch (currentCall.status) {
        case Status::SEARCHING:
        case Status::CONNECTING:
        case Status::OUTGOING_RINGING:
        case Status::INCOMING_RINGING:
            [infoContainer setHidden: NO];
            [headerContainer setHidden:YES];
            [headerGradientView setHidden:YES];
            [controlsPanel setHidden:YES];
            [controlsStackView setHidden:YES];
            [self.distantView fillWithBlack];
            [self.previewView fillWithBlack];
            [hidePreviewBackground setHidden:YES];
            [self.previewView setHidden: YES];
            [self.distantView setHidden: YES];
            self.previewView.videoRunning = NO;
            self.distantView.videoRunning = NO;
            [backgroundImage setHidden:NO];
            [bluerBackgroundEffect setHidden:NO];
            break;
        case Status::PAUSED:
            [infoContainer setHidden: NO];
            [headerContainer setHidden:NO];
            [headerGradientView setHidden:NO];
            [controlsPanel setHidden:NO];
            [controlsStackView setHidden:NO];
            [backgroundImage setHidden:NO];
            [bluerBackgroundEffect setHidden:NO];
            if(!currentCall.isAudioOnly) {
                [self.distantView fillWithBlack];
                [self.previewView fillWithBlack];
                [hidePreviewBackground setHidden:YES];
                [self.previewView setHidden: YES];
                [self.distantView setHidden: YES];
                self.previewView.videoRunning = NO;
                self.distantView.videoRunning = NO;
            }
            break;
        case Status::INACTIVE:
            if(currentCall.isAudioOnly) {
                [self setUpAudioOnlyView];
            } else {
                [self setUpVideoCallView];
            }
            break;
        case Status::IN_PROGRESS:
            callModel->setCurrentCall([self getcallID]);
            [headerContainer setHidden:NO];
            [headerGradientView setHidden:NO];
            [controlsPanel setHidden:NO];
            [controlsStackView setHidden:NO];
            if(currentCall.isAudioOnly) {
                [self setUpAudioOnlyView];
            } else {
                [self setUpVideoCallView];
            }
            break;
        case Status::CONNECTED:
            break;
        case Status::ENDED:
        case Status::TERMINATING:
        case Status::INVALID:
        case Status::PEER_BUSY:
        case Status::TIMEOUT:
            connectingCalls[callUid_.toNSString()] = nil;
            [self.delegate callFinished];
            [self removeConferenceLayout];
            [self switchToNextConferenceCall: confUid_];
            break;
    }
}

-(void) setUpVideoCallView {
    [previewView fillWithBlack];
    [self.distantView fillWithBlack];
    [previewView setHidden: NO];
    [self.distantView setHidden:NO];
    [hidePreviewBackground setHidden: !self.previewView.videoRunning];
    [bluerBackgroundEffect setHidden:YES];
    [backgroundImage setHidden:YES];
    self.previewView.videoRunning = true;
    self.distantView.videoRunning = true;
}

-(void) setUpAudioOnlyView {
    [self.previewView setHidden: YES];
    [self.distantView setHidden: YES];
    [hidePreviewBackground setHidden: YES];
    [bluerBackgroundEffect setHidden:NO];
    [backgroundImage setHidden:NO];
}

-(void) setBackground {
    NSImage *image= [self getContactImageOfSize:120.0 withDefaultAvatar:NO];
    if(image) {
        @autoreleasepool {
            CIImage * ciImage = [[CIImage alloc] initWithData:[image TIFFRepresentation]];
            CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"];
            [clamp setValue:[NSAffineTransform transform] forKey:@"inputTransform"];
            [clamp setValue:ciImage forKey: kCIInputImageKey];
            CIFilter* bluerFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
            [bluerFilter setDefaults];
            [bluerFilter setValue:[NSNumber numberWithFloat: 9] forKey:@"inputRadius"];
            [bluerFilter setValue:[clamp valueForKey:kCIOutputImageKey] forKey: kCIInputImageKey];
            CIImage *result = [bluerFilter valueForKey:kCIOutputImageKey];
            CIContext *context = [CIContext contextWithOptions:nil];
            CGImageRef cgImage = [context createCGImage:result fromRect: [ciImage extent]];
            NSImage *bluredImage = [[NSImage alloc] initWithCGImage:cgImage size:NSSizeFromCGSize(CGSizeMake(image.size.width, image.size.height))];
            backgroundImage.layer.contents = bluredImage;
            [backgroundImage setHidden:NO];
            [bluerBackgroundEffect setFillColor:[NSColor darkGrayColor]];
            [bluerBackgroundEffect setAlphaValue:0.6];
        }
    } else {
        contactNameLabel.textColor = [NSColor textColor];
        contactIdLabel.textColor = [NSColor textColor];
        callStateLabel.textColor = [NSColor textColor];
        backgroundImage.layer.contents = nil;
        [bluerBackgroundEffect setFillColor:[NSColor windowBackgroundColor]];
        [bluerBackgroundEffect setAlphaValue:1];
        [backgroundImage setHidden:YES];
    }
}

-(NSImage *) getContactImageOfSize: (double) size withDefaultAvatar:(BOOL) shouldDrawDefault {
    @autoreleasepool {
        auto* convModel = accountInfo_->conversationModel.get();
        auto conv = accountInfo_->conversationModel->getConversationForUID(convUid_);
        if (conv.uid.isEmpty() || conv.participants.empty()) {
            return nil;
        }
        if(shouldDrawDefault) {
            auto& imgManip = reinterpret_cast<Interfaces::ImageManipulationDelegate&>(GlobalInstances::pixmapManipulator());
            QVariant photo = imgManip.conversationPhoto(conv, *accountInfo_, QSize(size, size), NO);
            return QtMac::toNSImage(qvariant_cast<QPixmap>(photo));
        }
        auto contact = accountInfo_->contactModel->getContact(conv.participants[0]);
        NSData *imageData = [[NSData alloc] initWithBase64EncodedString:contact.profileInfo.avatar.toNSString() options:NSDataBase64DecodingIgnoreUnknownCharacters];
        return [[NSImage alloc] initWithData:imageData];
    }
}

-(void) setupContactInfo:(NSImageView*)imageView
{
    [imageView setImage: [self getContactImageOfSize:120.0 withDefaultAvatar:YES]];
}

-(void)collapseRightView
{
    NSView *right = [[splitView subviews] objectAtIndex:1];
    NSView *left  = [[splitView subviews] objectAtIndex:0];
    NSRect leftFrame = [left frame];
    [right setHidden:YES];
    [splitView display];
}

-(void) connectVideoSignals
{
    if (accountInfo_ == nil)
        return;
    [self connectRenderer];
}

-(void) connectRenderer
{
    QObject::disconnect(renderConnections.frameUpdated);
    QObject::disconnect(renderConnections.stopped);
    QObject::disconnect(renderConnections.started);
    renderConnections.started =
    QObject::connect(mediaModel,
                     &lrc::api::AVModel::rendererStarted,
                     [=](const QString& id) {
                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
                             [self.previewView setHidden:NO];
                             [hidePreviewBackground setHidden: NO];
                             self.previewView.videoRunning = true;
                         } else if ([self isCurrentCall: id]) {
                             [self mouseIsMoving: NO];
                             self.distantView.videoRunning = true;
                             [self.distantView setHidden:NO];
                             [bluerBackgroundEffect setHidden:YES];
                             [backgroundImage setHidden:YES];
                         }
                     });
    renderConnections.stopped =
    QObject::connect(mediaModel,
                     &lrc::api::AVModel::rendererStopped,
                     [=](const QString& id) {
                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
                             [self.previewView setHidden:YES];
                             self.previewView.videoRunning = false;
                         } else if ([self isCurrentCall: id]) {
                             [self mouseIsMoving: YES];
                             self.distantView.videoRunning = false;
                             [self.distantView setHidden:YES];
                             [bluerBackgroundEffect setHidden:NO];
                             [backgroundImage setHidden:NO];
                         }
                     });
    renderConnections.frameUpdated =
    QObject::connect(mediaModel,
                     &lrc::api::AVModel::frameUpdated,
                     [=](const QString& id) {
                         if (id == lrc::api::video::PREVIEW_RENDERER_ID) {
                             auto renderer = &mediaModel->getRenderer(lrc::api::video::PREVIEW_RENDERER_ID);
                             if(!renderer->isRendering()) {
                                 return;
                             }
                             [hidePreviewBackground setHidden: !self.previewView.videoRunning];
                             [self rendererPreview: renderer];
                         } else if ([self isCurrentCall: id]) {
                             auto renderer = &mediaModel->getRenderer(id);
                             if(!renderer->isRendering()) {
                                 return;
                             }
                             [self rendererDistantView: renderer];
                         }
                     });
}

-(void) rendererDistantView: (const lrc::api::video::Renderer*)renderer {
    @autoreleasepool {
        auto framePtr = renderer->currentAVFrame();
        auto frame = framePtr.get();
        if(!frame || !frame->width || !frame->height)  {
            return;
        }
        auto frameSize = CGSizeMake(frame->width, frame->height);
        framesize = frameSize;
        auto rotation = 0;
        if (auto matrix = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
            const int32_t* data = reinterpret_cast<int32_t*>(matrix->data);
            rotation = av_display_rotation_get(data);
        }
        if (frame->data[3] != NULL && (CVPixelBufferRef)frame->data[3]) {
            [self.distantView renderWithPixelBuffer: (CVPixelBufferRef)frame->data[3]
                                   size: frameSize
                               rotation: rotation
                              fillFrame: false];
        }
        if (CVPixelBufferRef pixelBuffer = [self getBufferForDistantViewFromFrame:frame]) {
            [self.distantView renderWithPixelBuffer: pixelBuffer
                                   size: frameSize
                               rotation: rotation
                              fillFrame: false];
        }
    }
}

-(void) rendererPreview: (const lrc::api::video::Renderer*)renderer {
    @autoreleasepool {
        auto framePtr = renderer->currentAVFrame();
        auto frame = framePtr.get();
        if(!frame || !frame->width || !frame->height)  {
            return;
        }
        auto frameSize = CGSizeMake(frame->width, frame->height);
        auto rotation = 0;
        if (auto matrix = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {
            const int32_t* data = reinterpret_cast<int32_t*>(matrix->data);
            rotation = av_display_rotation_get(data);
        }
        if (frame->data[3] != NULL && (CVPixelBufferRef)frame->data[3]) {
            [self.previewView renderWithPixelBuffer: (CVPixelBufferRef)frame->data[3]
                                   size: frameSize
                               rotation: rotation
                              fillFrame: false];
        }
        if (CVPixelBufferRef pixelBuffer = [self getBufferForPreviewFromFrame:frame]) {
            [self.previewView renderWithPixelBuffer: pixelBuffer
                                   size: frameSize
                               rotation: rotation
                              fillFrame: true];
        }
    }
}

-(CVPixelBufferRef) getBufferForPreviewFromFrame:(const AVFrame*)frame {
    [VideoCommon fillPixelBuffr:&pixelBufferPreview fromFrame:frame bufferPool:&pixelBufferPoolPreview];
    CVPixelBufferRef buffer  = pixelBufferPreview;
    return buffer;
}

-(CVPixelBufferRef) getBufferForDistantViewFromFrame:(const AVFrame*)frame {
    [VideoCommon fillPixelBuffr:&pixelBufferDistantView fromFrame:frame bufferPool:&pixelBufferPoolDistantView];
    CVPixelBufferRef buffer  = pixelBufferDistantView;
    return buffer;
}

- (void) initFrame
{
    [self.view setFrame:self.view.superview.bounds];
    [self.view setHidden:YES];
    self.view.layer.position = self.view.frame.origin;
    [self collapseRightView];
}

# pragma private IN/OUT animations

-(void)uncollapseRightView
{
    NSView *left  = [[splitView subviews] objectAtIndex:0];
    NSView *right = [[splitView subviews] objectAtIndex:1];
    [right setHidden:NO];

    CGFloat dividerThickness = [splitView dividerThickness];

    // get the different frames
    NSRect leftFrame = [left frame];
    NSRect rightFrame = [right frame];

    leftFrame.size.width = (leftFrame.size.width - rightFrame.size.width - dividerThickness);
    rightFrame.origin.x = leftFrame.size.width + dividerThickness;
    [left setFrameSize:leftFrame.size];
    [right setFrame:rightFrame];
    [splitView display];

    [self.chatVC takeFocus];
}

-(void) cleanUp
{
    if(self.splitView.isInFullScreenMode)
        [self.splitView exitFullScreenModeWithOptions:nil];
    QObject::disconnect(renderConnections.frameUpdated);
    QObject::disconnect(renderConnections.started);
    QObject::disconnect(renderConnections.stopped);
    QObject::disconnect(self.messageConnection);

    [self.chatButton setPressed:NO];
    [self collapseRightView];

    [timeSpentLabel setStringValue:@""];
    [contactIdLabel setStringValue:@""];
    [contactNameLabel setStringValue:@""];
    [contactPhoto setImage:nil];
    //background view
    [bluerBackgroundEffect setHidden:NO];
    [backgroundImage setHidden:NO];
    backgroundImage.layer.contents = nil;
    [self.previewView setHidden:YES];
    [self.distantView setHidden:YES];

    contactNameLabel.textColor = [NSColor highlightColor];
    contactNameLabel.textColor = [NSColor highlightColor];
    contactIdLabel.textColor = [NSColor highlightColor];
    callStateLabel.textColor = [NSColor highlightColor];
    [self.chatVC clearData];
}

/*
 * update ui
*/

-(void) setupCallView
{
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();

    /* check if text media is already present */
    if(not callModel->hasCall(callUid_))
        return;

    // when call comes in we want to show the controls/header
    [self mouseIsMoving: YES];
    [loadingIndicator setAnimates:YES];
    auto currentCall = callModel->getCall([self getcallID]);
    [previewView setHidden: YES];
    [self setUpPreviewFrame];
    [self updatePendingCalls];
    [self updateCall];
}

-(void) showWithAnimation:(BOOL)animate
{
    if (!animate) {
        [self.view setHidden:NO];
        [self setupCallView];
        return;
    }

    CGRect frame = CGRectOffset(self.view.superview.bounds, -self.view.superview.bounds.size.width, 0);
    [self.view setHidden:NO];

    [CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setFromValue:[NSValue valueWithPoint:frame.origin]];
    [animation setToValue:[NSValue valueWithPoint:self.view.superview.bounds.origin]];
    [animation setDuration:0.2f];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    [CATransaction setCompletionBlock:^{
        [self setupCallView];
    }];

    [self.view.layer addAnimation:animation forKey:animation.keyPath];
    [CATransaction commit];
}

-(void) hideWithAnimation:(BOOL)animate
{
    if(self.view.frame.origin.x < 0) {
        return;
    }

    if (!animate) {
        [self.view setHidden:YES];
        return;
    }

    CGRect frame = CGRectOffset(self.view.frame, -self.view.frame.size.width, 0);
    [CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setFromValue:[NSValue valueWithPoint:self.view.frame.origin]];
    [animation setToValue:[NSValue valueWithPoint:frame.origin]];
    [animation setDuration:0.2f];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];

    [CATransaction setCompletionBlock:^{
        [self.view setHidden:YES];
        // first make sure everything is disconnected
        [self cleanUp];
//        if (currentCall_) {
//            [self animateIn];
//        }
    }];
    [self.view.layer addAnimation:animation forKey:animation.keyPath];

    [self.view.layer setPosition:frame.origin];
    [CATransaction commit];
}

/**
 *  Debug purpose
 */
-(void) dumpFrame:(CGRect) frame WithName:(NSString*) name
{
    NSLog(@"frame %@ : %f %f %f %f \n\n",name ,frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
}

#pragma mark - Button methods

- (IBAction)hangUp:(id)sender {
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();
    callModel->hangUp(callUid_);
}

- (IBAction)accept:(id)sender {
    if (accountInfo_ == nil)
        return;

    // If we accept a conversation with a non trusted contact, we first accept it
    auto conv = accountInfo_->conversationModel->getConversationForUID(convUid_);
    if (conv.uid.isEmpty() || conv.participants.empty()) {
        return;
    }
    auto& contact = accountInfo_->contactModel->getContact(conv.participants[0]);
    if (contact.profileInfo.type == lrc::api::profile::Type::PENDING) {
        accountInfo_->conversationModel->makePermanent(convUid_);
    }

    auto* callModel = accountInfo_->callModel.get();
    callModel->accept(callUid_);
}

- (IBAction)toggleRecording:(id)sender {
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();
    callModel->toggleAudioRecord(callUid_);
    if (callModel->isRecording(callUid_)) {
        [recordOnOffButton startBlinkAnimationfrom:[NSColor buttonBlinkColorColor] to:[NSColor whiteColor] scaleFactor: 1 duration: 1.5];
    } else {
        [recordOnOffButton stopBlinkAnimation];
    }
}

- (IBAction)toggleHold:(id)sender {
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();
    callModel->togglePause([self getcallID]);
}

- (IBAction)showDialpad:(id)sender {
    AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
    [appDelegate showDialpad];
}

-(IBAction)toggleChat:(id)sender;
{
    BOOL rightViewCollapsed = [[self splitView] isSubviewCollapsed:[[[self splitView] subviews] objectAtIndex: 1]];
    if (rightViewCollapsed) {
        [self uncollapseRightView];
    } else {
        [self collapseRightView];
    }
    [chatButton setPressed:rightViewCollapsed];
}

- (IBAction)muteAudio:(id)sender
{
    if (accountInfo_ == nil)
        return;

    auto* callModel = accountInfo_->callModel.get();
    auto currentCall = callModel->getCall(callUid_);
    if (currentCall.audioMuted) {
        muteAudioButton.image = [NSImage imageNamed:@"ic_action_audio.png"];
    } else {
       muteAudioButton.image = [NSImage imageNamed:@"ic_action_mute_audio.png"];
    }
    callModel->toggleMedia(callUid_, lrc::api::NewCallModel::Media::AUDIO);
}

- (IBAction)muteVideo:(id)sender
{
    if (accountInfo_ == nil)
        return;
    auto* callModel = accountInfo_->callModel.get();
    auto currentCall = callModel->getCall(callUid_);
    if(!currentCall.isAudioOnly) {
        if (currentCall.videoMuted) {
            muteVideoButton.image = [NSImage imageNamed:@"ic_action_video.png"];
        } else {
            muteVideoButton.image = [NSImage imageNamed:@"ic_action_mute_video.png"];
        }
    }
    callModel->toggleMedia(callUid_, lrc::api::NewCallModel::Media::VIDEO);
}

- (IBAction)toggleTransferView:(id)sender {

}

- (IBAction)toggleAddParticipantView:(id)sender {
    if (brokerPopoverVC != nullptr) {
        [brokerPopoverVC performClose:self];
        brokerPopoverVC = NULL;
    } else {
        auto* contactSelectorVC = [[ChooseContactVC alloc] initWithNibName:@"ChooseContactVC" bundle:nil];
        auto* convModel = accountInfo_->conversationModel.get();
        [contactSelectorVC setConversationModel:convModel andCurrentConversation: convUid_];
        contactSelectorVC.delegate = self;
        brokerPopoverVC = [[NSPopover alloc] init];
        [brokerPopoverVC setContentSize:contactSelectorVC.view.frame.size];
        [brokerPopoverVC setContentViewController:contactSelectorVC];
        [brokerPopoverVC setAnimates:YES];
        [brokerPopoverVC setBehavior:NSPopoverBehaviorTransient];
        [brokerPopoverVC setDelegate:self];
        [brokerPopoverVC showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMinYEdge];
    }
}

- (IBAction)hidePreview:(id)sender {
    CGRect previewFrame = previewView.frame;
    CGRect newPreviewFrame;
    if (previewFrame.size.width > HIDE_PREVIEW_BUTTON_SIZE) {
        self.movableBaseForView.movable = false;
        newPreviewFrame = self.getVideoPreviewCollapsedSize;
        hidePreviewButton.image = [NSImage imageNamed: NSImageNameTouchBarEnterFullScreenTemplate];
    } else {
        self.movableBaseForView.movable = true;
        newPreviewFrame = CGRectMake(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT);
        hidePreviewButton.image = [NSImage imageNamed: NSImageNameTouchBarExitFullScreenTemplate];
    }
    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
        context.duration = 0.2f;
        context.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut];
        previewView.animator.frame = newPreviewFrame;
    } completionHandler: nil];
}

#pragma mark - NSSplitViewDelegate

/* Return YES if the subview should be collapsed because the user has double-clicked on an adjacent divider. If a split view has a delegate, and the delegate responds to this message, it will be sent once for the subview before a divider when the user double-clicks on that divider, and again for the subview after the divider, but only if the delegate returned YES when sent -splitView:canCollapseSubview: for the subview in question. When the delegate indicates that both subviews should be collapsed NSSplitView's behavior is undefined.
 */
- (BOOL)splitView:(NSSplitView *)splitView shouldCollapseSubview:(NSView *)subview forDoubleClickOnDividerAtIndex:(NSInteger)dividerIndex;
{
    NSView* rightView = [[splitView subviews] objectAtIndex:1];
    return ([subview isEqual:rightView]);
}


- (BOOL)splitView:(NSSplitView *)splitView canCollapseSubview:(NSView *)subview;
{
    NSView* rightView = [[splitView subviews] objectAtIndex:1];
    return ([subview isEqual:rightView]);
}


# pragma mark - CallnDelegate

- (void) callShouldToggleFullScreen
{
    if(self.splitView.isInFullScreenMode)
        [self.splitView exitFullScreenModeWithOptions:nil];
    else {
        NSApplicationPresentationOptions options = NSApplicationPresentationDefault +NSApplicationPresentationAutoHideDock +
        NSApplicationPresentationAutoHideMenuBar + NSApplicationPresentationAutoHideToolbar;
        NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInt:options],
                              NSFullScreenModeApplicationPresentationOptions, nil];

        [self.splitView enterFullScreenMode:[NSScreen mainScreen]  withOptions:opts];
    }
    for (ConferenceOverlayView* participant: [participantsOverlays allValues]) {
        [participant sizeChanged];
    }
}

-(void) mouseIsMoving:(BOOL) move
{
    [[controlsPanel animator] setAlphaValue:move];// fade out
    [[controlsStackView animator] setAlphaValue:move];
    [[headerContainer animator] setAlphaValue:move];
    [[headerGradientView animator] setAlphaValue:move];
}

- (BOOL)splitView:(NSSplitView *)splitView shouldHideDividerAtIndex:(NSInteger)dividerIndex
{
    return YES;
}

-(void) screenShare {
    NSScreen *mainScreen = [NSScreen mainScreen];
    NSRect screenFrame = mainScreen.frame;
    QRect captureRect = QRect(screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height);
    mediaModel->setDisplay(0, screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height);
}
-(void) switchToDevice:(int)deviceID {
    auto devices = mediaModel->getDevices();
    auto device = devices[deviceID];
    mediaModel->switchInputTo(device);
}

-(QVector<QString>) getDeviceList {
    QVector<QString> devicesVector;
    for (auto device : mediaModel->getDevices()) {
        try {
            auto settings = mediaModel->getDeviceSettings(device);
            devicesVector.append(settings.name);
        } catch (...) {}
    }
    return devicesVector;
}

-(NSString*) getDefaultDeviceName {
    auto type = mediaModel->getCurrentRenderedDevice(callUid_).type;
    switch (type) {
        case lrc::api::video::DeviceType::CAMERA:
            try {
                auto device = mediaModel->getCurrentRenderedDevice(callUid_).name;
                auto settings = mediaModel->getDeviceSettings(device);
                return settings.name.toNSString();
            } catch (...) {}
        case lrc::api::video::DeviceType::DISPLAY:
            return NSLocalizedString(@"Share screen", @"Contextual menu entry");
        default:
            return @"";
    }
}

-(void) switchToFile:(QString)uri {
    mediaModel->setInputFile(uri);
}

-(CGRect) getVideoPreviewCollapsedSize {
    CGPoint origin;
    switch (movableBaseForView.closestCorner) {
        case TOP_LEFT:
            origin = CGPointMake(0, movableBaseForView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE);
            break;
        case BOTTOM_LEFT:
            origin = CGPointMake(0, 0);
            break;
        case TOP_RIGHT:
            origin = CGPointMake(movableBaseForView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE, movableBaseForView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE);
            break;
        case BOTTOM_RIGHT:
            origin = CGPointMake(movableBaseForView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE, 0);
            break;
    }
    return CGRectMake(origin.x, origin.y, HIDE_PREVIEW_BUTTON_SIZE, HIDE_PREVIEW_BUTTON_SIZE);
}

-(CGRect) frameForExpendPreviewButton {
    CGPoint origin = CGPointMake(self.previewView.frame.size.width - HIDE_PREVIEW_BUTTON_SIZE,
                                 self.previewView.frame.size.height - HIDE_PREVIEW_BUTTON_SIZE);
    return CGRectMake(origin.x, origin.y, HIDE_PREVIEW_BUTTON_SIZE, HIDE_PREVIEW_BUTTON_SIZE);
}

# pragma mark -ChooseContactVCDelegate

-(void)callToContact:(const QString&)contactUri convUID:(const QString&)convID {
    if (brokerPopoverVC != nullptr) {
        [brokerPopoverVC performClose:self];
        brokerPopoverVC = NULL;
    }
    auto* callModel = accountInfo_->callModel.get();
    auto currentCall = callModel->getCall([self getcallID]);
    auto* convModel = accountInfo_->conversationModel.get();
    auto newCall = callModel->callAndAddParticipant(contactUri,
                                                    [self getcallID],
                                                    currentCall.isAudioOnly);
    [self addPreviewForContactUri:contactUri call: newCall];
}

-(void)joinCall:(const QString&)callId {
    if (brokerPopoverVC != nullptr) {
        [brokerPopoverVC performClose:self];
        brokerPopoverVC = NULL;
    }
    auto* callModel = accountInfo_->callModel.get();
    callModel->joinCalls([self getcallID], callId);
}

# pragma mark -CallInConferenceVCDelegate

-(void)removePreviewForContactUri:(const QString&)uri forCall:(const QString&) callId {
    NSMutableDictionary * calls = connectingCalls[callId.toNSString()];
    if (!calls) {
        return;
    }
    NSViewController *callView = calls[uri.toNSString()];
    if (!callView) {
        return;
    }
    calls[uri.toNSString()] = nil;
    [self.callingWidgetsContainer removeView:callView.view];
}

-(void)addPreviewForContactUri:(const QString&)uri call:(const QString&)callId {
    NSMutableDictionary *calls = connectingCalls[callUid_.toNSString()];
    if (!calls) {
        calls = [[NSMutableDictionary alloc] init];
    }
    if (calls[uri.toNSString()]) {
        return;
    }
    CallInConferenceVC *callingView = [self callingViewForCallId: callId];
    calls[uri.toNSString()] = callingView;
    connectingCalls[callUid_.toNSString()] = calls;
    [self.callingWidgetsContainer addView:callingView.view inGravity:NSStackViewGravityBottom];
    [self.callingWidgetsContainer updateConstraints];
    [self.callingWidgetsContainer updateLayer];
    [self.callingWidgetsContainer setNeedsDisplay:YES];
}

-(CallInConferenceVC*) callingViewForCallId:(const QString&)callId {
    CallInConferenceVC *callView = [[CallInConferenceVC alloc]
                                    initWithNibName:@"CallInConferenceVC"
                                    bundle:nil
                                    callId:callId
                                    accountInfo:accountInfo_];
    callView.delegate = self;
    callView.initiatorCallId = callUid_;
    return callView;
}

-(const QString&)getcallID {
    return confUid_.isEmpty() ? callUid_ : confUid_;
}

-(bool)isCurrentCall:(const QString&)callId {
    return (callId == confUid_ || callId == callUid_);
}

#pragma mark ConferenceLayoutDelegate

-(void)hangUpParticipant:(NSString*)uri {
    if (accountInfo_ == nil)
        return;
    auto* callModel = accountInfo_->callModel.get();

    auto convIt = getConversationFromURI(QString::fromNSString(uri), *accountInfo_->conversationModel);
    auto callId = convIt->callId;
    if (not callModel->hasCall(callId)){
        return;
    }
    callModel->hangUp(callId);
}

-(void)minimizeParticipant {
    if (accountInfo_ == nil)
        return;
    auto* callModel = accountInfo_->callModel.get();
    auto confId = [self getcallID];
    if (not callModel->hasCall(confId)) {
        return;
    }
    try {
        auto call = callModel->getCall(confId);
        switch (call.layout) {
            case lrc::api::call::Layout::GRID:
                break;
            case lrc::api::call::Layout::ONE_WITH_SMALL:
                callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
                break;
            case lrc::api::call::Layout::ONE:
                callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
                break;
        };
    } catch (...) {}
}

-(int)getCurrentLayout {
    auto* callModel = accountInfo_->callModel.get();
    auto confId = [self getcallID];
    if (not callModel->hasCall(confId)){
        return -1;
    }
    return static_cast<int>(callModel->getCall(confId).layout);
}

-(BOOL)isMasterCall {
    auto conv = accountInfo_->conversationModel->getConversationForUID(convUid_);
    if (conv.uid.isEmpty()) {
        return false;
    }
    auto* callModel = accountInfo_->callModel.get();
    try {
        auto call = callModel->getCall(conv.callId);
        if (call.participantsInfos.size() == 0) {
            return true;
        }
        return !conv.confId.isEmpty() && callModel->hasCall(conv.confId);
    } catch (...) {}
    return true;
}

-(BOOL)isCallModerator {
    if (accountInfo_ == nil)
        return false;
    auto* callModel = accountInfo_->callModel.get();
    return callModel->isModerator([self getcallID]);
}


-(void)maximizeParticipant:(NSString*)uri active:(BOOL)isActive {
    if (accountInfo_ == nil)
        return;
    BOOL localVideo = accountInfo_->profileInfo.uri == QString::fromNSString(uri);
    auto* callModel = accountInfo_->callModel.get();
    auto confId = [self getcallID];
    if (not callModel->hasCall(confId) && !localVideo)
        return;
    try {
        auto call = callModel->getCall(confId);
        switch (call.layout) {
            case lrc::api::call::Layout::GRID:
                callModel->setActiveParticipant(confId, QString::fromNSString(uri));
                callModel->setConferenceLayout(confId, lrc::api::call::Layout::ONE_WITH_SMALL);
                break;
            case lrc::api::call::Layout::ONE_WITH_SMALL:
                callModel->setActiveParticipant(confId, QString::fromNSString(uri));
                callModel->setConferenceLayout(confId,
                                               isActive ? lrc::api::call::Layout::ONE : lrc::api::call::Layout::ONE_WITH_SMALL);
                break;
            case lrc::api::call::Layout::ONE:
                callModel->setActiveParticipant(confId, QString::fromNSString(uri));
                callModel->setConferenceLayout(confId, lrc::api::call::Layout::GRID);
                break;
        };
    } catch (...) {}
}

#pragma mark Popover delegate

- (void)popoverWillClose:(NSNotification *)notification
{
    if (brokerPopoverVC != nullptr) {
        [brokerPopoverVC performClose:self];
        brokerPopoverVC = NULL;
    }
}
@end
