/***************************************************************************
    copyright            : (C) 2001 by mean
    email                : fixounet@free.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "Q_audioTrackClass.h"
#include "ADM_audioFilterInterface.h"
#include "DIA_fileSel.h"
#include "ADM_last.h"

/**
    \fn audioTrackQt4
    \brief ctor
*/  
audioTrackQt4::audioTrackQt4( PoolOfAudioTracks *pool, ActiveAudioTracks *xactive ) : 
        DIA_audioTrackBase( pool, xactive )
{
        // Duplicate _srcActive to active
        for(int i=0;i<_srcActive->size() && i<NB_MENU;i++)
        {
            EditableAudioTrack *copy=
                    new EditableAudioTrack(*(_srcActive->atEditable(i)));
            active.addTrack(copy);
        }
        for(int i=_srcActive->size() ;i<NB_MENU;i++)
        {
            EditableAudioTrack *copy=new EditableAudioTrack();
            active.addTrack(copy);
        }
        // create windows
        window=new audioTrackWindow(_srcActive->size());
        window->setModal(true);

        languages=ADM_getLanguageList();
        nbLanguage=ADM_getLanguageListSize();

        // Populate lists of languages, tracks and encoders.
        for(int i=0;i<NB_MENU;i++)
        {
            for(int j=0;j<nbLanguage;j++)
            {
                window->languages[i]->addItem(languages[j].eng_name);
            }
            buildTrackMenu(i);
            setCurrentLanguage(i);
            buildEncoderMenu(i);
        }

        // bind it
        for(int i=0;i<NB_MENU;i++)
        {
            QObject::connect( window->filters[i],SIGNAL(clicked(bool)),
                            this,SLOT(filtersClicked(bool)));
            QObject::connect( window->codecConf[i],SIGNAL(clicked(bool)),
                            this,SLOT(codecConfClicked(bool)));
            QObject::connect( window->enabled[i],SIGNAL(stateChanged(int)),
                            this,SLOT(enabledStateChanged(int)));
            QObject::connect( window->inputs[i],SIGNAL(currentIndexChanged(int)),
                            this,SLOT(inputChanged(int)));
            QObject::connect( window->codec[i],SIGNAL(currentIndexChanged(int)),
                            this,SLOT(codecChanged(int)));
/*
            QObject::connect( window->languages[i],SIGNAL(currentIndexChanged(int)),
                            this,SLOT(languagesClicked(int)));   
 * */          
        }
        QObject::connect( window->dupConfig,SIGNAL(clicked(bool)),this,SLOT(dupConfigClicked(bool)));
};
/**
 * \fn setLanguageFromPool
 * @param menuIndex
 * @param poolIndex
 */
void            audioTrackQt4::setLanguageFromPool(int menuIndex, int poolIndex)
{
     // Refresh language
    ADM_edAudioTrack *track=_pool->at(poolIndex);
    if(track)
     {           
                 std::string lang=track->getLanguage(); 
                 int langIndex=ADM_getIndexForIso639(lang.c_str());
                 if(langIndex<0) langIndex=0; //  0 is unknown
                 QComboBox *q=window->languages[menuIndex];
                 q->setCurrentIndex(langIndex);
     }

}

/**
    \fn inputChanged
*/
void audioTrackQt4::inputChanged(int signal)
{
        int dex=-1;
        QObject *ptr=sender();

        for(int i=0;i<NB_MENU;i++) if(ptr==window->inputs[i]) {dex=i;break;}
        if(dex==-1)
        {
            ADM_warning("Cannot find originating input\n");
            return;
        }
        //
        QComboBox *me=(QComboBox *)ptr;
        // get size
        int count=me->count();
        int thisIndex=me->currentIndex();
        printf("index=%d count=%d\n",thisIndex,count);
        if(thisIndex!=count-1)
        {
           ADM_info("Existing track\n");
           setLanguageFromPool(dex,thisIndex);
           //
           return;
        }
        // Trying to add a new track...
        // ..........
        ADM_info("Adding external audio track for index=%d\n",dex);
        // start fileselector
        #define MAX_SOURCE_LENGTH 1024
        char fileName[MAX_SOURCE_LENGTH];
        std::string lastFolder;
        admCoreUtils::getLastReadFolder(lastFolder);
        if(!FileSel_SelectRead(QT_TRANSLATE_NOOP("qaudiotracks","Select audio file"),fileName,MAX_SOURCE_LENGTH-1,lastFolder.c_str()))
        {
            ADM_info("No file selected as audioTrack\n");
            if(thisIndex>0)
            {
                me->blockSignals(true);
                me->setCurrentIndex(thisIndex-1);
                me->blockSignals(false);
                return;
            }
            // deactivate me
            me->blockSignals(true);
            me->setCurrentIndex(-1);
            me->blockSignals(false);
            disable(dex); // just to be on the safe side..
            return;
        }
        admCoreUtils::setLastReadFolder(std::string(fileName));

        ADM_edAudioTrackExternal *ext=create_edAudioExternal(fileName);
        if(!ext)
        {
            GUI_Error_HIG(QT_TRANSLATE_NOOP("qaudiotracks","Error"),QT_TRANSLATE_NOOP("qaudiotracks","Cannot use that file as audio track"));
            if(thisIndex>0)
            {
                me->blockSignals(true);
                me->setCurrentIndex(thisIndex-1);
                me->blockSignals(false);
            }else
            {
                me->blockSignals(true);
                me->setCurrentIndex(-1);
                me->blockSignals(false);
                disable(dex);
            }
            return;
        }
        int poolIndex=_pool->size();
        _pool->addInternalTrack(ext);
        for(int i=0;i<NB_MENU;i++)
        {
            bool checked=window->enabled[i]->isChecked();
            int forced=window->inputs[i]->currentIndex();
            if(i==dex)
            {
                checked=true;
                forced=poolIndex;
                window->languages[i]->setCurrentIndex(0); // unknown
            }
            buildTrackMenu(i,forced);
            // restore enabled / disabled state
            window->enabled[i]->blockSignals(true);
            if(checked)
                enable(i);
            else
                disable(i);
            window->enabled[i]->blockSignals(false);
        }
        return;
}
  
/**
     \fn enabledStateChanged
*/
bool  audioTrackQt4::enabledStateChanged(int state)
{
        int dex=-1;
        QObject *ptr=sender();

        for(int i=0;i<NB_MENU;i++) if(ptr==window->enabled[i]) {dex=i;break;}
        if(dex==-1)
        {
            ADM_warning("No track found matching that enabling\n");
            return true;
        }
        if(Qt::Checked==state)
        {
            enable(dex);
        }
        else        
        {
            disable(dex);
        }
        
        int lastChechked = -1;
        for (int i=0; i<NB_MENU;i++)
        {
            if (window->enabled[i]->isChecked())
                lastChechked = i;
        }
        lastChechked++;
        window->showTracks(lastChechked);
        
        return true;

}
/**
    \fn codecConfClicked
*/
bool  audioTrackQt4::codecConfClicked(bool a)
{
 QObject *ptr=sender();
        int dex=-1;
        for(int i=0;i<NB_MENU;i++) if(ptr==window->codecConf[i]) {dex=i;break;}
        if(dex==-1)
        {
            ADM_warning("No track found matching that codec\n");
            return true;
        }
        printf("codec at %d\n",dex);
        // get index
        int codecIndex=window->codec[dex]->currentIndex();
        if(codecIndex<=0) return true; // no configure

        EditableAudioTrack *ed=active.atEditable(dex);
        if(!ed)
        {
            ADM_warning("No track found at index %d\n",dex);
            return true;
        }
        audioCodecConfigureCodecIndex( codecIndex,&(ed->encoderConf));
        return true;
}
/**
    \fn filtersClicked
*/
bool       audioTrackQt4::filtersClicked(bool a)
{
        QObject *ptr=sender();
        int dex=-1;
        for(int i=0;i<NB_MENU;i++) if(ptr==window->filters[i]) {dex=i;break;}
        if(dex==-1)
        {
            ADM_warning("No track found matching that filter\n");
            return true;
        }
        printf("Editable at %d\n",dex);
        EditableAudioTrack *ed=active.atEditable(dex);
        ADM_assert(ed);
        ed->audioEncodingConfig.audioFilterConfigure();
        return true;
}
/**
    \fn dupConfigClicked
*/
bool audioTrackQt4::dupConfigClicked(bool a)
{
    int codecIndex=window->codec[0]->currentIndex();
    if(codecIndex<=0)
    {
        for (int i=0; i<NB_MENU; i++)
        {
            window->codec[i]->setCurrentIndex(0);
            window->codecConf[i]->setEnabled(false);
            window->filters[i]->setEnabled(false);           
        }
        
        return true;
    }
    EditableAudioTrack *firstEd=active.atEditable(0);
    ADM_assert(firstEd);
    for (int i=0; i<NB_MENU; i++)
    {
        if (window->enabled[i]->isVisible()&& window->enabled[i]->isChecked())
        {
            window->codec[i]->blockSignals(true);
            window->codec[i]->setCurrentIndex(codecIndex);
            window->codecConf[i]->setEnabled(true);
            window->filters[i]->setEnabled(true);
            EditableAudioTrack *ed=active.atEditable(i);
            if (ed)
            {
                ed->audioEncodingConfig.audioFilterCopyConfig(&(firstEd->audioEncodingConfig));
                ed->encoderConf->duplicate(firstEd->encoderConf);
            }
            window->codec[i]->blockSignals(false);
        }
    }
    return true;
}
/**
    \fn audioTrackQt4
    \brief dtor
*/
audioTrackQt4::~audioTrackQt4()
{
    active.clear();
    if(window) delete window;
    window=NULL;
}
/**
    \fn run
    \brief run the dialog 
*/
bool      audioTrackQt4::run(void)
{
    ADM_info("Running QT4 audioTrack GUI\n");
    bool r=false;
    qtRegisterDialog(window);
    again:
    if(window->exec()==QDialog::Accepted)
    {
        r=true;
        if(false==updateActive()) 
        {
            goto again;
        }
       
    }
    qtUnregisterDialog(window);
    ADM_info("/Running QT4 audioTrack GUI\n");
    return r;
}
              
/**
    \fn updateActive
*/
bool  audioTrackQt4::updateActive(void)
{
    // 1 - check for duplicates 
    int map[32]; // The size is related to the INPUT number of tracks, not output thx Rickard
    for(int i=0;i<32;i++)
        map[i]=0;
    
    for(int i=0;i<NB_MENU;i++)
    {
        if(window->enabled[i]->checkState()==Qt::Checked)
        {
            int trackIndex=window->inputs[i]->currentIndex();
            if(map[trackIndex])
            {
                GUI_Error_HIG(QT_TRANSLATE_NOOP("qaudiotracks","Error"), QT_TRANSLATE_NOOP("qaudiotracks","Some tracks are used multiple times"));
                return false;
            }
            map[trackIndex]++;
        }
    }

    // 2 - recreate audio tracks from menu, set language
    
    _srcActive->clear();
    
    for(int i=0;i<NB_MENU;i++)
    {
        if(window->enabled[i]->checkState()!=Qt::Checked) continue;
            int trackIndex=window->inputs[i]->currentIndex();
            ADM_info("Checking input %d for track %d\n",trackIndex,i);
            if(trackIndex>=_pool->size()) 
            {
                ADM_warning("Referencing a non existing track in pool (%d/%d)\n",trackIndex,_pool->size());
                continue;
            }
            
            int dex=window->languages[i]->currentIndex();
            ADM_edAudioTrack *trk=_pool->at(trackIndex);
            if(trk && dex!=-1)
            {
                      std::string lang=languages[dex].iso639_2;
                      trk->setLanguage(lang);   
                      ADM_info("\tSetting language %s to pool %d\n",lang.c_str(),trackIndex);
                      //ADM_info("\tPool language is now %s\n",_pool->at(trackIndex)->getLanguage().c_str());
                      
            }else
                ADM_warning("Cannot set language for track %d\n",i);
    }
    int done=0;
    for(int i=0;i<NB_MENU;i++)
    {
        if(window->enabled[i]->checkState()==Qt::Checked)
        {
            ADM_info("Processing input %d for track %d\n",i,done);
            int trackIndex=window->inputs[i]->currentIndex();
            if(trackIndex>=_pool->size()) 
            {
                ADM_warning("Referencing a non existing track in pool (%d/%d)\n",trackIndex,_pool->size());
                continue;
            }
            _srcActive->addTrack(trackIndex,_pool->at(trackIndex));
            //
            EditableAudioTrack *dest=_srcActive->atEditable(done);
            // set codec
            dest->encoderIndex=window->codec[i]->currentIndex();
            // conf
            EditableAudioTrack *src=active.atEditable(i);
            if(src)
            {
                dest->encoderConf=CONFcouple::duplicate(src->encoderConf);
                // filters
                dest->audioEncodingConfig=src->audioEncodingConfig;
            }
#if 0
            ADM_info("Language for pool %d is %s\n",trackIndex,_pool->at(trackIndex)->getLanguage().c_str());
            ADM_info("Language for track is %s\n",dest->edTrack->getLanguage().c_str());
#endif        
            // next
            done++;
        }
    }
    _srcActive->dump();
    return true;
}

/**
    \fn enable
*/
void audioTrackQt4::enable(int i)
{
#define ONOFF(x)  window->x[i]->setEnabled(true)
    window->enabled[i]->setCheckState(Qt::Checked);
    ONOFF(inputs);
    ONOFF(languages);
    ONOFF(codec);
    if (i==0) window->dupConfig->setEnabled(true);
#undef ONOFF
#define ONOFF(x) window->x[i]->setEnabled(window->codec[i]->currentIndex() > 0)
    ONOFF(codecConf);
    ONOFF(filters);
}
/**
    \fn disable
*/
#undef ONOFF
#define ONOFF(x)  window->x[i]->setEnabled(false)

void audioTrackQt4::disable(int i)
{
    window->enabled[i]->setCheckState(Qt::Unchecked);
    ONOFF(inputs);
    ONOFF(codec);
    ONOFF(codecConf);
    ONOFF(filters);
    ONOFF(languages);
    if (i==0) window->dupConfig->setEnabled(false);
}
/**
    \fn setCurrentLanguage
*/
void audioTrackQt4::setCurrentLanguage(int dex)
{
    int idx = window->inputs[dex]->currentIndex();
    if(idx == -1)
    {
        ADM_warning("Cannot setup language for track %d\n",dex);
        return;
    }
    setLanguageFromPool(dex,idx);
}
/**
    \fn buildEncoderMenu
*/
void audioTrackQt4::buildEncoderMenu(int dex)
{
    int nbAud = audioEncoderGetNumberOfEncoders();
    window->codec[dex]->clear();
    window->codec[dex]->addItem(QString::fromUtf8(QT_TRANSLATE_NOOP("qaudiotracks","copy")));
    for(uint32_t i=1;i<nbAud;i++)
    {
        window->codec[dex]->addItem(audioEncoderGetDisplayName(i));
    }
    if(active.atEditable(dex)->edTrack)
    {
        int selected=active.atEditable(dex)->encoderIndex;
        enable(dex);
        window->codec[dex]->setCurrentIndex(selected);
        window->codecConf[dex]->setEnabled(selected > 0); // not copy
        window->filters[dex]->setEnabled(selected > 0);
    }else
    {
        disable(dex);
    }
}

/**
    \fn buildTrackMenu
*/
void audioTrackQt4::buildTrackMenu(int dex, int forcedIndex)
{
    ADM_edAudioTrack *edTrack;
    ADM_info("For track %d, index=%d\n",dex,forcedIndex);
    window->inputs[dex]->blockSignals(true);
    window->inputs[dex]->clear();

    for(int i=0;i<_pool->size();i++)
    {
        QString str;
        //
        edTrack=_pool->at(i);
        switch(edTrack->getTrackType())
        {
                case ADM_EDAUDIO_FROM_VIDEO:
                                {
                                QString num;
                                ADM_edAudioTrackFromVideo *fromVideo=edTrack->castToTrackFromVideo() ;
                                num.setNum(fromVideo->getMyTrackIndex());
                                str=QString::fromUtf8(QT_TRANSLATE_NOOP("qaudiotracks","Track "))+num+QString::fromUtf8(QT_TRANSLATE_NOOP("qaudiotracks"," from video"));
                                }
                                break;
                case ADM_EDAUDIO_EXTERNAL:
                                {
                                ADM_edAudioTrackExternal *ext=edTrack->castToExternal() ;
                                ADM_assert(ext);
                                std::string name=ext->getMyName();
                                str=QString::fromUtf8(QT_TRANSLATE_NOOP("qaudiotracks","File "))+QString::fromUtf8(name.c_str());
                                }
                                break;
                default:
                                ADM_assert(0);
                                break;
        }
        // Get info about that track
        WAVHeader *hdr=_pool->at(i)->getInfo();
        if(hdr)
        {
            int bitrate=hdr->byterate;
            QString sBitrate,sChan;
            switch(hdr->channels)
            {
                case 1: sChan="Mono";break;
                case 2: sChan="Stereo";break;
                default: sChan.setNum(hdr->channels);sChan+=" chan";break;
            }
            bitrate*=8;
            bitrate/=1000;
            sBitrate.setNum(bitrate);
            str += " (";
            str += getStrFromAudioCodec(hdr->encoding);
            str += ", ";
            str += sChan;
            str += ", ";
            str += sBitrate;
            str += " kbps)";
        }
        window->inputs[dex]->addItem(str); 
    }
   
    //--
    // add the "add audio track" item
    window->inputs[dex]->addItem(QString::fromUtf8(QT_TRANSLATE_NOOP("qaudiotracks",".... Add audio track")));
    // set index if possible
    if(forcedIndex==-1)
    {
        EditableAudioTrack *ed;
        ed=active.atEditable(dex);

        // set current track if it exists
        if(ed)
        {
            if(ed->edTrack)
            {
                int poolIndex=ed->poolIndex;
                window->inputs[dex]->setCurrentIndex(poolIndex);             
            }
         }
        if(!_pool->size())   window->inputs[dex]->setCurrentIndex(-1);          
    }else
    {
                window->inputs[dex]->setCurrentIndex(forcedIndex);  
    }
    window->inputs[dex]->blockSignals(false);
}
/**
    \fn codecChanged
*/
void audioTrackQt4::codecChanged(int ix)
{
    int dex = -1;
    QObject *ptr = sender();

    for(int i=0;i<NB_MENU;i++)
    {
        if(ptr == window->codec[i])
        {
            dex=i;
            break;
        }
    }
    if(dex == -1)
    {
        ADM_warning("Cannot find originating codec combobox\n");
        return;
    }
    window->codecConf[dex]->setEnabled(ix > 0);
    window->filters[dex]->setEnabled(ix > 0);
}
/**
        \fn createEncoding
*/
namespace ADM_Qt4CoreUIToolkit
{
DIA_audioTrackBase *createAudioTrack( PoolOfAudioTracks *pool, ActiveAudioTracks *active )
{
        return new audioTrackQt4(pool,active);
}
}
//********************************************
//EOF
