Configuration::Configuration(Applet *applet, KConfigDialog *parent) : QObject(parent),
    m_applet(applet),
    m_editedLauncher(NULL)
{
    KConfigGroup configuration = m_applet->config();
    KMenu *addLauncherMenu = new KMenu(parent);
    QWidget *generalWidget = new QWidget;
    QWidget *appearanceWidget = new QWidget;
    QWidget *arrangementWidget = new QWidget;
    QWidget *actionsWidget = new QWidget;
    QAction *addLauncherApplicationAction = addLauncherMenu->addAction(KIcon("application-x-executable"), i18n("Add Application..."));
    QAction *addLauncherFromFileAction = addLauncherMenu->addAction(KIcon("inode-directory"), i18n("Add File or Directory..."));
    QAction *addMenuLauncher = addLauncherMenu->addAction(KIcon("start-here"), i18n("Add Menu"));
    KMenu *addMenuLauncherMenu = new KMenu(addLauncherMenu);

    addMenuLauncher->setMenu(addMenuLauncherMenu);

    QAction *action = addMenuLauncherMenu->addAction(QString());
    action->setData("/");
    action->setVisible(false);

    m_generalUi.setupUi(generalWidget);
    m_appearanceUi.setupUi(appearanceWidget);
    m_arrangementUi.setupUi(arrangementWidget);
    m_actionsUi.setupUi(actionsWidget);

    connectWidgets(generalWidget);
    connectWidgets(appearanceWidget);

    m_arrangementUi.addLauncherButton->setMenu(addLauncherMenu);

    m_generalUi.groupingStrategy->addItem(i18n("Do Not Group"), QVariant(TaskManager::GroupManager::NoGrouping));
    m_generalUi.groupingStrategy->addItem(i18n("Manually"), QVariant(TaskManager::GroupManager::ManualGrouping));
    m_generalUi.groupingStrategy->addItem(i18n("By Program Name"), QVariant(TaskManager::GroupManager::ProgramGrouping));
    m_generalUi.groupingStrategy->setCurrentIndex(m_generalUi.groupingStrategy->findData(QVariant(configuration.readEntry("groupingStrategy", static_cast<int>(TaskManager::GroupManager::NoGrouping)))));

    m_generalUi.sortingStrategy->addItem(i18n("Do Not Sort"), QVariant(TaskManager::GroupManager::NoSorting));
    m_generalUi.sortingStrategy->addItem(i18n("Manually"), QVariant(TaskManager::GroupManager::ManualSorting));
    m_generalUi.sortingStrategy->addItem(i18n("Alphabetically"), QVariant(TaskManager::GroupManager::AlphaSorting));
    m_generalUi.sortingStrategy->addItem(i18n("By Desktop"), QVariant(TaskManager::GroupManager::DesktopSorting));
    m_generalUi.sortingStrategy->setCurrentIndex(m_generalUi.sortingStrategy->findData(QVariant(configuration.readEntry("sortingStrategy", static_cast<int>(TaskManager::GroupManager::ManualSorting)))));

    m_generalUi.showOnlyCurrentDesktop->setChecked(configuration.readEntry("showOnlyCurrentDesktop", false));
    m_generalUi.showOnlyCurrentActivity->setChecked(configuration.readEntry("showOnlyCurrentActivity", true));
    m_generalUi.showOnlyCurrentScreen->setChecked(configuration.readEntry("showOnlyCurrentScreen", false));
    m_generalUi.showOnlyMinimized->setChecked(configuration.readEntry("showOnlyMinimized", false));
    m_generalUi.showOnlyTasksWithLaunchers->setChecked(configuration.readEntry("showOnlyTasksWithLaunchers", false));
    m_generalUi.connectJobsWithTasks->setChecked(configuration.readEntry("connectJobsWithTasks", false));
    m_generalUi.groupJobs->setChecked(configuration.readEntry("groupJobs", true));

    m_generalUi.jobCloseMode->addItem(i18n("Instantly"), QVariant(InstantClose));
    m_generalUi.jobCloseMode->addItem(i18n("After delay"), QVariant(DelayedClose));
    m_generalUi.jobCloseMode->addItem(i18n("Manually"), QVariant(ManualClose));
    m_generalUi.jobCloseMode->setCurrentIndex(m_generalUi.jobCloseMode->findData(QVariant(configuration.readEntry("jobCloseMode", static_cast<int>(DelayedClose)))));

    QStringList moveAnimationNames;
    moveAnimationNames << i18n("None") << i18n("Zoom") << i18n("Jump") << i18n("Spotlight") << i18n("Glow") << i18n("Fade");

    QList<AnimationType> moveAnimationIds;
    moveAnimationIds << NoAnimation << ZoomAnimation << JumpAnimation << SpotlightAnimation << GlowAnimation << FadeAnimation;

    for (int i = 0; i < moveAnimationIds.count(); ++i)
    {
        m_appearanceUi.moveAnimation->addItem(moveAnimationNames.at(i), QVariant(moveAnimationIds.at(i)));
    }

    QStringList iconAnimationNames;
    iconAnimationNames << i18n("None") << i18n("Bounce") << i18n("Zoom") << i18n("Blink") << i18n("Spotlight") << i18n("Rotate") << i18n("Glow");

    QList<AnimationType> iconAnimationIds;
    iconAnimationIds << NoAnimation << BounceAnimation << ZoomAnimation << BlinkAnimation << SpotlightAnimation << RotateAnimation << GlowAnimation;

    for (int i = 0; i < iconAnimationIds.count(); ++i)
    {
        m_appearanceUi.demandsAttentionAnimation->addItem(iconAnimationNames.at(i), QVariant(iconAnimationIds.at(i)));
        m_appearanceUi.startupAnimation->addItem(iconAnimationNames.at(i), QVariant(iconAnimationIds.at(i)));
    }

    m_appearanceUi.titleLabelMode->addItem(i18n("Never"), QVariant(NoLabel));
    m_appearanceUi.titleLabelMode->addItem(i18n("On mouse-over"), QVariant(MouseOverLabel));
    m_appearanceUi.titleLabelMode->addItem(i18n("For active icon"), QVariant(ActiveIconLabel));
    m_appearanceUi.titleLabelMode->addItem(i18n("Always"), QVariant(AlwaysShowLabel));
    m_appearanceUi.titleLabelMode->setCurrentIndex(m_appearanceUi.titleLabelMode->findData(QVariant(configuration.readEntry("titleLabelMode", static_cast<int>(AlwaysShowLabel)))));

    m_appearanceUi.activeIconIndication->addItem(i18n("None"), QVariant(NoIndication));
    m_appearanceUi.activeIconIndication->addItem(i18n("Zoom"), QVariant(ZoomIndication));
    m_appearanceUi.activeIconIndication->addItem(i18n("Glow"), QVariant(GlowIndication));
    m_appearanceUi.activeIconIndication->addItem(i18n("Fade"), QVariant(FadeIndication));
    m_appearanceUi.activeIconIndication->setCurrentIndex(m_appearanceUi.activeIconIndication->findData(QVariant(configuration.readEntry("activeIconIndication", static_cast<int>(FadeIndication)))));

    m_appearanceUi.customBackgroundImage->setUrl(KUrl(configuration.readEntry("customBackgroundImage", QString())));
    m_appearanceUi.customBackgroundImage->setFilter("image/svg+xml image/svg+xml-compressed");

    if (m_applet->location() != Plasma::Floating && (!m_applet->containment() || m_applet->containment()->objectName() != "FancyPanel")) {
        m_appearanceUi.customBackgroundImageLabel->hide();
        m_appearanceUi.customBackgroundImage->hide();
    }

    m_appearanceUi.moveAnimation->setCurrentIndex(moveAnimationIds.indexOf(static_cast<AnimationType>(configuration.readEntry("moveAnimation", static_cast<int>(GlowAnimation)))));
    m_appearanceUi.parabolicMoveAnimation->setChecked(configuration.readEntry("parabolicMoveAnimation", false));
    m_appearanceUi.demandsAttentionAnimation->setCurrentIndex(iconAnimationIds.indexOf(static_cast<AnimationType>(configuration.readEntry("demandsAttentionAnimation", static_cast<int>(BlinkAnimation)))));
    m_appearanceUi.startupAnimation->setCurrentIndex(iconAnimationIds.indexOf(static_cast<AnimationType>(configuration.readEntry("startupAnimation", static_cast<int>(BounceAnimation)))));

    m_arrangementUi.removeButton->setIcon(KIcon("go-previous"));
    m_arrangementUi.addButton->setIcon(KIcon("go-next"));
    m_arrangementUi.moveUpButton->setIcon(KIcon("go-up"));
    m_arrangementUi.moveDownButton->setIcon(KIcon("go-down"));

    KConfig kickoffConfiguration("kickoffrc", KConfig::NoGlobals);
    KConfigGroup favoritesGroup(&kickoffConfiguration, "Favorites");
    const QStringList currentEntries = configuration.readEntry("arrangement", QStringList("tasks"));
    QStringList availableEntries;
    availableEntries << i18n("--- separator ---") << i18n("--- tasks area ---") << i18n("--- jobs area ---") << "menu:/";
    availableEntries.append(favoritesGroup.readEntry("FavoriteURLs", QStringList()));

    for (int i = 0; i < currentEntries.count(); ++i)
    {
        QListWidgetItem *item = NULL;

        if (currentEntries.at(i) == "tasks")
        {
            item = new QListWidgetItem(i18n("--- tasks area ---"), m_arrangementUi.currentEntriesListWidget);
        }
        else if (currentEntries.at(i) == "jobs")
        {
            item = new QListWidgetItem(i18n("--- jobs area ---"), m_arrangementUi.currentEntriesListWidget);
        }
        else if (currentEntries.at(i) == "separator")
        {
            item = new QListWidgetItem(i18n("--- separator ---"), m_arrangementUi.currentEntriesListWidget);
        }
        else
        {
            if (hasEntry(currentEntries.at(i), false))
            {
                continue;
            }

            Launcher *launcher = m_applet->launcherForUrl(KUrl(currentEntries.at(i)));

            if (!launcher)
            {
                continue;
            }

            item = new QListWidgetItem(launcher->icon(), launcher->title(), m_arrangementUi.currentEntriesListWidget);
            item->setToolTip(launcher->launcherUrl().pathOrUrl());

            m_rules[launcher->launcherUrl().pathOrUrl()] = qMakePair(launcher->rules(), launcher->isExcluded());
        }

        m_arrangementUi.currentEntriesListWidget->addItem(item);
    }

    for (int i = 0; i < availableEntries.count(); ++i)
    {
        if (i > 0 && hasEntry(availableEntries.at(i), false))
        {
            continue;
        }

        QListWidgetItem *item = NULL;

        if (availableEntries.at(i).startsWith("--- "))
        {
            item = new QListWidgetItem(availableEntries.at(i), m_arrangementUi.availableEntriesListWidget);
        }
        else
        {
            Launcher *launcher = m_applet->launcherForUrl(KUrl(availableEntries.at(i)));

            if (!launcher)
            {
                continue;
            }

            item = new QListWidgetItem(launcher->icon(), launcher->title(), m_arrangementUi.availableEntriesListWidget);
            item->setToolTip(launcher->launcherUrl().pathOrUrl());

            m_rules[launcher->launcherUrl().pathOrUrl()] = qMakePair(launcher->rules(), launcher->isExcluded());
        }

        m_arrangementUi.availableEntriesListWidget->addItem(item);
    }

    QMap<QPair<Qt::MouseButtons, Qt::KeyboardModifiers>, IconAction> iconActions = m_applet->iconActions();
    QMap<QPair<Qt::MouseButtons, Qt::KeyboardModifiers>, IconAction>::iterator iterator;
    int i = 0;

    m_actionsUi.actionsTableWidget->setItemDelegateForColumn(0, new ActionDelegate(this));
    m_actionsUi.actionsTableWidget->setItemDelegateForColumn(1, new TriggerDelegate(this));

    for (iterator = iconActions.begin(); iterator != iconActions.end(); ++iterator)
    {
        if (iterator.key().first == Qt::NoButton)
        {
            continue;
        }

        QStringList action;

        if (iterator.key().first & Qt::LeftButton)
        {
            action.append("left");
        }

        if (iterator.key().first & Qt::MiddleButton)
        {
            action.append("middle");
        }

        if (iterator.key().first & Qt::RightButton)
        {
            action.append("right");
        }

        if (iterator.key().second & Qt::ShiftModifier)
        {
            action.append("shift");
        }

        if (iterator.key().second & Qt::ControlModifier)
        {
            action.append("ctrl");
        }

        if (iterator.key().second & Qt::AltModifier)
        {
            action.append("alt");
        }

        QTableWidgetItem *triggerItem = new QTableWidgetItem(action.join(QChar('+')));
        triggerItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);

        QTableWidgetItem *actionItem = new QTableWidgetItem(QString::number(static_cast<int>(iterator.value())));
        actionItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);

        m_actionsUi.actionsTableWidget->setRowCount(i + 1);
        m_actionsUi.actionsTableWidget->setItem(i, 0, actionItem);
        m_actionsUi.actionsTableWidget->setItem(i, 1, triggerItem);

        ++i;
    }

    moveAnimationTypeChanged(m_appearanceUi.moveAnimation->currentIndex());

    parent->addPage(generalWidget, i18n("General"), "go-home");
    parent->addPage(appearanceWidget, i18n("Appearance"), "preferences-desktop-theme");
    parent->addPage(arrangementWidget, i18n("Arrangement"), "format-list-unordered");
    parent->addPage(actionsWidget, i18n("Actions"), "configure-shortcuts");

    connect(parent, SIGNAL(applyClicked()), this, SLOT(save()));
    connect(parent, SIGNAL(okClicked()), this, SLOT(save()));
    connect(m_appearanceUi.moveAnimation, SIGNAL(currentIndexChanged(int)), this, SLOT(moveAnimationTypeChanged(int)));
    connect(m_appearanceUi.customBackgroundImage, SIGNAL(textChanged(QString)), this, SLOT(modify()));
    connect(m_arrangementUi.availableEntriesListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(availableEntriesCurrentItemChanged(int)));
    connect(m_arrangementUi.currentEntriesListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(currentEntriesCurrentItemChanged(int)));
    connect(m_arrangementUi.removeButton, SIGNAL(clicked()), this, SLOT(removeItem()));
    connect(m_arrangementUi.addButton, SIGNAL(clicked()), this, SLOT(addItem()));
    connect(m_arrangementUi.moveUpButton, SIGNAL(clicked()), this, SLOT(moveUpItem()));
    connect(m_arrangementUi.moveDownButton, SIGNAL(clicked()), this, SLOT(moveDownItem()));
    connect(m_arrangementUi.editLauncherButton, SIGNAL(clicked()), this, SLOT(editLauncher()));
    connect(m_actionsUi.actionsTableWidget, SIGNAL(clicked(QModelIndex)), this, SLOT(actionClicked(QModelIndex)));
    connect(m_actionsUi.actionsTableWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(actionSelectionChanged()));
    connect(m_actionsUi.addButton, SIGNAL(clicked()), this, SLOT(addAction()));
    connect(m_actionsUi.removeButton, SIGNAL(clicked()), this, SLOT(removeAction()));
    connect(addLauncherApplicationAction, SIGNAL(triggered()), this, SLOT(findLauncher()));
    connect(addLauncherFromFileAction, SIGNAL(triggered()), this, SLOT(addLauncher()));
    connect(addMenuLauncherMenu, SIGNAL(aboutToShow()), this, SLOT(populateMenu()));
    connect(addMenuLauncherMenu, SIGNAL(triggered(QAction*)), this, SLOT(addMenu(QAction*)));
}