//-*-c++-*-
/***************************************************************************
 *   Copyright (C) 2003 by Fred Schaettgen                                 *
 *   kbluetoothd@schaettgen.de                                             *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#include "application.h"
#include <kcmdlineargs.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kconfig.h>
#include "metaserver.h"
#include "hcidevmonitor.h"
#include "trayicon.h"
#include "devicenamecache.h"
#include "devicescanner.h"
#include "pinserver.h"
#include "mostrecentlyused.h"
#include "hcilistener.h"
#include <kdebug.h>
#include <libkbluetooth/configinfo.h>
#include <bluetooth/hci.h>

using namespace KBluetooth;
using namespace std;

KBluetoothdApp::KBluetoothdApp() :
    KUniqueApplication()
{
    m_config = new KConfig("kbluetoothdrc");
    // Enable autostart
    m_config->setGroup("General");
    m_config->writeEntry("AutoStart", true);
    m_config->sync();

    metaServer = NULL;
    hciListener = new HciListener(this);
    deviceScanner = NULL;
    hciDevMonitor = new HciDevMonitor(this);

    deviceNameCache = new DeviceNameCache(this);
    pinServer = new PinServer(this);
    mru = new MostRecentlyUsed(this);
    trayIcon = new TrayIcon(this);
    setMainWidget(trayIcon);

    connect(hciDevMonitor, SIGNAL(hciDeviceFound()), this, SLOT(slotHciDeviceFound()));
    connect(hciDevMonitor, SIGNAL(hciDeviceLost()), this, SLOT(slotHciDeviceLost()));
    connect(hciDevMonitor, SIGNAL(hciNoStartupDevice()), trayIcon, SLOT(slotNoStartupDevice()));

    QTimer::singleShot(0, hciDevMonitor, SLOT(start()));
    hciListener->start();
    bFirstNewInstance = true;
    trayIcon->slotMruMenuUpdate();

    // Warn the user if the location of kbluepin has changed
    // Don't show if bluez-libs is 3.x
#ifndef HCI_VIRTUAL
    QString dontShowKey = QString("kbluepinLocInfo%1").arg(KDEBluetoothConfig::libDir);
    dontShowKey = dontShowKey.replace("/", "-").replace(" ","-");
    KMessageBox::information(trayIcon, i18n("<p>You may replace bluez's pin helper program \
with kbluepin; it is located in <b>%1</b> now.</p>").arg(QString(KDEBluetoothConfig::libDir)),
        "KBluetoothD", dontShowKey);
#endif
}

KBluetoothdApp::~KBluetoothdApp()
{
    mru->writeConfig();
    delete m_config;
    delete trayIcon;
}

int KBluetoothdApp::newInstance()
{
    // KBluetoothd is started via autostart. If session management
    // is activated it will be called twice after login. This would
    // set the tray icon to visible every time, so we turn off
    // session management.
    disableSessionManagement();

    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
    // If kbluetoothd is started while already running we
    // make the tray icon permanently visible
    if (bFirstNewInstance == false) {
        if ((args->isSet("dontforceshow") == false) && trayIcon) {
            trayIcon->setAlwaysShowIcon(true);
        }
    }
    bFirstNewInstance = false;

    if (trayIcon) {
        connect(hciDevMonitor, SIGNAL(hciDeviceFound()), trayIcon, SLOT(slotDeviceFound()));
        connect(hciDevMonitor, SIGNAL(hciDeviceLost()), trayIcon, SLOT(slotDeviceLost()));
    }

    return 0;
}

void KBluetoothdApp::configUpdate()
{
}

void KBluetoothdApp::slotHciDeviceFound()
{
    startServices();
}

void KBluetoothdApp::slotHciDeviceLost()
{
    endServices();
}

void KBluetoothdApp::startServices()
{
    delete hciListener;
    hciListener = new HciListener(this);
    connect(hciListener, SIGNAL(nameRequestComplete(int,KBluetooth::DeviceAddress,QString)),
        deviceNameCache, SLOT(slotNameRequest(int,KBluetooth::DeviceAddress,QString)));
    connect(hciListener, SIGNAL(inquiryResult(KBluetooth::DeviceAddress,int)),
        deviceNameCache, SLOT(slotInquiryResult(KBluetooth::DeviceAddress, int)));
    connect(hciListener, SIGNAL(connectionComplete(int,KBluetooth::DeviceAddress)),
        trayIcon, SLOT(slotConnectionComplete(int,KBluetooth::DeviceAddress)));
    connect(hciListener, SIGNAL(connectionStateChanged()),
        trayIcon, SLOT(slotConnectionStateChanged()));

    deviceScanner = new DeviceScanner(this, hciListener);
    connect(deviceScanner, SIGNAL(neighboursChanged()),
        trayIcon, SLOT(slotMruMenuUpdate()));

    delete metaServer;
    metaServer = new MetaServer(this);
    connect(hciListener, SIGNAL(connectionStateChanged()),
        trayIcon, SLOT(slotConnectionStateChanged()));

    hciListener->start();
    deviceScanner->start();

    trayIcon->slotConnectionStateChanged();
}

void KBluetoothdApp::endServices()
{
    delete deviceScanner;
    deviceScanner = NULL;

    delete hciListener;
    hciListener = NULL;

    delete metaServer;
    metaServer = NULL;

    //delete deviceNameCache;
    //deviceNameCache = NULL;
}

#include "application.moc"
