/* -*- c++ -*-
 *
 * hostmanager.cpp
 *
 * Copyright (C) 2003 Petter Stokke <ummo@hellokitty.com>
 * Copyright (C) 2003 Sebastian Sauer <mail@dipe.org> 
 *
 * 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 <kconfig.h>
#include <kconfiggroup.h>
#include <kstandarddirs.h>
#include <kdirwatch.h>
#include <kicon.h>
#include <QSignalMapper>
#include <KMenu>

#include "donkeyhost.h"

#include "hostmanager.h"
#include "hostmanager.moc"

HostManager::HostManager(QObject* parent, const char* name, bool disableNotification)
    : QObject(parent)
{
    setObjectName(name ? name : "HostManager");
    refreshHostList();

    if (!disableNotification) {
        configWatcher = new KDirWatch(this);
        configWatcher->addFile( KStandardDirs::locateLocal("config", "mldonkeyrc") );

        connect(configWatcher, SIGNAL(dirty(const QString&)), SLOT(fileChanged(const QString&)));
        connect(configWatcher, SIGNAL(created(const QString&)), SLOT(fileChanged(const QString&)));
        connect(configWatcher, SIGNAL(deleted(const QString&)), SLOT(fileChanged(const QString&)));
    }
}

HostManager::~HostManager()
{
    qDeleteAll(m_hosts);
}

void HostManager::refreshHostList()
{
    qDeleteAll(m_hosts);
    m_hosts.clear();
    m_default = QString::null;

    KConfig *config = new KConfig("mldonkeyrc");

    QStringList list = config->groupList();
    QStringList::iterator it;
    for (it = list.begin(); it != list.end(); ++it) {
        KConfigGroup group = config->group(*it);
        if(group.hasKey("DonkeyHost")) {
            DonkeyHost* entry = new DonkeyHost(*it,
                group.readEntry("DonkeyHost", "localhost"),
                group.readEntry("DonkeyGuiPort", 4001),
                group.readEntry("DonkeyHTTPPort", 4080),
                group.readEntry("DonkeyUsername", "admin"),
                group.readEntry("DonkeyPassword"),
                (HostInterface::HostType)group.readEntry("HostMode", 0),
                KUrl( group.readEntry<QString>("BinaryPath", QString()) ),
                KUrl( group.readEntry<QString>("RootPath", QString()) ),
                (HostInterface::StartupMode)group.readEntry("StartupMode", 0) );

            if (group.readEntry("Default", false) && m_default.isNull())
                m_default = entry->name();
            m_hosts.insert(entry->name(), entry);
        }
    }
    if (m_hosts.empty()) { // create default
        DonkeyHost* entry = new DonkeyHost("MLDonkey", "localhost", 4001, 4080, "admin", "", HostInterface::External);
        m_default = entry->name();
        m_hosts.insert(entry->name(), entry);
    }
    if (m_default.isNull()) {
        QMap<QString,HostInterface*>::Iterator it = m_hosts.begin();
        m_default = it.key();
    }

    delete config;
}

void HostManager::fileChanged(const QString&)
{
    refreshHostList();
    emit hostListUpdated();
}

QStringList HostManager::hostList() const
{
    return m_hosts.keys();
}

QStringList HostManager::hostList(HostInterface::HostType filter) const
{
    QMap<QString,HostInterface*>::ConstIterator it;
    QStringList l;
    for (it = m_hosts.begin(); it != m_hosts.end(); ++it) {
        if (it.value()->type() == filter)
            l.append(it.key());
    }
    return l;
}

const QString& HostManager::defaultHostName() const
{
    return m_default;
}

void HostManager::setDefaultHostName(const QString& hostname)
{
    m_default = hostname;
}

HostInterface* HostManager::defaultHost() const
{
    return m_hosts[m_default];
}

HostInterface* HostManager::hostProperties(const QString& hostName) const
{
    return m_hosts[hostName];
}

bool HostManager::validHostName(const QString& hostName) const
{
    return m_hosts.contains(hostName);
}

HostInterface::HostType HostManager::hostType(const QString& hostName) const
{
    if (!validHostName(hostName)) return HostInterface::Unknown;
    return m_hosts[hostName]->type();
}

HostSelectAction::HostSelectAction(const QString& text, const QString& icon,
                                   HostManager* hostManager, QObject* parent)
    : KActionMenu(KIcon(icon), text, parent)
{
    setObjectName("HostSelectAction");
    if (hostManager)
        m_hostManager = hostManager;
    else
        m_hostManager = new HostManager(this);
    setDelayed(true);
    m_connectMapper = new QSignalMapper(this);
    connect(m_connectMapper, SIGNAL(mapped(const QString&)), SLOT(slotItemSelected(const QString&)));
    populateMenu();
    connect(m_hostManager, SIGNAL(hostListUpdated()), SLOT(populateMenu()));
}

void HostSelectAction::populateMenu()
{
    qDeleteAll(menu()->actions());
    foreach (const QString &host, m_hostManager->hostList()) {
        KAction *action = new KAction(host, this);
        connect(action, SIGNAL(activated()), m_connectMapper, SLOT(map()));
        m_connectMapper->setMapping(action, host);
        addAction(action);
    }
}

void HostSelectAction::slotItemSelected(const QString& item)
{
    if (m_hostManager->validHostName(item)) {
        emit hostSelected(item);
        emit hostSelected(m_hostManager->hostProperties(item));
    }
}
