/*
 *
 *  Device Manager Gui for tdebluez
 *
 *  Copyright (C) 2018  Emanoil Kotsev <deloptes@gmail.com>
 *
 *
 *  This file is part of tdebluez.
 *
 *  tdebluez 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.
 *
 *  tdebluez 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 kbluetooth; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <tqdbusobjectpath.h>
#include <tdeconfig.h>
#include <tqpushbutton.h>
#include <knotifydialog.h>
#include <knotifyclient.h>

#include <devicemimeconverter.h>
#include <btuuids.h>

#include "application.h"
#include "devicewizard.h"

#define LOGOTIMEOUT   80 //80 msec
#define CONTIMEOUT  5000 //5 sec

DeviceWizard::DeviceWizard(TDEBluetoothApp* a) :
        DeviceDialog(), app(a)
{
    // use the first powered adapter
    TQMap<TQString, AdapterImpl*>::Iterator ait = app->adapters.begin();
    for (ait; ait != app->adapters.end(); ++ait)
    {
        AdapterImpl *adptr = ait.data();
        if (adptr)
        {
            TQT_DBusError dbuserr;
            if (adptr->getPowered(dbuserr))
            {
                adapter = ait.data();
                break;
            }
            if (dbuserr.isValid())
                tqDebug(i18n("Get powered for active adapter failed: %1").arg(dbuserr.message()));
        }
    }

    // else use the first available
    if (!adapter)
        adapter = (app->adapters).begin().data();

    devicesetupwizard = new DeviceSetupWizard(app->manager);

    devicedlg_ext = new DeviceDialog_Ext(this);
    setExtension(devicedlg_ext->newDevFrame);
    setOrientation(TQt::Vertical);

    mainlogo = TDEGlobal::iconLoader()->loadIcon("tdebluez", TDEIcon::Small, 16);
    setIcon(mainlogo);

    connectingDevice = {ConState::IDLE, TQString(), TQStringList()};

    pix = TDEGlobal::iconLoader()->loadIcon("bluetooth", TDEIcon::Small, 48);
    pixmapLabel->setPixmap(pix);
    pixmapLabel->show();

    logoBlend = pix;
    KPixmapEffect::blend(logoBlend, -1, red, KPixmapEffect::DiagonalGradient);

    deviceBox->header()->hide();

    // add devices
    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        kdDebug() << "device path: " << dit.key() << endl;
        slotInsertDevice(dit.key());
    }

    int colSize = deviceBox->columnWidth(1);
    deviceBox->setColumnWidth(1, colSize + 20);

    /* disable button by default */
    setStateDeviceButtons(false);

    devicedlg_ext->newdevList->header()->hide();
    devicedlg_ext->newdevList->setColumnAlignment(2, TQt::AlignVCenter);
    devicedlg_ext->setupButton->setEnabled(false);

    // connect signals
    // devicedlg_ext
    connect(devicedlg_ext->setupButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotSetupNewDevice()));
    connect(devicedlg_ext->newdevList, TQ_SIGNAL(clicked(TQListViewItem*)),
            this, TQ_SLOT(slotChangeSetupButton(TQListViewItem*)));

    // deviceBox
    connect(deviceBox, TQ_SIGNAL(clicked(TQListViewItem*)),
            this, TQ_SLOT(slotDeviceBoxClicked(TQListViewItem*)));

    // this wizard
    connect(addButton, TQ_SIGNAL(toggled(bool)),
            this, TQ_SLOT(showExtension(bool)));
    connect(addButton, TQ_SIGNAL(toggled(bool)),
            this, TQ_SLOT(slotSearch(bool)));

    connect(okButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotCloseDialog()));

    connect(configureButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotConfigDevice()));
    connect(connectButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotConnectButton()));
    connect(deleteButton, TQ_SIGNAL(clicked()),
            this, TQ_SLOT(slotDeleteDevice()));

    // ADAPTER -> DIALOG
    connect(app->manager, TQ_SIGNAL(adapterDiscoveringChanged(const TQString&, bool)),
            this, TQ_SLOT(slotAdapterDiscoveringChanged(const TQString&, bool)));

    // DEVICE -> DIALOG
    connect(app->manager, TQ_SIGNAL(deviceConnectedChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDeviceConnectedChanged(const TQString&, bool)));
    connect(app->manager, TQ_SIGNAL(deviceAdded(const TQString&)),
            this, TQ_SLOT(slotInsertDevice(const TQString&)));
    connect(app->manager, TQ_SIGNAL(deviceRemoved(const TQString&)),
            this, TQ_SLOT(slotDeviceRemoved(const TQString&)));
    connect(app->manager, TQ_SIGNAL(deviceNameChanged(const TQString&, const TQString&)),
            this, TQ_SLOT(slotDeviceNameChanged(const TQString&, const TQString&)));
    connect(app->manager, TQ_SIGNAL(deviceAliasChanged(const TQString&, const TQString&)),
            this, TQ_SLOT(slotDeviceNameChanged(const TQString&, const TQString&)));
    connect(app->manager, TQ_SIGNAL(devicePairedChanged(const TQString&,bool)),
            this, TQ_SLOT(slotDevicePairedChanged(const TQString&,bool)));

    //	connect(app->manager, TQ_SIGNAL(mediaControlConnectedChanged(const TQString&,bool)),
    //			TQ_SLOT(slotMediaControlConnectedChanged(const TQString&,bool)));

    chgLogoTimer = new TQTimer(this);
    TQObject::connect(chgLogoTimer, TQ_SIGNAL(timeout()), this, TQ_SLOT(slotUpdateLogo()));
    timer = false;
}

DeviceWizard::~DeviceWizard()
{
//	if (mediaCtlDialog)
//		delete mediaCtlDialog;
    delete devicedlg_ext;
    delete devicesetupwizard;
}

void DeviceWizard::slotCloseDialog()
{
    close();
}

void DeviceWizard::slotDeviceBoxClicked(TQListViewItem *dev)
{
    if (!dev)
    {
        setStateDeviceButtons(true);
        return;
    }

    TQString selAddr = dev->text(2);
    if (connectingDevice.state == ConState::CONNECTING)
    {
        if (selAddr == connectingDevice.address)
        {
            connectButton->setText(i18n("&Disconnect"));
            connectButton->setEnabled(true);
        }
        else
        {
            setStateDeviceButtons(false);
            TQMessageBox::information(this,
                    i18n("Trying to connect device: ") + connectingDevice.address,
                    i18n("Either wait or try disconnecting first"),
                    TQMessageBox::Ok | TQMessageBox::Default,
                    TQMessageBox::NoButton,
                    TQMessageBox::NoButton);
        }
        return;
    }


    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (selAddr == addr)
        {
            bool connected = dit.data()->getConnected(dbuserr);
            if (dbuserr.isValid())
                tqDebug(i18n("Device getConnected failed: %1").arg(dbuserr.message()));
            if (connected)
            {
                connectButton->setText(i18n("&Disconnect"));
            }
            else
            {
                connectButton->setText(i18n("C&onnect"));
            }
            break;
        }
    }
    setStateDeviceButtons(true);
}

void DeviceWizard::slotChangeSetupButton(TQListViewItem *dev)
{
    devicedlg_ext->setupButton->setEnabled(true);
}

void DeviceWizard::slotConnectButton()
{
    TQListViewItem *sel = deviceBox->selectedItem();

    if (!sel)
        return;

    setStateDeviceButtons(false);

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (sel->text(2) == addr)
        {
            if (connectButton->text() == i18n("C&onnect"))
            {
                connectingDevice.state = ConState::CONNECTING;
                connectingDevice.address = addr;

                app->m_config->setGroup(addr);
                TQStringList profiles = app->m_config->readListEntry("profile");
                connectingDevice.profiles = profiles;

                if (connectingDevice.profiles.isEmpty())
                {
                    devicesetupwizard->setDevice(dit.data());
                    devicesetupwizard->show();
                    devicesetupwizard->raise();
                    devicedlg_ext->setupButton->setEnabled(false);
                }
                else
                {
                    slotConnectNextProfile();
                }
            }
            else
            {
                int asyncCallId = 0;
                if (dit.data()->DisconnectAsync(asyncCallId, dbuserr))
                {
                    app->manager->getConnection()->scheduleDispatch();
                    connectingDevice.state = ConState::DISCONNECTING;
                    connectingDevice.profiles.clear();
                }
                if (dbuserr.isValid())
                {
                    tqDebug(i18n("DisconnectAsync failed: %1").arg(dbuserr.message()));
                }
            }
            break;
        }
    }
}

void DeviceWizard::slotConnectNextProfile()
{
    TQString profile = connectingDevice.profiles.first();
    if (profile.isEmpty())
    {
        connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
        return;
    }

    TQT_DBusError dbuserr;
    TQString path;
    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (addr == connectingDevice.address)
        {
            path = dit.key();
            break;
        }
    }

    if (path.isEmpty())
    {
        connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
        return;
    }

    int asyncCallId = 0;
    if (app->devices[path]->ConnectProfileAsync(asyncCallId, profile, dbuserr))
    {
        app->manager->getConnection()->scheduleDispatch();

        connectingDevice.profiles.pop_front();
        if (!connectingDevice.profiles.isEmpty())
            TQTimer::singleShot(CONTIMEOUT, this, TQ_SLOT(slotConnectNextProfile()));
    }
    else
    {
        if (dbuserr.isValid())
            tqDebug(i18n("ConnectProfileAsync failed: %1").arg(dbuserr.message()));

        TQString text = i18n("<p>Attempt to start connection with the device failed</p>"
                    "<p>You can retry to connect or click <b>Cancel</b> to stop.</p>");
        int status = KMessageBox::warningContinueCancel(this,
                text,
                i18n("Connection attempts will be interrupted"),
                KStdGuiItem::quit());
        if (status == KMessageBox::Continue)
            TQTimer::singleShot(CONTIMEOUT, this, TQ_SLOT(slotConnectNextProfile()));
        else
            connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
    }
}

void DeviceWizard::slotSetAdapter(const TQString &path, const TQString &name)
{
    adapter = app->adapters[path];
}

void DeviceWizard::setStateDeviceButtons(bool state)
{
    connectButton->setEnabled(state);
    deleteButton->setEnabled(state);
    configureButton->setEnabled(state);
}

void DeviceWizard::slotDeviceConnectedChanged(const TQString &path, bool connect)
{
    TQT_DBusError dbuserr;
    TQString addr = app->devices[path]->getAddress(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));

    TQListViewItem *devItem = deviceBox->findItem(addr, 2, TQt::ExactMatch);
    if (!devItem)
        return; // may be it was already deleted

    //this is the selected item
    if (devItem == deviceBox->selectedItem())
    {
        if (connect)
            connectButton->setText(i18n("&Disconnect"));
        else
            connectButton->setText(i18n("C&onnect"));
        setStateDeviceButtons(true);
    }

    if (connect)
    {
        KPixmap pix = TDEGlobal::iconLoader()->loadIcon("bookmark", TDEIcon::Small, 16);
        devItem->setPixmap(0, pix);
    }
    else
    {
        devItem->setPixmap(0, TQPixmap());
    }

    // If we initiated the connection request, set state
    if (addr == connectingDevice.address)
    {
        switch (connectingDevice.state)
        {
            case ConState::CONNECTING:
                if (connectingDevice.profiles.isEmpty())
                    connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
                break;
            case ConState::DISCONNECTING:
                connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
                break;
        }
    }
}

void DeviceWizard::slotDeleteDevice()
{
    TQListViewItem *sel = deviceBox->selectedItem();
    /* No device selected */
    if (!sel)
        return;

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (sel->text(2) == addr)
        {
            if (!adapter->RemoveDevice(TQT_DBusObjectPath(dit.key()), dbuserr))
            {
                TQString err = (dbuserr.isValid()) ? dbuserr.message() : i18n("No error message");
                TQMessageBox::information(this,
                        i18n("Remove failed"),
                        i18n("Device ") + addr + i18n(" could not be removed!\nReason: ") + err,
                        TQMessageBox::Ok | TQMessageBox::Default,
                        TQMessageBox::NoButton,
                        TQMessageBox::NoButton);
            }

            app->m_config->deleteGroup(addr);
            app->m_config->sync();

            break;
        }
    }
    // fix for not emitting signal after device was remove
    // this results in not updating the device wizard and
    // leaving the device in the list, while the device is
    // removed from the adapter list
    app->manager->getConnection()->scheduleDispatch();
    // selection is to be removed
    setStateDeviceButtons(false);
}

void DeviceWizard::slotDeviceRemoved(const TQString& path)
{
    kdDebug() << __func__ << endl;
    //  because device was already deleted from the devicemap
    //  we need to find out which view item it is
    TQStringList addrList1 = TQStringList();
    TQStringList addrList2 = TQStringList();

    TQListViewItemIterator it1(deviceBox);
    while (it1.current())
    {
        TQString addr = it1.current()->text(2);
        addrList1.append(addr);
        ++it1;
    }

    TQListViewItemIterator it2(devicedlg_ext->newdevList);
    while (it2.current())
    {
        TQString addr = it2.current()->text(1);
        addrList2.append(addr);
        ++it2;
    }

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (addrList1.grep(addr).size() == 1)
            addrList1.remove(addr);
        if (addrList2.grep(addr).size() == 1)
            addrList2.remove(addr);
    }
    for (TQStringList::Iterator it = addrList1.begin(); it != addrList1.end();
            ++it)
    {
        TQListViewItem *item = deviceBox->findItem((*it), 2, TQt::ExactMatch);
        if (item)
            delete item;
    }
    for (TQStringList::Iterator it = addrList2.begin(); it != addrList2.end();
            ++it)
    {
        TQListViewItem *item = devicedlg_ext->newdevList->findItem((*it), 1, TQt::ExactMatch);
        if (item)
            delete item;
    }

    devicedlg_ext->setupButton->setEnabled(false);
    setStateDeviceButtons(false);
}

void DeviceWizard::slotConfigDevice()
{
    TQListViewItem *sel = deviceBox->selectedItem();
    // No device selected
    if (!sel)
        return;

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (sel->text(2) == addr)
        {
            // device to be configured
            setStateDeviceButtons(false);
            devicesetupwizard->setDevice(dit.data());
            devicesetupwizard->show();
            devicesetupwizard->raise();
            devicedlg_ext->setupButton->setEnabled(false);
            kdDebug() << "address: _____________" << addr << endl;
            break;
        }
    }
}

void DeviceWizard::slotSearch(bool state)
{
    // Discovering can be enabled and disabled only from
    // the one and the same application
    TQT_DBusError dbuserr;
    if (state)
    {
        adapter->StartDiscovery(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device StartDiscovery failed: %1").arg(dbuserr.message()));
        addButton->setText(i18n("&Stop Discovery >>"));
    }
    else
    {
        adapter->StopDiscovery(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device StopDiscovery failed: %1").arg(dbuserr.message()));
        addButton->setText(i18n("&Start Discovery <<"));
    }
}

void DeviceWizard::slotAdapterDiscoveringChanged(const TQString& path, bool state)
{
    timer = state;

    if (state)
    {
//        new device list should be empty when starting search/discovery
//        but also the device should be removed from the bluetooth cache
//        this means iterate over devicedlg_ext->newdevList and call
//        adapter->RemoveDevice(object_path, error) on the device
        disconnect(app->manager, TQ_SIGNAL(deviceRemoved(const TQString&)),
                this, TQ_SLOT(slotDeviceRemoved(const TQString&)));
        TQListViewItemIterator it2(devicedlg_ext->newdevList);
        while (it2.current())
        {
            TQString addr = it2.current()->text(1);
            TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
            for (dit; dit != app->devices.end(); ++dit)
            {
                TQT_DBusError dbuserr;
                TQString thepath = dit.data()->getPath();
                TQString theaddr = dit.data()->getAddress(dbuserr);
                if (dbuserr.isValid())
                    tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
                if (addr == theaddr)
                {
                    adapter->RemoveDevice(thepath, dbuserr);
                    if (dbuserr.isValid())
                        tqDebug(i18n("Remove Device failed: %1").arg(dbuserr.message()));
                    break;
                }
            }
            ++it2;
        }
        devicedlg_ext->newdevList->clear();
        connect(app->manager, TQ_SIGNAL(deviceRemoved(const TQString&)),
                this, TQ_SLOT(slotDeviceRemoved(const TQString&)));
        devicedlg_ext->statusbar->setText(i18n("Device Discovery started"));
        chgLogoTimer->start(LOGOTIMEOUT);
    }
    else
    {
        chgLogoTimer->stop();
        pixmapLabel->setPixmap(pix);
    }
}

void DeviceWizard::slotInsertDevice(const TQString& path)
{
    TQT_DBusError dbuserr;
    TQString addr = app->devices[path]->getAddress(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
    TQString name = app->devices[path]->getName(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getName failed: %1").arg(dbuserr.message()));
    bool paired = app->devices[path]->getPaired(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getPaired failed: %1").arg(dbuserr.message()));
    TQ_UINT32 devclass = app->devices[path]->getClass(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getClass failed: %1").arg(dbuserr.message()));
    bool connected = app->devices[path]->getConnected(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getConnected failed: %1").arg(dbuserr.message()));


    connect(app->devices[path], TQ_SIGNAL(AsyncErrorResponseDetected(int /*asyncCallId*/, const TQT_DBusError)),
            this, TQ_SLOT(slotAsyncErrorResponseDetected(int /*asyncCallId*/, const TQT_DBusError)));
//    connect(app->devices[path], TQ_SIGNAL(ConnectAsyncReply(int /*asyncCallId*/)),
//            this, TQ_SLOT(slotConnectAsyncReply(int /*asyncCallId*/)));
//    connect(app->devices[path], TQ_SIGNAL(DisonnectAsyncReply(int /*asyncCallId*/)),
//            this, TQ_SLOT(slotDisconnectAsyncReply(int /*asyncCallId*/)));
//    connect(app->devices[path], TQ_SIGNAL(ConnectProfileAsyncReply(int /*asyncCallId*/)),
//            this, TQ_SLOT(slotConnectProfileAsyncReply(int /*asyncCallId*/)));


    TQListViewItem *devItem = deviceBox->findItem(addr, 2, TQt::ExactMatch);
    int nitems=0;
    TQListViewItem * devItem2 = deviceBox->firstChild();
    while( devItem2 ) {
        TQString iname = devItem2->text(1);
        if ( iname.startsWith(name) )
                nitems++;
        devItem2 = devItem2->nextSibling();
    }
    // device with same name already exists
    if (nitems>0)
        name = name.append("#%1").arg(nitems);
    //device was already setup but is not in the deviceBox
    if (paired && !devItem)
    {
        TQListViewItem *toAddDev = new TQListViewItem(deviceBox);
        toAddDev->setText(1, name);
        toAddDev->setText(2, addr);
        TQString iconName = DeviceMimeConverter::classToIconName(devclass);
        KPixmap pix2 = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::Small, 16);
        toAddDev->setPixmap(3, pix2);

        KPixmap pix3 = TDEGlobal::iconLoader()->loadIcon("bookmark", TDEIcon::Small, 16);

        if (connected)
            toAddDev->setPixmap(0, pix3);
        deviceBox->insertItem(toAddDev);
        return;
    }

    //device was not setup it belongs to the new device list
    TQString mimeType = DeviceMimeConverter::classToMimeType(devclass);
    TQListViewItem *ndevlist = new TQListViewItem(devicedlg_ext->newdevList, name, addr);
    TQString type;
    if (mimeType == "bluetooth/peripheral-device-class")
    {
        type = i18n("peripheral");
    }
    else if (mimeType == "bluetooth/av-device-class")
    {
        type = i18n("A/V");
    }
    else if (mimeType == "bluetooth/phone-device-class")
    {
        type = i18n("phone");
    }
    else if (mimeType == "bluetooth/wearable-device-class")
    {
        type = i18n("wearable");
    }
    else if (mimeType == "bluetooth/toy-device-class")
    {
        type = i18n("toy");
    }
    else if (mimeType == "bluetooth/health-device-class")
    {
        type = i18n("toy");
    }
    else if (mimeType == "bluetooth/computer-device-class")
    {
        type = i18n("computer");
    }
    else
    {
        type = i18n("unknown");
        ndevlist->setSelectable(false);
    }

    TQString iconName = DeviceMimeConverter::classToIconName(devclass);
    KPixmap pix2 = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::Small, 32);
    ndevlist->setPixmap(2, pix2);

    devicedlg_ext->newdevList->insertItem(ndevlist);

    int size1 = devicedlg_ext->newdevList->columnWidth(0);
    devicedlg_ext->newdevList->setColumnWidth(0, size1 + 15);

    int size2 = devicedlg_ext->newdevList->columnWidth(1);
    devicedlg_ext->newdevList->setColumnWidth(1, size2 + 15);

    devicedlg_ext->statusbar->setText(i18n("Found new %1 device.").arg(type));
}

void DeviceWizard::slotDeviceNameChanged(const TQString& path, const TQString& newname)
{
    TQT_DBusError dbuserr;
    TQString addr = app->devices[path]->getAddress(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));

    TQListViewItem *tmp = devicedlg_ext->newdevList->findItem(addr, 1, TQt::ExactMatch);
    if (tmp) {
        if (tmp->text(0) == "")
        {
            const TQPixmap *ico = tmp->pixmap(2);
            devicedlg_ext->newdevList->takeItem(tmp);
            TQListViewItem *ndevlist = new TQListViewItem(devicedlg_ext->newdevList, newname, addr);
            if (ndevlist)
            {
                ndevlist->setPixmap(2, (*ico));
                devicedlg_ext->newdevList->insertItem(ndevlist);
            }
        }
        return;
    }

    tmp = deviceBox->findItem(addr, 2, TQt::ExactMatch);
    if (tmp) {
        if (tmp->text(0) == "")
        {
            const TQPixmap *ico = tmp->pixmap(2);
            deviceBox->takeItem(tmp);
            TQListViewItem *devlist = new TQListViewItem(deviceBox, newname, addr);
            if (devlist)
            {
                devlist->setPixmap(2, (*ico));
                deviceBox->insertItem(devlist);
            }
        }
    }
}

void DeviceWizard::slotAsyncErrorResponseDetected(int asyncCallId, const TQT_DBusError dbuserr)
{
    tqDebug("AsyncErrorResponseDetected (%i): %i %s %s", asyncCallId, dbuserr.type(), dbuserr.name().local8Bit().data(), dbuserr.message().local8Bit().data());

    connectingDevice = {ConState::IDLE, TQString(), TQStringList()};
    connectButton->setText(i18n("C&onnect"));
    setStateDeviceButtons(true);

    KNotifyClient::event(TDEApplication::kApplication()->mainWidget()->winId(),
            "ConnectionError", i18n("AsyncErrorResponseDetected: %1\n%2\n%3")
                        .arg(dbuserr.type())
                        .arg(dbuserr.name())
                        .arg(dbuserr.message()));
}

void DeviceWizard::slotSetupNewDevice()
{
    TQListViewItem *confSel = devicedlg_ext->newdevList->currentItem();
    if (!confSel)
    {
        TQMessageBox::information(this,
                i18n("Setup device"),
                i18n("You have to select a remote Device to setup!"),
                TQMessageBox::Ok | TQMessageBox::Default,
                TQMessageBox::NoButton,
                TQMessageBox::NoButton);
        return;
    }

    if (!confSel->isSelectable())
    {
        TQMessageBox::information(this,
                i18n("Setup device"),
                i18n("This device is not configurable!"),
                TQMessageBox::Ok | TQMessageBox::Default,
                TQMessageBox::NoButton,
                TQMessageBox::NoButton);
        return;
    }

    TQString selAddr = confSel->text(1);
    DeviceImpl *newdev;

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (selAddr == addr)
        {
            newdev = dit.data();
            break;
        }
    }

    if (!newdev)
    {
        TQMessageBox::information(this,
                i18n("Setup device"),
                i18n("No device matching selection was found!"),
                TQMessageBox::Ok | TQMessageBox::Default,
                TQMessageBox::NoButton,
                TQMessageBox::NoButton);
        return;
    }

    setStateDeviceButtons(false);
    devicesetupwizard->setDevice(newdev);
    devicesetupwizard->show();
    devicesetupwizard->raise();
    devicedlg_ext->setupButton->setEnabled(false);

    kdDebug() << "address: _____________" << selAddr << endl;
}

void DeviceWizard::slotDevicePairedChanged(const TQString& path, bool)
{
    TQListViewItem *confSel = devicedlg_ext->newdevList->currentItem();
    if (!confSel)
        return;

    TQString selAddr = confSel->text(1);
    TQListViewItem* newDeviceBoxItem = new TQListViewItem(deviceBox);
    newDeviceBoxItem->setText(1, confSel->text(0));
    newDeviceBoxItem->setText(2, selAddr);

    TDEBluetoothApp::DevicesMap::Iterator dit = app->devices.begin();
    for (dit; dit != app->devices.end(); ++dit)
    {
        TQT_DBusError dbuserr;
        TQString addr = dit.data()->getAddress(dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Device getAddress failed: %1").arg(dbuserr.message()));
        if (addr == selAddr)
        {
            TQString iconName = DeviceMimeConverter::classToIconName(dit.data()->getClass(dbuserr));
            KPixmap pix4 = TDEGlobal::iconLoader()->loadIcon(iconName, TDEIcon::Small, 16);
            newDeviceBoxItem->setPixmap(3, pix4);
            break;
        }
    }

    deviceBox->insertItem(newDeviceBoxItem);
    delete confSel;
}

//void DeviceWizard::slotMediaControlConnectedChanged(const TQString &path,
//		bool connect)
//{
//	if (connect)
//		mediaCtlDialog = new MediaControl(path, app->manager->getConnection());
//	else
//		mediaCtlDialog->close();
//}

void DeviceWizard::slotUpdateLogo()
{
    if (!addButton->isOn()) {
        timer = false;
        pixmapLabel->setPixmap(pix);
        return;
    }

    if (timer == false)
    {
        pixmapLabel->setPixmap(logoBlend);
        timer = true;
    }
    else
    {
        pixmapLabel->setPixmap(pix);
        timer = false;
    }
}

#include "devicewizard.moc"

