Andy's CarPlayer

Under construction

/***************************************************************************
                          play_tracks.c  -  description
                             -------------------
    begin                : Mon Feb 28 2005
    copyright            : (C) 2005 by Andy
    email                : 
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 
 #include 
 #include 
 #include 


 #include "display.h"
 #include "main.h"
 #include "log.h"
 #include "tools.h"
 #include "mpg_interface.h"

  #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 void play_track(VALUES song); // need to put here, as VALUES is defined in main.h
 
 void setup_initial_arrays()
 {
   char query[255];
   int number_of_rows, i;
   
   MYSQL_RES *res;
   MYSQL_ROW row;
   char Album[30], Artist[30];
   
   res = db_query("SELECT album FROM albums WHERE available=1 ORDER BY album");
   MP3_system.number_of_albums = mysql_num_rows(res);
   for (i = 0; i < MP3_system.number_of_albums; i++)
   {
     mysql_data_seek(res, i);
     row = mysql_fetch_row(res);
     mysql_real_escape_string(&mysql, Album, row[0], strlen(row[0]));
     strcpy(albums[i].album, Album);
     log_printf(LOG_NOISY_DEBUG, "setup_inital_arrays :album %s\n", albums[i].album);
   }
   res = db_query("SELECT artist FROM artists WHERE available=1 ORDER BY artist");
   MP3_system.number_of_artists = mysql_num_rows(res);
   for (i = 0; i < MP3_system.number_of_artists; i++)
   {
     mysql_data_seek(res, i);
     row = mysql_fetch_row(res);
     mysql_real_escape_string(&mysql, Artist, row[0], strlen(row[0]));
     strcpy(artists[i].artist, Artist);
     log_printf(LOG_NOISY_DEBUG, "setup_inital_arrays :artist %s\n", artists[i].artist);
   }
   
 }

 void play_single_track()
 {
  char track_str[5];
  int track;

  MYSQL_RES *res;
  MYSQL_ROW row;

  char query[400];

  MP3_system.playing_type = SINGLE;
  clear_win(player_win[MAIN_SCREEN]);
  nocbreak();
  echo();
  do       // Ensure that the request is done at least once...
  {
    mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Select track (0 - %-5i)", MP3_system.number_of_tracks -1);
    wtimeout(player_win[MAIN_SCREEN], -1);
    wgetstr(player_win[MAIN_SCREEN], track_str);  // Get the artist number as a string from the MAIN_SCREEN
    track=atoi(track_str);  //Convert to int
  }
  while (track > MP3_system.number_of_tracks -1);

  sprintf(query, "SELECT filename, track, album, artist, genre, available FROM all_songs WHERE available=1 order by album, filename");
  log_printf(LOG_NOISY_DEBUG, "play_single_track ; %s\n", query);
  res = db_query(query);
  mysql_data_seek(res, track);
  row = mysql_fetch_row(res);
  strcpy(current_song.filename, row[0]);
  strcpy(current_song.track,    row[1]);
  strcpy(current_song.album,    row[2]);
  strcpy(current_song.artist,   row[3]);
  strcpy(current_song.genre,    row[4]);

  play_track(current_song);
}

 
 void random_play_init()
{
  int i, j, selected_number_of_tracks;
  char query[300], option;

  MYSQL_RES *res, *res1;
  MYSQL_ROW row, row1;

  sprintf(query, "DELETE FROM random_play");  // delete the random table
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  res = db_query(query);
  mysql_free_result(res);

// Select all music tracks from the main database table
  sprintf(query, "SELECT track, filename FROM all_songs WHERE available=1 AND genre != \"Speech\"");
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  res = db_query(query);
  selected_number_of_tracks = mysql_num_rows(res); // Holds the number of available music tracks


  clear_win(player_win[MAIN_SCREEN]);
  LCD_clear();
  mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Press 0 to save current random tracks");
  tty_write("1", "Rebuild random list");
  tty_write("2", "  Press 0 to save");
  for (i = 1; i<= selected_number_of_tracks ; i++)
  {
    do
    {
      j = rand()%selected_number_of_tracks;
      log_printf(LOG_NOISY_DEBUG, "Random_play : random offset = %i\n", j);
// Seek in the results for the track
      if (j != 0) mysql_data_seek(res, j-1);
      else mysql_data_seek(res, 0);
// Get the track details
      row = mysql_fetch_row(res);
 // Used to ensure no duplications. Gets very slow towards the end though...
      sprintf(query, "SELECT filename FROM random_play WHERE filename=\"%s\"", row[1]);
      res1 = db_query(query);
      row1 = mysql_fetch_row(res1);
    }
    while (row1 != NULL); // i.e. repeat while there is a track present

// Add the track and filename info into the random play table
    sprintf(query, "INSERT INTO random_play (track, filename) VALUES (\"%s\", \"%s\")", row[0], row[1]);
    log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
    db_query(query);
    mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Added %-5i Tracks out of %i", i, selected_number_of_tracks);
// Give the user an opt-out if it is taking too long...
    wtimeout(player_win[MAIN_SCREEN], 1);
    option = wgetch(player_win[MAIN_SCREEN]);
      switch (option)
      {
        case '0':
          i = selected_number_of_tracks + 1;
          break;
      }
  }
  mysql_free_result(res);
  wtimeout(player_win[MAIN_SCREEN], 2);
}

void new_random_play_init()
{
  char query[300], option;

  MYSQL_RES *res, *res1;
  MYSQL_ROW row, row1;

  clear_win(player_win[MAIN_SCREEN]);
  LCD_clear();
  tty_write("1", "Rebuild random list");

  sprintf(query, "DELETE FROM random_play");  // delete the random table
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  res = db_query(query);
  mysql_free_result(res);

// Select all music tracks from the main database table
  sprintf(query, "INSERT INTO random_play (track, filename) (SELECT track, filename FROM all_songs WHERE available=1 AND genre != \"Speech\" order by rand())");
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  res = db_query(query);
  wtimeout(player_win[MAIN_SCREEN], 2);
}
   


random_play()
{
  int i, j, current_pos, selected_number_of_tracks;
  char query[300];

  MYSQL_RES *res, *res1;
  MYSQL_ROW row;

  char Song[30], Artist[30], Album[30];

  current_pos = 1;
  sprintf(query, "select track, filename, last_played from random_play where last_played is NULL OR last_played=CURDATE()");
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  res = db_query(query);
  selected_number_of_tracks = mysql_num_rows(res);
  log_printf(LOG_NOISY_DEBUG, "Random_play : Random track count %i\n", selected_number_of_tracks);
  MP3_system.play_status = STOPPED;
  MP3_system.playing_type = RANDOM;
// Skip through tracks already played today
  do
  {
    mysql_data_seek(res, current_pos);
    row = mysql_fetch_row(res);
    current_pos++;
  }
  while (row[2] != NULL);
  current_pos = current_pos - 2; // starts playing from the last track that was played.
// Main random play bit (plays the rest of the tracks, but lets you scroll back through todays tracks.
  while ((MP3_system.play_status != RECONFIGURE) && (MP3_system.play_status != TERMINATE) && (current_pos <= selected_number_of_tracks))
  {
    clear_win(player_win[MAIN_SCREEN]);
    mvwprintw(player_win[MAIN_SCREEN], 8, 2, "Number of tracks available : %-5i Currently played today %i", selected_number_of_tracks, current_pos);
    mysql_data_seek(res, current_pos);
    row = mysql_fetch_row(res);

    sprintf(query, "select filename, track, album, artist, genre, year from all_songs where filename = \"%s\"", row[1]);
    log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
    if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 2, 1, "%s", query);
    }
  
  res1 = db_query(query);
  row = mysql_fetch_row(res1);
      mysql_real_escape_string(&mysql, Song, row[1], strlen(row[1]));
      mysql_real_escape_string(&mysql, Album, row[2], strlen(row[2]));
      mysql_real_escape_string(&mysql, Artist, row[3], strlen(row[3]));
  strcpy(current_song.filename, row[0]);
  strncpy(current_song.track,    Song, 30);
  strncpy(current_song.album,    Album, 30);
  strncpy(current_song.artist,   Artist, 30);
  strcpy(current_song.genre,    row[4]);
strcpy(current_song.year,    row[5]);
/*  mvwprintw(player_win[MAIN_SCREEN], 1, 2, "Current Song   : %-30s", current_song.track);
  mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Current Album  : %-30s ", current_song.album);
  mvwprintw(player_win[MAIN_SCREEN], 3, 2, "Current Artist : %s", current_song.artist);
*/
log_printf(LOG_DEBUG, "Random_play : about to play %s\n", current_song.filename);
log_printf(LOG_DEBUG, "Random_play : Track %s\n", current_song.track);
log_printf(LOG_DEBUG, "Random_play : Album %s\n", current_song.album);
log_printf(LOG_DEBUG, "Random_play : Artist %s\n", current_song.artist);
log_printf(LOG_DEBUG, "Random_play : Year %s\n", current_song.year);
log_printf(LOG_DEBUG, "Random_play : Genre %s\n", current_song.genre);

  play_track(current_song);
  sprintf(query, "UPDATE random_play SET last_played=CURDATE() WHERE filename=\"%s\"", current_song.filename);
  log_printf(LOG_NOISY_DEBUG, "Random_play : %s\n", query);
  db_query(query);

  if ((MP3_system.play_status == NEXT) && (current_pos < selected_number_of_tracks))
    current_pos++;
  else if ((MP3_system.play_status == PREVIOUS) && (current_pos > 1))
    current_pos--;
  }
}

void play_album()
{
  char album_str[5], temp, text[10];
  int Album, char_count, valid_choice, i;

  MP3_system.playing_type = ALBUM;

  nocbreak();
  echo();
  do       // Ensure that the request is done at least once...
  {
    for (i = 0; i<= 5; i++) { album_str[i] = "\0";}
    clear_win(player_win[MAIN_SCREEN]);
    LCD_clear();
    mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Select Album (0 - %-5i)", MP3_system.number_of_albums -1);
    tty_write("1", "Select Album");
    sprintf(text, "(0 -> %-5i)",  MP3_system.number_of_albums -1);
    tty_write("2", text);
    wtimeout(player_win[MAIN_SCREEN], -1);
 /*   temp=wgetch(player_win[MAIN_SCREEN]);
log_printf(LOG_NOISY_DEBUG, "input : %s", temp);
    char_count = 0;
    while ( (temp != '\n') && (char_count <= 4))
    {
      if (temp == '-')
      {
        album_str[char_count--] = '\0';
      }
      album_str[char_count++] = temp;
      sprintf(text, "> %s", temp);
      tty_write("3", text);
      temp=wgetch(player_win[MAIN_SCREEN]);
log_printf(LOG_NOISY_DEBUG, "input : %s", temp);
    }
    */
    wgetstr(player_win[MAIN_SCREEN], album_str);  // Get the album number as a string from the MAIN_SCREEN
    
    Album=atoi(album_str); // Convert to int
  }
  while (Album > MP3_system.number_of_albums - 1);
  do
  {
    play_album_number(Album);
  }
  while(MP3_system.play_status != TERMINATE);
  Album = (int)NULL;
}

void play_album_number(int Album)
{
  char query[400], curr_date[25];
  int counter=0, plays, position, i, number_of_rows, terminate = FALSE;
  MYSQL_RES *res;
  MYSQL_ROW row;

  MP3_system.playing_type = ALBUM;
  
  if (Album == -1)
    sprintf(query, "select track, position, number_of_plays from albums where album=\"%s\"", current_song.album);
  else
    sprintf(query, "select track, position, number_of_plays from albums where album=\"%s\"", albums[Album].album);

  if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 1, 1, "%s", query);
    }
 log_printf(LOG_NOISY_DEBUG, "play_album_number : %s\n", query);
  res = db_query(query);
  row = mysql_fetch_row(res);
//  (row[0] == NULL) \
//      ? mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Track does not exist") \
//      : mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Track (%s) exists", row[0]);
  number_of_rows = mysql_num_rows(res);
  if (number_of_rows > 0)
  {
    if (row[1] != NULL)
      position = atoi(row[1]);
    else
      position = 0;

    if (row[2] != NULL)     // just in case the number-of-plays field has not been set yet...
      plays = atoi(row[2]);
    else
      plays = 0;

    mysql_free_result(res);
  } else
  {
    position = 0;
    mysql_free_result(res);
  }

  if (Album == -1)
    sprintf(query, "select filename, track, artist, genre, year from all_songs where album = \"%s\" order by filename", current_song.album);
  else
    sprintf(query, "select filename, track, artist, genre, year from all_songs where album = \"%s\" order by filename", albums[Album].album);

  if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 2, 1, "%s", query);
    }
  log_printf(LOG_NOISY_DEBUG, "play_album_number : %s\n", query);
  res = db_query(query);
  mysql_data_seek(res, position);
  row = mysql_fetch_row(res);
  strcpy(current_song.filename, row[0]);
  strcpy(current_song.track, row[1]);
  if (Album != -1)
    strcpy(current_song.album, albums[Album].album);
  strcpy(current_song.artist, row[2]);
  strcpy(current_song.genre, row[3]);
strcpy(current_song.year,    row[4]);
  number_of_rows = mysql_num_rows(res);
//  mvwprintw(player_win[INFO_SCREEN], 3, 1, "Number of rows : %i  (current pos : %i)", number_of_rows, position+1);

  if (position < (number_of_rows -1))   // number_of_rows = number of tracks.
  {
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : Selecting");
    mysql_data_seek(res, position + 1);
    row = mysql_fetch_row(res);
    strcpy(current_song.next_track, row[1]);
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : %s", current_song.next_track);
  }
  else
  {
 //   strcpy(current_song.next_track, (char) NULL);
    current_song.next_track[0]=(char)NULL;
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : Invalid                       ");
    terminate = TRUE;
    terminate = true ;
  }
  if (position > 0)
  {
    mysql_data_seek(res, position - 1);
    row = mysql_fetch_row(res);
    mvwprintw(player_win[MAIN_SCREEN], 8, 2, "Previous Track : %s", row[1]);
  } else
  {
    mvwprintw(player_win[MAIN_SCREEN], 8, 2, "Previous Track : Invalid");
  }
/*  mvwprintw(player_win[MAIN_SCREEN], 1, 2, "Current Song   : %-30s", current_song.track);
  mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Current Album  : %-30s (plays to date : %i)", current_song.album, plays);
  mvwprintw(player_win[MAIN_SCREEN], 3, 2, "Current Artist : %s", current_song.artist);
  mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Current Genre  : %s", current_song.genre);
*/
  play_track(current_song);  // This bit handles the playing of the song.
  switch (MP3_system.play_status)
  {
    case NEXT:
      if (position < number_of_rows -1)
      {
        lastframepos = 0;  //reset play position to the start
        position++;
      }
      else
      {
        lastframepos = 0; //reset play position to the start
        position = (int)NULL;
        plays++;
        terminate = TRUE;
      }
      break;
    case PREVIOUS:
      log_printf(LOG_NOISY_DEBUG, "Play_album_number : case PREVIOUS\n");
      if (position > 0)
      {
        lastframepos = 0; //reset play position to the start
        position--;
      }
      break;
   }
  get_date(curr_date);
  sprintf(query, "UPDATE albums SET track=\"%s\", position=%i, number_of_plays=%i, last_played=\"%s\" WHERE album=\"%s\"",\
                    current_song.track,\
                    position,\
                    plays,\
                    curr_date,\
                    current_song.album);
  log_printf(LOG_NOISY_DEBUG, "play_album_number : %s\n", query);
  log_printf(LOG_NOISY_DEBUG, "play_album_number : Play_status = %i\n", MP3_system.play_status);
  if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 2, 1, "%s", query);
    }
  res = db_query(query);
  mysql_free_result(res);
  if (terminate)
     MP3_system.play_status = TERMINATE;

  cbreak();
  noecho();
}


void select_play_album()
{
 ITEM **my_items;
 MENU *my_menu;
 int c, n_choices, i;
 char *num;

 n_choices = ARRAY_SIZE(albums);
 mvwprintw(player_win[INFO_SCREEN], 1, 1, "Number of items: %i      ", n_choices);
 my_items = (ITEM **)calloc(n_choices, sizeof(ITEM *));
 for (i = 0; i< n_choices; ++i)
 {
    my_items[i] = new_item("i", albums[i+1].album);
 }
 my_menu = new_menu((ITEM **)my_items);

 set_menu_win(my_menu, player_win[MAIN_SCREEN]);
 //   derwin(window, rows, columns, start_line, start_column).
 set_menu_sub(my_menu, derwin(player_win[MAIN_SCREEN], 13, 57, 1, 2));
 set_menu_format(my_menu, 13, 1);
 set_menu_mark(my_menu, "* ");

 post_menu(my_menu);
 noecho();
 wtimeout(player_win[MAIN_SCREEN], -1);
 while ((c = wgetch(player_win[MAIN_SCREEN])) != 10)
 {
//   mvwprintw(player_win[INFO_SCREEN], 1, 1, "key pressed : %i            ", c);
   switch(c)
   {
     case KEY_DOWN:
     case '2':
//       mvwprintw(player_win[INFO_SCREEN], 2, 1, "DOWN           ");
       menu_driver((MENU *)player_win[MAIN_SCREEN], REQ_DOWN_ITEM);
       break;
     case KEY_UP:
     case '8':
//       mvwprintw(player_win[INFO_SCREEN], 2, 1, "UP              ");
       menu_driver((MENU *)player_win[MAIN_SCREEN], REQ_UP_ITEM);
       break;
   }
 }
 echo();
 wtimeout(player_win[MAIN_SCREEN], 2);
 unpost_menu(my_menu);
 free_menu(my_menu);
 for(i = 0; i < n_choices; ++i)
   free_item(my_items[i]);
}


void play_artist()
{
  char artist_str[5];
  int Artist;

  MP3_system.playing_type = ARTIST;
  clear_win(player_win[MAIN_SCREEN]);
  LCD_clear();
  nocbreak();
  echo();
  do       // Ensure that the request is done at least once...
  {
    mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Select Artist (0 - %-5i)", MP3_system.number_of_artists -1);
    tty_write("1", "Select Artist");
    wtimeout(player_win[MAIN_SCREEN], -1);
    wgetstr(player_win[MAIN_SCREEN], artist_str);  // Get the artist number as a string from the MAIN_SCREEN
    Artist=atoi(artist_str);  //Convert to int
  }
  while (Artist > MP3_system.number_of_artists - 1);
  do
  {
    play_artist_number(Artist);
  }
  while(MP3_system.play_status != TERMINATE);
  Artist = (int)NULL;
}

void play_artist_number(int Artist)
{
  char query[400], curr_date[25];
  int plays, position, i, number_of_rows, terminate = FALSE;
  MYSQL_RES *res;
  MYSQL_ROW row;

  MP3_system.playing_type = ARTIST;
  
  if (Artist == -1)
    sprintf(query, "select track, position, number_of_plays from artists where artist=\"%s\"", current_song.artist);
  else
    sprintf(query, "select track, position, number_of_plays from artists where artist=\"%s\"", artists[Artist].artist);

  res = db_query(query);
  row = mysql_fetch_row(res);

  number_of_rows = mysql_num_rows(res);
  if (number_of_rows > 0)
  {
    if (row[1] != NULL)
      position = atoi(row[1]);
    else
      position = 0;

    if (row[2] != NULL)     // just in case the number-of-plays field has not been set yet...
      plays = atoi(row[2]);
    else
      plays = 0;

    mysql_free_result(res);
  } else
  {
    position = 0;
    mysql_free_result(res);
  }

  if (Artist == -1)
    sprintf(query, "select filename, track, album, genre, year from all_songs where artist = \"%s\"", current_song.artist);
  else
    sprintf(query, "select filename, track, album, genre, year from all_songs where artist = \"%s\"", artists[Artist].artist);

  if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 2, 1, "%s", query);
    }
  res = db_query(query);
  mysql_data_seek(res, position);
  row = mysql_fetch_row(res);
  strcpy(current_song.filename, row[0]);
  strcpy(current_song.track, row[1]);
  if (Artist != -1)
    strcpy(current_song.artist, artists[Artist].artist);
  strcpy(current_song.album, row[2]);
  strcpy(current_song.genre, row[3]);
strcpy(current_song.year,    row[4]);
  number_of_rows = mysql_num_rows(res);
//  mvwprintw(player_win[INFO_SCREEN], 3, 1, "Number of rows : %i  (current pos : %i)", number_of_rows, position+1);

  if (position < (number_of_rows -1))   // number_of_rows = number of tracks.
  {
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : Selecting");
    mysql_data_seek(res, position + 1);
    row = mysql_fetch_row(res);
    strcpy(current_song.next_track, row[1]);
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : %s", current_song.next_track);
  }
  else
  {
 //   strcpy(current_song.next_track, (char) NULL);
    current_song.next_track[0]=(char)NULL;
    mvwprintw(player_win[MAIN_SCREEN], 7, 2, "Next Track     : Invalid                       ");
    terminate = TRUE;
    terminate = true ;
  }
  if (position > 0)
  {
    mysql_data_seek(res, position - 1);
    row = mysql_fetch_row(res);
    mvwprintw(player_win[MAIN_SCREEN], 8, 2, "Previous Track : %s", row[1]);
  } else
  {
    mvwprintw(player_win[MAIN_SCREEN], 8, 2, "Previous Track : Invalid");
  }
//  mvwprintw(player_win[MAIN_SCREEN], 1, 2, "Current Song   : %-30s", current_song.track);
//  mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Current Album  : %-30s (plays to date : %i)", current_song.album, plays);
//  mvwprintw(player_win[MAIN_SCREEN], 3, 2, "Current Artist : %s", current_song.artist);
//  mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Current Genre  : %s", current_song.genre);

  play_track(current_song);  // This bit handles the playing of the song.
  switch (MP3_system.play_status)
  {
    case NEXT:
      if (position < number_of_rows -1)
      {
        position++;
      }
      else
      {
        position = (int)NULL;
        plays++;
        terminate = TRUE;
      }
      break;
    case PREVIOUS:
      log_printf(LOG_NOISY_DEBUG, "Play_artist : case PREVIOUS\n");
      if (position > 0)
        position--;
      break;
   }
  get_date(curr_date);
  sprintf(query, "UPDATE artists SET track=\"%s\", position=%i, number_of_plays=%i, last_played=\"%s\" WHERE artist=\"%s\"",\
                    current_song.track,\
                    position,\
                    plays,\
                    curr_date,\
                    current_song.artist);
  log_printf(LOG_NOISY_DEBUG, "play_artist : %s\n", query);
  log_printf(LOG_NOISY_DEBUG, "play_artist : Play_status = %i\n", MP3_system.play_status);
  if (debug_level >= LOG_NOISY_DEBUG)
    {
//      for (i=1; i < COLS - 1; i++)
//        mvwprintw(player_win[INFO_SCREEN], 2, i, " ");
//      mvwprintw(player_win[INFO_SCREEN], 2, 1, "%s", query);
    }
  res = db_query(query);
  mysql_free_result(res);
  if (terminate)
     MP3_system.play_status = TERMINATE;

  cbreak();
  noecho();
}

void print_database()
{
  int i, number_of_rows;
  char query[400], LCD_buffer[17];
  FILE *filename, *filename1;

  MYSQL_RES *res, *res1;
  MYSQL_ROW row;
  char Album[30], Artist[30];

  LCD_clear();
  tty_write("1", "Printing database...");
  
  if ((filename=fopen("./track_list","w")) != NULL)
  {
  if ((filename1=fopen("./audio_book_list","w")) != NULL)
  {
    sprintf(query, "select track, album, artist, genre from all_songs WHERE available=1 order by album, filename");
    res = db_query(query);
    number_of_rows = mysql_num_rows(res);
    for (i = 0; i < number_of_rows; i++)
    {
      mysql_data_seek(res, i);
      row = mysql_fetch_row(res);
      mysql_real_escape_string(&mysql, Album, row[1], strlen(row[1]));
      mysql_real_escape_string(&mysql, Artist, row[2], strlen(row[2]));
      if (strcmp(row[3], "Speech") == 0)
        fprintf(filename1, "%-5i > %-30s - %-30s - %-30s\n", i, row[0], Album, Artist);
      else
        fprintf(filename, "%-5i > %-30s - %-30s - %-30s\n", i, row[0], Album, Artist);
      mvwprintw(player_win[MAIN_SCREEN], 9,2, "Dumped %-5i tracks", i);
      sprintf(LCD_buffer, "Dumped %-5i tracks", i);
      tty_write("3", LCD_buffer);
    }
    mysql_free_result(res);
    fclose(filename);
  }
  }

  if ((filename=fopen("./artist_list","w")) != NULL)
  {
    sprintf(query, "select artist, album from artists WHERE available=1 order by artist");
    res = db_query(query);
    number_of_rows = mysql_num_rows(res);
    for (i = 0; i < number_of_rows; i++)
    {
      mysql_data_seek(res, i);
      row = mysql_fetch_row(res);
      mysql_real_escape_string(&mysql, Artist, row[0], strlen(row[0]));
      fprintf(filename, "%-5i > %-30s - ", i, Artist);
      sprintf(query, "SELECT COUNT(*) FROM all_songs WHERE artist=\"%s\"", Artist);
      res1 = db_query(query);
      row = mysql_fetch_row(res1);
      fprintf(filename, "%s\n", row[0]);
       mvwprintw(player_win[MAIN_SCREEN], 10,2, "Dumped %-5i artists", i);
      sprintf(LCD_buffer, "Dumped %-5i artists", i);
      tty_write("4", LCD_buffer);
      mysql_free_result(res1);
    }
    fclose(filename);
  }

  if ((filename=fopen("./album_list","w")) != NULL)
  {
    sprintf(query, "select album, artist, audio_book from albums WHERE available=1 order by album");
    res = db_query(query);
    number_of_rows = mysql_num_rows(res);
    for (i = 0; i < number_of_rows; i++)
    {
      mysql_data_seek(res, i);
      row = mysql_fetch_row(res);
      if (atoi(row[2]) == 0)
        fprintf(filename, "   %-5i > %-30s - %-30s - ", i, row[0], row[1]);
      else
        fprintf(filename, "** %-5i > %-30s - %-30s - ", i, row[0], row[1]);
      mysql_real_escape_string(&mysql, Album, row[0], strlen(row[0]));
      sprintf(query, "SELECT COUNT(*) FROM all_songs WHERE album=\"%s\"", Album);
      res1 = db_query(query);
      row = mysql_fetch_row(res1);
      fprintf(filename, "%s\n", row[0]);
       mvwprintw(player_win[MAIN_SCREEN], 11,2, "Dumped %-5i albums", i);
      sprintf(LCD_buffer, "Dumped %-5i albums", i);
      tty_write("5", LCD_buffer);
      mysql_free_result(res1);
    }
    mysql_free_result(res);
    fclose(filename);
  }
}

void play_track(VALUES song)
{
  MYSQL_RES *res;
  MYSQL_ROW row;
  char query[400];
  
  char option;
  char date_buffer[11], time_buffer[11], LCD_buffer[17];

  int framepos;

  noecho();
  MP3_system.play_status = SONG_PLAY;

  // reset LCD offset counters:
  MP3_system.track_LCD_offset = MP3_system.artist_LCD_offset = MP3_system.album_LCD_offset = 0;
  
log_printf(LOG_DEBUG, "Loading \"%s\"\n", song.filename);
  
  mpg123_load(song.filename);
  sprintf(query, "SELECT framepos FROM albums where album=\"%s\"", song.album);
  res = db_query(query);
  row = mysql_fetch_row(res);
  log_printf(LOG_NOISY_DEBUG, "play_track : framepos = %s\n", row[0]);

  if (row[0] != NULL)
  {
    framepos = atoi(row[0]);
    mpg123_position(framepos);
  }
  else
    framepos = 0;
  log_printf(LOG_NOISY_DEBUG, "play_track : framepos = %i\n", framepos);
  mysql_free_result(res);

  mvwprintw(player_win[MAIN_SCREEN], 1, 2, "Current Song   : %-30s", current_song.track);
  mvwprintw(player_win[MAIN_SCREEN], 2, 2, "Current Album  : %-30s", current_song.album);
  mvwprintw(player_win[MAIN_SCREEN], 3, 2, "Current Artist : %s", current_song.artist);
  mvwprintw(player_win[MAIN_SCREEN], 4, 2, "Current Genre  : %s", current_song.genre);
mvwprintw(player_win[MAIN_SCREEN], 5, 2, "Current Year  : %s", current_song.year);
  LCD_clear();

  if (strlen(song.track) > 15)
    strncpy(LCD_buffer, song.track, 15);
  else
    strcpy(LCD_buffer, song.track);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
  tty_write("1", LCD_buffer);
  log_printf(LOG_DEBUG, "Playing song : %s\n", LCD_buffer);

  if (strlen(song.artist) > 15)
    strncpy(LCD_buffer, song.artist, 15);
  else
    strcpy(LCD_buffer, song.artist);
  tty_write("2", LCD_buffer);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
  log_printf(LOG_DEBUG, "Playing aritst : %s\n", LCD_buffer);

  if (strlen(song.album) > 15)
    strncpy(LCD_buffer, song.album, 15);
  else
    strcpy(LCD_buffer, song.album);
  tty_write("3", LCD_buffer);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
  log_printf(LOG_DEBUG, "Playing album : %s\n", LCD_buffer);

  if (strlen(song.genre) > 15)
    strncpy(LCD_buffer, song.genre, 15);
  else
    strcpy(LCD_buffer, song.genre);
  tty_write("4", LCD_buffer);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
  log_printf(LOG_DEBUG, "Playing genre : %s\n", LCD_buffer);

  tty_write("5", song.year);
  log_printf(LOG_DEBUG, "Playing year : %s\n", song.year);

  wtimeout(player_win[MAIN_SCREEN], 2);
  do
  {
  option = wgetch(player_win[MAIN_SCREEN]);
    switch (option)
    {
      case '0':
        MP3_system.play_status = TERMINATE;
        mpg123_stop();
        break;
      case '+':
        MP3_system.play_status = NEXT;
        mpg123_stop();
        log_printf(LOG_NOISY_DEBUG, "play_track : selected PREVIOUS (%i).\n" , MP3_system.play_status);
 //       mvwprintw(player_win[INFO_SCREEN], 3, 2, "Next Track : %s", song.next_track);
        break;
      case '-':
        MP3_system.play_status = PREVIOUS;
        mpg123_stop();
        log_printf(LOG_NOISY_DEBUG, "play_track : selected PREVIOUS (%i).\n" , MP3_system.play_status);
        break;
      case '1':
        mpg123_position(0);
        break;
      case '2':
        mixer_change_volume("pcm", -5);
        MP3_system.PCM_volume = get_volume("pcm");
        break;
      case '4':
        if ((play_time - 1) > 0)
          mpg123_jump("-");
        break;
      case '5':
        mpg123_pause();
        break;
      case '6':
        if ((play_time_remaining - 10) > 0)
          mpg123_jump("+");
        break;
      case '7':
        if ((play_time - 50) > 0)
          mpg123_big_jump("-");
        break;
      case '8':  // Volume up.
        mixer_change_volume("pcm", 5);
        MP3_system.PCM_volume = get_volume("pcm");
        break;
      case '9':
        if ((play_time_remaining - 50) > 0)
          mpg123_big_jump("+");
        break;
      case '*':
//        if (MP3_system.playing_type == RANDOM);
        {
          wtimeout(player_win[MAIN_SCREEN], 2000);
          LCD_clear();

          tty_write("1", "Select new play mode");
          tty_write("2", "  3   Play artist");
          tty_write("3", "  4   Play album");
          mvwprintw(player_win[MAIN_SCREEN], 11, 2, "Select new play mode:");
          option = wgetch(player_win[MAIN_SCREEN]);
          switch (option)
          {
            case '3':
              MP3_system.play_status = RECONFIGURE;
              MP3_system.playing_type = SELECT_ARTIST;
              mpg123_stop();
              break;
            case '4':
              MP3_system.play_status = RECONFIGURE;
              MP3_system.playing_type = SELECT_ALBUM;
              mpg123_stop();
              break;
            default:
              if (strlen(song.track) > 15)
                strncpy(LCD_buffer, song.track, 15);
              else
                strcpy(LCD_buffer, song.track);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
              tty_write("1", LCD_buffer);

              if (strlen(song.artist) > 15)
                strncpy(LCD_buffer, song.artist, 15);
              else
                strcpy(LCD_buffer, song.artist);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
              tty_write("2", LCD_buffer);

              if (strlen(song.album) > 15)
                strncpy(LCD_buffer, song.album, 15);
              else
                strcpy(LCD_buffer, song.album);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
              tty_write("3", LCD_buffer);

              if (strlen(song.genre) > 15)
                strncpy(LCD_buffer, song.genre, 15);
              else
                strcpy(LCD_buffer, song.genre);
LCD_buffer[strlen(LCD_buffer) + 1] = "\n";
              tty_write("4", LCD_buffer);
            break;
          }
          wtimeout(player_win[MAIN_SCREEN], 2);
        }
        break;
      default:
        MP3_system.mpg123_status = mpg123_read();
        log_printf(LOG_NOISY_DEBUG, "play_track : status = %i\n", MP3_system.mpg123_status);
        switch (MP3_system.mpg123_status)
        {
          case -10:
            endwin();
            LCD_clear();
            tty_write("2", "  MPG123 error");
            tty_write("4", "   Bye Bye..");
            exit(-1);
//            terminate = TRUE;
//            mpg123_quit();
            break;
          case SONG_END:
            MP3_system.play_status = NEXT;
            break;
          case SONG_TIME:
log_printf( LOG_NOISY_DEBUG, "In SONG_TIME part of play_track loop\n");
            get_date(date_buffer);
            get_time(time_buffer);
log_printf( LOG_NOISY_DEBUG, "Date & Time : %s %s\n", date_buffer, time_buffer);
log_printf( LOG_NOISY_DEBUG, "previous_sec & Time : %s %s\n", previous_sec, time_buffer);
//            if (previous_sec != play_time) //  replaced to allow VBR files to be played
            if (strcmp(previous_sec, time_buffer) != 0)
            {
//            previous_sec = play_time;   // replaced to allow VBR files to be played
              strcpy(previous_sec, time_buffer);
            mvwprintw(player_win[MAIN_SCREEN], 11, 2, "played : %0.2i:%0.2i remaining : %0.2i:%0.2i", play_time/60, play_time%60,\
                 play_time_remaining/60, play_time_remaining%60);
            sprintf(LCD_buffer, "%2i:%02d  (%2i:%02d)", play_time/60, play_time%60,\
                 play_time_remaining/60, play_time_remaining%60);
            tty_write("8", LCD_buffer);
            if ( play_time_remaining == 0)
              MP3_system.play_status = NEXT;

            MP3_system.PC_temp = temperature();
            mvwprintw(player_win[MAIN_SCREEN], 12, 2, "Temperature = %i, Volume = %i", MP3_system.PC_temp, MP3_system.PCM_volume);
//            get_date(date_buffer);
//            get_time(time_buffer);
            mvwprintw(player_win[MAIN_SCREEN], 13, 2, "%s %s", date_buffer ,time_buffer);
            sprintf(LCD_buffer, "Vol : %-3i T: %-2iC", MP3_system.PCM_volume, MP3_system.PC_temp);
            tty_write("7", LCD_buffer);
              
//            if ((MP3_system.playing_type == ALBUM) && (strcmp(song.genre, "Speech") == 0) && (lastframepos%200 == 0))
log_printf( LOG_NOISY_DEBUG, "Checking for Audiobook\n");
            if ((MP3_system.playing_type == ALBUM) && (strcmp(song.genre, "Speech") == 0) && (play_time%10 == 0))
            //if (strcmp(song.genre, "Speech") == 0)
            {
              sprintf(query, "UPDATE albums SET framepos=%i WHERE album=\"%s\"", lastframepos, song.album);
              log_printf(LOG_NOISY_DEBUG, "play_track: %s\n", query);
              db_query(query);
            }

log_printf( LOG_NOISY_DEBUG, "Checking for long names\n");
log_printf( LOG_NOISY_DEBUG, "Checking for track : %s (%i char long)\n", song.track, strlen(song.track));
            if (strlen(song.track) > 15)
             {
//             max_strlen=strlen(song.track);
             MP3_system.track_LCD_offset = full_scroll_text("1", song.track, MP3_system.track_LCD_offset);
             log_printf(LOG_NOISY_DEBUG,"LCD_song_offset : %i\n", MP3_system.track_LCD_offset);
             } else {
log_printf( LOG_NOISY_DEBUG, "short track name\n");
             }
log_printf( LOG_NOISY_DEBUG, "Checking for artist\n");
           if (strlen(song.artist) > 15)
           {
             MP3_system.artist_LCD_offset = full_scroll_text("2", song.artist, MP3_system.artist_LCD_offset);
           } else {
log_printf( LOG_NOISY_DEBUG, "short artist name\n");
             }
log_printf( LOG_NOISY_DEBUG, "Checking for artist\n");
           if (strlen(song.album) > 15)
           {
             MP3_system.album_LCD_offset = full_scroll_text("3", song.album, MP3_system.album_LCD_offset);
           } else {
log_printf( LOG_NOISY_DEBUG, "short album name\n");
             }
  log_printf( LOG_NOISY_DEBUG, "Completed SONG_TIME part of loop\n");
          }
          break;
        case SONG_PAUSE:
          tty_write("8", "     PAUSE    ");
          break;
        }
        break;
    }
  }
  while ((MP3_system.play_status != RECONFIGURE) && (MP3_system.play_status != TERMINATE) && (MP3_system.play_status != NEXT) && (MP3_system.play_status != PREVIOUS));
  do {} while (mpg123_read() != SONG_END); // loop until all data is recovered from the buffer i.e. SONG_END
  if ((MP3_system.play_status != TERMINATE) && (MP3_system.playing_type == ALBUM) && (strcmp(song.genre, "Speech") == 0))
  {
    sprintf(query, "UPDATE albums SET framepos=0 WHERE album=\"%s\"", song.album);
    log_printf(LOG_NOISY_DEBUG, "play_track: %s\n", query);
    db_query(query);
  }
  
//  mvwprintw(player_win[INFO_SCREEN], 3, 2, "Next Track : %s ....", song.next_track);
}