/*
    This file is part of Akonadi Contact.

    Copyright (c) 2009 Tobias Koenig <tokoe@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 "contacteditorwidget.h"
#include "config-akonadi-contact.h"

#include "addresseditwidget.h"
#include "categorieseditwidget.h"
#include "contacteditorpageplugin.h"
#include "contactmetadata_p.h"
#include "customfieldseditwidget.h"
#include "dateeditwidget.h"
#include "displaynameeditwidget.h"
#include "emaileditwidget.h"
#include "freebusyeditwidget.h"
#include "geoeditwidget.h"
#include "imagewidget.h"
#include "imeditwidget.h"
#include "nameeditwidget.h"
#include "phoneeditwidget.h"
#include "soundeditwidget.h"

#include <kconfig.h>
#include <kconfiggroup.h>
#include <KLineEdit>
#include <KLocalizedString>
#include <qtabwidget.h>
#include <ktextedit.h>
#include <QUrl>

#include <QtCore/QDirIterator>
#include <QtCore/QPluginLoader>
#include <QGroupBox>
#include <QLabel>
#include <QCheckBox>
#include <QVBoxLayout>
#include <KCompletion/KLineEdit>

class Q_DECL_HIDDEN ContactEditorWidget::Private
{
public:
    Private(ContactEditorWidget::DisplayMode displayMode, ContactEditorWidget *parent)
        : mDisplayMode(displayMode)
        , mParent(parent)
        , mCustomFieldsWidget(0)
    {
    }

    void initGui();
    void initGuiContactTab();
    void initGuiLocationTab();
    void initGuiBusinessTab();
    void initGuiPersonalTab();
    void initGuiNotesTab();
    void initGuiCustomFieldsTab();

    void loadCustomPages();

    QString loadCustom(const KContacts::Addressee &contact, const QString &key) const;
    void storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const;

    ContactEditorWidget::DisplayMode mDisplayMode;
    ContactEditorWidget *mParent;
    QTabWidget *mTabWidget;

    // widgets from name group
    NameEditWidget *mNameWidget;
    ImageWidget *mPhotoWidget;
    DisplayNameEditWidget *mDisplayNameWidget;
    KLineEdit *mNickNameWidget;
    SoundEditWidget *mPronunciationWidget;

    // widgets from Internet group
    EmailEditWidget *mEmailWidget;
    KLineEdit *mHomepageWidget;
    KLineEdit *mBlogWidget;
    IMEditWidget *mIMWidget;

    // widgets from phones group
    PhoneEditWidget *mPhonesWidget;

    CategoriesEditWidget *mCategoriesWidget;

    KComboBox *mMailPreferFormatting;
    QCheckBox *mAllowRemoteContent;

    // widgets from addresses group
    AddressEditWidget *mAddressesWidget;

    // widgets from coordinates group
    GeoEditWidget *mCoordinatesWidget;

    // widgets from general group
    ImageWidget *mLogoWidget;
    KLineEdit *mOrganizationWidget;
    KLineEdit *mProfessionWidget;
    KLineEdit *mTitleWidget;
    KLineEdit *mDepartmentWidget;
    KLineEdit *mOfficeWidget;
    KLineEdit *mManagerWidget;
    KLineEdit *mAssistantWidget;

    // widgets from groupware group
    FreeBusyEditWidget *mFreeBusyWidget;

    // widgets from notes group
    KTextEdit *mNotesWidget;

    // widgets from dates group
    DateEditWidget *mBirthdateWidget;
    DateEditWidget *mAnniversaryWidget;

    // widgets from family group
    KLineEdit *mPartnerWidget;

    // widgets from custom fields group
    CustomFieldsEditWidget *mCustomFieldsWidget;

    // custom editor pages
    QList<Akonadi::ContactEditorPagePlugin *> mCustomPages;
};

void ContactEditorWidget::Private::initGui()
{
    QVBoxLayout *layout = new QVBoxLayout(mParent);
    layout->setMargin(0);

    mTabWidget = new QTabWidget(mParent);
    layout->addWidget(mTabWidget);

    initGuiContactTab();
    initGuiLocationTab();
    initGuiBusinessTab();
    initGuiPersonalTab();
    initGuiNotesTab();
    if (mDisplayMode == FullMode) {
        initGuiCustomFieldsTab();
        loadCustomPages();
    }
}

void ContactEditorWidget::Private::initGuiContactTab()
{
    QWidget *widget = new QWidget;
    QGridLayout *layout = new QGridLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab", "Contact"));

    QGroupBox *nameGroupBox = new QGroupBox(i18nc("@title:group Name related properties of a contact", "Name"));
    QGroupBox *internetGroupBox = new QGroupBox(i18nc("@title:group", "Internet"));
    QGroupBox *phonesGroupBox = new QGroupBox(i18nc("@title:group", "Phones"));

    nameGroupBox->setMinimumSize(320, 200);
    layout->addWidget(nameGroupBox, 0, 0);
    layout->addWidget(internetGroupBox, 0, 1);
    layout->addWidget(phonesGroupBox, 1, 0, 4, 1);

    QGridLayout *nameLayout = new QGridLayout(nameGroupBox);
    QGridLayout *internetLayout = new QGridLayout(internetGroupBox);
    QGridLayout *phonesLayout = new QGridLayout(phonesGroupBox);

    // setup name group box
    QLabel *label = new QLabel(i18nc("@label The name of a contact", "Name:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    nameLayout->addWidget(label, 0, 0);

    mNameWidget = new NameEditWidget;
    label->setBuddy(mNameWidget);
    nameLayout->addWidget(mNameWidget, 0, 1);

    mPhotoWidget = new ImageWidget(ImageWidget::Photo);
    nameLayout->addWidget(mPhotoWidget, 0, 2, 4, 1);

    label = new QLabel(i18nc("@label The display name of a contact", "Display:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    nameLayout->addWidget(label, 1, 0);

    mDisplayNameWidget = new DisplayNameEditWidget;
    label->setBuddy(mDisplayNameWidget);
    nameLayout->addWidget(mDisplayNameWidget, 1, 1);

    label = new QLabel(i18nc("@label The nickname of a contact", "Nickname:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    nameLayout->addWidget(label, 2, 0);

    mNickNameWidget = new KLineEdit;
    mNickNameWidget->setTrapReturnKey(true);
    label->setBuddy(mNickNameWidget);
    nameLayout->addWidget(mNickNameWidget, 2, 1);

    label = new QLabel(i18nc("@label The pronunciation of a contact's name", "Pronunciation:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    nameLayout->addWidget(label, 3, 0);

    mPronunciationWidget = new SoundEditWidget;
    label->setBuddy(mPronunciationWidget);
    nameLayout->addWidget(mPronunciationWidget, 3, 1);

    nameLayout->setRowStretch(4, 1);

    // setup Internet group box
    label = new QLabel(i18nc("@label The email address of a contact", "Email:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    internetLayout->addWidget(label, 0, 0);

    mEmailWidget = new EmailEditWidget;
    label->setBuddy(mEmailWidget);
    internetLayout->addWidget(mEmailWidget, 0, 1);

    label = new QLabel(i18nc("@label The homepage URL of a contact", "Homepage:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    internetLayout->addWidget(label, 1, 0);

    mHomepageWidget = new KLineEdit;
    mHomepageWidget->setTrapReturnKey(true);
    label->setBuddy(mHomepageWidget);
    internetLayout->addWidget(mHomepageWidget, 1, 1);

    label = new QLabel(i18nc("@label The blog URL of a contact", "Blog:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    internetLayout->addWidget(label, 2, 0);

    mBlogWidget = new KLineEdit;
    mBlogWidget->setTrapReturnKey(true);
    label->setBuddy(mBlogWidget);
    internetLayout->addWidget(mBlogWidget, 2, 1);

    label = new QLabel(i18nc("@label The instant messaging address of a contact", "Messaging:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    internetLayout->addWidget(label, 3, 0);

    mIMWidget = new IMEditWidget;
    label->setBuddy(mIMWidget);
    internetLayout->addWidget(mIMWidget, 3, 1);

    internetLayout->setRowStretch(4, 1);

    // setup phones group box
    mPhonesWidget = new PhoneEditWidget;
    phonesLayout->addWidget(mPhonesWidget, 0, 0);

    //phonesLayout->setRowStretch( 1, 1 );

    // setup categories section
    QHBoxLayout *categoriesLayout = new QHBoxLayout;
    label = new QLabel(i18nc("@label The categories of a contact", "Categories:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    mCategoriesWidget = new CategoriesEditWidget;
    label->setBuddy(mCategoriesWidget);

    categoriesLayout->addWidget(label);
    categoriesLayout->addWidget(mCategoriesWidget);

    layout->addLayout(categoriesLayout, 1, 1);

    QGroupBox *receivedMessageGroupBox = new QGroupBox(i18n("Messages"));
    layout->addWidget(receivedMessageGroupBox, 2, 1);

    QVBoxLayout *vbox = new QVBoxLayout(receivedMessageGroupBox);

    QHBoxLayout *mailPreferFormattingLayout = new QHBoxLayout;
    label = new QLabel(i18n("Show messages received from this contact as:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    mMailPreferFormatting = new KComboBox;
    label->setBuddy(mMailPreferFormatting);
    QStringList listFormat;
    listFormat << i18n("Default") << i18n("Plain Text") << i18n("HTML");
    mMailPreferFormatting->addItems(listFormat);
    mailPreferFormattingLayout->addWidget(label);
    mailPreferFormattingLayout->addWidget(mMailPreferFormatting);

    vbox->addLayout(mailPreferFormattingLayout);

    mAllowRemoteContent = new QCheckBox(i18n("Allow remote content in received HTML messages"));
    vbox->addWidget(mAllowRemoteContent);

    layout->setRowStretch(4, 1);
}

void ContactEditorWidget::Private::initGuiLocationTab()
{
    QWidget *widget = new QWidget;
    QHBoxLayout *layout = new QHBoxLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab", "Location"));

    QGroupBox *addressesGroupBox = new QGroupBox(i18nc("@title:group", "Addresses"));
    QGroupBox *coordinatesGroupBox = new QGroupBox(i18nc("@title:group", "Coordinates"));

    layout->addWidget(addressesGroupBox);
    layout->addWidget(coordinatesGroupBox);

    QGridLayout *addressesLayout = new QGridLayout(addressesGroupBox);
    QGridLayout *coordinatesLayout = new QGridLayout(coordinatesGroupBox);

    // setup addresses group box
    mAddressesWidget = new AddressEditWidget(addressesGroupBox);
    mAddressesWidget->setMinimumHeight(200);
    addressesLayout->addWidget(mAddressesWidget, 0, 0);
    addressesLayout->setRowStretch(1, 1);

    // setup coordinates group box
    mCoordinatesWidget = new GeoEditWidget;
    coordinatesLayout->addWidget(mCoordinatesWidget, 0, 0);
    coordinatesLayout->setRowStretch(1, 1);
}

void ContactEditorWidget::Private::initGuiBusinessTab()
{
    QWidget *widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab", "Business"));

    QGroupBox *generalGroupBox = new QGroupBox(i18nc("@title:group General properties of a contact", "General"));
    QGroupBox *groupwareGroupBox = new QGroupBox(i18nc("@title:group", "Groupware"));

    layout->addWidget(generalGroupBox);
    layout->addWidget(groupwareGroupBox);

    QGridLayout *generalLayout = new QGridLayout(generalGroupBox);
    QGridLayout *groupwareLayout = new QGridLayout(groupwareGroupBox);

    // setup general group box
    mLogoWidget = new ImageWidget(ImageWidget::Logo);
    generalLayout->addWidget(mLogoWidget, 0, 2, 6, 1, Qt::AlignTop);

    QLabel *label = new QLabel(i18nc("@label The organization of a contact", "Organization:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 0, 0);

    mOrganizationWidget = new KLineEdit;
    mOrganizationWidget->setTrapReturnKey(true);
    label->setBuddy(mOrganizationWidget);
    generalLayout->addWidget(mOrganizationWidget, 0, 1);

    label = new QLabel(i18nc("@label The profession of a contact", "Profession:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 1, 0);

    mProfessionWidget = new KLineEdit;
    mProfessionWidget->setTrapReturnKey(true);
    label->setBuddy(mProfessionWidget);
    generalLayout->addWidget(mProfessionWidget, 1, 1);

    label = new QLabel(i18nc("@label The title of a contact", "Title:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 2, 0);

    mTitleWidget = new KLineEdit;
    mTitleWidget->setTrapReturnKey(true);
    label->setBuddy(mTitleWidget);
    generalLayout->addWidget(mTitleWidget, 2, 1);

    label = new QLabel(i18nc("@label The department of a contact", "Department:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 3, 0);

    mDepartmentWidget = new KLineEdit;
    mDepartmentWidget->setTrapReturnKey(true);
    label->setBuddy(mDepartmentWidget);
    generalLayout->addWidget(mDepartmentWidget, 3, 1);

    label = new QLabel(i18nc("@label The office of a contact", "Office:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 4, 0);

    mOfficeWidget = new KLineEdit;
    mOfficeWidget->setTrapReturnKey(true);
    label->setBuddy(mOfficeWidget);
    generalLayout->addWidget(mOfficeWidget, 4, 1);

    label = new QLabel(i18nc("@label The manager's name of a contact", "Manager's name:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 5, 0);

    mManagerWidget = new KLineEdit;
    mManagerWidget->setTrapReturnKey(true);
    label->setBuddy(mManagerWidget);
    generalLayout->addWidget(mManagerWidget, 5, 1);

    label = new QLabel(i18nc("@label The assistant's name of a contact", "Assistant's name:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    generalLayout->addWidget(label, 6, 0);

    mAssistantWidget = new KLineEdit;
    mAssistantWidget->setTrapReturnKey(true);
    label->setBuddy(mAssistantWidget);
    generalLayout->addWidget(mAssistantWidget, 6, 1);

    // setup groupware group box
    label = new QLabel(i18nc("@label The free/busy information of a contact", "Free/Busy:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    groupwareLayout->addWidget(label, 0, 0);

    mFreeBusyWidget = new FreeBusyEditWidget;
    label->setBuddy(mFreeBusyWidget);
    groupwareLayout->addWidget(mFreeBusyWidget, 0, 1);
    groupwareLayout->setRowStretch(1, 1);
}

void ContactEditorWidget::Private::initGuiPersonalTab()
{
    QWidget *widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab Personal properties of a contact", "Personal"));

    QGroupBox *datesGroupBox = new QGroupBox(i18nc("@title:group Date related properties of a contact", "Dates"));
    QGroupBox *familyGroupBox = new QGroupBox(i18nc("@title:group Family related properties of a contact", "Family"));

    layout->addWidget(datesGroupBox);
    layout->addWidget(familyGroupBox);

    QGridLayout *datesLayout = new QGridLayout(datesGroupBox);
    QGridLayout *familyLayout = new QGridLayout(familyGroupBox);

    // setup dates group box
    QLabel *label = new QLabel(i18nc("@label The birthdate of a contact", "Birthdate:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    datesLayout->addWidget(label, 0, 0);

    mBirthdateWidget = new DateEditWidget(DateEditWidget::Birthday);
    label->setBuddy(mBirthdateWidget);
    datesLayout->addWidget(mBirthdateWidget, 0, 1);

    label = new QLabel(i18nc("@label The wedding anniversary of a contact", "Anniversary:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    datesLayout->addWidget(label, 1, 0);

    mAnniversaryWidget = new DateEditWidget(DateEditWidget::Anniversary);
    label->setBuddy(mAnniversaryWidget);
    datesLayout->addWidget(mAnniversaryWidget, 1, 1);

    datesLayout->setRowStretch(2, 1);
    datesLayout->setColumnStretch(1, 1);

    // widgets from family group
    label = new QLabel(i18nc("@label The partner's name of a contact", "Partner's name:"));
    label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    familyLayout->addWidget(label, 0, 0);

    mPartnerWidget = new KLineEdit;
    mPartnerWidget->setTrapReturnKey(true);
    label->setBuddy(mPartnerWidget);
    familyLayout->addWidget(mPartnerWidget, 0, 1);

    familyLayout->setRowStretch(1, 1);
}

void ContactEditorWidget::Private::initGuiNotesTab()
{
    QWidget *widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab", "Notes"));

    mNotesWidget = new KTextEdit;
    mNotesWidget->setAcceptRichText(false);
    layout->addWidget(mNotesWidget);
}

void ContactEditorWidget::Private::initGuiCustomFieldsTab()
{
    QWidget *widget = new QWidget;
    QVBoxLayout *layout = new QVBoxLayout(widget);

    mTabWidget->addTab(widget, i18nc("@title:tab", "Custom Fields"));

    mCustomFieldsWidget = new CustomFieldsEditWidget;
    layout->addWidget(mCustomFieldsWidget);
}

void ContactEditorWidget::Private::loadCustomPages()
{
    qDeleteAll(mCustomPages);
    mCustomPages.clear();

    const QString pluginDirectory = QStringLiteral("%1/akonadi/contact/editorpageplugins/").arg(QStringLiteral(AKONADI_CONTACT_LIB));
    QDirIterator it(pluginDirectory, QDir::Files);

    while (it.hasNext()) {
        QPluginLoader loader(it.next());
        if (!loader.load()) {
            continue;
        }

        Akonadi::ContactEditorPagePlugin *plugin = qobject_cast<Akonadi::ContactEditorPagePlugin *>(loader.instance());
        if (!plugin) {
            continue;
        }

        mCustomPages.append(plugin);
    }

    foreach (Akonadi::ContactEditorPagePlugin *plugin, mCustomPages) {
        mTabWidget->addTab(plugin, plugin->title());
    }
}

QString ContactEditorWidget::Private::loadCustom(const KContacts::Addressee &contact, const QString &key) const
{
    return contact.custom(QStringLiteral("KADDRESSBOOK"), key);
}

void ContactEditorWidget::Private::storeCustom(KContacts::Addressee &contact, const QString &key, const QString &value) const
{
    if (value.isEmpty()) {
        contact.removeCustom(QStringLiteral("KADDRESSBOOK"), key);
    } else {
        contact.insertCustom(QStringLiteral("KADDRESSBOOK"), key, value);
    }
}

ContactEditorWidget::ContactEditorWidget(QWidget *parent)
    : d(new Private(FullMode, this))
{
    Q_UNUSED(parent)
    d->initGui();

    connect(d->mNameWidget, &NameEditWidget::nameChanged, d->mDisplayNameWidget, &DisplayNameEditWidget::changeName);
    connect(d->mOrganizationWidget, &QLineEdit::textChanged, d->mDisplayNameWidget, &DisplayNameEditWidget::changeOrganization);
}

ContactEditorWidget::ContactEditorWidget(ContactEditorWidget::DisplayMode displayMode, QWidget *parent)
    : d(new Private(displayMode, this))
{
    Q_UNUSED(parent)
    d->initGui();

    connect(d->mNameWidget, &NameEditWidget::nameChanged, d->mDisplayNameWidget, &DisplayNameEditWidget::changeName);
    connect(d->mOrganizationWidget, &QLineEdit::textChanged, d->mDisplayNameWidget, &DisplayNameEditWidget::changeOrganization);
}

ContactEditorWidget::~ContactEditorWidget()
{
    delete d;
}

void ContactEditorWidget::loadContact(const KContacts::Addressee &contact, const Akonadi::ContactMetaData &metaData)
{
    // name group
    d->mPhotoWidget->loadContact(contact);
    d->mNameWidget->loadContact(contact);
    d->mDisplayNameWidget->loadContact(contact);
    d->mNickNameWidget->setText(contact.nickName());
    d->mPronunciationWidget->loadContact(contact);

    // Internet group
    d->mEmailWidget->loadContact(contact);
    d->mHomepageWidget->setText(contact.url().url().toString());
    d->mBlogWidget->setText(d->loadCustom(contact, QStringLiteral("BlogFeed")));
    d->mIMWidget->loadContact(contact);

    // phones group
    d->mPhonesWidget->loadContact(contact);

    // categories section
    d->mCategoriesWidget->loadContact(contact);

    const QString mailPreferedFormatting = d->loadCustom(contact, QStringLiteral("MailPreferedFormatting"));
    if (mailPreferedFormatting.isEmpty()) {
        d->mMailPreferFormatting->setCurrentIndex(0);
    } else if (mailPreferedFormatting == QLatin1String("TEXT")) {
        d->mMailPreferFormatting->setCurrentIndex(1);
    } else if (mailPreferedFormatting == QLatin1String("HTML")) {
        d->mMailPreferFormatting->setCurrentIndex(2);
    } else {
        d->mMailPreferFormatting->setCurrentIndex(0);
    }

    const QString mailAllowToRemoteContent = d->loadCustom(contact, QStringLiteral("MailAllowToRemoteContent"));
    d->mAllowRemoteContent->setChecked(mailAllowToRemoteContent == QLatin1String("TRUE"));

    // address group
    d->mAddressesWidget->loadContact(contact);

    // coordinates group
    d->mCoordinatesWidget->loadContact(contact);

    // general group
    d->mLogoWidget->loadContact(contact);
    d->mOrganizationWidget->setText(contact.organization());
    d->mProfessionWidget->setText(d->loadCustom(contact, QStringLiteral("X-Profession")));
    d->mTitleWidget->setText(contact.title());
    d->mDepartmentWidget->setText(contact.department());
    d->mOfficeWidget->setText(d->loadCustom(contact, QStringLiteral("X-Office")));
    d->mManagerWidget->setText(d->loadCustom(contact, QStringLiteral("X-ManagersName")));
    d->mAssistantWidget->setText(d->loadCustom(contact, QStringLiteral("X-AssistantsName")));

    // groupware group
    d->mFreeBusyWidget->loadContact(contact);

    // notes group
    d->mNotesWidget->setPlainText(contact.note());

    // dates group
    d->mBirthdateWidget->setDate(contact.birthday().date());
    d->mAnniversaryWidget->setDate(QDate::fromString(d->loadCustom(contact, QStringLiteral("X-Anniversary")),
                                   Qt::ISODate));

    // family group
    d->mPartnerWidget->setText(d->loadCustom(contact, QStringLiteral("X-SpousesName")));

    d->mDisplayNameWidget->setDisplayType((DisplayNameEditWidget::DisplayType)metaData.displayNameMode());

    if (d->mDisplayMode == FullMode) {
        // custom fields group
        d->mCustomFieldsWidget->setLocalCustomFieldDescriptions(metaData.customFieldDescriptions());
        d->mCustomFieldsWidget->loadContact(contact);

        // custom pages
        foreach (Akonadi::ContactEditorPagePlugin *plugin, d->mCustomPages) {
            plugin->loadContact(contact);
        }
    }
}

void ContactEditorWidget::storeContact(KContacts::Addressee &contact, Akonadi::ContactMetaData &metaData) const
{
    // name group
    d->mPhotoWidget->storeContact(contact);
    d->mNameWidget->storeContact(contact);
    d->mDisplayNameWidget->storeContact(contact);
    contact.setNickName(d->mNickNameWidget->text().trimmed());
    d->mPronunciationWidget->storeContact(contact);

    // Internet group
    d->mEmailWidget->storeContact(contact);
    KContacts::ResourceLocatorUrl resourceLocatorUrl;
    resourceLocatorUrl.setUrl(QUrl(d->mHomepageWidget->text().trimmed()));
    contact.setUrl(resourceLocatorUrl);
    d->storeCustom(contact, QStringLiteral("BlogFeed"), d->mBlogWidget->text().trimmed());
    d->mIMWidget->storeContact(contact);

    // phones group
    d->mPhonesWidget->storeContact(contact);

    // categories section
    d->mCategoriesWidget->storeContact(contact);

    QString mailPreferedFormatting;
    const int index = d->mMailPreferFormatting->currentIndex();
    if (index == 0) {
        //Nothing => remove custom variable
    } else if (index == 1) {
        mailPreferedFormatting = QStringLiteral("TEXT");
    } else if (index == 2) {
        mailPreferedFormatting = QStringLiteral("HTML");
    }
    d->storeCustom(contact, QStringLiteral("MailPreferedFormatting"), mailPreferedFormatting);

    QString mailAllowToRemoteContent;
    if (d->mAllowRemoteContent->isChecked()) {
        mailAllowToRemoteContent = QStringLiteral("TRUE");
    }
    d->storeCustom(contact, QStringLiteral("MailAllowToRemoteContent"), mailAllowToRemoteContent);

    // address group
    d->mAddressesWidget->storeContact(contact);

    // coordinates group
    d->mCoordinatesWidget->storeContact(contact);

    // general group
    d->mLogoWidget->storeContact(contact);
    contact.setOrganization(d->mOrganizationWidget->text());
    d->storeCustom(contact, QStringLiteral("X-Profession"), d->mProfessionWidget->text().trimmed());
    contact.setTitle(d->mTitleWidget->text().trimmed());
    contact.setDepartment(d->mDepartmentWidget->text().trimmed());
    d->storeCustom(contact, QStringLiteral("X-Office"), d->mOfficeWidget->text().trimmed());
    d->storeCustom(contact, QStringLiteral("X-ManagersName"), d->mManagerWidget->text().trimmed());
    d->storeCustom(contact, QStringLiteral("X-AssistantsName"), d->mAssistantWidget->text().trimmed());

    // groupware group
    d->mFreeBusyWidget->storeContact(contact);

    // notes group
    contact.setNote(d->mNotesWidget->toPlainText());

    // dates group
    QDateTime birthday = QDateTime(d->mBirthdateWidget->date(), QTime(), contact.birthday().timeSpec());
    // This is needed because the constructor above sets the time component
    // of the QDateTime to midnight.  We want it to stay invalid.
    birthday.setTime(QTime());

    contact.setBirthday(birthday);
    d->storeCustom(contact, QStringLiteral("X-Anniversary"), d->mAnniversaryWidget->date().toString(Qt::ISODate));

    // family group
    d->storeCustom(contact, QStringLiteral("X-SpousesName"), d->mPartnerWidget->text().trimmed());

    if (d->mDisplayMode == FullMode) {
        // custom fields group
        d->mCustomFieldsWidget->storeContact(contact);
        metaData.setCustomFieldDescriptions(d->mCustomFieldsWidget->localCustomFieldDescriptions());

        metaData.setDisplayNameMode(d->mDisplayNameWidget->displayType());

        // custom pages
        foreach (Akonadi::ContactEditorPagePlugin *plugin, d->mCustomPages) {
            plugin->storeContact(contact);
        }
    }
}

void ContactEditorWidget::setReadOnly(bool readOnly)
{
    // widgets from name group
    d->mNameWidget->setReadOnly(readOnly);
    d->mPhotoWidget->setReadOnly(readOnly);
    d->mDisplayNameWidget->setReadOnly(readOnly);
    d->mNickNameWidget->setReadOnly(readOnly);
    d->mPronunciationWidget->setReadOnly(readOnly);

    // widgets from Internet group
    d->mEmailWidget->setReadOnly(readOnly);
    d->mHomepageWidget->setReadOnly(readOnly);
    d->mBlogWidget->setReadOnly(readOnly);
    d->mIMWidget->setReadOnly(readOnly);

    // widgets from phones group
    d->mPhonesWidget->setReadOnly(readOnly);

    // widgets from categories section
    d->mCategoriesWidget->setReadOnly(readOnly);

    // Preferred Mail formatting option
    d->mMailPreferFormatting->setEnabled(!readOnly);
    d->mAllowRemoteContent->setEnabled(!readOnly);

    // widgets from addresses group
    d->mAddressesWidget->setReadOnly(readOnly);

    // widgets from coordinates group
    d->mCoordinatesWidget->setReadOnly(readOnly);

    // widgets from general group
    d->mLogoWidget->setReadOnly(readOnly);
    d->mOrganizationWidget->setReadOnly(readOnly);
    d->mProfessionWidget->setReadOnly(readOnly);
    d->mTitleWidget->setReadOnly(readOnly);
    d->mDepartmentWidget->setReadOnly(readOnly);
    d->mOfficeWidget->setReadOnly(readOnly);
    d->mManagerWidget->setReadOnly(readOnly);
    d->mAssistantWidget->setReadOnly(readOnly);

    // widgets from groupware group
    d->mFreeBusyWidget->setReadOnly(readOnly);

    // widgets from notes group
    d->mNotesWidget->setReadOnly(readOnly);

    // widgets from dates group
    d->mBirthdateWidget->setReadOnly(readOnly);
    d->mAnniversaryWidget->setReadOnly(readOnly);

    // widgets from family group
    d->mPartnerWidget->setReadOnly(readOnly);

    if (d->mDisplayMode == FullMode) {
        // widgets from custom fields group
        d->mCustomFieldsWidget->setReadOnly(readOnly);

        // custom pages
        foreach (Akonadi::ContactEditorPagePlugin *plugin, d->mCustomPages) {
            plugin->setReadOnly(readOnly);
        }
    }
}
