/*
  Copyright (c) 2015 Montel Laurent <montel@kde.org>

  This library is free software; you can redistribute it and/or modify it
  under the terms of the GNU Library General Public License as published by
  the Free Software Foundation; either version 2 of the License, or (at your
  option) any later version.

  This library 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 Library General Public
  License for more details.

  You should have received a copy of the GNU Library General Public License
  along with this library; see the file COPYING.LIB.  If not, write to the
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  02110-1301, USA.

*/

#include "recentaddresswidget.h"
#include "recentaddresses.h"
#include <kpimutils/email.h>

#include <KConfig>
#include <KConfigGroup>
#include <KDebug>
#include <KGlobal>
#include <KLocale>
#include <KLineEdit>
#include <KPushButton>
#include <KMessageBox>

#include <QCoreApplication>
#include <QLayout>
#include <QVBoxLayout>
#include <QListWidget>
#include <QKeyEvent>


using namespace KPIM;
RecentAddressWidget::RecentAddressWidget(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout( this );

    mLineEdit = new KLineEdit(this);
    mLineEdit->setObjectName(QLatin1String("line_edit"));
    layout->addWidget(mLineEdit);

    mLineEdit->setTrapReturnKey(true);
    mLineEdit->installEventFilter(this);

    connect(mLineEdit,SIGNAL(textChanged(QString)),SLOT(slotTypedSomething(QString)));
    connect(mLineEdit,SIGNAL(returnPressed()),SLOT(slotAddItem()));


    QHBoxLayout* hboxLayout = new QHBoxLayout;

    QVBoxLayout* btnsLayout = new QVBoxLayout;
    btnsLayout->addStretch();
    mNewButton = new KPushButton(KIcon(QLatin1String("list-add")), i18n("&Add"), this);
    mNewButton->setObjectName(QLatin1String("new_button"));
    connect(mNewButton, SIGNAL(clicked()), SLOT(slotAddItem()));
    btnsLayout->insertWidget(0 ,mNewButton);

    mRemoveButton = new KPushButton(KIcon(QLatin1String("list-remove")), i18n("&Remove"), this);
    mRemoveButton->setObjectName(QLatin1String("remove_button"));
    mRemoveButton->setEnabled(false);
    connect(mRemoveButton, SIGNAL(clicked()), SLOT(slotRemoveItem()));
    btnsLayout->insertWidget(1, mRemoveButton);


    mListView = new QListWidget(this);
    mListView->setObjectName(QLatin1String("list_view"));
    mListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
    mListView->setSortingEnabled(true);
    hboxLayout->addWidget(mListView);
    hboxLayout->addLayout(btnsLayout);
    layout->addLayout(hboxLayout);
    connect(mListView, SIGNAL(itemSelectionChanged()),
            SLOT(slotSelectionChanged()));
    // maybe supplied lineedit has some text already
    slotTypedSomething( mLineEdit->text() );
}

RecentAddressWidget::~RecentAddressWidget()
{

}

void RecentAddressWidget::slotTypedSomething(const QString& text)
{
    if (mListView->currentItem()) {
        if (mListView->currentItem()->text() != mLineEdit->text() && !mLineEdit->text().isEmpty()) {
            // IMHO changeItem() shouldn't do anything with the value
            // of currentItem() ... like changing it or emitting signals ...
            // but TT disagree with me on this one (it's been that way since ages ... grrr)
            bool block = mListView->signalsBlocked();
            mListView->blockSignals( true );
            QListWidgetItem *currentIndex = mListView->currentItem();
            if ( currentIndex ) {
                currentIndex->setText(text);
                mDirty = true;
            }
            mListView->blockSignals( block );
        }
    }
}

void RecentAddressWidget::slotAddItem()
{
    if (mListView->count() > 0) {
        const QString text = mListView->item(0)->text();
        if (text.isEmpty()) {
            return;
        }
    }
    mListView->blockSignals(true);
    mListView->insertItem(0, QString());
    mListView->blockSignals(false);
    mListView->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
    mLineEdit->setFocus();
    mDirty = true;
    updateButtonState();
}

void RecentAddressWidget::slotRemoveItem()
{
    QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
    if (selectedItems.isEmpty())
        return;
    if (KMessageBox::Yes == KMessageBox::questionYesNo(this, i18np("Do you want to remove this email?", "Do you want to remove %1 emails?", selectedItems.count()), i18n("Remove"))) {
        Q_FOREACH(QListWidgetItem *item, selectedItems) {
            delete mListView->takeItem(mListView->row(item));
        }
        mDirty = true;
        updateButtonState();
    }
}

void RecentAddressWidget::updateButtonState()
{
    QList<QListWidgetItem *> selectedItems = mListView->selectedItems();
    const int numberOfElementSelected(selectedItems.count());
    mRemoveButton->setEnabled(numberOfElementSelected);
    mNewButton->setEnabled(numberOfElementSelected <= 1);
    mLineEdit->setEnabled(numberOfElementSelected <= 1);

    if (numberOfElementSelected == 1) {
        const QString text = mListView->currentItem()->text();
        if (text != mLineEdit->text())
            mLineEdit->setText(text);
    } else {
        mLineEdit->clear();
    }
}

void RecentAddressWidget::slotSelectionChanged()
{
    updateButtonState();
}

void RecentAddressWidget::setAddresses( const QStringList &addrs )
{
    mListView->clear();
    mListView->addItems( addrs );
}

bool RecentAddressWidget::eventFilter( QObject* o, QEvent* e )
{
    if (o == mLineEdit && e->type() == QEvent::KeyPress ) {
        QKeyEvent* keyEvent = (QKeyEvent*)e;
        if (keyEvent->key() == Qt::Key_Down ||
                keyEvent->key() == Qt::Key_Up) {
            return ((QObject*)mListView)->event(e);
        }
    }

    return false;
}

void RecentAddressWidget::storeAddresses(KConfig *config)
{
    const int numberOfItem(mListView->count());
    for (int i = 0; i < numberOfItem; ++i) {
        KPIM::RecentAddresses::self( config )->add( mListView->item(i)->text() );
    }
}

bool RecentAddressWidget::wasChanged() const
{
    return mDirty;
}
