/*
 *   This file is part of Dianara
 *   Copyright 2012-2019  JanKusanagi JRR <jancoding@gmx.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 2 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 "peoplewidget.h"

PeopleWidget::PeopleWidget(QString buttonText,
                           int type,
                           PumpController *pumpController,
                           QWidget *parent) : QWidget(parent)
{
    m_pumpController = pumpController;
    connect(m_pumpController, &PumpController::contactListReceived,
            this, &PeopleWidget::updateAllContactsList);

    connect(m_pumpController, &PumpController::contactFollowed,
            this, &PeopleWidget::addContact);
    connect(m_pumpController, &PumpController::contactUnfollowed,
            this, &PeopleWidget::removeContact);


    this->setMinimumSize(240, 280);

    m_searchLabel = new QLabel(tr("&Search:"), this);

    m_searchLineEdit = new QLineEdit(this);
    m_searchLineEdit->setPlaceholderText(tr("Enter a name here to search for it"));
    m_searchLineEdit->setClearButtonEnabled(true);

    m_searchLabel->setBuddy(m_searchLineEdit);
    connect(m_searchLineEdit, &QLineEdit::textChanged,
            this, &PeopleWidget::filterList);


    m_itemModel = new QStandardItemModel(this);

    m_filterModel = new QSortFilterProxyModel(this);
    m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
    m_filterModel->setSourceModel(m_itemModel);

    m_allContactsListView = new QListView(this);
    m_allContactsListView->setAlternatingRowColors(true);
    m_allContactsListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_allContactsListView->setDragDropMode(QListView::DragDrop);
    m_allContactsListView->setDefaultDropAction(Qt::CopyAction);
    m_allContactsListView->setModel(m_filterModel);
    connect(m_allContactsListView, &QAbstractItemView::activated,
            this, &PeopleWidget::returnClickedContact);


    m_addToButton = new QPushButton(QIcon::fromTheme("list-add",
                                                     QIcon(":/images/list-add.png")),
                                    buttonText,
                                    this);
    connect(m_addToButton, &QAbstractButton::clicked,
            this, &PeopleWidget::returnContact);



    // Layout
    m_buttonsLayout = new QHBoxLayout();
    m_buttonsLayout->addWidget(m_addToButton);
    m_buttonsLayout->addStretch();

    m_mainLayout = new QVBoxLayout();
    m_mainLayout->addWidget(m_searchLabel);
    m_mainLayout->addWidget(m_searchLineEdit);
    m_mainLayout->addSpacing(2);
    m_mainLayout->addWidget(m_allContactsListView);
    m_mainLayout->addSpacing(4);
    m_mainLayout->addLayout(m_buttonsLayout);
    this->setLayout(m_mainLayout);



    if (type == EmbeddedWidget)
    {
        //allContactsListWidget->setSelectionMode(QListView::ExtendedSelection);

        // FIXME 1.4.x: For now, Single selection mode in both cases
        m_allContactsListView->setSelectionMode(QListView::SingleSelection);
    }
    else     // StandaloneWidget
    {
        this->setWindowTitle(tr("Add a contact to a list")
                             + " - Dianara");
        this->setWindowIcon(QIcon::fromTheme("system-users",
                                             QIcon(":/images/button-users.png")));
        this->setWindowFlags(Qt::Dialog);
        this->setWindowModality(Qt::WindowModal);
        this->setMinimumSize(520, 500);

        m_allContactsListView->setSelectionMode(QListView::SingleSelection);

        m_cancelButton = new QPushButton(QIcon::fromTheme("dialog-cancel",
                                                          QIcon(":/images/button-cancel.png")),
                                         tr("&Cancel"),
                                         this);
        connect(m_cancelButton, &QAbstractButton::clicked,
                this, &QWidget::hide);
        m_buttonsLayout->addWidget(m_cancelButton);
    }

    qDebug() << "PeopleWidget created";
}


PeopleWidget::~PeopleWidget()
{
    qDebug() << "PeopleWidget destroyed";
}


void PeopleWidget::resetWidget()
{
    m_allContactsListView->scrollToTop();

    m_searchLineEdit->clear(); // Might also trigger filterLists()
    m_searchLineEdit->setFocus();
}


QStandardItem *PeopleWidget::createContactItem(ASPerson *contact)
{
    QStandardItem *item;

    QString singleContactString = contact->getNameWithFallback()
                                  + "   <" + contact->getId() + ">";

    QString avatarFilename = MiscHelpers::getCachedAvatarFilename(contact->getAvatarUrl());
    QPixmap avatarPixmap = QPixmap(avatarFilename);
    if (!avatarPixmap.isNull())
    {
        item = new QStandardItem(QIcon(avatarPixmap),
                                 singleContactString);
    }
    else
    {
        item = new QStandardItem(QIcon::fromTheme("user-identity",
                                                  QIcon(":/images/no-avatar.png")),
                                 singleContactString);
    }

    item->setToolTip(contact->getTooltipInfo());
    item->setData(contact->getNameWithFallback(), Qt::UserRole + 1);
    item->setData(contact->getId(),               Qt::UserRole + 2);
    item->setData(contact->getUrl(),              Qt::UserRole + 3);

    return item;
}



//////////////////////////////////////////////////////////////////////////////
///////////////////////////////// SLOTS //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////


/*
 * Filter the list of all contacts based on what
 * the user entered in the search box
 *
 */
void PeopleWidget::filterList(QString searchTerms)
{
    m_filterModel->setFilterFixedString(searchTerms);
    m_filterModel->sort(0);
}


/*
 * Update the list of all contacts (actually, 'following')
 * from the PumpController
 *
 */
void PeopleWidget::updateAllContactsList(QString listType,
                                         QVariantList contactsVariantList,
                                         int totalReceivedCount)
{
    if (listType != "following")
    {
        return;
    }
    qDebug() << "PeopleWidget: received list of Following; updating...";

    if (totalReceivedCount <= 200)  // Only on first batch
    {
        m_itemModel->clear();
    }

    foreach (const QVariant contactVariant, contactsVariantList)
    {
        ASPerson *contact = new ASPerson(contactVariant.toMap(), this);
        QStandardItem *item = this->createContactItem(contact);
        m_itemModel->appendRow(item);

        delete contact;
    }

    m_filterModel->sort(0); // Sort by first column
}



void PeopleWidget::addContact(ASPerson *contact)
{
    m_itemModel->appendRow(this->createContactItem(contact));

    contact->deleteLater();
}


void PeopleWidget::removeContact(ASPerson *contact)
{
    foreach (QStandardItem *item, m_itemModel->findItems("<" + contact->getId() + ">",
                                                         Qt::MatchEndsWith))
    {
        m_itemModel->removeRow(item->row());
    }

    contact->deleteLater();
}



/*
 * Send current contact icon and string in a SIGNAL
 *
 * Used when selecting a row and clicking the "add" button
 *
 */
void PeopleWidget::returnContact()
{
    if (m_allContactsListView->currentIndex().row() != -1)
    {
        QStandardItem *item = m_itemModel->itemFromIndex(m_filterModel->mapToSource(m_allContactsListView->currentIndex()));

        if (item != 0)
        {
            emit addButtonPressed(item->icon(),
                                  item->text(),
                                  item->data(Qt::UserRole + 1).toString(),
                                  item->data(Qt::UserRole + 2).toString(),
                                  item->data(Qt::UserRole + 3).toString());
        }
    }
}


/*
 * Used when clicking a contact
 *
 */
void PeopleWidget::returnClickedContact(QModelIndex modelIndex)
{
    QStandardItem *item = m_itemModel->itemFromIndex(m_filterModel->mapToSource(modelIndex));

    QIcon icon;
    if (item != 0) // Valid item
    {
        icon = item->icon();
    }

    emit contactSelected(icon,
                         modelIndex.data().toString(),
                         modelIndex.data(Qt::UserRole + 1).toString(),
                         modelIndex.data(Qt::UserRole + 2).toString(),
                         modelIndex.data(Qt::UserRole + 3).toString());
}
