/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Designer of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "appfontdialog.h"

#include <iconloader_p.h>
#include <abstractsettings_p.h>

#include <QtGui/QTreeView>
#include <QtGui/QToolButton>
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QSpacerItem>
#include <QtGui/QFileDialog>
#include <QtGui/QStandardItemModel>
#include <QtGui/QMessageBox>
#include <QtGui/QFontDatabase>
#include <QtGui/QDialogButtonBox>

#include <QtCore/QSettings>
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QFileInfo>
#include <QtCore/QtAlgorithms>
#include <QtCore/QVector>
#include <QtCore/QDebug>

QT_BEGIN_NAMESPACE

enum {FileNameRole = Qt::UserRole + 1, IdRole =  Qt::UserRole + 2 };
enum { debugAppFontWidget = 0 };

static const char fontFileKeyC[] = "fontFiles";

// AppFontManager: Singleton that maintains the mapping of loaded application font
// ids to the file names (which are not stored in QFontDatabase)
// and provides API for loading/unloading fonts as well for saving/restoring settings.

class AppFontManager
{
    Q_DISABLE_COPY(AppFontManager)
    AppFontManager();
public:
    static AppFontManager &instance();

    void save(QDesignerSettingsInterface *s, const QString &prefix) const;
    void restore(const QDesignerSettingsInterface *s, const QString &prefix);

    // Return id or -1
    int add(const QString &fontFile, QString *errorMessage);

    bool remove(int id, QString *errorMessage);
    bool remove(const QString &fontFile, QString *errorMessage);
    bool removeAt(int index, QString *errorMessage);

    // Store loaded fonts as pair of file name and Id
    typedef QPair<QString,int> FileNameFontIdPair;
    typedef QList<FileNameFontIdPair> FileNameFontIdPairs;
    const FileNameFontIdPairs &fonts() const;

private:
    FileNameFontIdPairs m_fonts;
};

AppFontManager::AppFontManager()
{
}

AppFontManager &AppFontManager::instance()
{
    static AppFontManager rc;
    return rc;
}

void AppFontManager::save(QDesignerSettingsInterface *s, const QString &prefix) const
{
    // Store as list of file names
    QStringList fontFiles;
    const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
    for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it)
        fontFiles.push_back(it->first);

    s->beginGroup(prefix);
    s->setValue(QLatin1String(fontFileKeyC),  fontFiles);
    s->endGroup();

    if (debugAppFontWidget)
        qDebug() << "AppFontManager::saved" << fontFiles.size() << "fonts under " << prefix;
}

void AppFontManager::restore(const QDesignerSettingsInterface *s, const QString &prefix)
{
    QString key = prefix;
    key += QLatin1Char('/');
    key += QLatin1String(fontFileKeyC);
    const QStringList fontFiles = s->value(key, QStringList()).toStringList();

    if (debugAppFontWidget)
        qDebug() << "AppFontManager::restoring" << fontFiles.size() << "fonts from " << prefix;
    if (!fontFiles.empty()) {
        QString errorMessage;
        const QStringList::const_iterator cend = fontFiles.constEnd();
        for (QStringList::const_iterator it = fontFiles.constBegin(); it != cend; ++it)
            if (add(*it, &errorMessage) == -1)
                qWarning("%s", qPrintable(errorMessage));
    }
}

int AppFontManager::add(const QString &fontFile, QString *errorMessage)
{
    const QFileInfo inf(fontFile);
    if (!inf.isFile()) {
        *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a file.").arg(fontFile);
        return -1;
    }
    if (!inf.isReadable()) {
        *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' does not have read permissions.").arg(fontFile);
        return -1;
    }
    const QString fullPath = inf.absoluteFilePath();
    // Check if already loaded
    const FileNameFontIdPairs::const_iterator cend = m_fonts.constEnd();
    for (FileNameFontIdPairs::const_iterator it = m_fonts.constBegin(); it != cend; ++it) {
        if (it->first == fullPath) {
            *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' is already loaded.").arg(fontFile);
            return -1;
        }
    }

    const int id = QFontDatabase::addApplicationFont(fullPath);
    if (id == -1) {
        *errorMessage = QCoreApplication::translate("AppFontManager", "The font file '%1' could not be loaded.").arg(fontFile);
        return -1;
    }

    if (debugAppFontWidget)
        qDebug() << "AppFontManager::add" << fontFile << id;
    m_fonts.push_back(FileNameFontIdPair(fullPath, id));
    return id;
}

bool AppFontManager::remove(int id, QString *errorMessage)
{
    const int count = m_fonts.size();
    for (int i = 0; i < count; i++)
        if (m_fonts[i].second == id)
            return removeAt(i, errorMessage);

    *errorMessage = QCoreApplication::translate("AppFontManager", "'%1' is not a valid font id.").arg(id);
    return false;
}

bool AppFontManager::remove(const QString &fontFile, QString *errorMessage)
{
    const int count = m_fonts.size();
    for (int i = 0; i < count; i++)
        if (m_fonts[i].first == fontFile)
            return removeAt(i, errorMessage);

    *errorMessage = QCoreApplication::translate("AppFontManager", "There is no loaded font matching the id '%1'.").arg(fontFile);
    return false;
}

bool AppFontManager::removeAt(int index, QString *errorMessage)
{
    Q_ASSERT(index >= 0 && index < m_fonts.size());

    const QString fontFile = m_fonts[index].first;
    const int id = m_fonts[index].second;

    if (debugAppFontWidget)
        qDebug() << "AppFontManager::removeAt" << index << '(' <<  fontFile << id << ')';

    if (!QFontDatabase::removeApplicationFont(id)) {
        *errorMessage = QCoreApplication::translate("AppFontManager", "The font '%1' (%2) could not be unloaded.").arg(fontFile).arg(id);
        return false;
    }
    m_fonts.removeAt(index);
    return true;
}

const AppFontManager::FileNameFontIdPairs &AppFontManager::fonts() const
{
    return  m_fonts;
}

// ------------- AppFontModel
class AppFontModel : public QStandardItemModel {
    Q_DISABLE_COPY(AppFontModel)
public:
    AppFontModel(QObject *parent = 0);

    void init(const AppFontManager &mgr);
    void add(const QString &fontFile, int id);
    int idAt(const QModelIndex &idx) const;
};

AppFontModel::AppFontModel(QObject * parent) :
    QStandardItemModel(parent)
{
    setHorizontalHeaderLabels(QStringList(AppFontWidget::tr("Fonts")));
}

void AppFontModel::init(const AppFontManager &mgr)
{
    typedef AppFontManager::FileNameFontIdPairs FileNameFontIdPairs;

    const FileNameFontIdPairs &fonts = mgr.fonts();
    const FileNameFontIdPairs::const_iterator cend = fonts.constEnd();
    for (FileNameFontIdPairs::const_iterator it = fonts.constBegin(); it != cend; ++it)
        add(it->first, it->second);
}

void AppFontModel::add(const QString &fontFile, int id)
{
    const QFileInfo inf(fontFile);
    // Root item with base name
    QStandardItem *fileItem = new QStandardItem(inf.completeBaseName());
    const QString fullPath = inf.absoluteFilePath();
    fileItem->setData(fullPath, FileNameRole);
    fileItem->setToolTip(fullPath);
    fileItem->setData(id, IdRole);
    fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);

    appendRow(fileItem);
    const QStringList families = QFontDatabase::applicationFontFamilies(id);
    const QStringList::const_iterator cend = families.constEnd();
    for (QStringList::const_iterator it = families.constBegin(); it != cend; ++it) {
        QStandardItem *familyItem = new QStandardItem(*it);
        familyItem->setToolTip(fullPath);
        familyItem->setFont(QFont(*it));
        familyItem->setFlags(Qt::ItemIsEnabled);
        fileItem->appendRow(familyItem);
    }
}

int AppFontModel::idAt(const QModelIndex &idx) const
{
    if (const QStandardItem *item = itemFromIndex(idx))
        return item->data(IdRole).toInt();
    return -1;
}

// ------------- AppFontWidget
AppFontWidget::AppFontWidget(QWidget *parent) :
    QGroupBox(parent),
    m_view(new QTreeView),
    m_addButton(new QToolButton),
    m_removeButton(new QToolButton),
    m_removeAllButton(new QToolButton),
    m_model(new AppFontModel(this))
{
    m_model->init(AppFontManager::instance());
    m_view->setModel(m_model);
    m_view->setSelectionMode(QAbstractItemView::ExtendedSelection);
    m_view->expandAll();
    connect(m_view->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(selectionChanged(QItemSelection,QItemSelection)));

    m_addButton->setToolTip(tr("Add font files"));
    m_addButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("plus.png")));
    connect(m_addButton, SIGNAL(clicked()), this, SLOT(addFiles()));

    m_removeButton->setEnabled(false);
    m_removeButton->setToolTip(tr("Remove current font file"));
    m_removeButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("minus.png")));
    connect(m_removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveFiles()));

    m_removeAllButton->setToolTip(tr("Remove all font files"));
    m_removeAllButton->setIcon(qdesigner_internal::createIconSet(QString::fromUtf8("editdelete.png")));
    connect(m_removeAllButton, SIGNAL(clicked()), this, SLOT(slotRemoveAll()));

    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->addWidget(m_addButton);
    hLayout->addWidget(m_removeButton);
    hLayout->addWidget(m_removeAllButton);
    hLayout->addItem(new QSpacerItem(0, 0,QSizePolicy::MinimumExpanding));

    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addWidget(m_view);
    vLayout->addLayout(hLayout);
    setLayout(vLayout);
}

void AppFontWidget::addFiles()
{
    const QStringList files =
        QFileDialog::getOpenFileNames(this, tr("Add Font Files"), QString(),
                                      tr("Font files (*.ttf)"));
    if (files.empty())
        return;

    QString errorMessage;

    AppFontManager &fmgr = AppFontManager::instance();
    const QStringList::const_iterator cend = files.constEnd();
    for (QStringList::const_iterator it = files.constBegin(); it != cend; ++it) {
        const int id = fmgr.add(*it, &errorMessage);
        if (id != -1) {
            m_model->add(*it, id);
        } else {
            QMessageBox::critical(this, tr("Error Adding Fonts"), errorMessage);
        }
    }
    m_view->expandAll();
}

static void removeFonts(const QModelIndexList &selectedIndexes, AppFontModel *model, QWidget *dialogParent)
{
    if (selectedIndexes.empty())
        return;

    // Reverse sort top level rows and remove
    AppFontManager &fmgr = AppFontManager::instance();
    QVector<int> rows;
    rows.reserve(selectedIndexes.size());

    QString errorMessage;
    const QModelIndexList::const_iterator cend = selectedIndexes.constEnd();
    for (QModelIndexList::const_iterator it = selectedIndexes.constBegin(); it != cend; ++it) {
        const int id = model->idAt(*it);
        if (id != -1) {
            if (fmgr.remove(id, &errorMessage)) {
                rows.push_back(it->row());
            } else {
                QMessageBox::critical(dialogParent, AppFontWidget::tr("Error Removing Fonts"), errorMessage);
            }
        }
    }

    qStableSort(rows.begin(), rows.end());
    for (int i = rows.size() - 1; i >= 0; i--)
        model->removeRow(rows[i]);
}

void AppFontWidget::slotRemoveFiles()
{
    removeFonts(m_view->selectionModel()->selectedIndexes(), m_model, this);
}

void AppFontWidget::slotRemoveAll()
{
    const int count = m_model->rowCount();
    if (!count)
        return;

    const QMessageBox::StandardButton answer =
        QMessageBox::question(this, tr("Remove Fonts"), tr("Would you like to remove all fonts?"),
                              QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
    if (answer == QMessageBox::No)
        return;

    QModelIndexList topLevels;
    for (int i = 0; i < count; i++)
        topLevels.push_back(m_model->index(i, 0));
    removeFonts(topLevels, m_model, this);
}

void AppFontWidget::selectionChanged(const QItemSelection &selected, const QItemSelection & /*deselected*/)
{
     m_removeButton->setEnabled(!selected.indexes().empty());
}

void AppFontWidget::save(QDesignerSettingsInterface *s, const QString &prefix)
{
    AppFontManager::instance().save(s, prefix);
}

void AppFontWidget::restore(const QDesignerSettingsInterface *s, const QString &prefix)
{
    AppFontManager::instance().restore(s, prefix);
}

// ------------ AppFontDialog
AppFontDialog::AppFontDialog(QWidget *parent) :
    QDialog(parent),
    m_appFontWidget(new AppFontWidget)
{
    setAttribute(Qt::WA_DeleteOnClose, true);
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    setWindowTitle(tr("Additional Fonts"));
    setModal(false);
    QVBoxLayout *vl = new  QVBoxLayout;
    vl->addWidget(m_appFontWidget);

    QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Close);
    QDialog::connect(bb, SIGNAL(rejected()), this, SLOT(reject()));
    vl->addWidget(bb);
    setLayout(vl);
}

QT_END_NAMESPACE
