/*
 *  Copyright (C) 2016-2017 Savoir-faire Linux Inc.
 *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
 *  Author: Alexandre Viau <alexandre.viau@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.
 */

#include "chatview.h"
#include "utils/accounts.h"

#include <gtk/gtk.h>
#include <call.h>
#include <callmodel.h>
#include <contactmethod.h>
#include <person.h>
#include <media/text.h>
#include <media/textrecording.h>
#include "ringnotify.h"
#include "profilemodel.h"
#include "profile.h"
#include "numbercategory.h"
#include <QtCore/QDateTime>
#include "utils/calling.h"
#include "utils/files.h"
#include "webkitchatcontainer.h"

// LRC
#include <account.h>


static constexpr GdkRGBA RING_BLUE  = {0.0508, 0.594, 0.676, 1.0}; // outgoing msg color: (13, 152, 173)

struct _ChatView
{
    GtkBox parent;
};

struct _ChatViewClass
{
    GtkBoxClass parent_class;
};

typedef struct _ChatViewPrivate ChatViewPrivate;

struct _ChatViewPrivate
{
    GtkWidget *box_webkit_chat_container;
    GtkWidget *webkit_chat_container;
    GtkWidget *scrolledwindow_chat;
    GtkWidget *hbox_chat_info;
    GtkWidget *label_peer;
    GtkWidget *combobox_cm;
    GtkWidget *label_cm;
    GtkWidget *button_close_chatview;
    GtkWidget *button_placecall;
    GtkWidget *button_send_invitation;

    GSettings *settings;

    /* only one of the three following pointers should be non void;
     * either this is an in-call chat (and so the in-call chat APIs will be used)
     * or it is an out of call chat (and so the account chat APIs will be used) */
    Call          *call;
    Person        *person;
    ContactMethod *cm;

    QMetaObject::Connection new_message_connection;
    QMetaObject::Connection message_changed_connection;
    QMetaObject::Connection update_name;
    QMetaObject::Connection update_send_invitation;

    gulong webkit_ready;
    gulong webkit_send_text;
};

G_DEFINE_TYPE_WITH_PRIVATE(ChatView, chat_view, GTK_TYPE_BOX);

#define CHAT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAT_VIEW_TYPE, ChatViewPrivate))

enum {
    NEW_MESSAGES_DISPLAYED,
    HIDE_VIEW_CLICKED,
    LAST_SIGNAL
};

static guint chat_view_signals[LAST_SIGNAL] = { 0 };

static void
chat_view_dispose(GObject *object)
{
    ChatView *view;
    ChatViewPrivate *priv;

    view = CHAT_VIEW(object);
    priv = CHAT_VIEW_GET_PRIVATE(view);

    QObject::disconnect(priv->new_message_connection);
    QObject::disconnect(priv->message_changed_connection);
    QObject::disconnect(priv->update_name);
    QObject::disconnect(priv->update_send_invitation);

    /* Destroying the box will also destroy its children, and we wouldn't
     * want that. So we remove the webkit_chat_container from the box. */
    if (priv->webkit_chat_container) {
        /* disconnect for webkit signals */
        g_signal_handler_disconnect(priv->webkit_chat_container, priv->webkit_ready);
        priv->webkit_ready = 0;
        g_signal_handler_disconnect(priv->webkit_chat_container, priv->webkit_send_text);
        priv->webkit_send_text = 0;

        gtk_container_remove(
            GTK_CONTAINER(priv->box_webkit_chat_container),
            GTK_WIDGET(priv->webkit_chat_container)
        );
        priv->webkit_chat_container = nullptr;

    }

    G_OBJECT_CLASS(chat_view_parent_class)->dispose(object);
}

static void
hide_chat_view(G_GNUC_UNUSED GtkWidget *widget, ChatView *self)
{
    g_signal_emit(G_OBJECT(self), chat_view_signals[HIDE_VIEW_CLICKED], 0);
}

ContactMethod*
get_active_contactmethod(ChatView *self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    if (priv->cm) {
        return priv->cm;
    } else if (priv->person) {
        auto cms = priv->person->phoneNumbers();
        if (cms.size() == 1) {
            return cms.first();
        } else if (cms.size() > 1) {
            auto active = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->combobox_cm));
            if (active >= 0 && active < cms.size()) {
                return cms.at(active);
            }
        }
    }

    return nullptr;
}

static void
display_links_toggled(ChatView *self)
{
    auto priv = CHAT_VIEW_GET_PRIVATE(self);
    if (priv->webkit_chat_container) {
        webkit_chat_container_set_display_links(
            WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
            g_settings_get_boolean(priv->settings, "enable-display-links")
        );
    }
}

static void
placecall_clicked(ChatView *self)
{
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    if (priv->person) {
        // get the chosen cm
        auto cm = get_active_contactmethod(self);
        if (cm) {
            place_new_call(cm);
        } else {
            g_warning("no ContactMethod chosen; cannot place call");
        }
    } else if (priv->cm) {
        place_new_call(priv->cm);
    } else {
        g_warning("no Person or ContactMethod set; cannot place call");
    }
}

static void
button_send_invitation_clicked(ChatView *self)
{
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    if (priv->person) {
        priv->cm = get_active_contactmethod(self);
    }

    if (!priv->cm) {
        g_warning("invalid contact, cannot send invitation!");
        return;
    }

    // try first to use the account associated to the contact method
    auto account = priv->cm->account();
    if (not account) {

        // get the choosen account
        account = get_active_ring_account();

        if (not account) {
            g_warning("invalid account, cannot send invitation!");
            return;
        }
    }

    // perform the request
    if (not account->sendContactRequest(priv->cm))
        g_warning("contact request not forwarded, cannot send invitation!");

    // TODO : add an entry in the conversation to tell the user an invitation was sent.
}

static void
webkit_chat_container_send_text(G_GNUC_UNUSED GtkWidget* webview, gchar *message, ChatView* self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    /* make sure there is more than just whitespace, but if so, send the original text */
    auto text = QString(message);
    // NOTE for now, because we only have a send text action from the webkit.
    if (text.startsWith("SEND:"))
        text.remove(0, 5);
    if (!text.trimmed().isEmpty()) {
        QMap<QString, QString> messages;
        messages["text/plain"] = text;

        if (priv->call) {
            // in call message
            priv->call->addOutgoingMedia<Media::Text>()->send(messages);
        } else if (priv->person) {
            // get the chosen cm
            auto cm = get_active_contactmethod(self);
            if (cm) {
                if (!cm->sendOfflineTextMessage(messages))
                    g_warning("message failed to send"); // TODO: warn the user about this in the UI
            } else {
                g_warning("no ContactMethod chosen; message not sent");
            }
        } else if (priv->cm) {
            if (!priv->cm->sendOfflineTextMessage(messages))
                g_warning("message failed to send"); // TODO: warn the user about this in the UI
        } else {
            g_warning("no Call, Person, or ContactMethod set; message not sent");
        }
    }
}

static void
chat_view_init(ChatView *view)
{
    gtk_widget_init_template(GTK_WIDGET(view));

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(view);
    priv->settings = g_settings_new_full(get_ring_schema(), NULL, NULL);

    g_signal_connect(priv->button_close_chatview, "clicked", G_CALLBACK(hide_chat_view), view);
    g_signal_connect_swapped(priv->button_placecall, "clicked", G_CALLBACK(placecall_clicked), view);
    g_signal_connect_swapped(priv->button_send_invitation, "clicked", G_CALLBACK(button_send_invitation_clicked), view);
}

static void
chat_view_class_init(ChatViewClass *klass)
{
    G_OBJECT_CLASS(klass)->dispose = chat_view_dispose;

    gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass),
                                                "/cx/ring/RingGnome/chatview.ui");

    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, box_webkit_chat_container);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, scrolledwindow_chat);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, hbox_chat_info);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, label_peer);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, label_cm);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, combobox_cm);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_close_chatview);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_placecall);
    gtk_widget_class_bind_template_child_private(GTK_WIDGET_CLASS (klass), ChatView, button_send_invitation);

    chat_view_signals[NEW_MESSAGES_DISPLAYED] = g_signal_new (
        "new-messages-displayed",
        G_TYPE_FROM_CLASS(klass),
        (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
        0,
        nullptr,
        nullptr,
        g_cclosure_marshal_VOID__VOID,
        G_TYPE_NONE, 0);

    chat_view_signals[HIDE_VIEW_CLICKED] = g_signal_new (
        "hide-view-clicked",
        G_TYPE_FROM_CLASS(klass),
        (GSignalFlags) (G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION),
        0,
        nullptr,
        nullptr,
        g_cclosure_marshal_VOID__VOID,
        G_TYPE_NONE, 0);
}



static void
print_message_to_buffer(ChatView* self, const QModelIndex &idx)
{
    if (!idx.isValid()) {
        g_warning("QModelIndex in im model is not valid");
        return;
    }

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    webkit_chat_container_print_new_message(
        WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
        idx
    );
}

static void
set_participant_images(ChatView* self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    webkit_chat_container_clear_sender_images(
        WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container)
    );

    /* Set the sender image for the peer */
    ContactMethod* sender_contact_method_peer;
    QVariant photo_variant_peer;

    if (priv->person)
    {
        photo_variant_peer = priv->person->photo();
        sender_contact_method_peer = get_active_contactmethod(self);
    }
    else
    {
        if (priv->cm)
        {
            sender_contact_method_peer = priv->cm;
        }
        else
        {
            sender_contact_method_peer = priv->call->peerContactMethod();
        }
        photo_variant_peer = sender_contact_method_peer->roleData((int) Call::Role::Photo);
    }

    if (photo_variant_peer.isValid())
    {
        webkit_chat_container_set_sender_image(
            WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
            sender_contact_method_peer,
            photo_variant_peer
        );
    }

    /* set sender image for "ME" */
    auto profile = ProfileModel::instance().selectedProfile();
    if (profile)
    {
        auto person = profile->person();
        if (person)
        {
            auto photo_variant_me = person->photo();
            if (photo_variant_me.isValid())
            {
                webkit_chat_container_set_sender_image(
                    WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
                    nullptr,
                    photo_variant_me
                );
            }
        }
    }
}

static void
print_text_recording(Media::TextRecording *recording, ChatView *self)
{
    g_return_if_fail(IS_CHAT_VIEW(self));
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

     /* set the photos of the chat participants */
     set_participant_images(self);

    /* only text messages are supported for now */
    auto model = recording->instantTextMessagingModel();

    /* new model, disconnect from the old model updates and clear the text buffer */
    QObject::disconnect(priv->new_message_connection);

    /* put all the messages in the im model into the text view */
    for (int row = 0; row < model->rowCount(); ++row) {
        QModelIndex idx = model->index(row, 0);
        print_message_to_buffer(self, idx);
    }
    /* mark all messages as read */
    recording->setAllRead();


    /* messages modified */
    /* connecting on instantMessagingModel and not textMessagingModel */
    priv->message_changed_connection = QObject::connect(
        model,
        &QAbstractItemModel::dataChanged,
        [self, priv] (const QModelIndex & topLeft, G_GNUC_UNUSED const QModelIndex & bottomRight)
        {
            webkit_chat_container_update_message(
                WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
                topLeft
            );
        }
    );

    /* append new messages */
    priv->new_message_connection = QObject::connect(
        model,
        &QAbstractItemModel::rowsInserted,
        [self, priv, model] (const QModelIndex &parent, int first, int last) {
            for (int row = first; row <= last; ++row) {
                QModelIndex idx = model->index(row, 0, parent);
                print_message_to_buffer(self, idx);
                /* make sure these messages are marked as read */
                model->setData(idx, true, static_cast<int>(Media::TextRecording::Role::IsRead));
                g_signal_emit(G_OBJECT(self), chat_view_signals[NEW_MESSAGES_DISPLAYED], 0);
            }
        }
    );
}

static void
update_send_invitation(ChatView *self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    auto cm = get_active_contactmethod(self);

    if (cm && cm->isConfirmed()) {
        gtk_widget_hide(priv->button_send_invitation);
    }
}

static void
selected_cm_changed(ChatView *self)
{
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    /* make sure the webkit view is ready, in case we get this signal before it is */
    if (!webkit_chat_container_is_ready(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container)))
        return;

    auto cm = get_active_contactmethod(self);
    if (cm){
        print_text_recording(cm->textRecording(), self);

        QObject::disconnect(priv->update_send_invitation);
        priv->update_send_invitation = QObject::connect(
            get_active_contactmethod(self),
            &ContactMethod::changed,
            [self] () { update_send_invitation(self); }
        );
    } else {
        g_warning("no valid ContactMethod selected to display chat conversation");
    }
}

static void
render_contact_method(G_GNUC_UNUSED GtkCellLayout *cell_layout,
                     GtkCellRenderer *cell,
                     GtkTreeModel *model,
                     GtkTreeIter *iter,
                     G_GNUC_UNUSED gpointer data)
{
    GValue value = G_VALUE_INIT;
    gtk_tree_model_get_value(model, iter, 0, &value);
    auto cm = (ContactMethod *)g_value_get_pointer(&value);

    gchar *number = nullptr;
    if (cm && cm->category()) {
        // try to get the number category, eg: "home"
        number = g_strdup_printf("(%s) %s", cm->category()->name().toUtf8().constData(),
                                            cm->bestId().toUtf8().constData());
    } else if (cm) {
        number = g_strdup_printf("%s", cm->bestId().toUtf8().constData());
    }

    g_object_set(G_OBJECT(cell), "text", number, NULL);
    g_free(number);
}

static void
update_contact_methods(ChatView *self)
{
    g_return_if_fail(IS_CHAT_VIEW(self));
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    g_return_if_fail(priv->call || priv->person || priv->cm);

    /* model for the combobox for the choice of ContactMethods */
    auto cm_model = gtk_list_store_new(
        1, G_TYPE_POINTER
    );

    Person::ContactMethods cms;

    if (priv->person)
        cms = priv->person->phoneNumbers();
    else if (priv->cm)
        cms << priv->cm;
    else if (priv->call)
        cms << priv->call->peerContactMethod();

    for (int i = 0; i < cms.size(); ++i) {
        GtkTreeIter iter;
        gtk_list_store_append(cm_model, &iter);
        gtk_list_store_set(cm_model, &iter,
                           0, cms.at(i),
                           -1);
    }

    gtk_combo_box_set_model(GTK_COMBO_BOX(priv->combobox_cm), GTK_TREE_MODEL(cm_model));
    g_object_unref(cm_model);

    auto renderer = gtk_cell_renderer_text_new();
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(priv->combobox_cm), renderer, FALSE);
    gtk_cell_layout_set_cell_data_func(
        GTK_CELL_LAYOUT(priv->combobox_cm),
        renderer,
        (GtkCellLayoutDataFunc)render_contact_method,
        nullptr, nullptr);

    /* select the last used cm */
    if (!cms.isEmpty()) {
        auto last_used_cm = cms.at(0);
        int last_used_cm_idx = 0;
        for (int i = 1; i < cms.size(); ++i) {
            auto new_cm = cms.at(i);
            if (difftime(new_cm->lastUsed(), last_used_cm->lastUsed()) > 0) {
                last_used_cm = new_cm;
                last_used_cm_idx = i;
            }
        }

        gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combobox_cm), last_used_cm_idx);

        if (last_used_cm->isConfirmed())
            gtk_widget_hide(priv->button_send_invitation);
    }

    /* if there is only one CM, make the combo box insensitive */
    if (cms.size() < 2) {
        auto active = cms.at(gtk_combo_box_get_active(GTK_COMBO_BOX(priv->combobox_cm)));
        std::string ring_id = active->roleData(static_cast<int>(Ring::Role::Number)).toString().toUtf8().constData();
        std::string displayed = gtk_label_get_text(GTK_LABEL(priv->label_peer));
        gtk_label_set_text(GTK_LABEL(priv->label_cm), ring_id.c_str());
        gtk_widget_hide(priv->combobox_cm);
        if (displayed == ring_id) {
            gtk_widget_hide(priv->label_cm);
        } else {
            gtk_widget_show(priv->label_cm);
        }
    } else {
        gtk_widget_show(priv->combobox_cm);
        gtk_widget_hide(priv->label_cm);
    }

    /* if no CMs make the call button insensitive */
    gtk_widget_set_sensitive(priv->button_placecall, !cms.isEmpty());
}

static void
update_name(ChatView *self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    g_return_if_fail(priv->person || priv->cm || priv->call);

    QString name;
    if (priv->person) {
        name = priv->person->roleData(static_cast<int>(Ring::Role::Name)).toString();
    } else if (priv->cm) {
        name = priv->cm->roleData(static_cast<int>(Ring::Role::Name)).toString();
    } else if (priv->call) {
        name = priv->call->peerContactMethod()->roleData(static_cast<int>(Ring::Role::Name)).toString();
    }
    gtk_label_set_text(GTK_LABEL(priv->label_peer), name.toUtf8().constData());
}

static void
webkit_chat_container_ready(ChatView* self)
{
    /* The webkit chat container has loaded the javascript libraries, we can
     * now use it. */

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    webkit_chat_container_clear(
        WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container)
    );

    display_links_toggled(self);

    /* print the text recordings */
    if (priv->call) {
        print_text_recording(priv->call->peerContactMethod()->textRecording(), self);
    } else if (priv->cm) {
        print_text_recording(priv->cm->textRecording(), self);
    } else if (priv->person) {
        /* get the selected cm and print the text recording */
        selected_cm_changed(self);
    }
}

static void
build_chat_view(ChatView* self)
{
    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);

    gtk_container_add(GTK_CONTAINER(priv->box_webkit_chat_container), priv->webkit_chat_container);
    gtk_widget_show(priv->webkit_chat_container);

    /* keep name updated */
    if (priv->call) {
        priv->update_name = QObject::connect(
            priv->call,
            &Call::changed,
            [self] () { update_name(self); }
        );
    } else if (priv->cm) {
        priv->update_name = QObject::connect(
            priv->cm,
            &ContactMethod::changed,
            [self] () { update_name(self); }
        );
    } else if (priv->person) {
        priv->update_name = QObject::connect(
            priv->person,
            &Person::changed,
            [self] () { update_name(self); }
        );
    }

    priv->update_send_invitation = QObject::connect(
        get_active_contactmethod(self),
        &ContactMethod::changed,
        [self] () { update_send_invitation(self); }
    );

    update_name(self);
    update_send_invitation(self);

    /* keep selected cm updated */
    update_contact_methods(self);
    g_signal_connect_swapped(priv->combobox_cm, "changed", G_CALLBACK(selected_cm_changed), self);

    priv->webkit_ready = g_signal_connect_swapped(
        priv->webkit_chat_container,
        "ready",
        G_CALLBACK(webkit_chat_container_ready),
        self
    );

    priv->webkit_send_text = g_signal_connect(priv->webkit_chat_container,
        "send-message",
        G_CALLBACK(webkit_chat_container_send_text),
        self);

    if (webkit_chat_container_is_ready(WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container)))
        webkit_chat_container_ready(self);

    /* we only show the chat info in the case of cm / person */
    gtk_widget_set_visible(priv->hbox_chat_info, (priv->cm || priv->person));
}

GtkWidget *
chat_view_new_call(WebKitChatContainer *webkit_chat_container, Call *call)
{
    g_return_val_if_fail(call, nullptr);

    ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL));

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
    priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container);
    priv->call = call;

    build_chat_view(self);

    return (GtkWidget *)self;
}

GtkWidget *
chat_view_new_cm(WebKitChatContainer *webkit_chat_container, ContactMethod *cm)
{
    g_return_val_if_fail(cm, nullptr);

    ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL));

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
    priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container);
    priv->cm = cm;

    build_chat_view(self);

    return (GtkWidget *)self;
}

GtkWidget *
chat_view_new_person(WebKitChatContainer *webkit_chat_container, Person *p)
{
    g_return_val_if_fail(p, nullptr);

    ChatView *self = CHAT_VIEW(g_object_new(CHAT_VIEW_TYPE, NULL));

    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
    priv->webkit_chat_container = GTK_WIDGET(webkit_chat_container);
    priv->person = p;

    build_chat_view(self);

    return (GtkWidget *)self;
}

Call*
chat_view_get_call(ChatView *self)
{
    g_return_val_if_fail(IS_CHAT_VIEW(self), nullptr);
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    return priv->call;
}

ContactMethod*
chat_view_get_cm(ChatView *self)
{
    g_return_val_if_fail(IS_CHAT_VIEW(self), nullptr);
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    return priv->cm;
}

Person*
chat_view_get_person(ChatView *self)
{
    g_return_val_if_fail(IS_CHAT_VIEW(self), nullptr);
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    return priv->person;
}

void
chat_view_set_header_visible(ChatView *self, gboolean visible)
{
    auto priv = CHAT_VIEW_GET_PRIVATE(self);

    gtk_widget_set_visible(priv->hbox_chat_info, visible);
}
