/* 
 *  Playlist calculator
 */

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

#define BLANK_COLUMN  "                                       "
#define PROMPT "Song number? "

#define LINE_LEN 80      /* max allowed input line length */
#define SONG_LEN 28      /* max displayed name (and artist) length */
#define TAPE_LEN 50      /* available recording time in minutes */

/* Column type - the two columns of the display */
typedef enum  { left, right }  columns;

   const char kPlaylistFilename[] =  "playlist.txt";

   typedef struct
   {
      char song[LINE_LEN];     /* song name */
      char artist[LINE_LEN];   /* who sang it  */
      int  time;               /* song duration in seconds */
      int  year;               /* release year */
      columns column;          /* which column currently contains the song */   
   }
   song_t;

/* Display an integer number of seconds as minutes and seconds
   in the form MM:HH */
    void showTime(int seconds)
   {
      printf("%2d:%02d", seconds/60, seconds%60);
   }

/* Calculate remaining time available to record */
    int getRemainingTime(const song_t songList[],     /* song times in seconds */
               int numberSongs)            /* how many songs in the list */
   {
      int total = 0;  /* total time of all songs to be recorded */
      int item;
      for (item = 1; item<=numberSongs; item++)
      { 
        /* If the song is in the selected column accumulate time */
         if (songList[item].column == 1)
         {
            total = total + songList[item].time;
         }
      }
      if (total > TAPE_LEN * 60 )
      {
         total = TAPE_LEN * 60;
      }
      return TAPE_LEN * 60 - total;
   }
        

/* Display the two column table of songs */
    void showTable(song_t songList[],  /* song list */
               int numberSongs)            /* how many songs in the list */
   {
      int total = 0;  /* total time of all songs to be recorded */
      int remain;     /* recording time available */
      int i1 = 1;     /* index to song pool */
      char title[SONG_LEN+1];
    
    /* Loop until all songs are shown */
      while (i1 <= numberSongs)
      {
       /* If there are any songs in the pool left to be displayed */
         if (songList[i1].column == 1)
         {
          /* Display blanks in column 1 */
            printf(BLANK_COLUMN);
            printf(" ");  /* column separator */
          /* Add this song's time to the total of selected songs */
            total = total + songList[i1].time;
         }
       /* Display the song info */
         printf("[%2d] ", i1);
         showTime(songList[i1].time);
         strncpy(title, songList[i1].song, SONG_LEN);
         title[SONG_LEN] = '\0';
         printf(" %s", title);
         printf("\n"); 
      
       /* Advance to the next song */ 
         i1++;
         
      }
   
    /* Convert the total time into minutes:seconds and show it */
      printf(BLANK_COLUMN);
      printf (" Total: ");
      showTime(total);
   
    /* Compute time remaining and show it */
      remain = getRemainingTime(songList,numberSongs);
      printf("   Remaining: ");
      showTime(remain);
      printf("\n");
    
   }

    /* Save the playlist to a file using entire song and artist names */
    void saveTable(song_t songList[],  /* song list */
               int numberSongs)            /* how many songs in the list */
   {
      FILE *inf;
      int i;
      int written = 0; /* count of songs written */
   
      inf = fopen(kPlaylistFilename, "w");
      {
         for (i=1; i<=numberSongs; i++)
         {
            if (songList[i].column)
            {
               fprintf(inf, "%4d %4d %-30s %-30s\n", songList[i].time, songList[i].year, songList[i].song, songList[i].artist);
               written = written + 1;
            }
         
         }
      }
      fclose(inf);
      printf("%d records written to %s.\n", written, kPlaylistFilename);
   
   }
/* Fill the list of songs from the data file */ 
    int fillTable(song_t songlist[])  /* song list */
   {
      FILE *inFile;                  /* file handle */
      int input_status;                  /* i/o status indicator */
      int count = 1;       /* song counter */
   
      /* Open the song file for reading */
      inFile = fopen("songdata.txt", "r");
      if (inFile == NULL) 
      {
         printf("Unable to open songdata.txt - missing file?");
         exit(1);
      }
      /* Obtain the song info */
      input_status = fscanf(inFile, "%s%d%s%d", songlist[count].song, &songlist[count].time, songlist[count].artist, &songlist[count].year);
   
      /* Loop until EOF */
      while (input_status != EOF)
      { 
          /* Increment how many songs we've read */
         count = count + 1;
          /* Get the next entry in the file */
         input_status = fscanf(inFile, "%s%d%s%d", songlist[count].song, &songlist[count].time, songlist[count].artist, &songlist[count].year);
      }
      return count - 1;
   }

    int 
    main(void)
   {
      song_t songlist[99];   /* a list of song records */
    
      int numberSongs;     /* final count of number of songs */
      int userSelection;   /* song number entered by user */
      
      numberSongs = fillTable(songlist);      
      
      /* Interact with user until they enter a zero */
      do 
      {
         showTable(songlist,numberSongs);
         printf(PROMPT);
         scanf("%d", &userSelection);
          
          /* If attempting to add a song to selected list */
         if (songlist[userSelection].column == 0)
         {
              /*  See if there is enough time  */
            if (getRemainingTime(songlist,numberSongs) > songlist[userSelection].time)
            {
                  /* Toggle column indicator for this item:  
                  false means col 1, true means col 2 */
               songlist[userSelection].column = !songlist[userSelection].column;
            }   
            else
            {
               printf("\n     **** Not enough remaining time for song #%d ****\n\n",userSelection);
            }
         }     
         else /* remove song from playlist column */
         {
            songlist[userSelection].column = !songlist[userSelection].column;
         }
      }while (userSelection != 0);
      saveTable(songlist,numberSongs);
      return (0);
   }