/****************************************************************************
** dialogaudio.cpp
**
** This file handles the audio setting for multiple audio tracks for a 
** SourceFileInfo, or DVDMenu.
**
**   Created : 
**        by : Varol Okan using Kate
** Copyright : (c) Varol Okan
**   License : GPL v 2.0
**
*****************************************************************************/

#include <qlabel.h>
#include <qtimer.h>
#include <qlayout.h>
#include <qspinbox.h>
#include <qfileinfo.h>
#include <qgroupbox.h>
#include <qlistview.h>
#include <qcombobox.h>
#include <qcheckbox.h>
#include <qpushbutton.h>

#include "utils.h"
#include "dvdmenu.h"
#include "messagebox.h"
#include "dialogaudio.h"
#include "uidialogsubtitle.h"
#include "sourcefileentry.h"

DialogAudio::DialogAudio ( QWidget* parent, const char* name, bool modal, WFlags fl )
  : uiDialogAudio ( parent, name, modal, fl )
{
  m_pSourceFileEntry     = NULL;
  m_pOrigSourceFileEntry = NULL;
  m_pSourceFileInfo      = NULL;
  m_pOrigSourceFileInfo  = NULL;
  m_pSelectItem          = NULL;
  m_pDVDMenu             = NULL;

  // signals and slots connections
  connect( m_pButtonHelp,   SIGNAL( clicked (      ) ), this, SLOT( slotHelp        (      ) ) );
  connect( m_pButtonAdd,    SIGNAL( clicked (      ) ), this, SLOT( slotAdd         (      ) ) );
  connect( m_pButtonEdit,   SIGNAL( clicked (      ) ), this, SLOT( slotEdit        (      ) ) );
  connect( m_pButtonDelete, SIGNAL( clicked (      ) ), this, SLOT( slotDelete      (      ) ) );
  connect( m_pCheckEnable,  SIGNAL( toggled ( bool ) ), this, SLOT( slotTranscoding ( bool ) ) );
  connect( m_pListViewAudio,SIGNAL( currentChanged ( QListViewItem * ) ), this,  SLOT ( slotCurrentChanged ( QListViewItem * ) ) );
}

/*
 *  Destroys the object and frees any allocated resources
 */
DialogAudio::~DialogAudio ( )
{
  // Here we delete the temp sourceFileEntry
  if ( m_pOrigSourceFileEntry && ( m_pOrigSourceFileEntry->bSoundSource ) && ( m_pSourceFileInfo ) )
    delete m_pSourceFileInfo;
  if ( m_pSourceFileEntry )
    delete m_pSourceFileEntry;
  m_pSourceFileEntry = NULL;
  m_pSourceFileInfo  = NULL;
}

void DialogAudio::initMe ( SourceFileInfo *pInfo, SourceFileEntry *pEntry, QString &qsFileName )
{
  // This dialog holds the logic of how we distribute the Language settings through the 
  // 8 avail Audio stream - slots available per Title.
  // You could have multiple PGCs in a Title, thus multiple SourceFileInfos 
  // could share the 8 audio streams.
 
  // The Entry maintains an active array linking audioNumber to language code.
  // The Info has to make sure it does not exceed the avail 8 streams.
  // lets find the index to the original SourceFileInfo.
  // Note that pInfo is a copy from DialogMovie.

  int         t;
  bool        bStartLanguageDialog = true;
  Utils       theUtils;
  QString     qsLang;
  AudioEntry *pAudio;
  QFileInfo fileInfo ( qsFileName );

  m_qsFileName = qsFileName;
  m_pComboAudioEntry->hide ( );

  for ( t=0; t<(int)pEntry->listFileInfos.count ( ); t++ ) {
    if ( pEntry->listFileInfos[t]->qsFileName == pInfo->qsFileName )
      break;
  }
  m_pLabelFile->setText ( QString ( "<b>%1</b>" ).arg ( fileInfo.fileName ( ) ) );

  m_pOrigSourceFileEntry = pEntry;
  m_pOrigSourceFileInfo  = pInfo;
  m_pSourceFileEntry     = new SourceFileEntry;
  *m_pSourceFileEntry    = *pEntry; // make a deep copy.
  m_pSourceFileInfo      = m_pSourceFileEntry->listFileInfos [ t ];
  // The original SourceFileEntry might hold outdated data for the SourceFileInfo in question
  *m_pSourceFileInfo     = *m_pOrigSourceFileInfo;

  // VAROL
  /*
  SourceFileEntry *p = m_pSourceFileEntry;
  printf ( "%s::%s : %d > ORIG > ", __FILE__, __FUNCTION__, __LINE__ );
  for ( int e=0;e<MAX_AUDIO;e++ )
    printf ( "[%d=%s] ", p->arrayAudioEntries[e].iAudioNumber, p->arrayAudioEntries[e].qsIso639.ascii() );
  printf ( "\n" );
  SourceFileInfo *p1 = m_pSourceFileInfo;
  printf ( "%s::%s : %d > NEW  > ", __FILE__, __FUNCTION__, __LINE__ );
  for ( int e=0;e<MAX_AUDIO;e++ )
    if ( p1->arrayAudio[e] )
     printf ( "[%d=%s] ", p1->arrayAudio[e]->iAudioNumber, p1->arrayAudio[e]->qsIso639.ascii() );
  printf ( "\n" );
  */
  for ( t=0; t<MAX_AUDIO; t++ ) {
    pAudio = &( pEntry->arrayAudioEntries[ t ] );
    if ( pAudio->iAudioNumber == -1 )
      continue;
    bStartLanguageDialog = false;
    qsLang = theUtils.iso639 ( pAudio->qsIso639, false );
    new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( pAudio->iAudioNumber ), pAudio->qsIso639, qsLang );
  }
  if ( bStartLanguageDialog )
    slotAdd ( );
  else { 
    QListViewItem *pFirst = m_pListViewAudio->firstChild ( );
    //    if ( pFirst )
    //         pFirst->setSelected    ( true );
    qsLang = pFirst->text       ( 2 );
    m_pLabelLanguage->setText   ( tr ( "<p align=\"right\"><b>Assign %1 to : </b></p>" ).arg ( qsLang ) );
    m_pButtonEdit->setEnabled   ( true );
    m_pButtonDelete->setEnabled ( true );
    buttonOk->setEnabled        ( true );
    m_pSelectItem = pFirst;
    QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
  }
}

void DialogAudio::initMe ( SourceFileEntry *pEntry )
{
  // coming in this way means the user came from the SoureToolbar and only want to 
  // change the SourceFileEntries language - list.
  if ( pEntry->bSoundSource ) {
    initAudioSource ( pEntry );
    return;
  }
  int         t;
  bool        bStartLanguageDialog = true;
  Utils       theUtils;
  QString     qsLang;
  AudioEntry *pAudio;

  m_pLabelFile      ->hide ( );
  m_pLabelLanguage  ->hide ( );
  m_pGroupAudioFile ->hide ( );
  m_pComboAudioEntry->hide ( );

  m_pOrigSourceFileEntry = pEntry;
  m_pSourceFileEntry     = new SourceFileEntry;
  *m_pSourceFileEntry    = *pEntry; // make a deep copy.
  
  for ( t=0; t<MAX_AUDIO; t++ ) {
    pAudio = &( pEntry->arrayAudioEntries[ t ] );
    if ( pAudio->iAudioNumber == -1 )
      continue;
    bStartLanguageDialog = false;
    qsLang = theUtils.iso639 ( pAudio->qsIso639, false );
    new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( pAudio->iAudioNumber ), pAudio->qsIso639, qsLang );
  }
  if ( bStartLanguageDialog )
    slotAdd ( );
  else { 
    QListViewItem *pFirst = m_pListViewAudio->firstChild ( );
    //    qsLang = pFirst->text       ( 2 );
    //    m_pLabelLanguage->setText   ( tr ( "<p align=\"right\"><b>Assign %1 to : </b></p>" ).arg ( qsLang ) );
    m_pButtonEdit->setEnabled   ( true );
    m_pButtonDelete->setEnabled ( true );
    buttonOk->setEnabled        ( true );
    m_pSelectItem = pFirst;
    QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
  }
}

void DialogAudio::initMe ( DVDMenu *pDVDMenu )
{
  m_pDVDMenu = pDVDMenu;
  unsigned  int t;
  QString   qsLang;
  Audio    *pAudio;
  Utils     theUtils;
  QFileInfo fileInfo;

  for ( t=0; t<pDVDMenu->getInterface ( )->listSoundEntries.count ( ); t++ ) {
    pAudio  =  pDVDMenu->getInterface ( )->listSoundEntries[t];
    if ( ! pAudio )
      continue;
    fileInfo.setFile ( pAudio->qsFileName );
    m_pComboAudioEntry->insertItem ( fileInfo.fileName ( ) );

    qsLang = theUtils.iso639 ( pAudio->qsIso639, false );
    new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( t ), pAudio->qsIso639, qsLang );
  }
  slotAudioEntryChanged ( 0 );

  connect ( m_pComboAudioEntry, SIGNAL ( activated ( int) ), this, SLOT ( slotAudioEntryChanged ( int ) ) );
}

void DialogAudio::setTranscode ( TranscodeInterface *pTranscode )
{
  initAudioInfo ( pTranscode );
}

void DialogAudio::initAudioSource ( SourceFileEntry *pEntry )
{
  int t;
  QFileInfo fileInfo;
  SourceFileInfo *pInfo = NULL;

  m_pLabelLanguage->hide ( );
  m_pLabelFile    ->hide ( );
  m_pGroupLanguage->hide ( );
  //  delete m_pSpacer;

  m_pOrigSourceFileEntry = pEntry;
  for ( t=0; t<(int)pEntry->listFileInfos.count ( ); t++ ) {
    pInfo = pEntry->listFileInfos[t];
    fileInfo.setFile ( pInfo->qsFileName );
    m_pComboAudioEntry->insertItem ( fileInfo.fileName ( ) );
  }
  // Finally we set the current file ...
  slotAudioEntryChanged ( 0 );

  connect ( m_pComboAudioEntry, SIGNAL ( activated ( int) ), this, SLOT ( slotAudioEntryChanged ( int ) ) );
}

void DialogAudio::initAudioInfo ( SourceFileInfo *pInfo )
{
  if ( ! pInfo )
    return;

  TranscodeInterface *pInterface = pInfo->pTranscodeInterface;

  if ( ! m_pSourceFileInfo )
         m_pSourceFileInfo = new SourceFileInfo;

  *m_pSourceFileInfo = *pInfo;

  initAudioInfo ( pInterface );
}

void DialogAudio::initAudioInfo ( Audio *pAudio )
{
  if ( ! pAudio )
    return;

  TranscodeInterface *pInterface = pAudio->pTranscodeInterface;
  initAudioInfo ( pInterface );
}

void DialogAudio::initAudioInfo ( TranscodeInterface *pInterface )
{
  bool    bEnableTranscoding = ( pInterface );
  QString qsTemp;
  Utils   theUtils;
  long    iBitrate, iSample;
  m_pCheckEnable->setChecked ( bEnableTranscoding );
  m_pGroupAudio ->setEnabled ( bEnableTranscoding );
  if ( bEnableTranscoding )  {
    qsTemp = pInterface->qsAudioType;
    qsTemp.remove ( "Keep " );
    if ( qsTemp.length ( ) < 1 )
      qsTemp = "mp2";
    m_pComboAudioType->setCurrentText ( qsTemp );

    iBitrate = pInterface->iAudioBitrate;
    if ( iBitrate < 0 )
         iBitrate *= -1;
    m_pComboAudioBitrate->setCurrentText ( theUtils.longToNorm( iBitrate ) + QString ( "bps" ) );
    iSample = pInterface->iSample;
    if ( iSample < 0 )
         iSample *= -1;
    m_pComboAudioSampleRate->setCurrentText ( QString ( "%1" ).arg( iSample ) );
  }
}

void DialogAudio::slotAudioEntryChanged ( int )
{
  unsigned  int t;
  SourceFileInfo *pInfo  = NULL;
  Audio          *pAudio = NULL;
  QFileInfo fileInfo;
  QString   qsFile = m_pComboAudioEntry->currentText ( );

  if ( m_pDVDMenu ) {
    for ( t=0; t<m_pDVDMenu->getInterface ( )->listSoundEntries.count ( ); t++ ) {
      pAudio   = m_pDVDMenu->getInterface ( )->listSoundEntries[t];
      fileInfo.setFile ( pAudio->qsFileName );
      if ( fileInfo.fileName  ( ) == qsFile ) {
        initAudioInfo  ( pAudio );
        break;
      }
    }
  }
  else {
    for ( t=0; t<m_pOrigSourceFileEntry->listFileInfos.count ( ); t++ ) {
      pInfo = m_pOrigSourceFileEntry->listFileInfos[t];
      fileInfo.setFile ( pInfo->qsFileName );
      if ( fileInfo.fileName ( ) == qsFile ) {
        initAudioInfo  ( pInfo );
        break;
      }
    }
  }
}

int DialogAudio::getSelectedNumber ( )
{
  int  iSelectedAudioTrack = -1;
  bool bOkay;
  QListViewItem *pItem = m_pListViewAudio->currentItem ( );
  if ( ! pItem )
    return -1;

  iSelectedAudioTrack = pItem->text ( 0 ).toInt ( &bOkay );
  if ( ! bOkay )
    return -1;

  return iSelectedAudioTrack;
}

TranscodeInterface *DialogAudio::getTranscode ( )
{
  if ( ! m_pCheckEnable->isChecked ( ) )
    return NULL;

  QString qsTemp;
  Utils theUtils;
  int iBitrate, iSample;
  TranscodeInterface *pTranscodeInterface = new TranscodeInterface;

  pTranscodeInterface->qsAudioFormat = m_pComboAudioOut->currentText  ( );
  pTranscodeInterface->qsAudioType   = m_pComboAudioType->currentText ( );
  qsTemp = m_pComboAudioBitrate->currentText ( );
  iBitrate =  theUtils.normToLong ( qsTemp );
  pTranscodeInterface->iAudioBitrate = iBitrate;
  qsTemp = m_pComboAudioSampleRate->currentText ( );
  iSample =  qsTemp.toInt ( );
  pTranscodeInterface->iSample       = iSample;
			
  return pTranscodeInterface;
}

QString DialogAudio::showLanguageDialog ( )
{
  // This will add a new audio track to the PGC (Title)
  // For simplicity we abuse the SubtitleDialog.
  uiDialogSubtitle theDialog;
  theDialog.m_pTextNumber->hide ( );
  theDialog.m_pSpinboxNumber->hide ( );
  theDialog.setCaption ( "Select language" );
  int     t;
  Utils   theUtils;
  QString qsLang, qsCode, qsEmpty;

  for ( t=0; t<MAX_AUDIO; t++ ) {
    if ( m_pSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber == -1 )
      continue;
    break;
  }

  t = 0;
  qsLang = "Somthing"; //qsNone;
  theDialog.m_pComboLanguage->clear ( );
  while ( ! qsLang.isEmpty ( ) ) {
    qsLang = theUtils.iso639 ( qsCode,  false,  t++ );
    theDialog.m_pComboLanguage->insertItem ( qsLang );
  }

  if ( theDialog.exec ( ) == QDialog::Rejected )
    return qsEmpty;

  // At this point we should get the language ...
  qsLang = theDialog.m_pComboLanguage->currentText ( );
  return qsLang;
}

void DialogAudio::slotCurrentChanged ( QListViewItem *pItem )
{
  if ( pItem ) {
    QString qsLang = pItem->text ( 2 );
    m_pLabelLanguage->setText ( tr ( "<p align=\"right\"><b>Assign %1 to : </b></p>" ).arg ( qsLang ) ); 
 }
}

void DialogAudio::slotAdd ( )
{
  int     t;
  Utils   theUtils;
  QString qsLang, qsCode;
  QListViewItem *pItem;

  qsLang = showLanguageDialog ( );
  if ( qsLang.isEmpty ( ) )
    return;

  // and now we can add the language to the ListView of possible languages.
  qsCode = theUtils.iso639 ( qsLang, true );
  for ( t=0; t<MAX_AUDIO; t++ ) {
    if ( m_pSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber == -1 )
      break;
  }
  if ( t==MAX_AUDIO ) {
    MessageBox::information ( this, tr ( "No more audio slots available." ), tr ( "No more audio slots available.\nPlease delete another stream first." ) );
    return;
  }
  m_pSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber = t;
  m_pSourceFileEntry->arrayAudioEntries [ t ].qsIso639     = qsCode;
  pItem = new QListViewItem ( m_pListViewAudio, QString ( "%1" ).arg ( t ), qsCode, qsLang );
  //  pItem->setSelected ( true );
  m_pLabelLanguage->setText ( tr ( "<p align=\"right\"><b>Assign %1 to : </b></p>" ).arg ( qsLang ) );

  // Since we also selected the newly added language, we can enable the buttons.
  m_pButtonEdit->setEnabled   ( true );
  m_pButtonDelete->setEnabled ( true );
  buttonOk->setEnabled ( true );

  m_pSelectItem = pItem;
  QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
}

void DialogAudio::slotSetSelectedItem ( )
{
  m_pListViewAudio->clearSelection ( );
  if ( m_pSelectItem ) {
    m_pSelectItem->setSelected ( true );
    m_pListViewAudio->setCurrentItem ( m_pSelectItem );
  }
  m_pSelectItem = NULL;
}

void DialogAudio::slotEdit ( )
{
  QListViewItem *pItem = m_pListViewAudio->currentItem ( );
  if ( ! pItem )
    return;
  QString qsLang, qsCode;
  Utils   theUtils;
  int     iAudioNumber;

  qsLang = showLanguageDialog ( );
  if ( qsLang.isEmpty ( ) )
    return;

  qsCode  =  theUtils.iso639 ( qsLang, true );
  iAudioNumber = pItem->text ( 0 ). toInt ( );

  pItem->setText ( 1, qsCode );
  pItem->setText ( 2, qsLang );

  int t;
  SourceFileInfo *pInfo;
  if ( m_pSourceFileEntry->arrayAudioEntries [ iAudioNumber ].qsIso639 != qsCode ) {
    for ( t=0; t<(int)m_pSourceFileEntry->listFileInfos.count ( ); t++ ) {
      pInfo = m_pSourceFileEntry->listFileInfos [ t ];
      if ( pInfo && ( pInfo->arrayAudio [ iAudioNumber ] ) ) {
	pInfo->arrayAudio [ iAudioNumber ]->qsIso639 = qsCode;
      }
    }
  }
  m_pSourceFileEntry->arrayAudioEntries [ iAudioNumber ].iAudioNumber = iAudioNumber;
  m_pSourceFileEntry->arrayAudioEntries [ iAudioNumber ].qsIso639     = qsCode;
}

void DialogAudio::slotDelete ( )
{
  // This will delete the currently selected audio track from the PGC (Title)
  QListViewItem *pItem = m_pListViewAudio->currentItem ( );
  if ( ! pItem )
    return;

  int iAudioNumber = pItem->text ( 0 ).toInt ( );
  if ( ( iAudioNumber == 0 ) ) { // no longer a restriction, as we could have elementary streams.
    MessageBox::warning ( this, tr ( "Can't delete main audio track." ), 
			  tr ( "You can not delete Audio track number 0.\nEither Edit or choose a different track." ), 
			  QMessageBox::Ok, QMessageBox::NoButton );
    return;
  }
  // next we have to check if the audioNumber is in use by any other SourceFileInfo of 
  // the m_pSourceFileEntry
  if ( ! checkAudioNumber ( iAudioNumber ) )
    return;

  m_pSourceFileEntry->arrayAudioEntries [ iAudioNumber ].iAudioNumber = -1;

  delete pItem;
  pItem = m_pListViewAudio->firstChild ( );
  //  if ( pItem )
  //    pItem->setSelected ( true );
  //  else if ( m_pListViewAudio->childCount ( ) < 1 ){
  if ( ( !pItem ) || ( m_pListViewAudio->childCount ( ) < 1 ) ) {
    buttonOk->setEnabled ( false );
    m_pButtonEdit->setEnabled   ( false );
    m_pButtonDelete->setEnabled ( false );
  }
  m_pSelectItem = pItem;
  QTimer::singleShot ( 10, this, SLOT ( slotSetSelectedItem ( ) ) );
}

bool DialogAudio::checkAudioNumber ( int iAudioNumber )
{
  int t, i;
  SourceFileInfo *pInfo = NULL;
  Audio    *pAudio = NULL;
  QString   qsInfo;
  QFileInfo fileInfo;
  int iFound = 0;

  if ( ( iAudioNumber < 1 ) || ( iAudioNumber >= MAX_AUDIO ) )
    return false;

  qsInfo = tr ( "The following File(s) use the audio track number %1, language %2.\n\n" ).arg ( iAudioNumber ).arg ( m_pSourceFileEntry->arrayAudioEntries[ iAudioNumber ].qsIso639 );
  for ( t=0; t<(int)m_pSourceFileEntry->listFileInfos.count ( ); t++ ) {
    pInfo = m_pSourceFileEntry->listFileInfos[ t ];
    // if we found the same info, we know we do the right thing.
    if ( ( ! pInfo ) || ( pInfo == m_pSourceFileInfo ) )
      continue;
    for ( i=0; i<MAX_AUDIO; i++ ) {
      pAudio = pInfo->arrayAudio[ i ];
      if ( ! pAudio )
	continue;
      if ( pAudio->iAudioNumber == iAudioNumber ) {
	iFound++;
	fileInfo.setFile ( pInfo->qsFileName );
	qsInfo += tr ( "%1\n" ).arg ( fileInfo.fileName ( ) );
      }
    }
  }
  if ( iFound > 0 ) {
    if ( iFound == 1 )
      qsInfo += tr ( "\nAre you sure you want to remove this track ?\n" );
    else 
      qsInfo += tr ( "\nAre you sure you want to remove all of these tracks ?\n" );
    if ( MessageBox::warning ( this, tr ( "Audio Track in use." ), qsInfo, 
			       QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No )
      return false;
    SourceFileEntry *pEntry = m_pSourceFileEntry;
    //    if ( ! m_pSourceFileInfo )
    //      pEntry = m_pOrigSourceFileEntry;
    // Okay at this point we should remove all said audio tracks from all SourceFIleInfos
    for ( t=0; t<(int)pEntry->listFileInfos.count ( ); t++ ) {
      pInfo = pEntry->listFileInfos[ t ];
      removeAudioTrack ( pInfo, iAudioNumber );
    }
  }
  else 
    removeAudioTrack ( m_pSourceFileInfo, iAudioNumber );

  return true;
}

void DialogAudio::removeAudioTrack ( SourceFileInfo *pInfo, int iAudioNumber )
{
  if ( ! pInfo )
    return;
  int t;
  Audio *pAudio;
  for ( t=0; t<MAX_AUDIO; t++ ) {
    pAudio = pInfo->arrayAudio [ t ];
    if ( ! pAudio )
      continue;
    if ( pAudio->iAudioNumber == iAudioNumber ) {
      delete pAudio;
      pInfo->arrayAudio[ t ] = NULL;
    }
  }
}

void DialogAudio::setAudioInfo ( SourceFileInfo *pOrig, SourceFileInfo *pNew )
{
  int t;
  for ( t=0; t<MAX_AUDIO; t++ ) {
    if ( pOrig->arrayAudio[ t ] ) {
         delete pOrig->arrayAudio [ t ];
         pOrig->arrayAudio[ t ] = NULL;
    }
    if ( pNew->arrayAudio [ t ] ) {
        pOrig->arrayAudio [ t ] = new Audio;
       *pOrig->arrayAudio [ t ] = *pNew->arrayAudio [ t ];
    }
  }
}

void DialogAudio::slotTranscoding ( bool bEnabled )
{
    m_pGroupAudio->setEnabled ( bEnabled );
}

void DialogAudio::slotHelp ( )
{
  QSize helpSize ( 600, 400 );
  MessageBox::help ( this, tr ("DVD Audio streams" ), "audio_streams.html", helpSize );
}

void DialogAudio::accept ( )
{
  // At this point we want to apply the changes to m_pOrigSourceFileEntry,
  // which is the original Entry.
  // and to m_pOrigSourceFileInfo, which is the copy from DialogMovie.
  int t, i, iAudioNumber;
  QListViewItem *pItem;
  Audio *pAudio;
  SourceFileInfo *pInfo1, *pInfo2;

  pItem = m_pListViewAudio->currentItem ( );
  if ( ! pItem ) {
    reject ( );
    return;
  }

  iAudioNumber = getSelectedNumber ( );
  if ( ( iAudioNumber < 1 ) && ( m_pSourceFileInfo && m_pSourceFileInfo->bHasAudioTrack ) ) {
    MessageBox::warning ( this, tr ("Can not select track 0" ), tr ( "You can not select track number 0.\nThis track holds the original audio track from the movie." ) );
    return;
  }

  // first we reset all audio setting in m_pOrigSourceFileEntry and m_pOrigSourceFileInfo.
  for ( t=0; t<MAX_AUDIO; t++ ) {
    m_pOrigSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber = -1;
    m_pOrigSourceFileEntry->arrayAudioEntries [ t ].qsIso639 = QString ( );
    // Next we copy the info over ...
    if (  m_pSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber != -1 ) {
      m_pOrigSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber = m_pSourceFileEntry->arrayAudioEntries [ t ].iAudioNumber;
      m_pOrigSourceFileEntry->arrayAudioEntries [ t ].qsIso639     = m_pSourceFileEntry->arrayAudioEntries [ t ].qsIso639;
    }
  }
  if ( m_pSourceFileInfo ) {
    // Next we take care of the SourceFileInfo ...
    pAudio = new Audio;
    pAudio->iAudioNumber = iAudioNumber; //getSelectedNumber ( ); //pItem->text ( 0 ).toInt ( );
    pAudio->qsIso639     = pItem->text ( 1 );
    pAudio->qsFileName   = m_qsFileName;

    pAudio->pTranscodeInterface = getTranscode ( );
    if ( ( pAudio->iAudioNumber > -1 ) && ( pAudio->iAudioNumber < MAX_AUDIO ) ) {
      if ( m_pSourceFileInfo->arrayAudio [ pAudio->iAudioNumber ] )
        delete m_pSourceFileInfo->arrayAudio [ pAudio->iAudioNumber ];

      m_pSourceFileInfo->arrayAudio [ pAudio->iAudioNumber ] = pAudio;

      for ( t=0; t<(int)m_pOrigSourceFileEntry->listFileInfos.count ( ); t++ )
        setAudioInfo  ( m_pOrigSourceFileEntry->listFileInfos [ t ], m_pSourceFileEntry->listFileInfos [ t ] );
      setAudioInfo ( m_pOrigSourceFileInfo, m_pSourceFileInfo );
    }
  }
  else {
    // Comming from the SourceToolbar I want to copy the language info over to the associated Infos
    for ( t=0; t<(int)m_pOrigSourceFileEntry->listFileInfos.count ( ); t++ ) {
      pInfo1 = m_pOrigSourceFileEntry->listFileInfos [ t ];
      pInfo2 = NULL;
      if (  (int)m_pSourceFileEntry->listFileInfos.count ( ) >= t )
        pInfo2 = m_pSourceFileEntry->listFileInfos [ t ];

      // Next we move the Audio objects over ...
      if ( pInfo1 && pInfo2 ) {
        for ( i=0; i<MAX_AUDIO; i++ ) {
          // First we delete the original Audio - object
          if ( pInfo1->arrayAudio [ i ] )
            delete pInfo1->arrayAudio [ i ];
          pInfo1->arrayAudio [ i ] = NULL;
          // ... and then move the Audio - object from the tempSourceFileEntry over
          if ( pInfo2->arrayAudio [ i ] )
               pInfo1->arrayAudio [ i ] = pInfo2->arrayAudio [ i ];	  
          pInfo2->arrayAudio [ i ] = NULL;
        }
      }
    }
  }

  /*
  SourceFileEntry *p = m_pOrigSourceFileEntry;
  printf ( "%s::%s : %d > ORIG > ", __FILE__, __FUNCTION__, __LINE__ );
  for ( int e=0;e<MAX_AUDIO;e++ )
    printf ( "[%d=%s] ", p->arrayAudioEntries[e].iAudioNumber, p->arrayAudioEntries[e].qsIso639.ascii() );
  printf ( "\n" );
  SourceFileInfo *p1 = m_pOrigSourceFileInfo;
  printf ( "%s::%s : %d > Transc<%p>  > ", __FILE__, __FUNCTION__, __LINE__, p1->pTranscodeInterface );
  for ( int e=0;e<MAX_AUDIO;e++ )
    if ( p1->arrayAudio[e] )
      printf ( "[%d=%s<%p>] ", p1->arrayAudio[e]->iAudioNumber, p1->arrayAudio[e]->qsIso639.ascii(), p1->arrayAudio[e]->pTranscodeInterface );
  printf ( "\n" );
  */

  QDialog::accept ( );
}
