#include "seffectwidget.h"

#include <phonon/effectwidget.h>
#include <phonon/objectdescription.h>
#include <phonon/effectparameter.h>
#include <phonon/effect.h>

#include <QSlider>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QList>
#include <QHash>
#include <QVariant>
#include <QComboBox>
#include <QDebug>

class SEffectSlider : public QWidget
{
public:
    SEffectSlider( QWidget *parent = 0 );

    QSlider *slider;
    QLabel *label;
    QVBoxLayout *layout;
};

SEffectSlider::SEffectSlider( QWidget *parent ) : QWidget( parent )
{
    slider = new QSlider( Qt::Vertical );
        slider->setAttribute( Qt::WA_AlwaysShowToolTips , true );

    label = new QLabel("0");
        label->setAlignment( Qt::AlignCenter );

    layout = new QVBoxLayout( this );
        layout->addWidget( slider );
        layout->addWidget( label );
}






class SEffectWidgetPrivate
{
public:
    QHBoxLayout *hlayout;
    QVBoxLayout *vlayout;
    QList<Phonon::EffectParameter> parameters;
    Phonon::Effect *effect;
    QHash<Phonon::EffectParameter,QWidget *> hash;
};

SEffectWidget::SEffectWidget( Phonon::Effect *effect , QWidget *parent ) :
    QWidget(parent)
{
    p = new SEffectWidgetPrivate;
    p->effect = effect;

    p->hlayout = new QHBoxLayout( this );
        p->hlayout->setContentsMargins( 0 , 0 , 0 , 0 );
        p->hlayout->setSpacing( 0 );

    SEffectSlider *slider;
    QComboBox *combo;

    p->parameters = p->effect->parameters();
    for( int i=0 ; i<p->parameters.count() ; i++ )
    {
        Phonon::EffectParameter parameter = p->parameters.at(i);
        QVariant variant = p->effect->parameterValue( parameter );

        if( QString(variant.typeName()).contains("float") )
            variant.setValue( (double)variant.toFloat() );

        switch( static_cast<int>(variant.type()) )
        {
        case QVariant::Double :
            slider = new SEffectSlider();
                slider->slider->setToolTip( parameter.description() );
                if( QString(variant.typeName()).contains("float") )
                {
                    slider->slider->setMaximum( parameter.maximumValue().toFloat()*10 );
                    slider->slider->setMinimum( parameter.minimumValue().toFloat()*10 );
                }
                else
                {
                    slider->slider->setMaximum( parameter.maximumValue().toDouble()*10 );
                    slider->slider->setMinimum( parameter.minimumValue().toDouble()*10 );
                }
                slider->slider->setValue( variant.toDouble()*10 );
                slider->slider->setMaximumWidth( 21 );

            p->hlayout->addWidget( slider );
            p->hash.insert( parameter , slider );
            QObject::connect( slider->slider , SIGNAL(valueChanged(int)) , SLOT(process()) );
            break;

        case QVariant::Int :
            slider = new SEffectSlider();
                slider->slider->setToolTip( parameter.description() );
                slider->slider->setMaximum( parameter.maximumValue().toInt() );
                slider->slider->setMinimum( parameter.minimumValue().toInt() );
                slider->slider->setValue( variant.toInt() );

            p->hlayout->addWidget( slider );
            p->hash.insert( parameter , slider );
            QObject::connect( slider->slider , SIGNAL(valueChanged(int)) , SLOT(process()) );
            break;

        case QVariant::StringList :
            combo = new QComboBox();
                combo->addItems( variant.toStringList() );
                combo->setToolTip( parameter.description() );

            p->vlayout->addWidget( combo );
            p->hash.insert( parameter , combo );
            QObject::connect( combo , SIGNAL(currentIndexChanged(int)) , SLOT(process()) );
            break;
        }
    }

    this->setWindowTitle( effect->description().name() );

    this->process();
}

void SEffectWidget::process()
{
    SEffectSlider *slider;
    QComboBox *combo;

    QVariant evar;
    QStringList str_list;

    for( int i=0 ; i<p->parameters.count() ; i++ )
    {
        Phonon::EffectParameter parameter = p->parameters.at(i);
        QVariant variant = p->effect->parameterValue( parameter );

        if( QString(variant.typeName()).contains("float") )
            variant.setValue( (double)variant.toFloat() );

        switch( static_cast<int>(variant.type()) )
        {
        case QVariant::Double :
            slider = static_cast<SEffectSlider *>( p->hash.value(parameter) );
            if( QString(variant.typeName()).contains("float") )
                evar = (float)slider->slider->value()/10;
            else
                evar = (double)slider->slider->value()/10;

            p->effect->setParameterValue( parameter , evar );
            slider->label->setText( QString::number(evar.toDouble()) );

            break;

        case QVariant::Int :
            slider = static_cast<SEffectSlider *>( p->hash.value(parameter) );
            evar = (int)slider->slider->value();

            p->effect->setParameterValue( parameter , evar );
            slider->label->setText( QString::number(evar.toInt()) );
            break;

        case QVariant::StringList :
            combo = static_cast<QComboBox *>( p->hash.value(parameter) );

            str_list.clear();
            for( int i=0 ; i<combo->count() ; i++ )
                str_list << combo->itemText(i);

            evar = str_list;
            p->effect->setParameterValue( parameter , evar );
            break;
        }
    }
}
