/***************************************************************************
 *   Copyright (C) 2004 by Predrag Viceic                                  *
 *   viceic@net2000.ch                                             *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "ladspadialog.h"

LADSPADialog::LADSPADialog(QWidget* parent, const char * name)
 : LADSPADialogBase(parent,name)
{
    table->setColumnWidth( 0, 320 );
    table->setColumnWidth( 3, 70 );
    selectedUniqueId=-1;
    QHeader* header=table->horizontalHeader();
    connect(header,SIGNAL(clicked(int)),this,SLOT(headerClicked(int)));
    doublePlugCheckbox->setChecked(FALSE);
    currentRow=0;
    sortingColumn=0;
}


LADSPADialog::~LADSPADialog()
{
}




/*!
    \fn LADSPADialog::setEffectsList(LADSPAEffects*)
 */
void LADSPADialog::setEffectsList(LADSPAEffects* el)
{
    effects=el;
    table->setNumRows(effects->getEffects()->count());
    int count=0;
    for (QPtrList<LADSPAEffect>::Iterator it = effects->getEffects()->begin();
            it!=effects->getEffects()->end();++it){

        table->setText(count,NAME,(*it)->getName());
        table->setText(count,LABEL,(*it)->getLabel());
        table->setText(count,MAKER,(*it)->getMaker());
        table->setText(count,UID,QString::number((*it)->getUniqueID()));
        table->setColumnReadOnly( count, TRUE );
        count++;
    }

}

void LADSPADialog::accept(){
    table->removeSelection(0);
    if(selectedUniqueId!=-1){
        if (checkPortAssignments()){
            std::cout<<"Effect added:"<<selectedUniqueId<<"\n";
            QDialog::accept();
            emit(addEffect(selectedUniqueId));
        }
    }
}

void LADSPADialog::currentChanged_(int row, int){
    currentRow=row;
    clearScrollViews();
    doublePlugCheckbox->setEnabled(TRUE);
    selectedUniqueId=table->text(row,3).toInt();
    LADSPAEffect* currentEffect=effects->getEffect(selectedUniqueId);
    currentEffect->setDoublePlugin(doublePlugCheckbox->isChecked());
    if(!currentEffect) return;
    connect(doublePlugCheckbox,SIGNAL(toggled(bool)),currentEffect,SLOT(setDoublePlugin(bool)));
    QString pluginText(table->text(row,0)+":\n\n");
    pluginText+="Label: "+table->text(row,1)+"\n";
    pluginText+="Maker: "+table->text(row,2)+"\n";
    pluginText+="Unique ID: "+table->text(row,3)+"\n";
    pluginText+="Copyright: "+QString::fromAscii(currentEffect->getCopyright())+"\n";
    pluginText+="Port count: "+QString::number(currentEffect->getPortCount())+"\n";
    pluginText+="Hard RT: "+QString::number(currentEffect->isHardRTCapable())+"\n";
    pluginText+="Inplace broken: "+QString::number(currentEffect->isInplaceBroken())+"\n";
    pluginText+="Realtime: "+QString::number(currentEffect->isRealtime());
    pluginTextLabel->setText(tr(pluginText));

    QString controlInputsText("");

    for (QPtrList<LADSPAPort>::Iterator it = currentEffect->getControlInputPorts()->begin();
            it!=currentEffect->getControlInputPorts()->end();++it){
        controlInputsText+=(*it)->getPortName()+"\n";
    }
    controlInputsTextLabel->setText(controlInputsText);

    QString controlOutputsText("!NOT USED!\n");

    for (QPtrList<LADSPAPort>::Iterator it = currentEffect->getControlOutputPorts()->begin();
            it!=currentEffect->getControlOutputPorts()->end();++it){
        controlOutputsText+=(*it)->getPortName()+"\n";
    }
    controlOutputsTextLabel->setText(controlOutputsText);



    //
    QScrollView* audioInputScroll1=new QScrollView(audioInputsFrame);
    QVBox* mainAudioInputBox1=new QVBox(audioInputScroll1->viewport());

    QScrollView* audioInputScroll2=0;
    QVBox* mainAudioInputBox2=0;
    audioInputScroll1->setGeometry(audioInputsFrame->contentsRect());
    audioInputScroll1->show();
    audioInputScroll1->viewport()->setBackgroundColor(backgroundColor());
    audioInputScroll1->addChild(mainAudioInputBox1);
    mainAudioInputBox1->show();
    mainAudioInputBox1->setGeometry(audioInputScroll1->viewport()->rect());
    mainAudioInputBox1->setSpacing(5);
    if(doublePlugCheckbox->isChecked()){
        audioInputScroll2=new QScrollView(audioInputsFrame);
        mainAudioInputBox2=new QVBox(audioInputScroll2->viewport());
        QRect rect=audioInputsFrame->contentsRect();
        rect.setBottom(rect.y()+(rect.height()/2));
        audioInputScroll1->setGeometry(rect);
        rect.moveTop(rect.bottom());
        audioInputScroll2->setGeometry(rect);
        audioInputScroll2->show();
        audioInputScroll2->viewport()->setBackgroundColor(backgroundColor());
        audioInputScroll2->addChild(mainAudioInputBox2);
        mainAudioInputBox2->show();
        mainAudioInputBox2->setGeometry(audioInputScroll2->viewport()->rect());
        mainAudioInputBox2->setSpacing(5);
    }
    int count=0;
    for (QPtrList<LADSPAPort>::Iterator it = currentEffect->getAudioInputPorts()->begin();
            it!=currentEffect->getAudioInputPorts()->end();++it){
        initAudioBox(mainAudioInputBox1,*it,count,FALSE);
        if(doublePlugCheckbox->isChecked()){
            initAudioBox(mainAudioInputBox2,*it,count,TRUE);
        }
        count++;
    }
    //
    //
    QScrollView* audioOutputScroll1=new QScrollView(audioOutputsFrame);
    QVBox* mainAudioOutputBox1=new QVBox(audioOutputScroll1->viewport());

    QScrollView* audioOutputScroll2=0;
    QVBox* mainAudioOutputBox2=0;

    audioOutputScroll1->setGeometry(audioOutputsFrame->contentsRect());
    audioOutputScroll1->show();
    audioOutputScroll1->viewport()->setBackgroundColor(backgroundColor());
    audioOutputScroll1->addChild(mainAudioOutputBox1);
    mainAudioOutputBox1->show();
    mainAudioOutputBox1->setGeometry(audioOutputScroll1->viewport()->rect());
    mainAudioOutputBox1->setSpacing(5);
    if(doublePlugCheckbox->isChecked()){
        audioOutputScroll2=new QScrollView(audioOutputsFrame);
        mainAudioOutputBox2=new QVBox(audioOutputScroll2->viewport());
        QRect rect=audioOutputsFrame->contentsRect();
        rect.setBottom(rect.y()+(rect.height()/2));
        audioOutputScroll1->setGeometry(rect);
        rect.moveTop(rect.bottom());
        audioOutputScroll2->setGeometry(rect);
        audioOutputScroll2->show();
        audioOutputScroll2->viewport()->setBackgroundColor(backgroundColor());
        audioOutputScroll2->addChild(mainAudioOutputBox2);
        mainAudioOutputBox2->show();
        mainAudioOutputBox2->setGeometry(audioOutputScroll2->viewport()->rect());
        mainAudioOutputBox2->setSpacing(5);
    }
    count=0;
    for (QPtrList<LADSPAPort>::Iterator it = currentEffect->getAudioOutputPorts()->begin();
            it!=currentEffect->getAudioOutputPorts()->end();++it){
        initAudioBox(mainAudioOutputBox1,*it,count,FALSE);
        if(doublePlugCheckbox->isChecked()){
            initAudioBox(mainAudioOutputBox2,*it,count,TRUE);
        }
        count++;
    }
    //

}


/*!
    \fn LADSPADialog::checkPortAssignments()
 */
bool LADSPADialog::checkPortAssignments()
{

    QStringList list;
    const QObjectList* l=audioOutputsFrame->queryList("QComboBox");
    QObjectListIt it( *l);
    QObject *obj;

    while ( (obj = it.current()) != 0 ) {
        ++it;
        list.push_back(QString::number(((QComboBox*)(obj))->currentItem()));
        std::cout<<((QComboBox*)(obj))->currentText()<<"\n";
    }
    delete l; // delete the list, not the objects


    if((list.grep("2").count() + list.grep("0").count())>1){
        QMessageBox::critical(NULL,"Audio output port mapping error",
                              " Wave R output should be assigned  only once.");
        return false;
    }
    if((list.grep("1").count() + list.grep("0").count())>1) {
        QMessageBox::critical(NULL,"Audio output port mapping error",
                              "Wave L output should be assigned  only once.");
        return false;
    }


    return true;

}


/*!
    \fn LADSPADialog::exec()
 */
int LADSPADialog::exec()
{
    table->sortColumn(sortingColumn,TRUE,TRUE);
    currentRow=uidToRow(selectedUniqueId);
    table->removeSelection(0);
    table->selectRow(currentRow);
    table->selectCells (currentRow, 0,currentRow,3);
    table->ensureCellVisible(currentRow,0);
    return LADSPADialogBase::exec();
}


/*!
    \fn LADSPADialog::headerClicked(int)
 */
void LADSPADialog::headerClicked(int column)
{
    sortingColumn=column;
    table->sortColumn(sortingColumn,TRUE,TRUE);
    currentRow=uidToRow(selectedUniqueId);
    table->removeSelection(0);
    table->selectRow(currentRow);
    table->selectCells (currentRow, 0,currentRow,3);
    table->ensureCellVisible(currentRow,0);
    //cout<<"setting to row: "<<currentRow<<" uid: "<<selectedUniqueId<<endl;
}


/*!
    \fn LADSPADialog::stateChanged()
 */
void LADSPADialog::stateChanged()
{
    currentChanged_(table->currentRow(),table->currentColumn());
}


/*!
    \fn LADSPADialog::initAudioBox(Qframe* parent)
 */
void LADSPADialog::initAudioBox(QVBox* parent,LADSPAPort* port,int count,bool connectToDouble)
{
    /// @todo implement me
        QHBox* audioBox=new QHBox(parent);
        audioBox->setSpacing(10);
        audioBox->show();
        audioBox->setMinimumWidth(parent->rect().width());
        QComboBox* combo=new QComboBox(audioBox);
        combo->setGeometry(audioBox->contentsRect());
        combo->show();
        QFont combo_font(  combo->font() );
        combo_font.setPointSize( 7 );
        combo->setFont( combo_font );
        combo->insertItem("Wave L + R",0);
        combo->insertItem("Wave L",1);
        combo->insertItem("Wave R",2);
        combo->insertItem("Zero",3);
        if(!connectToDouble)
            connect(combo,SIGNAL(activated(const QString&)),port,SLOT(setConnectionMethod(const QString&)));
        else
            connect(combo,SIGNAL(activated(const QString&)),port,SLOT(setConnectionMethodDouble(const QString&)));

            if(count==0 ){
                if(!connectToDouble){
                    combo->setCurrentItem(1);
                    port->setConnectionMethod("Wave L");
                }
                else{
                    combo->setCurrentItem(2);
                    port->setConnectionMethod("Wave R");
                }
            }
            else if(count==1){
                combo->setCurrentItem(2);
                if(!connectToDouble){
                    combo->setCurrentItem(2);
                    port->setConnectionMethod("Wave R");
                }
                else{
                    combo->setCurrentItem(3);
                    port->setConnectionMethod("Zero");
                }
            }
            else{
                combo->setCurrentItem(3);
                port->setConnectionMethod("Zero");
            }

        QLabel* label=new QLabel(audioBox);
        label->setAlignment(AlignLeft);
        label->setGeometry(audioBox->contentsRect());
        label->setText(port->getPortName());
        label->show();

        QFont label_font(  label->font() );
        label_font.setPointSize( 7 );
        label->setFont( label_font );
}


/*!
    \fn LADSPADialog::clearScrollViews()
 */
void LADSPADialog::clearScrollViews()
{
    QObjectList *l = audioInputsFrame->queryList( "QScrollView" );
    QObjectListIt it( *l );
    QObject *obj;

    while ( (obj = it.current()) != 0 ) {
        // for each found object...
        ++it;
        l->removeRef(obj);
        audioInputsFrame->removeChild(obj);
        ((QWidget*)obj)->close();
    }
    delete l; // delete the list, not the objects

    QObjectList *l2 = audioOutputsFrame->queryList( "QScrollView" );
    QObjectListIt it2( *l2 );

    while ( (obj = it2.current()) != 0 ) {
        // for each found object...
        ++it2;
        l2->removeRef(obj);
        audioOutputsFrame->removeChild(obj);
        ((QWidget*)obj)->close();
    }
    delete l2; // delete the list, not the objects

}


/*!
    \fn LADSPADialog::uidToRow(int uid)
 */
int LADSPADialog::uidToRow(int uid)
{
    for (int i=0;i<table->numRows();i++){
        if(table->text(i,3).toInt()==uid) return i;
    }
    return 0;
}
