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


ProfileEditor::ProfileEditor(PumpController *pumpController,
                             QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle(tr("Profile Editor") + " - Dianara");
    this->setWindowIcon(QIcon::fromTheme("user-properties",
                                         QIcon(":/images/no-avatar.png")));
    this->setWindowFlags(Qt::Dialog);
    this->setWindowModality(Qt::ApplicationModal);
    this->setMinimumSize(500, 400);

    QSettings settings;
    this->resize(settings.value("ProfileEditor/profileWindowSize",
                                QSize(580, 480)).toSize());


    this->pController = pumpController;


    QFont infoFont;
    infoFont.setPointSize(infoFont.pointSize() - 1);

    webfingerLabel = new QLabel(this);
    webfingerLabel->setFont(infoFont);
    webfingerLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    webfingerLabel->setToolTip("<b></b>"
                               + tr("This is your Pump address"));

    const QString emailExplanation = tr("This is the e-mail address associated "
                                        "with your account, for things such as "
                                        "notifications and password recovery");

    emailChanger = new EmailChanger(emailExplanation,
                                    this->pController,
                                    this);

    emailLabel = new QLabel(this);
    emailLabel->setFont(infoFont);
    emailLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
    emailLabel->setToolTip("<b></b>" // Make the tooltip HTML so it gets wordwrap
                           + emailExplanation);

    changeEmailButton = new QPushButton(QIcon::fromTheme("view-pim-mail",
                                                         QIcon(":/images/button-post.png")),
                                        tr("Change &E-mail..."),
                                        this);
    connect(changeEmailButton, SIGNAL(clicked()),
            emailChanger, SLOT(show()));


    avatarLabel = new QLabel(this);
    avatarLabel->setPixmap(QIcon::fromTheme("user-properties",
                                            QIcon(":/images/no-avatar.png"))
                           .pixmap(96, 96));

    changeAvatarButton = new QPushButton(QIcon::fromTheme("folder-image-people"),
                                         tr("Change &Avatar..."),
                                         this);
    connect(changeAvatarButton, SIGNAL(clicked()),
            this, SLOT(findAvatarFile()));

    this->avatarChanged = false;


    fullNameLineEdit = new QLineEdit(this);
    fullNameLineEdit->setToolTip("<b></b>"
                                 + tr("This is your visible name"));
    connect(fullNameLineEdit, SIGNAL(textEdited(QString)),
            this, SLOT(enableSaveButton()));

    hometownLineEdit = new QLineEdit(this);
    connect(hometownLineEdit, SIGNAL(textEdited(QString)),
            this, SLOT(enableSaveButton()));

    bioTextEdit = new QTextEdit(this);
    bioTextEdit->setTabChangesFocus(true);
    bioTextEdit->setSizePolicy(QSizePolicy::MinimumExpanding,
                               QSizePolicy::MinimumExpanding);
    connect(bioTextEdit, SIGNAL(textChanged()),
            this, SLOT(enableSaveButton()));


    newAvatarInfoLabel = new QLabel("\n"
                                    + tr("Changing your avatar will create a "
                                         "post in your timeline with it.\n"
                                         "If you delete that post your avatar "
                                         "will be deleted too.")
                                    + "\n",
                                    this);
    newAvatarInfoLabel->setWordWrap(true);
    newAvatarInfoLabel->setAlignment(Qt::AlignCenter);
    newAvatarInfoLabel->setFrameStyle(QFrame::Box | QFrame::Raised);
    newAvatarInfoLabel->setAutoFillBackground(true);
    newAvatarInfoLabel->setForegroundRole(QPalette::HighlightedText);
    newAvatarInfoLabel->setBackgroundRole(QPalette::Highlight);
    newAvatarInfoLabel->hide();


    saveButton = new QPushButton(QIcon::fromTheme("document-save",
                                                  QIcon(":/images/button-save.png")),
                                 tr("&Save Profile"),
                                 this);
    connect(saveButton, SIGNAL(clicked()),
            this, SLOT(saveProfile()));

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


    // ESC to cancel, too
    cancelAction = new QAction(this);
    cancelAction->setShortcut(QKeySequence(Qt::Key_Escape));
    connect(cancelAction, SIGNAL(triggered()),
            this, SLOT(close()));
    this->addAction(cancelAction);


    // Layout
    this->emailLayout = new QHBoxLayout();
    emailLayout->addWidget(emailLabel);
    emailLayout->addStretch(1);
    emailLayout->addWidget(changeEmailButton);

    this->avatarLayout = new QHBoxLayout();
    avatarLayout->addWidget(avatarLabel);
    avatarLayout->addStretch(1);
    avatarLayout->addWidget(changeAvatarButton);


    this->topLayout = new QFormLayout();
    topLayout->setContentsMargins(0, 0, 0, 0);
    topLayout->addRow(tr("Webfinger ID"), webfingerLabel);
    topLayout->addRow(tr("E-mail"),       emailLayout);

    topLayout->addRow(tr("Avatar"),       avatarLayout);

    topLayout->addRow(tr("Full &Name"),   fullNameLineEdit);
    topLayout->addRow(tr("&Hometown"),    hometownLineEdit);
    topLayout->addRow(tr("&Bio"),         bioTextEdit);
    // FIXME: the FormLayout doesn't let the bioTextField row grow taller than its sizeHint()


    this->bottomLayout = new QHBoxLayout();
    bottomLayout->setAlignment(Qt::AlignRight | Qt::AlignBottom);
    bottomLayout->setContentsMargins(0, 0, 0, 0);
    bottomLayout->addWidget(saveButton);
    bottomLayout->addWidget(cancelButton);


    this->mainLayout = new QVBoxLayout();
    mainLayout->addLayout(topLayout,     9);
    mainLayout->addWidget(newAvatarInfoLabel);
    mainLayout->addLayout(bottomLayout,  1);
    this->setLayout(mainLayout);


    // Disable some stuff until profile is received
    this->toggleWidgetsEnabled(false);
    this->saveButton->setEnabled(false);

    qDebug() << "ProfileEditor created";
}



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



/*
 * Fill the fields from received info
 *
 */
void ProfileEditor::setProfileData(QString avatarUrl, QString fullName,
                                   QString hometown, QString bio,
                                   QString eMail)
{
    this->webfingerLabel->setText(pController->currentUserId());
    if (eMail.isEmpty())
    {
        this->emailLabel->setText("<" + tr("Not set",
                                           "In reference to the e-mail "
                                           "not being set for the account")
                                  + ">");
    }
    else
    {
        this->emailLabel->setText(eMail);
        this->emailChanger->setCurrentEmail(eMail);
    }

    this->currentAvatarURL = avatarUrl;
    QString avatarFilename = MiscHelpers::getCachedAvatarFilename(this->currentAvatarURL);
    if (QFile::exists(avatarFilename))
    {
        this->avatarLabel->setPixmap(QPixmap(avatarFilename).scaled(96, 96,
                                                                    Qt::KeepAspectRatio,
                                                                    Qt::SmoothTransformation));
    }
    else
    {
        // FIXME: Should fetch the avatar
    }

    this->fullNameLineEdit->setText(fullName);
    this->hometownLineEdit->setText(hometown);
    this->bioTextEdit->setText(bio);

    // Enable all widgets, since the profile is valid now
    this->toggleWidgetsEnabled(true);
    this->saveButton->setDisabled(true); // But disable Save button until necessary
}

/*
 * Enable or disable some widgets depending on whether the profile has been received
 *
 */
void ProfileEditor::toggleWidgetsEnabled(bool state)
{
    this->changeEmailButton->setEnabled(state);
    this->changeAvatarButton->setEnabled(state);

    this->fullNameLineEdit->setEnabled(state);
    this->hometownLineEdit->setEnabled(state);
    this->bioTextEdit->setEnabled(state);
}



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


void ProfileEditor::findAvatarFile()
{
    newAvatarFilename = QFileDialog::getOpenFileName(this,
                                                     tr("Select avatar image"),
                                                     QDir::homePath(),
                                                     tr("Image files")
                                                     + " (*.png *.jpg *.jpeg *.gif);;"
                                                     + tr("All files") + " (*)");

    if (!newAvatarFilename.isEmpty())
    {
        qDebug() << "Selected" << newAvatarFilename << "as new avatar for upload";

        // FIXME: in the future, check file size and image size
        // and scale the pixmap to something sane before uploading.
        QPixmap avatarPixmap = QPixmap(newAvatarFilename);

        this->newAvatarContentType = MiscHelpers::getFileMimeType(newAvatarFilename);
        if (!avatarPixmap.isNull() && !newAvatarContentType.isEmpty())
        {
            this->avatarLabel->setPixmap(QPixmap(newAvatarFilename)
                                         .scaled(96, 96,
                                                 Qt::KeepAspectRatio,
                                                 Qt::SmoothTransformation));
            this->avatarChanged = true;
            this->newAvatarInfoLabel->show();
            this->enableSaveButton(); // Enable, since something has been changed
        }
        else
        {
            QMessageBox::warning(this,
                                 tr("Invalid image"),
                                 tr("The selected image is not valid."));
            qDebug() << "Invalid avatar file selected";
        }
    }
}



void ProfileEditor::saveProfile()
{
    if (avatarChanged)
    {
        connect(pController, SIGNAL(avatarUploaded(QString)),
                this, SLOT(sendProfileData(QString)));

        this->pController->uploadFile(this->newAvatarFilename,
                                      this->newAvatarContentType,
                                      PumpController::UploadAvatarRequest);
    }
    else
    {
        this->sendProfileData(); // without a new image ID
    }
}



void ProfileEditor::sendProfileData(QString newImageUrl)
{
    if (avatarChanged)
    {
        disconnect(pController, SIGNAL(avatarUploaded(QString)),
                   this, SLOT(sendProfileData(QString)));

        this->avatarChanged = false; // For next time the dialog is shown
        this->newAvatarInfoLabel->hide();
    }

    QString newFullName = this->fullNameLineEdit->text().trimmed();
    if (newFullName.isEmpty())
    {
        // To avoid having empty names, use the username part from the ID
        newFullName = this->pController->currentUsername();
    }

    this->pController->updateUserProfile(newImageUrl,
                                         newFullName,
                                         this->hometownLineEdit->text().trimmed(),
                                         this->bioTextEdit->toPlainText().trimmed());


    this->close();
}


/*
 * Enable the 'Save' button when something actually changes
 *
 */
void ProfileEditor::enableSaveButton()
{
    this->saveButton->setEnabled(true);
}


/****************************************************************************/
/****************************** PROTECTED ***********************************/
/****************************************************************************/


void ProfileEditor::closeEvent(QCloseEvent *event)
{
    this->saveButton->setDisabled(true); // Disabled for next time

    // FIXME? Maybe avatarChanged should be set to false, and the explanation hidden here

    QSettings settings;
    if (settings.isWritable())
    {
        settings.setValue("ProfileEditor/profileWindowSize", this->size());
    }

    this->hide();
    event->ignore();
}
