/*
 *
 *  Adapter config dialog 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 <kdebug.h>
#include "adapterconfig.h"
#include  <devicemimeconverter.h>

#include <btuuids.h>

AdapterConfig::AdapterConfig(ObjectManagerImpl *mgr, AdapterImpl *a)
{
    adapterDialog = new AdapterDialog();
    manager = mgr;
    adapter = a;

    TQT_DBusError dbuserr;
    name = adapter->getAlias(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get alias for the adapter failed: %1").arg(dbuserr.message()));

    adapterDialog->deviceModes->insertItem(i18n("Hidden"));
    adapterDialog->deviceModes->insertItem(i18n("Always visible"));
    adapterDialog->deviceModes->insertItem(i18n("Temporary visible"));

    adapterDialog->deviceClass->insertItem(i18n("Unknown"));
    adapterDialog->deviceClass->insertItem(i18n("Computer"));
    adapterDialog->deviceClass->setEnabled(false);

    adapterDialog->adapterName->setText(name);

    addAdapterDialogInfo();

    // ADAPTER -> MANAGER -> DIALOG
    connect(manager, TQ_SIGNAL(adapterNameChanged(const TQString&,const TQString&)),
            this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));
    connect(manager, TQ_SIGNAL(adapterAliasChanged(const TQString&,const TQString&)),
            this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));

    connect(manager, TQ_SIGNAL(adapterDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)),
            this, TQ_SLOT(slotDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)));
    connect(manager, TQ_SIGNAL(adapterDiscoverableChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDiscoverableChanged(const TQString&, bool)));
    connect(manager, TQ_SIGNAL(adapterPowerOnChanged(const TQString&, bool)), this, TQ_SLOT(slotPowerOnChanged(const TQString&, bool)));

    // DIALOG -> ADAPTER
    connect(adapterDialog->adapterName, TQ_SIGNAL(textChanged(const TQString &)),
            this, TQ_SLOT(slotChangeName(const TQString &)));
    connect(adapterDialog->deviceModes, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotSetMode(int)));
//	connect(adapterDialog->deviceClass, TQ_SIGNAL(activated(const TQString &)),
    //			this, TQ_SLOT(slotSetClass(const TQString &)));
    connect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));

    adapterDialog->setModal(false);
}

AdapterConfig::~AdapterConfig()
{
    if (adapterDialog)
        delete adapterDialog;
}

void AdapterConfig::addAdapterDialogInfo()
{
    TQT_DBusError dbuserr;
    bool disc = adapter->getDiscoverable(dbuserr);
    int timeout = adapter->getDiscoverableTimeout(dbuserr);
    if (disc)
    {
        if (timeout > 0)
        {
            adapterDialog->deviceModes->setCurrentItem(2);
            adapterDialog->timeout->setNum(int(timeout) / 60);
            adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
            adapterDialog->sliderTimeout->setValue(timeout);

            adapterDialog->sliderTimeout->setEnabled(true);
            adapterDialog->timeout->setEnabled(true);
            adapterDialog->textLabel9->setEnabled(true);

        }
        else
        {
            adapterDialog->deviceModes->setCurrentItem(1);
            adapterDialog->timeout->setNum(int(timeout) / 60);
            adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
            adapterDialog->sliderTimeout->setValue(timeout);

            adapterDialog->sliderTimeout->setEnabled(false);
            adapterDialog->timeout->setEnabled(false);
            adapterDialog->textLabel9->setEnabled(false);
        }
    }
    else
    {
        adapterDialog->deviceModes->setCurrentItem(0);
        adapterDialog->timeout->setText(i18n("none"));
        adapterDialog->sliderTimeout->setValue(0);

        adapterDialog->sliderTimeout->setEnabled(false);
        adapterDialog->timeout->setEnabled(false);
        adapterDialog->textLabel9->setEnabled(false);
    }

    slotSetClass(DeviceMimeConverter::classToMimeType(adapter->getClass(dbuserr)));
    if (dbuserr.isValid())
        tqDebug(i18n("Get class for the adapter failed: %1").arg(dbuserr.message()));

    TQString address = adapter->getAddress(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get address for the adapter failed: %1").arg(dbuserr.message()));
    TQStringList uuids = adapter->getUUIDs(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get uuids for the adapter failed: %1").arg(dbuserr.message()));
    TQVBoxLayout *infoLayout = new TQVBoxLayout(adapterDialog->groupBoxInfo->layout());
    //	GridLayout *infoGrid = new TQGridLayout(adapterDialog->groupBoxInfo->layout());

    if (!address.isNull())
        adapterDialog->macLabel->setText(i18n("MAC Address: <b>%1</b>").arg(address));

    if (!uuids.isEmpty())
    {
        TQString supported;
        //	DeviceList;
        for (TQStringList::iterator it = uuids.begin(); it != uuids.end(); ++it)
        {
            supported += resolveUUID((*it)) + ", ";
        }
        adapterDialog->verLabel->setText(i18n("<p>Services:<br/><b>%1</b></p>").arg(supported.left(supported.length() - 2)));
    }

}

//from adapter

void AdapterConfig::slotAdapterNameChanged(const TQString &path, const TQString &n)
{
    if (path != adapter->getPath())
        return;
    name = n;
    disconnect(adapterDialog->adapterName, TQ_SIGNAL(textChanged(const TQString &)),
            this, TQ_SLOT(slotChangeName(const TQString &)));

    adapterDialog->adapterName->setText(name);

    connect(adapterDialog->adapterName, TQ_SIGNAL(textChanged(const TQString &)),
            this, TQ_SLOT(slotChangeName(const TQString &)));
}

void AdapterConfig::slotPowerOnChanged(const TQString &path, bool state)
{
    if (path != adapter->getPath())
        return;

    addAdapterDialogInfo();

    adapterDialog->setEnabled(state);
}

void AdapterConfig::slotDiscoverableChanged(const TQString &path, bool changed)
{
    if (path != adapter->getPath())
        return;

    TQT_DBusError dbuserr;
    TQ_UINT32 timeout = adapter->getDiscoverableTimeout(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get discoverable timeout for the adapter failed: %1").arg(dbuserr.message()));
    disconnect(adapterDialog->deviceModes, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotSetMode(int)));
    disconnect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));

    if (changed)
    {
        if (timeout > 0)
        {
            adapterDialog->deviceModes->setCurrentItem(2);
            adapterDialog->timeout->setNum(int(timeout) / 60);
            adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
            adapterDialog->sliderTimeout->setValue(timeout);
            adapterDialog->sliderTimeout->setEnabled(false);
            adapterDialog->timeout->setEnabled(false);
            adapterDialog->textLabel9->setEnabled(false);
        }
        else
        {
            adapterDialog->deviceModes->setCurrentItem(1);
            adapterDialog->timeout->setNum(int(timeout) / 60);
            adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
            adapterDialog->sliderTimeout->setValue(timeout);
            adapterDialog->sliderTimeout->setEnabled(true);
            adapterDialog->timeout->setEnabled(true);
            adapterDialog->textLabel9->setEnabled(true);
        }
    }
    else
    {
        adapterDialog->deviceModes->setCurrentItem(0);
        adapterDialog->sliderTimeout->setValue(0);
        adapterDialog->timeout->setText(i18n("none"));
        adapterDialog->sliderTimeout->setEnabled(false);
        adapterDialog->timeout->setEnabled(false);
        adapterDialog->textLabel9->setEnabled(false);
    }
    connect(adapterDialog->deviceModes, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotSetMode(int)));
    connect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));
}

void AdapterConfig::slotDiscoverableTimeoutChanged(const TQString &path, TQ_UINT32 timeout)
{
    if (path != adapter->getPath())
        return;

    disconnect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));

    if (timeout == 0)
    {
        adapterDialog->sliderTimeout->setValue(0);
        adapterDialog->timeout->setText(i18n("none"));
        adapterDialog->sliderTimeout->setEnabled(false);
        adapterDialog->timeout->setEnabled(false);
        adapterDialog->textLabel9->setEnabled(false);
    }
    else
    {
        adapterDialog->timeout->setNum(int(timeout) / 60);
        adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
        adapterDialog->sliderTimeout->setValue(int(timeout));
        adapterDialog->sliderTimeout->setEnabled(true);
        adapterDialog->timeout->setEnabled(true);
        adapterDialog->textLabel9->setEnabled(true);
    }
    connect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));
}

// from dialog
void AdapterConfig::slotChangeName(const TQString &n)
{
    name = n;
    TQT_DBusError dbuserr;
    if (adapterDialog->adapterName->text() != name)
    {
        //otherwise signal textchanged() from the dialog and slot nameChanged
        //from the adapter will end in a endless loop.
        disconnect(manager, TQ_SIGNAL(adapterNameChanged(const TQString&,const TQString&)),
                this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));
        disconnect(manager, TQ_SIGNAL(adapterAliasChanged(const TQString&,const TQString&)),
                this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));

//		adapterDialog->adapterName->setText(name);
        adapter->setAlias(name, dbuserr);
        if (dbuserr.isValid())
            tqDebug(i18n("Set alias for the adapter failed: %1").arg(dbuserr.message()));

        connect(manager, TQ_SIGNAL(adapterNameChanged(const TQString&,const TQString&)),
                this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));
        connect(manager, TQ_SIGNAL(adapterAliasChanged(const TQString&,const TQString&)),
                this, TQ_SLOT(slotAdapterNameChanged(const TQString&, const TQString&)));
    }
}

void AdapterConfig::slotChangeTimeout(int timeout)
{
    // Disconnect signal of valueChanged!
    // D-Bus signal get emmited immeditaly ..
    // and would trigger a endless loop of signals!
    TQT_DBusError dbuserr;
    disconnect(manager, TQ_SIGNAL(adapterDiscoverableChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDiscoverableChanged(const TQString&, bool)));
    disconnect(manager, TQ_SIGNAL(adapterDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)),
            this, TQ_SLOT(slotDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)));

    adapterDialog->timeout->setNum(int(timeout) / 60);
    adapterDialog->sliderTimeout->setValue(int(timeout));
    adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
    adapter->setDiscoverableTimeout(timeout, dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Set discoverable timeout for the adapter failed: %1").arg(dbuserr.message()));

    connect(manager, TQ_SIGNAL(adapterDiscoverableChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDiscoverableChanged(const TQString&, bool)));
    connect(manager, TQ_SIGNAL(adapterDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)),
            this, TQ_SLOT(slotDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)));
}

void AdapterConfig::slotSetMode(int modenr)
{

    TQT_DBusError dbuserr;
    int timeout = adapter->getDiscoverableTimeout(dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get discoverable timeout for the adapter failed: %1").arg(dbuserr.message()));

    // Disconnect signal of valueChanged!
    // D-Bus signal get emmited immeditaly ..
    // and would trigger a endless loop of signals!
    disconnect(adapterDialog->deviceModes, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotSetMode(int)));
    disconnect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));
    disconnect(manager, TQ_SIGNAL(adapterDiscoverableChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDiscoverableChanged(const TQString&, bool)));
    disconnect(manager, TQ_SIGNAL(adapterDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)),
            this, TQ_SLOT(slotDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)));

    switch (modenr)
    {
    case 0:
    case 1:
        timeout = 0;
        adapterDialog->timeout->setText(i18n("none"));
        adapterDialog->sliderTimeout->setValue(timeout);

        adapterDialog->sliderTimeout->setEnabled(false);
        adapterDialog->timeout->setEnabled(false);
        adapterDialog->textLabel9->setEnabled(false);
        break;
    case 2:
        if (timeout == 0)
            timeout = 180;
        adapterDialog->timeout->setNum(timeout / 60);
        adapterDialog->timeout->setText(adapterDialog->timeout->text().append(i18n("min")));
        adapterDialog->sliderTimeout->setValue(timeout);

        adapterDialog->sliderTimeout->setEnabled(true);
        adapterDialog->timeout->setEnabled(true);
        adapterDialog->textLabel9->setEnabled(true);
        break;
    }
    adapter->setDiscoverable(((modenr > 0) ? true : false), dbuserr);
    adapter->setDiscoverableTimeout(timeout, dbuserr);
    if (dbuserr.isValid())
        tqDebug(i18n("Get discoverable for the adapter failed: %1").arg(dbuserr.message()));

    connect(adapterDialog->deviceModes, TQ_SIGNAL(activated(int)),
            this, TQ_SLOT(slotSetMode(int)));
    connect(adapterDialog->sliderTimeout, TQ_SIGNAL(valueChanged(int)),
            this, TQ_SLOT(slotChangeTimeout(int)));

    connect(manager, TQ_SIGNAL(adapterDiscoverableChanged(const TQString&, bool)),
            this, TQ_SLOT(slotDiscoverableChanged(const TQString&, bool)));
    connect(manager, TQ_SIGNAL(adapterDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)),
            this, TQ_SLOT(slotDiscoverableTimeoutChanged(const TQString&, TQ_UINT32)));
}

void AdapterConfig::slotSetClass(const TQString & deviceClass)
{
    if (deviceClass == "bluetooth/computer-device-class")
    {
        adapterDialog->deviceClass->setCurrentItem(1);
    }
    else
    {
        adapterDialog->deviceClass->setCurrentItem(0);
    }
}

#include "adapterconfig.moc"
