#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sentence.h"

#include "song.h"
Song::Song(  )
{

  // ctor
  m_lstSentences = NULL;
  reinit(  );
}

Song::~Song(  )
{
  reinit( 0 );

  // dtor
}
void Song::reinit( int realloc )
{
  m_nbSentences = 0;
  m_title[0] = 0;
  m_artiste[0] = 0;
  m_mp3FileName[0] = 0;
  m_BPM = 0;
  m_GAP = 0;
  m_RelativeTime = 0;
  m_currentTime = 0;
  if( m_lstSentences != NULL )

  {
    delete[]m_lstSentences;
    m_lstSentences = NULL;
  }
  if( realloc == 1 )

  {
    m_lstSentences = new Sentence[1000];
  }
}
void Song::ReadSong( const char *filename )
{
  FILE *file;
  char oneLine[256];
  char *ptrLine;
  reinit(  );
  file = fopen( filename, "rt" );
  if( file == NULL )

  {
    fprintf( stderr, "Can't open file: '%s'", filename );
  }

  else

  {
    ptrLine = fgets( oneLine, 256, file );
    while( ptrLine != NULL )

    {
      if( oneLine[0] == '#' )   // header
      {
        parseHeaderLine( oneLine );
      }

      else

      {
        parseBodyLine( oneLine );
      }
      ptrLine = fgets( oneLine, 256, file );
    }
    fclose( file );

    /*
     * Add path to mp3 filename 
     */
    makemp3filepath( filename );
  }
}
void Song::makemp3filepath( const char *filename )
{
  char *lastSlash;
  char tmp[256];
  strcpy( tmp, filename );
  lastSlash = strrchr( tmp, '/' );
  if( lastSlash != NULL )

  {
    lastSlash++;
    strcpy( lastSlash, m_mp3FileName );
    strcpy( m_mp3FileName, tmp );
  }

}
void Song::TrimR( char *ptr )
{
  char *stim;

  stim = strchr( ptr, 0x0a );
  if( stim != NULL )
    *stim = 0;
  stim = strchr( ptr, 0x0d );
  if( stim != NULL )
    *stim = 0;

}
void Song::parseHeaderLine( char *line )
{
  if( strstr( line, "#TITLE:" ) != NULL )

  {
    strcpy( m_title, line + 7 );
    TrimR( m_title );
    printf( "[karaoke] Title:'%s'\n", m_title );
  }
  if( strstr( line, "#ARTIST:" ) != NULL )

  {
    strcpy( m_artiste, line + 8 );
    TrimR( m_artiste );
    printf( "[karaoke] Artist:'%s'\n", m_artiste );
  }
  if( strstr( line, "#MP3:" ) != NULL )

  {
    strcpy( m_mp3FileName, line + 5 );
    TrimR( m_mp3FileName );
    printf( "[karaoke] mp3 file:'%s'\n", m_mp3FileName );
  }
  if( strstr( line, "#BPM:" ) != NULL )

  {
    m_BPM = 4 * atoi( line + 5 );
    printf( "[karaoke] BPM:%d\n", m_BPM / 4 );
  }
  if( strstr( line, "#GAP:" ) != NULL )

  {
    m_GAP = atoi( line + 5 );
    printf( "[karaoke] GAP:%d\n", m_GAP );
  }
  if( strstr( line, "#RELATIVE:YES" ) != NULL )
  {
    m_RelativeTime = 1;
    printf( "[karaoke] RELATIVE:yes\n" );
  }
}
void Song::parseBodyLine( char *line )
{
  char *pline = line;
  char strTmp[20];
  char strSyllable[20];
  int start, duration, note;
  if( line[0] == ':' || line[0] == '*' || line[0] == 'F' )

  {
    pline = getLineParam( pline, strTmp );  // dummy
    pline = getLineParam( pline, strTmp );  // Start
    start = atoi( strTmp );
    pline = getLineParam( pline, strTmp );  // Duration
    duration = atoi( strTmp );
    pline = getLineParam( pline, strTmp );  // Note
    note = atoi( strTmp );
    pline = getLineParamTxt( pline, strSyllable );  // Syllable

    if( m_RelativeTime == 0 )
      m_currentTime = start;
    else
      m_currentTime += start;
    m_lstSentences[m_nbSentences].addSyllable( m_currentTime, duration, note,
                                               strSyllable );
  }
  if( line[0] == '-' )

  {
    pline = getLineParam( pline, strTmp );  // dummy
    pline = getLineParam( pline, strTmp );  // Start
    start = atoi( strTmp );
    if( m_RelativeTime == 0 )
      m_currentTime = start;
    else
      m_currentTime += start;
    m_nbSentences++;
    m_lstSentences[m_nbSentences].setStart( start );
  }
}
char *Song::getLineParam( char *line, char *out )
{
  while( ( *line ) != 0 && ( *line ) != ' ' && ( *line ) != 0xd
         && ( *line ) != 0xa )

  {
    *out = *line;
    line++;
    out++;
  }
  if( ( *line ) == ' ' )
    line++;
  *out = 0;
  return ( line );
}
char *Song::getLineParamTxt( char *line, char *out )
{
  while( ( *line ) != 0 && ( *line ) != 0xd && ( *line ) != 0xa )

  {
    *out = *line;
    line++;
    out++;
  }
  *out = 0;
  return ( line );
}
int Song::SetCurrentTime( float time )
{
  int fin = 0;
  time -= m_GAP / 1000;
  time = ( time * m_BPM ) / 60;
  m_currentTime = ( int ) time;
  m_currentSentence = 0;
  while( fin == 0 )

  {
    if( m_currentTime <= m_lstSentences[m_currentSentence + 1].m_start )

    {
      m_lstSentences[m_currentSentence].setAtBegin(  );
      fin = 1;
    }

    else
      m_currentSentence++;
    if( m_currentSentence >= m_nbSentences )
      fin = 1;
  }
  return ( 0 );
}
int Song::getNextSyllable( Syllable & syll, int *status )
{
  syll.m_theSyllable[0] = 0;
  if( m_lstSentences[m_currentSentence].
      getNextSyllable( syll, status, m_currentTime ) == 1 )

  {
    m_currentSentence++;
    m_lstSentences[m_currentSentence].setAtBegin(  );
  }
  return ( m_currentSentence );
}


  /*
   *   #TITLE:Superstar (demo) #ARTIST:Jamelia #MP3:Jamelia - Superstar
   * (Demo).mp3 #BPM:110 #GAP:50 TypeP StartP DurationP NoteP LyricS :
   * 129 2 15 Peop : 131 1 15 le : 132 3 15 al : 135 1 15 ways : 137 1 13 
   * talk : 139 1 15 a : 141 2 10 bout - 152 : 161 2 15 All : 163 1 15
   * the : 164 2 15 things : 167 1 15 they're : 169 2 13 all : 171 2 15
   * a : 173 2 10 bout - 184 
   */
