/*
 * Squawk messenger.
 * Copyright (C) 2019  Yury Gubich <blue@macaw.me>
 *
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include "info.h"
#include "ui_info.h"

UI::Info::Info(const QString& p_jid, QWidget* parent):
    QWidget(parent),
    jid(p_jid),
    type(Shared::EntryType::none),
    m_ui(new Ui::Info()),
    contactGeneral(nullptr),
    contactContacts(nullptr),
#ifdef WITH_OMEMO
    omemo(nullptr),
#endif
    description(nullptr),
    overlay(new QWidget()),
    progress(new Progress(100)),
    progressLabel(new QLabel())
{
    m_ui->setupUi(this);
    m_ui->buttonBox->hide();
    m_ui->title->setText(tr("%1 info").arg(p_jid));
    m_ui->receivingTimeLabel->hide();

    initializeOverlay();
    initializeButtonBox();
}

UI::Info::~Info() {
    clear();
    overlay->deleteLater();
}

void UI::Info::setData(const Shared::Info& info) {
    bool editable = false;
    switch (info.getType()) {
        case Shared::EntryType::ownAccount:
            editable = true;
            [[fallthrough]];
        case Shared::EntryType::contact: {
            const Shared::VCard card = info.getVCardRef();
            QDateTime receivingTime = card.getReceivingTime();
            m_ui->receivingTimeLabel->show();
            m_ui->receivingTimeLabel->setText(tr("Received %1 at %2").arg(receivingTime.date().toString()).arg(receivingTime.time().toString()));
            initializeContactGeneral(jid, card, editable);
            initializeContactContacts(jid, card, editable);
            initializeDescription(card.getDescription(), editable);
#ifdef WITH_OMEMO
            initializeOmemo(info.getActiveKeysRef());
#endif
            type = info.getType();
        }
            break;
        default:
            clear();
            break;
    }

    if (!editable)
        m_ui->buttonBox->hide();
    else
        m_ui->buttonBox->show();

}

void UI::Info::initializeOverlay() {
    QGridLayout* gr = static_cast<QGridLayout*>(layout());
    gr->addWidget(overlay, 0, 0, 4, 1);
    QVBoxLayout* nl = new QVBoxLayout();
    QGraphicsOpacityEffect* opacity = new QGraphicsOpacityEffect();
    opacity->setOpacity(0.8);
    overlay->setLayout(nl);
    overlay->setBackgroundRole(QPalette::Base);
    overlay->setAutoFillBackground(true);
    overlay->setGraphicsEffect(opacity);
    progressLabel->setAlignment(Qt::AlignCenter);
    progressLabel->setFont(Shared::Global::getInstance()->titleFont);
    progressLabel->setWordWrap(true);
    nl->addStretch();
    nl->addWidget(progress);
    nl->addWidget(progressLabel);
    nl->addStretch();
    overlay->hide();
}

void UI::Info::initializeButtonBox() {
    connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &UI::Info::onButtonBoxAccepted);
    connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &UI::Info::close);

    m_ui->buttonBox->hide();
}

void UI::Info::onButtonBoxAccepted() {
    if (type == Shared::EntryType::ownAccount) {
        Shared::Info info(jid, Shared::EntryType::ownAccount);
        Shared::VCard& card = info.getVCardRef();
        contactGeneral->fillVCard(card);
        contactContacts->fillVCard(card);
        card.setDescription(description->description());
#ifdef WITH_OMEMO
        omemo->fillData(info.getActiveKeysRef());
#endif
        emit saveInfo(info);
        emit close();
    }
}

void UI::Info::showProgress(const QString& line) {
    if (line.size() > 0)
        progressLabel->setText(line);
    else
        progressLabel->setText(tr("Requesting information about %1").arg(jid));

    overlay->show();
    progress->start();
}

void UI::Info::hideProgress() {
    overlay->hide();
    progress->stop();
}

void UI::Info::initializeContactGeneral(const QString& jid, const Shared::VCard& card, bool editable) {
    if (contactGeneral == nullptr) {
        contactGeneral = new ContactGeneral;
        m_ui->tabWidget->addTab(contactGeneral, contactGeneral->title());
    }
    contactGeneral->setVCard(jid, card, editable);
}

void UI::Info::initializeContactContacts(const QString& jid, const Shared::VCard& card, bool editable) {
    if (contactContacts == nullptr) {
        contactContacts = new ContactContacts;
        m_ui->tabWidget->addTab(contactContacts, contactContacts->title());
    }
    contactContacts->setVCard(jid, card, editable);
}

void UI::Info::initializeDescription(const QString& descr, bool editable) {
    if (description == nullptr) {
        description = new Description;
        m_ui->tabWidget->addTab(description, description->title());
    }

    description->setDescription(descr);
    description->setEditable(editable);
}

QString UI::Info::getJid() const {
    return jid;
}

void UI::Info::clear() {
    if (contactGeneral != nullptr) {
        contactGeneral->deleteLater();
        contactGeneral = nullptr;
    }

    if (contactContacts != nullptr) {
        contactContacts->deleteLater();
        contactContacts = nullptr;
    }

    if (description != nullptr) {
        description->deleteLater();
        description = nullptr;
    }

#ifdef WITH_OMEMO
    if (omemo != nullptr) {
        omemo->deleteLater();
        omemo = nullptr;
    }
#endif

    type = Shared::EntryType::none;
}

#ifdef WITH_OMEMO
void UI::Info::initializeOmemo(const std::list<Shared::KeyInfo>& keys) {
    if (omemo == nullptr) {
        omemo = new Omemo();
        m_ui->tabWidget->addTab(omemo, omemo->title());
    }
    omemo->setData(keys);
}

#endif