/*
 *   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 "contactcard.h"

ContactCard::ContactCard(PumpController *pumpController,
                         GlobalObject *globalObject,
                         ASPerson *asPerson,
                         QWidget *parent)  :  QFrame(parent)
{
    this->pController = pumpController;
    this->globalObj = globalObject;
    asPerson->setParent(this); // reparent the person object


    this->setFrameStyle(QFrame::Box | QFrame::Raised);

    this->setSizePolicy(QSizePolicy::Minimum,
                        QSizePolicy::MinimumExpanding);


    // Left widget, user avatar
    avatarLabel = new QLabel(this);

    this->contactAvatarUrl = asPerson->getAvatar();

    // Get local file name, which is stored in base64 hash form
    QString avatarFilename = MiscHelpers::getCachedAvatarFilename(contactAvatarUrl);

    // Load avatar if already cached
    bool validAvatar = this->setAvatar(avatarFilename);
    if (!validAvatar && !contactAvatarUrl.isEmpty())
    {
        connect(pController, SIGNAL(avatarStored(QString,QString)),
                this, SLOT(redrawAvatar(QString,QString)));

        // Download avatar for next time
        pController->enqueueAvatarForDownload(contactAvatarUrl);
    }


    // Center widget, user info
    QFont nameFont;
    nameFont.setBold(true);
    nameFont.setUnderline(true);

    this->contactName = asPerson->getName(); // WithFallback()? FIXME
    this->contactId = asPerson->getId();
    this->contactUrl = asPerson->getUrl();
    this->contactOutbox = asPerson->getOutboxLink();


    QString userInfoString = QString("<b><u>%1</u></b><br>").arg(contactName);
    userInfoString.append(QString("%1<br>").arg(contactId));
    userInfoString.append("<small>"
                          + tr("Hometown")
                          + QString(": %1").arg(asPerson->getHometown())
                          + "</small>");
    QString userCreationDate = asPerson->getCreatedAt();
    if (!userCreationDate.isEmpty())
    {
        userInfoString.append("<br><small>"
                              + tr("Joined: %1")
                                .arg(Timestamp::fuzzyTime(userCreationDate))
                              + "</small>");
    }
    else
    {
        userCreationDate = asPerson->getupdatedAt();
        userInfoString.append("<br><small>"
                              + tr("Updated: %1")
                                .arg(Timestamp::fuzzyTime(userCreationDate))
                              + "</small>");
    }

    userInfoLabel = new QLabel(this);
    userInfoLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    userInfoLabel->setText(userInfoString);
    userInfoLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
    userInfoLabel->setWordWrap(true);
    userInfoLabel->setSizePolicy(QSizePolicy::Ignored,
                                 QSizePolicy::MinimumExpanding);


    // Bio as tooltip for the whole contact card
    QString contactBio = asPerson->getBio().replace("\n", "<br>");
    if (!contactBio.isEmpty())
    {
        this->setToolTip("<b><u>" // Make it rich text, so that it gets wordwrapped
                         + tr("Bio for %1",
                              "Abbreviation for Biography, "
                              "but you can use the full word; "
                              "%1=contact name")
                           .arg(contactName)
                         + "</u></b>"
                         "<br><br>"
                         + contactBio);
    }
    else
    {
        if (contactName.isEmpty())
        {
            this->setToolTip("<b></b>"
                             + tr("This user doesn't have a biography"));
        }
        else
        {
            this->setToolTip("<b></b>"
                             + tr("No biography for %1",
                                  "%1=contact name").arg(contactName));
        }
    }


    // Right column, buttons
    followButton = new QPushButton("*follow*", this);
    followButton->setFlat(true);    
    if (asPerson->isFollowed())
    {
        this->setButtonToUnfollow();
    }
    else
    {
        this->setButtonToFollow();
    }


    openProfileAction = new QAction(QIcon::fromTheme("internet-web-browser",
                                                     QIcon(":/images/button-download.png")),
                                    tr("Open Profile in Web Browser"),
                                    this);
    connect(openProfileAction, SIGNAL(triggered()),
            this, SLOT(openProfileInBrowser()));
    if (this->contactUrl.isEmpty()) // Disable if there is no URL
    {
        openProfileAction->setDisabled(true);
    }

    sendMessageAction = new QAction(QIcon::fromTheme("document-edit",
                                                     QIcon(":/images/button-edit.png")),
                                    tr("Send Message"),
                                    this);
    connect(sendMessageAction, SIGNAL(triggered()),
            this, SLOT(setMessagingModeForContact()));

    browsePostsAction = new QAction(QIcon::fromTheme("edit-find",
                                                     QIcon(":/images/menu-find.png")),
                                    tr("Browse Messages"),
                                    this);
    connect(browsePostsAction, SIGNAL(triggered()),
            this, SLOT(browseContactPosts()));


    addToListMenu = new QMenu(tr("In Lists..."), this);
    addToListMenu->setIcon(QIcon::fromTheme("format-list-unordered"));
    addToListMenu->addAction("fake list 1")->setCheckable(true); // FIXME...
    addToListMenu->addAction("fake list 2")->setCheckable(true);
    addToListMenu->addAction("fake list 3")->setCheckable(true);


    optionsMenu = new QMenu("*options*", this);
    optionsMenu->addAction(openProfileAction);
    optionsMenu->addAction(sendMessageAction);
    optionsMenu->addAction(browsePostsAction);
    browsePostsAction->setEnabled(pController->urlIsInOurHost(this->contactOutbox));
    //optionsMenu->addMenu(addToListMenu); // Don't include it for now, until 1.4 /FIXME


    optionsButton = new QPushButton(QIcon::fromTheme("user-properties",
                                                     QIcon(":/images/no-avatar.png")),
                                    tr("User Options"),
                                    this);
    optionsButton->setFlat(true);
    optionsButton->setMenu(optionsMenu);


    // Layout
    rightLayout = new QVBoxLayout();
    rightLayout->setAlignment(Qt::AlignTop);
    rightLayout->addWidget(followButton);
    rightLayout->addWidget(optionsButton);

    mainLayout = new QHBoxLayout();
    mainLayout->addWidget(avatarLabel,   0, Qt::AlignTop);
    mainLayout->addWidget(userInfoLabel, 1);
    mainLayout->addLayout(rightLayout);
    this->setLayout(mainLayout);

    qDebug() << "ContactCard created" << this->contactId;
}


ContactCard::~ContactCard()
{
    qDebug() << "ContactCard destroyed" << this->contactId;
}



void ContactCard::setButtonToFollow()
{
    followButton->setIcon(QIcon::fromTheme("list-add",
                                           QIcon(":/images/list-add.png")));
    followButton->setText(tr("Follow"));
    connect(followButton, SIGNAL(clicked()),
            this, SLOT(followContact()));
    disconnect(followButton, SIGNAL(clicked()),
               this, SLOT(unfollowContact()));
}


void ContactCard::setButtonToUnfollow()
{
    followButton->setIcon(QIcon::fromTheme("list-remove",
                                           QIcon(":/images/list-remove.png")));
    followButton->setText(tr("Stop Following"));
    connect(followButton, SIGNAL(clicked()),
            this, SLOT(unfollowContact()));
    disconnect(followButton, SIGNAL(clicked()),
               this, SLOT(followContact()));
}


bool ContactCard::setAvatar(QString avatarFilename)
{
    bool validAvatar = false;

    QPixmap avatarPixmap = QPixmap(avatarFilename)
                           .scaledToWidth(64, Qt::SmoothTransformation);
    if (!avatarPixmap.isNull())
    {
        avatarLabel->setPixmap(avatarPixmap);
        validAvatar = true;
    }


    if (!validAvatar)
    {
        // Placeholder image
        avatarLabel->setPixmap(QIcon::fromTheme("user-identity",
                                                QIcon(":/images/no-avatar.png")).pixmap(64, 64));
        qDebug() << "ContactCard: Using placeholder";
    }

    return validAvatar;
}


QString ContactCard::getNameAndIdString()
{
    return QString("%1 <%2>").arg(contactName).arg(contactId);
}

QString ContactCard::getId()
{
    return contactId;
}



/**************************************************************************/
/******************************** SLOTS ***********************************/
/**************************************************************************/



void ContactCard::followContact()
{
    this->pController->followContact(this->contactId);
    this->setButtonToUnfollow(); // FIXME: should wait for proper signal
}


void ContactCard::unfollowContact()
{
    QString nameWithId = ASPerson::makeNameIdString(this->contactName,
                                                    this->contactId);

    int confirmation = QMessageBox::question(this, tr("Stop following?"),
                                             tr("Are you sure you want to "
                                                "stop following %1?")
                                             .arg(nameWithId),
                                             tr("&Yes, stop following"),
                                             tr("&No"),
                                             "", 1, 1);

    if (confirmation == 0)
    {
        this->pController->unfollowContact(this->contactId);
        this->setButtonToFollow(); // FIXME: should wait for proper signal
    }
}


void ContactCard::openProfileInBrowser()
{
    QDesktopServices::openUrl(this->contactUrl);
}

void ContactCard::setMessagingModeForContact()
{
    this->globalObj->createMessageForContact(this->contactId,
                                             this->contactName,
                                             this->contactUrl);
}

void ContactCard::browseContactPosts()
{
    const QPixmap contactPixmap(this->avatarLabel->pixmap()->copy());

    this->globalObj->browseUserMessages(this->contactId,
                                        this->contactName,
                                        QIcon(contactPixmap),
                                        this->contactOutbox + "/major"); // TMP!
}



/*
 * Redraw contact's avatar after it's been downloaded and stored
 *
 */
void ContactCard::redrawAvatar(QString avatarUrl, QString avatarFilename)
{
    if (avatarUrl == this->contactAvatarUrl)
    {
        disconnect(pController, SIGNAL(avatarStored(QString,QString)),
                   this, SLOT(redrawAvatar(QString,QString)));

        this->setAvatar(avatarFilename);
    }
}
