#include "main_data.h"
#include "misc_utils.h"
#include <string>
#include <cstring>
#include <glib.h>
#include <glib/gi18n.h>

#include <tag.h>
#include <fileref.h> 

#include "interface_common.h"
#include "main_window_handler.h"
#include "select_frame_handler.h"
#include "status_frame_handler.h"

/* 
 * This function finds what to do next. type is WAV or MP3.
 * It returns -1 when there's no job left, 0 when a job's found
 *
 * finds the next track from cur_track. If cur_type is wav, it will find the
 * next wav file to rip. If cur_type is mp3, it will find the next mp3 file
 * to encode 
 **/

int MainData::find_next_job(int cur_track, 
			    CommonEncoderType cur_type,
			    int *next_track, 
			    CommonEncoderType *next_type) const
{
    int flag=1, track=cur_track+1;
    int temp_next;
    CommonEncoderType temp_type;

    /* Find next track from cur_track */

    while(track < this->num_tracks() && flag)
    {
        if(this->track[ track ].make_wav || this->track[ track ].make_mp3)
        {
            flag = 0;
        }
        else
        {
            ++track;
        }
    }

    if(flag)
    {
        return - 1;
    }

    /* for finding the next wav file, check to see if the file exists */
    if(cur_type == WAV && this->track[ track ].make_mp3
            && this->track[ track ].wav_exist == TRUE
            && config.make_mp3_from_existing_wav == TRUE)
    {
      if(find_next_job(track, WAV, &temp_next, &temp_type) >= 0)
        {
            *next_track = temp_next;
            *next_type = WAV;
        }
        else
        {
            return - 1;
        }
    }
    else
    {
        *next_track = track;
        *next_type = MP3;

    }

    return 0;
};


/* called after all jobs are finshed. Files are cleaned up and renamed */
void MainData::finish_job()
{
    int i;
    static char status_message[(MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH) * MAX_NUM_TRACK ];
    static char buffer[(MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH) * MAX_NUM_TRACK ];
    static char *wav_file=0, *enc_file=0;
    int madewavs = FALSE;
    int mademp3s = FALSE;
    int tracksdone = 0;
    char *artist;

    FILE *fp_playlist = NULL;
    char playlist_filespec[ MAX_FILE_PATH_LENGTH + MAX_FILE_NAME_LENGTH ];

    buffer[0] = 0;

    /* Clean up */
    for(i = 0; i < this->num_tracks(); i++)
    {
        create_file_names_for_track(this, i, &wav_file, &enc_file);

        if(this->track[ i ].wav_exist == FALSE)
        {
            unlink(wav_file);
        }
        else if(this->track[ i ].make_wav == TRUE)
        {
            madewavs = TRUE;

	    //write .inf files, for cdrecord - refactor this
	    //should do this whenever we keep the .wavs?
            if(config.cddb_config.create_id3 == TRUE)
            {
	      std::string inf_file(wav_file);
	      inf_file.resize(inf_file.size() - 3);
	      inf_file += "inf";
	      FILE * inf_fp = fopen(inf_file.c_str(), "w");
	      if (inf_fp) 
		{
		  if(!(artist = this->track[ i ].artist))
		    {
		      artist = this->disc_artist;
		    }

		  fprintf(inf_fp, 
			  "Albumperformer= '%s'\n", artist);
		  fprintf(inf_fp, 
			  "Performer= '%s'\n", this->track[ i ].artist);
		  fprintf(inf_fp, 
			  "Albumtitle= '%s'\n", this->disc_title);
		  fprintf(inf_fp, 
			  "Tracktitle= '%s'\n", this->track[ i ].title);
		  fprintf(inf_fp,
			  "Tracknumber= %d\n", i+1);
		  fclose(inf_fp);
		}
	      else 
		{
		  perror (inf_file.c_str());
		}
	    }

            sprintf(&buffer[strlen(buffer)], "%d: %s\n", ++tracksdone, file_name_without_path(wav_file));

        }

        this->track[ i ].make_wav = FALSE;

        if(this->track[ i ].mp3_exist == TRUE && this->track[ i ].make_mp3 == TRUE)
        {
            mademp3s = TRUE;

            /* add ID3 tag if requested */
            if(config.cddb_config.create_id3 == TRUE)
            {
                if(!(artist = this->track[ i ].artist))
                {
                    artist = this->disc_artist;
                }

		TagLib::FileRef file(enc_file);
		TagLib::Tag *tag = file.tag();
		if (tag) 
		  {
		    tag->setTitle(this->track[ i ].title);
		    tag->setArtist(artist);
		    tag->setAlbum(this->disc_title);
		    tag->setYear(atoi(this->disc_year));
		    tag->setTrack(i+1);
		    tag->setGenre(this->disc_category);
		    file.save();
		  }
            }

            //dc: strcat() is for sissies!
            sprintf(&buffer[strlen(buffer)], "%d: %s\n", ++tracksdone, file_name_without_path(enc_file));

            // tm: basic playlist support - thanks to Mark Tyler
            if(config.cddb_config.create_playlist == TRUE)
            {
                if(fp_playlist == NULL)
                {
                    sprintf(playlist_filespec, "%s/playlist.m3u", file_path_without_name(enc_file));
                    fp_playlist = fopen(playlist_filespec, "w");
                }

                // if we succeeded above, we can now write to this
                if(fp_playlist != NULL)
                {
                    fprintf(fp_playlist, "%s\n", file_name_without_path(enc_file));
                }
            }
        }

        this->track[ i ].make_mp3 = FALSE;
    } /* end loop over all tracks */

    if((config.cddb_config.create_playlist == TRUE) && (fp_playlist != NULL))
    {
        fclose(fp_playlist);
    }

    /* Generate status message */
    sprintf(status_message, _("Tracks Completed: %2d\n\nArtist: %s\nAlbum: %s\n\n%s"),
            tracksdone, this->disc_artist, this->disc_title, buffer);

    /* show status pop up */
    if(madewavs)
    {
        status_handler(STAT_FINISH_WAV, status_message);
    }
    else if(mademp3s)
    {
        status_handler(STAT_FINISH_MP3, status_message);
    }

    /* Clear status bar */
    main_window_handler(MW_CLEAR_STATUSBAR, NULL, NULL);

    /* Destroy status widget */
    wm_status_frame_handler(WIDGET_DESTROY, WAV, NULL, NULL);

    /* Create select frame */
    select_frame_handler(WIDGET_CREATE, 0, this);
    main_window_handler(MW_MODE_SELECT, NULL, NULL);

    select_frame_handler(SF_SYNC_SELECT_FRAME_TO_DATA, 0, this);
}

