/***************************************************************************
                           controlwidgetimpl.cpp
                           ---------------------
    begin                : Sun Nov 21 2004
    copyright            : (C) 2004 by Dirk Ziegelmeier
    email                : dziegel@gmx.de
 ***************************************************************************/

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include <qlayout.h>
#include <qlabel.h>
#include <qslider.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <qtabwidget.h>
#include <qcombobox.h>
#include <qradiobutton.h>

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

#include "controlwidgetimpl.h"
#include "controlwidgetimpl.moc"

#include "channel.h"

ControlWidgetImpl::ControlWidgetImpl(const Control::ControlList& controls, Channel* channel,
                                     const QString& dev,
                                     QWidget* parent, const char* name, WFlags f)
    : ControlWidget(parent, name, f),
      _controlList(controls),
      _channel(channel),
      _dev(dev)
{
    if(_channel != NULL) {
        _currentChannel->setChecked(channel->hasControls(_dev));
        _allChannels->setChecked(!channel->hasControls(_dev));
    }

    QGridLayout* basicLayout    = new QGridLayout(_basicControls,    controls.count(), 2, 5);
    QGridLayout* advancedLayout = new QGridLayout(_advancedControls, controls.count(), 2, 5);

    int basicRow    = 0;
    int advancedRow = 0;

    for(Control::ControlList::ConstIterator it = controls.constBegin();
        it != controls.constEnd();
        ++it) {
        const Control::Control* c = static_cast<Control*>(*it);
        QWidget* w;
        QGridLayout* l;
        int* row;

        if(c->advanced) {
            w   = _advancedControls;
            l   = advancedLayout;
            row = &advancedRow;
        } else {
            w   = _basicControls;
            l   = basicLayout;
            row = &basicRow;
        }

        _previousValues[c->internalName] = c->valueAsQVariant();

        switch(c->controlType) {
        case Control::Control_Int:
            {
                const IntegerControl* control = static_cast<const IntegerControl*>(c);
                QSlider* s = new QSlider(control->minimumValue,
                                         control->maximumValue,
                                         control->step,
                                         control->value(),
                                         Qt::Horizontal, w);
                l->addWidget(new QLabel(QString("%1:").arg(c->uiName), w), *row, 0);
                l->addWidget(s, *row, 1);
                connect(s, SIGNAL( valueChanged(int) ),
                        control, SLOT( setValue(int) ));
                connect(control, SIGNAL( changed(int) ),
                        s, SLOT( setValue(int) ));
            }
            break;
        case Control::Control_Bool:
            {
                const BooleanControl* control = static_cast<const BooleanControl*>(c);
                QCheckBox* cb = new QCheckBox(c->uiName, w);
                l->addMultiCellWidget(cb, *row, *row, 0, 1);
                cb->setChecked(control->value());
                connect(cb, SIGNAL( toggled(bool) ),
                        control, SLOT( setValue(bool) ));
                connect(control, SIGNAL( changed(bool) ),
                        cb, SLOT( setChecked(bool) ));
            }
            break;
        case Control::Control_Button:
            {
                const ButtonControl* control = static_cast<const ButtonControl*>(c);
                QPushButton* b = new QPushButton(c->uiName, w);
                l->addMultiCellWidget(b, *row, *row, 0, 1);
                connect(b, SIGNAL( clicked() ),
                        control, SLOT( click() ));
            }
            break;
        case Control::Control_Menu:
            {
                const MenuControl* control = static_cast<const MenuControl*>(c);
                QComboBox* b = new QComboBox(w, "ControlMenu");
                b->insertStringList(control->choices);
                b->setCurrentText(control->value());
                l->addWidget(new QLabel(QString("%1:").arg(c->uiName), w), *row, 0);
                l->addWidget(b, *row, 1);
                connect(b, SIGNAL( activated(const QString&) ),
                        control, SLOT( setValue(const QString&) ));
                connect(control, SIGNAL( changed(const QString&) ),
                        b, SLOT( setCurrentText(const QString&) ));
            }
            break;
        default:
            (*row)--;
            break;
        }

        (*row)++;
    }

    if(basicRow == 0) {
        _controlsTabWidget->removePage(_basicControls);
    }
    if(advancedRow == 0) {
        _controlsTabWidget->removePage(_advancedControls);
    }
}

ControlWidgetImpl::~ControlWidgetImpl()
{
}

void ControlWidgetImpl::defaults()
{
    for(Control::ControlList::Iterator it = _controlList.begin();
        it != _controlList.end();
        ++it) {
        Control::Control* c = static_cast<Control*>(*it);
        c->setDefault();
    }
    _currentChannel->setChecked(false);
}

void ControlWidgetImpl::apply()
{
    if(_channel != NULL) {
        _channel->setHasControls(_dev,_currentChannel->isChecked());
    }
}

void ControlWidgetImpl::cancel()
{
    for(Control::ControlList::Iterator it = _controlList.begin();
        it != _controlList.end();
        ++it) {
        Control::Control* c = static_cast<Control*>(*it);
        c->setValue(_previousValues[c->internalName]);
    }
}
