/***************************************************************************
                          devicewidgetimpl.cpp  -  description
                             -------------------
    begin                : Mon Jun 3 2002
    copyright            : (C) 2002 by Kevin Hessels, George Staikos
    email                : khessels@shaw.ca, staikos@kde.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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <qcombobox.h>

#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>

#include "cfgdata.h"
#include "devicewidgetimpl.h"
#include "qtvision.h"


DeviceWidgetImpl::DeviceWidgetImpl(QWidget *parent, ConfigData *currConfig, QtVision *qtv)
                 :DeviceWidget(parent), _qtv(qtv), _cfg(currConfig)
{
    connect(_device, SIGNAL(highlighted(const QString &)), this,
	        SLOT( slotChangeSources( const QString &) ) );
    scanDevices();
    connect(_device, SIGNAL(activated(int)), this, SLOT(slotDeviceChanged()));
    connect(_source, SIGNAL(activated(int)), this, SLOT(slotSourceChanged()));
} // DeviceWidgetImpl constructor


DeviceWidgetImpl::~DeviceWidgetImpl()
{
} // DeviceWidgetImpl destructor


void DeviceWidgetImpl::device(QtVision *qtv)
{
    if (!qtv)
        return;
       
    for (DeviceMap::Iterator it = _devs.begin(); it != _devs.end(); ++it) {
        for (QStringList::Iterator s = it.data().begin(); s != it.data().end(); ++s) {
            if (*s == _device->currentText()) {
//kdDebug() << "TRYING TO OPEN DEVICE: " << *s << endl;
                QVSourcePlugin *vsrc = 
                              _qtv->pluginFactory()->getVideoPlugin(&it.key(),
                                                                qtv->screen());
                if (vsrc) {
//kdDebug() << "SUCCESS" << endl;
                    vsrc->setDevice(*s);
                    if (vsrc->needsNorm())
                        vsrc->setNorm(_region->currentItem());
                    qtv->setDevice(vsrc);
                   break;
                } 
            } 
        }
    }

    if (!qtv->hasDevice()) {
        KMessageBox::sorry(this,
                          i18n("Error opening device.  Please select another."),
                          i18n("QtVision"));
    } else {
        qtv->setSource(_source->currentText());
    }
    _cfg->nps = _region->currentItem();
} // device


void DeviceWidgetImpl::setCurrentDevice()
{
    _devChanged = _srcChanged = false;

    if (_qtv->device()) {
        _region->setCurrentItem(_cfg->nps);
        QString dt = _qtv->device()->device();
        QString st = _qtv->device()->source();
        for (int i = 0; i < _device->count(); i++) {
            if (_device->text(i) == dt) {
               _device->setCurrentItem(i);
               slotChangeSources(dt);
               break;
            }
        }

        for (int i = 0; i < _source->count(); i++) {
            if (_source->text(i) == st) {
               _source->setCurrentItem(i);
               break;
            }
        }
    } else {
        _region->setCurrentItem(_cfg->nps);
        if (!_cfg->prevDev.isEmpty()) {
            for (int i = 0; i < _device->count(); i++) {
                if (_device->text(i) == _cfg->prevDev) {
                   _device->setCurrentItem(i);
                   slotChangeSources(_cfg->prevDev);
                   break;
                }
            }
        }

        if (!_cfg->prevSrc.isEmpty()) {
            for (int i = 0; i < _source->count(); i++) {
                if (_source->text(i) == _cfg->prevSrc) {
                   _source->setCurrentItem(i);
                   break;
                }
            }
        }
    }

    // determine whether to turn on or off the region widget
    updateRegionStatus();
} // setCurrentDevice


bool DeviceWidgetImpl::deviceChanged()
{
    return(_devChanged || _srcChanged);
} // deviceChanged


/***************************************************************************
*
* Protected Slots
*
***************************************************************************/

void DeviceWidgetImpl::slotChangeSources(const QString &dev)
{
    kdDebug() << "Change sources! dev=" << dev << " has srcs? " << (_srcs.contains(dev) ? "yes" : "no") << endl;
    this->_source->clear();
    this->_source->insertStringList(_srcs[dev]);
    QString lastSource = _cfg->lastSourceFor(dev);
    if (!lastSource.isEmpty()) {
        for (int i = 0; i < this->_source->count(); i++) {
            if (this->_source->text(i) == lastSource) {
                this->_source->setCurrentItem(i);
                break;
            }
        }
    }
} // slotChangeSources


/***************************************************************************
*
* Private Functions
*
***************************************************************************/

//
// The following function was written by George Staikos
//

void DeviceWidgetImpl::scanDevices()
{
    _devs.clear();
    _srcs.clear();
    bool first = true;

    _devTuner.clear();
    _devNeedsNorm.clear();

    QPtrList<PluginDesc>& vps(_qtv->pluginFactory()->videoPlugins());
    for (PluginDesc *plug = vps.first(); plug; plug = vps.next()) {
        kdDebug() << "Found a plugin:" << endl;
        kdDebug() << plug->name << endl;
        kdDebug() << plug->author << endl;
        kdDebug() << plug->comment << endl;
        QVSourcePlugin *vsrc = _qtv->pluginFactory()->getVideoPlugin(plug,
                                                                _qtv->screen());
        if (vsrc == 0)
            continue;

        vsrc->probeDevices();

        for (QStringList::ConstIterator it = vsrc->deviceList().begin();
                                         it != vsrc->deviceList().end();
                                                                    ++it) {
            QString thisDev = *it;
            kdDebug() << "Found device " << thisDev
                      << " in plugin " << plug->name << endl;
            kdDebug() << "Device contains " << vsrc->sourceList(thisDev).count()
                      << " sources." << endl;
            _devs[*plug] += thisDev;
            _srcs[thisDev] = vsrc->sourceList(thisDev);
            _devTuner[thisDev] = vsrc->isTuner(thisDev);
            _devNeedsNorm[thisDev] = vsrc->needsNorm();
            this->_device->insertItem(thisDev);
            if (first) {
                this->_source->insertStringList(_srcs[thisDev]);
                first = false;
            }
        }
        delete vsrc;
    }
    kdDebug() << "Done probing devices." << endl;
} // scanDevices


bool DeviceWidgetImpl::deviceIsTuner(const QString &device)
{
    return _devTuner[device];
} // deviceIsTuner


void DeviceWidgetImpl::updateRegionStatus()
{
    if (!deviceIsTuner(_device->currentText()))
        _region->setEnabled(false);
    else
        _region->setEnabled(_devNeedsNorm[_device->currentText()]);
} // updateRegionStatus
    


/***************************************************************************
*
* Private Slots
*
***************************************************************************/


void DeviceWidgetImpl::slotDeviceChanged()
{
    _devChanged = true;

    updateRegionStatus();
} // slotDeviceChanged


void DeviceWidgetImpl::slotSourceChanged()
{
    _srcChanged = true;
} // slotSourceChanged

