/****************************************************************************
** Keyword - class
**
** Created: Fri Dec 09 22:06:51 2005
**      by: Varol Okan using XEmacs
**
** This class will replace a given token in a string with the set value.
** This class is currently only used in QDVDAuthorInit to help generate
** the correct commands.
**
****************************************************************************/

#include "qdvdauthorinit.h"
#include "keyword.h"

Keyword::Keyword ()
{
  int t;
  char arrayKeys[12][35] = {"+DVDAUTHOR_XML+", "+PROJECT_PATH+", "+TEMP_PATH+", "+WIDTH+", "+HEIGHT+",
    "+FORMAT+", "+MENU_NAME+", "+START_POS+", "+DURATION+", "+BACKGROUND_FILE_NAME+", "+BACKGROUND_FULL_NAME+", "+SOUND_LIST+" };

  char arrayTranscodeKeys[19][35] = {"+DVDAUTHOR_XML+", "+PROJECT_PATH+", "+TEMP_PATH+", "+INPUT_NAME+", "+BASE_NAME+",
    "+FILE_EXT+", "+AUDIO_FORMAT+", "+AUDIO_TYPE+", "+AUDIO_BITRATE+", "+SAMPLE_RATE+", "+STARTING_AT+", "+ENDING_AT+",
    "+WIDTH+", "+HEIGHT+", "+VIDEO_FORMAT+", "+VIDEO_TYPE+", "+VIDEO_BITRATE+", "+FRAME_RATE+", "+RATIO+" };

  char arraySubtitlesKeys[5][35] = {"+PROJECT_PATH+", "+TEMP_PATH+", "+INPUT_FILE_NAME+", "+BASE_NAME+", "+BASE_EXTENSION+" };
  
  // init the key lists
  Entry *pEntry = NULL;
  
  for (t=0;t<KeyLast;t++) {
    pEntry = new Entry ();
    pEntry->qsKey = arrayKeys [ t ];
    m_listOfPair[   Keys   ].append ( pEntry ); 
  }
  for (t=0;t<TransLast;t++) {
    pEntry = new Entry ();
    pEntry->qsKey = arrayTranscodeKeys [ t ];
    m_listOfPair[TransKeys].append ( pEntry );
  }
  for (t=0;t<SubLast;t++) {
    pEntry = new Entry ();
    pEntry->qsKey = arraySubtitlesKeys [ t ];
    m_listOfPair[ SubKeys ].append ( pEntry );
  }
}

Keyword::~Keyword ()
{
  int t, i;
  Entry *pEntry = NULL;
  for ( i=0;i<BaseLast;i++) {
    for (t=0;t< count ( i );t++) {
      pEntry = m_listOfPair [ i ][ t ];
      if ( pEntry )
	delete pEntry;
    }
  }
}

QString Keyword::value ( int iWhichKeyset, int iWhichKey )
{
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return QString();
  if ( ( iWhichKey < 0 ) || ( iWhichKey >= (int) m_listOfPair[iWhichKeyset].count () ) )
    return QString ();

  return m_listOfPair[iWhichKeyset][iWhichKey]->qsValue;
}

QString Keyword::key ( int iWhichKeyset, int iWhichKey )
{
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return QString();
  if ( ( iWhichKey < 0 ) || ( iWhichKey >= (int) m_listOfPair[iWhichKeyset].count () ) )
    return QString ();

  return m_listOfPair[iWhichKeyset][iWhichKey]->qsKey;
}


int Keyword::count ( int iWhichKeyset )
{
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return 0;

  return (int) m_listOfPair[ iWhichKeyset ].count ();
}

void Keyword::clear ( int iWhichKeyset )
{
  return;
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return;

  int t;

  for (t=0;t< count ( iWhichKeyset );t++)
    m_listOfPair[iWhichKeyset][t]->qsValue = QString ();
}

QStringList Keyword::getKeys ( int iWhichKeyset )
{
  QStringList listOfValues;
  int t;
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return listOfValues;
  
  for (t=0;t<count ( iWhichKeyset ); t++)
    listOfValues.append ( key ( iWhichKeyset, t ) );

  return listOfValues;
}

QStringList Keyword::getValues ( int iWhichKeyset )
{
  QStringList listOfValues;
  int t;
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return listOfValues;
  
  for (t=0;t<count ( iWhichKeyset ); t++)
    listOfValues.append ( value ( iWhichKeyset, t ) );

  return listOfValues;
}

bool Keyword::setValue ( int iWhichKeyset, int iWhichKey, QString qsValue )
{
  if ( ( iWhichKeyset < 0 ) || ( iWhichKeyset >= BaseLast ) )
    return false;
  if ( ( iWhichKey < 0 ) || ( iWhichKey >= (int) m_listOfPair[iWhichKeyset].count () ) )
    return false;

  if ( ! m_listOfPair[iWhichKeyset][iWhichKey] )
    return false;

  m_listOfPair[iWhichKeyset][iWhichKey]->qsValue = qsValue;
  m_listOfPair[iWhichKeyset][iWhichKey]->iIndex  = iWhichKey;

  return true;
}

void Keyword::setKeywords ( int iWhichKeys, QValueList<QString> listKeywords )
{
  uint t;
  clear ( iWhichKeys );
  for ( t=0;t<listKeywords.count();t++)
    setValue ( iWhichKeys, t, listKeywords[t] );
}

QString Keyword::resolvString ( int iWhichKeyset, QString qsInput)
{
  // This function resolves the variables in the stored commands / commenst / names like
  // +MENU_NAME+, +WIDTH+, +BACKGROUND_FILE_NAME+ etc.
  QString qsOutput = qsInput;
  uint t;
  
  for (t=0;t<m_listOfPair[iWhichKeyset].count();t++)	{
    // Here we replace the actual keyword with the real string.
    if ( (m_listOfPair[iWhichKeyset][t]->qsValue.isNull()) || (m_listOfPair[iWhichKeyset][t]->qsValue.isEmpty()) )
      continue;
    qsOutput.replace ( m_listOfPair[iWhichKeyset][t]->qsKey, m_listOfPair[iWhichKeyset][t]->qsValue );
  }
  return qsOutput;
}

/**
 * This function is used for the TranscodeInterface - part of CommandQueueDialog.
 * It converts the input values to the propper format needed by the conversion tools.
 * E.g. aspect_ratio = "4:3" translates to '2' for transcode
 * \see resolveString()
 */
QString Keyword::resolvConvert (QString qsInput, QString qsConversionTool)
{
//	char arrayTranscodeKeys[19][35] = {"+DVDAUTHOR_XML+", "+PROJECT_PATH+", "+TEMP_PATH+", "+INPUT_NAME+", "+BASE_NAME+",
//		"+FILE_EXT+", "+AUDIO_FORMAT+", "+AUDIO_TYPE+", "+AUDIO_BITRATE+", "+SAMPLE_RATE+", "+STARTING_AT+", "+ENDING_AT+",
//		"+WIDTH+", "+HEIGHT+", "+VIDEO_FORMAT+", "+VIDEO_TYPE+", "+VIDEO_BITRATE+", "+FRAME_RATE+", "+RATIO+", 
//		};
  QString qsRatio, qsValue, qsKey, qsOutput = qsInput;
  uint t;
  long iAudioBitrate, iVideoBitrate;
  // Next we adjust it for the conversion tool.
  
  // These here are used for all conversion tools.
  iAudioBitrate = (int)( value ( TransKeys, TransAudioBitrate ).toInt () / 1000);
  if (iAudioBitrate < 32)		// according to DVD spec this is the minimum.
    iAudioBitrate = 32;	// Note: How to handle no audio (0) ?
  if (iAudioBitrate > 1536)
    iAudioBitrate = 1536;	// This is the max rate according to DVD spec.
  
  setValue ( TransKeys, TransAudioBitrate, QString ("%1").arg(iAudioBitrate) );
  iVideoBitrate = (int)( value ( TransKeys, TransVideoBitrate ).toInt ( ) / 1000.0);
  if (iVideoBitrate < 1856)	// according to DVD spec this is the minimum.
    iVideoBitrate = 1856;	// Note: How to handle no audio (0) ?
  setValue ( TransKeys, TransVideoBitrate, QString ("%1").arg( iVideoBitrate ) );

  if (qsConversionTool == QString ( SUB_BLOCK_TRANSCODE ) )	{
    qsRatio = value ( TransKeys, TransRatio );
    if ( qsRatio == QString ("1:1"))
      qsRatio = QString ("1");
    else if ( qsRatio == QString ("4:3"))
      qsRatio = QString ("2");
    else if ( qsRatio == QString ("16:9"))
      qsRatio = QString ("3");
    else if ( qsRatio == QString ("2.21:1"))
      qsRatio = QString ("4");
    else 
      qsRatio = QString ("2");
    setValue ( TransKeys, TransRatio, qsRatio );
  }
  else if (qsConversionTool == QString ( SUB_BLOCK_MENCODER ) )	{
    
  }
  else if (qsConversionTool == QString ( SUB_BLOCK_VIDEOTRANS ) )	{
    qsRatio = value ( TransKeys, TransRatio ); // only 4:3 and 16:9 are valid
    if ( ( qsRatio != QString ("4:3") ) && ( qsRatio != QString ("16:9") ) )
      setValue ( TransKeys, TransRatio, QString ( "4:3" ) );
  }
  
  for (t=0;t<m_listOfPair[TransKeys].count();t++)	{
    qsValue = value ( TransKeys, t );
    qsKey   = key   ( TransKeys, t );
    // Here we replace the actual keyword with the real string.
    if ( ( qsValue.isNull()) || ( qsValue.isEmpty()) )
      continue;
    qsOutput.replace( qsKey, qsValue );
  }
  return qsOutput;
}

void Keyword::printf ( int iWhichKeyset )
{
  int    t;
  Entry *pEntry;
  if ( iWhichKeyset >= BaseLast )
    iWhichKeyset = Keys;
  
  for (t=0;t<(int)m_listOfPair[iWhichKeyset].count();t++) {
    pEntry = m_listOfPair[iWhichKeyset][t];
    ::printf ("%d > index=<%d> : Key=<%s> value=<%s>\n", t, pEntry->iIndex, pEntry->qsKey.ascii(), pEntry->qsValue.ascii() );
  }  
}
