/*
 *   This file is part of Dianara
 *   Copyright 2012-2016  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)
{
    this->setMinimumSize(120, 120);

    this->pController = pumpController;
    connect(pController, SIGNAL(contactListReceived(QString,QVariantList,int)),
            this, SLOT(updateAllContactsList(QString,QVariantList,int)));

    connect(pController, SIGNAL(contactFollowed(ASPerson*)),
            this, SLOT(addContact(ASPerson*)));
    connect(pController, SIGNAL(contactUnfollowed(ASPerson*)),
            this, SLOT(removeContact(ASPerson*)));


    this->searchLabel = new QLabel(tr("&Search:"));

    this->searchLineEdit = new QLineEdit();
    searchLineEdit->setPlaceholderText(tr("Enter a name here to search for it"));
    searchLabel->setBuddy(searchLineEdit);
    connect(searchLineEdit, SIGNAL(textChanged(QString)),
            this, SLOT(filterList(QString)));


    itemModel = new QStandardItemModel(this);

    filterModel = new QSortFilterProxyModel(this);
    filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
    filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
    filterModel->setSourceModel(itemModel);

    allContactsListView = new QListView();
    allContactsListView->setAlternatingRowColors(true);
    allContactsListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    allContactsListView->setDragDropMode(QListView::DragDrop);
    allContactsListView->setDefaultDropAction(Qt::CopyAction);
    allContactsListView->setModel(filterModel);
    connect(allContactsListView, SIGNAL(activated(QModelIndex)),
            this, SLOT(returnClickedContact(QModelIndex)));


    addToButton = new QPushButton(QIcon::fromTheme("list-add",
                                                   QIcon(":/images/list-add.png")),
                                  buttonText);
    connect(addToButton, SIGNAL(clicked()),
            this, SLOT(returnContact()));



    // Layout
    mainLayout = new QVBoxLayout();
    mainLayout->addWidget(searchLabel);
    mainLayout->addWidget(searchLineEdit);
    mainLayout->addSpacing(2);
    mainLayout->addWidget(allContactsListView);
    mainLayout->addSpacing(4);
    mainLayout->addWidget(addToButton);
    this->setLayout(mainLayout);



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

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

        allContactsListView->setSelectionMode(QListView::SingleSelection);

        cancelButton = new QPushButton(QIcon::fromTheme("dialog-cancel",
                                                        QIcon(":/images/button-cancel.png")),
                                       tr("&Cancel"));
        connect(cancelButton, SIGNAL(clicked()),
                this, SLOT(hide()));
        mainLayout->addWidget(cancelButton);
    }


    qDebug() << "PeopleWidget created";
}


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


void PeopleWidget::resetWidget()
{
    this->allContactsListView->scrollToTop();

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


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

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

    QString avatarFilename = MiscHelpers::getCachedAvatarFilename(contact->getAvatar());
    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->getUrl(), Qt::UserRole + 1);

    return item;
}



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


/*
 * Filter the list of all contacts based on what
 * the user entered in the search box
 *
 */
void PeopleWidget::filterList(QString searchTerms)
{
    this->filterModel->setFilterFixedString(searchTerms);
    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
    {
        this->itemModel->clear();
    }

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

        delete contact;
    }

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



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

    contact->deleteLater();
}


void PeopleWidget::removeContact(ASPerson *contact)
{
    foreach (QStandardItem *item, itemModel->findItems("<" + contact->getId() + ">",
                                                       Qt::MatchEndsWith))
    {
        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 (this->allContactsListView->currentIndex().row() != -1)
    {
        QStandardItem *item = itemModel->itemFromIndex(filterModel->mapToSource(allContactsListView->currentIndex()));

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

        emit addButtonPressed(icon,
                              allContactsListView->currentIndex().data().toString(), // name <id>
                              allContactsListView->currentIndex().data(Qt::UserRole + 1).toString()); // URL
    }
}


/*
 * Used when clicking a contact
 *
 */
void PeopleWidget::returnClickedContact(QModelIndex modelIndex)
{
    QStandardItem *item = itemModel->itemFromIndex(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());
}
