#!/usr/bin/perl
#
# cdr.pl - CD-Rip
#
# Created by David Cantrell
# Currently maintained by Mike Hardy
#
# $Id: cdr.pl,v 1.36 2001/03/15 00:13:34 mike Exp $
#
$VERSION = "3.0.1-cvs";

# the prefix for all of the binaries
$prefix = "/usr/local/lib/cdr"; # default binary prefix for cdr

# the ncurses thingie for the menus and stuff
$cdialog = $prefix . '/cdialog';

&init();

until (0) {
    $box = "$cdialog --backtitle \"cdr\" --title \"CD Rip\" --menu \"\nThis Perl program provides a frontend for easily\nturning an audio CD into MP3s.\n\" 15 56 4 ";

    $box .= qq("CD RIP" "Make MP3s from a CD" );
    $box .= qq("SETUP" "Tweak cdr's many, many options" );
    $box .= qq("ABOUT" "What is this crazy thing called cdr?" );
    $box .= qq("EXIT" "Exit cdr");

    $mnuchoice = `$box 3>&1 1>&2 2>&3 3>&-`;
    if ($mnuchoice eq 'CD RIP') {
	&cdr_rip(1);
    } elsif ($mnuchoice eq 'SETUP') {
	&setup();
    } elsif ($mnuchoice eq 'ABOUT') {
	$tmpvar = '\n';
	$tmpvar .= 'c d r              version ' . $VERSION . '\n';
	$tmpvar .= '| | |               by: Mike Hardy\n';
	$tmpvar .= '+-+-+---- CD         mike@mikehardy.net\n';
	$tmpvar .= '    |\n';
	$tmpvar .= '    +-----Rip\n\n\n';
	$tmpvar .= 'Written to make creating mp3 files easier\n';

	$about = "$cdialog --title \"cdr::about\" --msgbox \"$tmpvar\" 14 47";
	system $about;
    } else {
	system 'reset';
	exit;
    }
}

#
# Rip audio module
#
sub cdr_rip {
    # If not configured, return to main menu

    # make local variables
    my (@tracklist, $artist, $album, @riptracks, $wavname, $retval,
	$tmpnum, $tmpname, $box, $idx, $tmpa, $tmpb, $tmpc);

    # get the variables for ripping an entire album
    my $convert_to_mp3 = $_[0];

    # See if we should only create the files, without ripping.
    my $files_only = ($_[0] == 2);

    # make sure m3u file setting is complete
    if ($convert_to_mp3 != 0) {
	$do_m3ufile = &get_m3ufile();
    }

    # Get the track name format
    $nameformat = &get_nameformat();
    
    # Get the TOC from the CD
    $retval = &get_toc();
    if ($retval eq '1') {
	&error_no_cd();
	return;
    }

    $artist = &parse_artist();
    $album = &parse_album();
    @tracklist = &parse_tracklist();

    unlink "/tmp/tocfile.$$";

    # set appropriate title for window
    if($convert_to_mp3 == 0) {
	$wintitle = "Rip Audio from CD";
    } elsif($convert_to_mp3 == 1) {
	$wintitle = "Rip and Encode Audio from CD";
    } elsif($convert_to_mp3 == 2) {
	$wintitle = "Build Playlist Files from CD";
    }

    ($artist, $album, $retval, @tracklist) = &select_tracks($wintitle, @tracklist);

    @riptracks = split ' ', $retval;

    for ($idx = 0; $idx < scalar(@riptracks); $idx++) {

	# take the quotes off of the returned numbers
	$riptracks[$idx] = substr($riptracks[$idx], 1);
	substr($riptracks[$idx], -1) = "";

	$tmpa = &clean_text($artist);
	$tmpb = &clean_text($tracklist[$riptracks[$idx] - 1]);
	$tmpc = &clean_text($album);
	$tmpd = $tracklist[$riptracks[$idx] - 1];

	if ($nameformat eq "flat") {
	    $wavname = "$tmpa-$tmpb.wav";
	    
	    # set the albumdir variable for the deletion of .info files
	    $albumdir = "";

	} elsif ($nameformat eq "tree1") {
	    # create necessary directories
	    if (!opendir(CHECKDIR, "$wav_dir/$tmpa")) {
		mkdir("$wav_dir/$tmpa", 0777)
		    || die "Cannot create/open directory \"$wav_dir/$tmpa\": $!";
	    } else {
		closedir(CHECKDIR);
	    }
	    if (!opendir(CHECKDIR, "$mp3_dir/$tmpa")) {
		mkdir("$mp3_dir/$tmpa", 0777)
		    || die "Cannot create/open directory \"$mp3_dir/$tmpa\": $!";
	    } else {
		closedir(CHECKDIR);
	    }

	    if (!opendir(CHECKDIR, "$wav_dir/$tmpa/$tmpc")) {
		mkdir("$wav_dir/$tmpa/$tmpc", 0777)
		    || die "Cannot create/open directory \"$wav_dir/$tmpa/$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }
	    if (!opendir(CHECKDIR, "$mp3_dir/$tmpa/$tmpc")) {
		mkdir("$mp3_dir/$tmpa/$tmpc", 0777)
		    || die "Cannot create/open directory \"$mp3_dir/$tmpa/$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }

	    # create the name
	    if ($riptracks[$idx] < 10) {
		$wavname = "$tmpa/$tmpc/0$riptracks[$idx]-$tmpb.wav";
	    } else {
		$wavname = "$tmpa/$tmpc/$riptracks[$idx]-$tmpb.wav";
	    }

	    # set the albumdir variable for the deletion of .info files
	    $albumdir = "$tmpa/$tmpc";

	} elsif ($nameformat eq "tree2") {
	    # create necessary directories
	    if (!opendir(CHECKDIR, "$wav_dir/$tmpa")) {
		mkdir("$wav_dir/$tmpa", 0777)
		    || die "Cannot create/open directory \"$wav_dir/$tmpa\": $!";
	    } else {
		closedir(CHECKDIR);
	    }
	    if (!opendir(CHECKDIR, "$mp3_dir/$tmpa")) {
		mkdir("$mp3_dir/$tmpa", 0777)
		    || die "Cannot create/open directory \"$mp3_dir/$tmpa\": $!";
	    } else {
		closedir(CHECKDIR);
	    }

	    if (!opendir(CHECKDIR, "$wav_dir/$tmpa/$tmpc")) {
		mkdir("$wav_dir/$tmpa/$tmpc", 0777)
		    || die "Cannot create/open directory \"$wav_dir/$tmpa/$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }
	    if (!opendir(CHECKDIR, "$mp3_dir/$tmpa/$tmpc")) {
		mkdir("$mp3_dir/$tmpa/$tmpc", 0777)
		    || die "Cannot create/open directory \"$mp3_dir/$tmpa/$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }

	    # create the name
	    $wavname = "$tmpa/$tmpc/$tmpa-$tmpb.wav";

	    # set the albumdir variable for the deletion of .info files
	    $albumdir = "$tmpa/$tmpc";

	} elsif ($nameformat eq "full") {
	    # create necessary directories
	    if (!opendir(CHECKDIR, "$wav_dir/$tmpa.$tmpc")) {
		mkdir("$wav_dir/$tmpa.$tmpc", 0777)
		    || die "Cannot create/open directory \"$wav_dir/$tmpa.$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }
	    if (!opendir(CHECKDIR, "$mp3_dir/$tmpa.$tmpc")) {
		mkdir("$mp3_dir/$tmpa.$tmpc", 0777)
		    || die "Cannot create/open directory \"$mp3_dir/$tmpa.$tmpc\": $!";
	    } else {
		closedir(CHECKDIR);
	    }

	    # create the name
	    if ($riptracks[$idx] < 10) {
		$wavname = "$tmpa.$tmpc/$tmpa.$tmpc-0$riptracks[$idx]-$tmpb.wav";
	    } else {
		$wavname = "$tmpa.$tmpc/$tmpa.$tmpc-$riptracks[$idx]-$tmpb.wav";
	    }

	    # set the albumdir variable for the deletion of .info files
	    $albumdir = "$tmpa.$tmpc";

	} else {
	    die "Internal error: $!";
	}

	# This is a hack - I was having a scoping issue and got bored with elegance. Sorry.
	$TAG_COMMAND =
	    $id3tagger . " -q -s \"".
		$tmpd . "\" -n \"" .
		    $artist . "\" -a \"" .
			$album . "\" -k \"" .
			    $riptracks[$idx] . "\"";

	if(!$files_only) {
	    system "$ripper -d $cdrom -v -w $riptracks[$idx] $wav_dir/$wavname";
	}

	# call cdr_crunch to convert wav file to mp3
	if ($convert_to_mp3 > 0) {
	    if ($do_m3ufile eq "Enabled") {
		$m3ufilename = "$mp3_dir/$albumdir/$tmpa-$tmpc.m3u";

		# add mp3 file name to .m3u file
		$mp3name = substr($wavname, rindex($wavname, '/') + 1);
		$mp3name = substr($mp3name, 0, length($mp3name) - 3);
		$mp3name .= "mp3";
		
		open M3UFILE, ">> $m3ufilename";
		print M3UFILE "$mp3name\n";
		close M3UFILE;
	    }

	    # See if we need to wait here for an encoding slot
	    if($#encoder_pids >= ($enc_slots - 1)) {
		
		# We need to wait here until one of the encoders finishes, so
		# check each slot for one that is finished until one is
		use POSIX ":sys_wait_h";
	        GETSLOT: while(1) {
		  
		  for(my $pid_counter = 0;
		      $pid_counter <= $#encoder_pids;
		      $pid_counter++) {
		      
		      my $wait_state = waitpid(@encoder_pids[$pid_counter], &WNOHANG);
		      
		      # See if this one finished
		      if($wait_state != 0) {
			  
			  # It finished, clear this slot up and bust out of the loop
			  splice @encoder_pids, $pid_counter, 1;
			  last GETSLOT;
		      }
		  }

		  # none were ready this time, sleep for a bit before the next poll
		  sleep(1);
	      }
	    }
	    
  	    # Try to fork and add the new encoder to the list of encoders
  	    defined($encoder_pid = fork) or die("Couldn't fork!");
	    
  	    # If we're the child we should start crunching now.
  	    if(!$encoder_pid) {
		&cdr_crunch($wavname);
		exit;
	    } else {
		push @encoder_pids, $encoder_pid;
	    }
	}
    }

    # Make sure all the encoding is done before we leave here
    while($#encoder_pids >= 0) {
	waitpid(shift(@encoder_pids), 0);
    }

    return;
} # end of the cdr_rip subroutine


#
# Crunch audio module
#
sub cdr_crunch {
    
    # see if we have a wav file name as an argument
    my $wav_filename = "";
    if ($_[0]) {
	$wav_filename = $_[0];
    }

    @tracklist = ($wav_filename);
    @crunchtracks = (1);

    for ($idx = 0; $idx < scalar(@crunchtracks); $idx++) {
	$crunchtracks[$idx] = substr($crunchtracks[$idx], 1);
	substr($crunchtracks[$idx], -1) = "";

	$nicewavname = substr($tracklist[$crunchtracks[$idx] - 1], length($wav_dir) + 1);
	$wavname = $tracklist[$crunchtracks[$idx] - 1];
	$mp3name = substr($tracklist[$crunchtracks[$idx] - 1], 0, rindex($crunchtracks[$idx - 1], '.wav') - 3);
	$mp3name .= qq(.mp3);

	print "ENCODING $nicewavname...\n";
	system "$encoder -h -b $bitrate $wav_dir/$wavname $mp3_dir/$mp3name";

	if ($delwav eq "Enabled") {
	    system "$rm -f $wav_dir/$wavname";
	}
	
	# Set the id3 tag information, if that's set
	$do_id3tag = &get_id3tag();
	
	if($do_id3tag) {
	    system "$TAG_COMMAND $mp3_dir/$mp3name";
	}
	
    }

    return;
} # end of the cdr_crunch subroutine


#
# clean_text -- Cleans the text passed in for use in filenames
# Arguments: $_[0]  ---  Text to be cleaned
#
sub clean_text {
    $retval = $_[0];

    $retval =~ s/ /_/g;
    $retval =~ s/&/and/g;

    $retval =~ s/\?//g;
    $retval =~ s/\~//g;
    $retval =~ s/\`//g;
    $retval =~ s/\#//g;
    $retval =~ s/\$//g;
    $retval =~ s/\&//g;
    $retval =~ s/\*//g;
    $retval =~ s/\(//g;
    $retval =~ s/\)//g;
    $retval =~ s/\\//g;
    $retval =~ s/\|//g;
    $retval =~ s/\[//g;
    $retval =~ s/\]//g;
    $retval =~ s/\{//g;
    $retval =~ s/\}//g;
    $retval =~ s/\;//g;
    $retval =~ s/\://g;
    $retval =~ s/\'//g;
    $retval =~ s/\"//g;
    $retval =~ s/\<//g;
    $retval =~ s/\>//g;
    $retval =~ s/\///g;
    $retval =~ s/\!//g;
    $retval =~ s/\+//g;
    $retval =~ s/__/_/g;
    
    return $retval;
}


#
# error_no_cd -- Displays idiot box with ``No CD'' message
#
sub error_no_cd {
    system "$cdialog --title \"Error: No CD Present\" --msgbox \"\nYou need to put the CD in the drive before trying to rip from it.\" 7 69";
    return;
}


#
# init -- initializes variables and checks environment
#
sub init {
    # set initial variables
    $cdrom = &get_cdrom();
    $editor = &get_editor();
    $lookup = &get_cddb();
    $cddbserver = &get_server();
    $cddbport = &get_port();
    $mp3_dir = &get_mp3_dir();
    $wav_dir = &get_wav_dir();
    $id3tag = &get_id3tag();
    $delwav = &get_delwav();
    $bitrate = &get_bitrate();
    $nameformat = &get_nameformat();
    $m3ufile = &get_m3ufile();
    $enc_slots = &get_enc_slots();
    
    # Define temp dir location and programs to use
    $encoder = $prefix . '/' . "lame";
    $ripper = $prefix . '/' . "cdparanoia";
    $id3tagger = $prefix . '/' . "id3ed";
    $tmp = '/tmp';
    $rm = '/bin/rm';

    return;
}


#
# get_toc -- Grab table of contents from CDDB
#
sub get_toc {

    if ($lookup eq "Enabled") 
    {
	system "clear";
	print "\nPlease wait while cdr gathers CDDB information...\n\n";
	system "$prefix/cdown -d $cdrom -H $cddbserver -P $cddbport > /tmp/tocfile.$$";
    } 
    else 
    {
	$numtracks = 1;
	$filename = "/tmp/cdparanoia.query.$$";
	system "$ripper -Q -d $cdrom > $filename 2>&1";
	
	open QUERY_FILE, "<$filename";
	while(<QUERY_FILE>)
	{
	    if(/^\s+(\d+)\..*/) { $numtracks = $1; }
	}
	close QUERY_FILE;
	unlink $filename;

	open TOCFILE, "> /tmp/tocfile.$$";

	print TOCFILE "tracks ";
	for( $idx = 1; $idx <= $numtracks; $idx++) { print TOCFILE "$idx "; }

	print TOCFILE "\ncdname Unknown Album Title\n";
	print TOCFILE "artist Unknown Artist\n";

	for ($idx = 1; $idx <= $numtracks; $idx++) 
	{
	    print TOCFILE "track Track Number $idx\n";
	}

	close TOCFILE;
    }

    
    system "$editor /tmp/tocfile.$$";
    return '0';
}

#
# select_tracks
#
sub select_tracks {

    (my $window_title, my @tracklist) = @_;

    $box = "$cdialog --title \"$window_title\" --checklist \"\n$artist\n$album\n\" 21 70 10 ";

    for ($idx = 0; $idx < scalar(@tracklist); $idx++) {
	$tmpnum = $idx + 1;
	($tmpname = substr($tracklist[$idx], 0, 45)) =~ s/\"/\\\"/g;

	# fix wide song names
	$tracklist[$idx] = &widesong($tracklist[$idx]);

	$box .= qq("$tmpnum" "$tracklist[$idx]" off );
    }

    $retval = `$box 3>&1 1>&2 2>&3 3>&-`;
    return ($artist, $album, $retval, @tracklist);
}
    

#
# parse_artist -- Return the artist from TOC
#
sub parse_artist {
    open TOC, "/tmp/tocfile.$$";

    while (<TOC>) {
	if (/^artist (.*) $/) {
	    $artist = $1;
	    last;
	}

	if (/^artist (.*)$/) {
	    $artist = $1;
	    last;
	}
    }

    close TOC;

    if ($artist eq "") {
	$artist = "Unknown Artist";
    }

    return $artist;
}

#
# parse_album -- Return the album from TOC
#
sub parse_album {
    open TOC, "/tmp/tocfile.$$";

    my $temp_album = "";
    
    while (<TOC>) {
	if (/cdname\ (.*)/) {
	    $temp_album .= $1;
	    chomp $temp_album;
	}
    }

    $album = $temp_album;

    close TOC;

    if ($album eq "") {
	$album = "Unknown Album";
    }

    return $album;
}

#
# parse_tracklist -- Return the tracklist from TOC
#
sub parse_tracklist {
    # flush out current tracklist array
    my @tl;
    my $numtracks = 0;
    
    open TOC, "/tmp/tocfile.$$";

    while (<TOC>) {
	if (/track\ /) {
	    $songname = substr($_, 6);
	    chomp $songname;

	    # clean the track name
	    $songname =~ s/\"//g;
	    
	    $numtracks++;
	    push @tl, $songname;
	}
    }
    close TOC;

    # Make sure we have something sensible here, and fix it if not
    if($numtracks == 0) {

	$tmpvar = "$cdialog --title \"Number of Tracks\" --inputbox \"\nThe CDDB doesn't contain this album, please\nenter the number of tracks on it.\n\" 12 60";
	$retval = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	if ($retval eq "") {
	    return '1';
	}
	for ($idx = 1; $idx <= $retval; $idx++) {
	    push @tl, "Track Number $idx";
	}
    }
    
    return @tl;
}


#
# Setup module
# Responsible for configuring the program and saving the settings
#
sub setup {
    # grab current program settings
    $cdrom = &get_cdrom();
    $lookup = &get_cddb();
    $editor = &get_editor();
    $cddbserver = &get_server();
    $cddbport = &get_port();
    $mp3_dir = &get_mp3_dir();
    $wav_dir = &get_wav_dir();
    $delwav = &get_delwav();
    $bitrate = &get_bitrate();
    $nameformat = &get_nameformat();
    $m3ufile = &get_m3ufile();
    $id3tag = &get_id3tag();
    $enc_slots = &get_enc_slots();
    
    $cdrom_mnu = "Configure CD-ROM device ($cdrom)";
    $lookup_mnu = "Use CDDB to name ripped tracks ($lookup)";
    $editor_mnu = "Text editor for album info ($editor)";
    $cddbserver_mnu = "CDDB server to use ($cddbserver)";
    $cddbport_mnu = "CDDB server port to connect to ($cddbport)";
    $mp3_dir_mnu = "MP3 directory to use ($mp3_dir)";
    $wav_dir_mnu = "WAV directory to use ($wav_dir)";
    $delwav_mnu = "Delete interim WAV files ($delwav)";
    $bitrate_mnu = "Bitrate for encoded MP3 files ($bitrate KB/s)";
    $nameformat_mnu = "Track filename format ($nameformat)";
    $m3ufile_mnu = "Build M3U files while ripping ($m3ufile)";
    $id3tag_mnu = "Create id3 tags on ripped files ($id3tag)";
    $enc_slots_mnu = "Number of parallel encoders ($enc_slots)";

    # main menu loop
    until (0) {
	$box = "$cdialog --backtitle \"cdr:setup\" ";
	$box .= qq(--title "Configure cdr" --menu "\nConfigure the following settings before using cdr.\n" 21 69 11 );

	$box .= qq("CD-ROM" "$cdrom_mnu" );
	$box .= qq("LOOKUP" "$lookup_mnu" );
	$box .= qq("EDITOR" "$editor_mnu" );
	$box .= qq("SERVER" "$cddbserver_mnu" );
	$box .= qq("PORT" "$cddbport_mnu" );
	$box .= qq("BITRATE" "$bitrate_mnu" );
	$box .= qq("MP3DIR" "$mp3_dir_mnu" );
	$box .= qq("WAVDIR" "$wav_dir_mnu" );
	$box .= qq("DELETE" "$delwav_mnu" );
	$box .= qq("NAMEFMT" "$nameformat_mnu" );
	$box .= qq("M3UFILE" "$m3ufile_mnu" );
	$box .= qq("ID3TAG" "$id3tag_mnu" );
	$box .= qq("ENC. SLOTS" "$enc_slots_mnu" );
	$box .= qq("MAIN" "Save changes and return to main menu");

	$mnuchoice = `$box 3>&1 1>&2 2>&3 3>&-`;
	if ($mnuchoice eq "") {
	    return;
	}

	if ($mnuchoice eq 'CD-ROM') {
	    $oldvar = $cdrom;

	    $tmpvar = "$cdialog --backtitle \"cdr:setup:cd-rom device\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the device name for the CD-ROM.\nThis is the regular CD-ROM device name,\nnot a generic SCSI name. This can be an\nIDE or SCSI device. cdr uses this device\nfor CDDB lookups and ripping tracks.\n" 15 44 "$cdrom");

	    $cdrom = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;
	    
	    if ($cdrom eq "") {
		$cdrom = "/dev/cdrom";
	    }
	    
	    $cdrom_mnu = "Configure CD-ROM device ($cdrom)";
	} elsif ($mnuchoice eq 'LOOKUP') {
	    $oldvar = $lookup;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::lookup\" ";
	    $tmpvar .= qq(--yesno "\nWould you like to use a CDDB server to get the names of\nthe tracks on the audio CD before ripping? This feature\ncan be used to name the tracks that you rip. You must\nhave an active Internet connection for this work.\n" 10 59);
	    $lookup = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($? eq "0") {
		$lookup = "Enabled";
	    } elsif ($? eq "256") {
		$lookup = "Disabled";
	    } else {
		$lookup = $oldvar;
	    }
	    $lookup_mnu = "Use CDDB lookups for naming ripped tracks ($lookup)";
	} elsif ($mnuchoice eq 'EDITOR') {
	    $oldvar = $editor;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::editor\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the name of the editor you\nwould like to use when editing track\ninformation.\n" 13 44 "$editor");
	    $editor = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($editor eq "") {
		$editor = $oldvar;
	    }
	    $editor_mnu = "Text editor for album info ($editor)";
	} elsif ($mnuchoice eq 'SERVER') {
	    $oldvar = $cddbserver;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::cddbserver\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the name of the CDDB server you\nwould like to use when performing track\nname lookups.\n" 13 44 "$cddbserver");
	    $cddbserver = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($cddbserver eq "") {
		$cddbserver = $oldvar;
	    }
	    $cddbserver_mnu = "CDDB server to use ($cddbserver)";
	} elsif ($mnuchoice eq 'PORT') {
	    $oldvar = $cddbport;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::cddbport\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the port to connect to on the CDDB server.\n" 11 52 "$cddbport");
	    $cddbport = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($cddbport eq "") {
		$cddbport = $oldvar;
	    }
	    $cddbport_mnu = "CDDB server port to connect to ($cddbport)";
	} elsif ($mnuchoice eq 'DELETE') {
	    $oldvar = $delwav;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::delete\" ";
	    $tmpvar .= qq(--yesno "\nWould you like to delete the interim WAV files made\nduring certain processes? This includes deleting the\nWAV file after encoding it as an MP3 and deleting\nthe WAV file after making a CDR track file.\n" 10 56);
	    $delwav = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($? eq "0") {
		$delwav = "Enabled";
	    } elsif ($? eq "256") {
		$delwav = "Disabled";
	    } else {
		$delwav = $oldvar;
	    }
	    $delwav_mnu = "Delete interim WAV files ($delwav)";
	} elsif ($mnuchoice eq 'MP3DIR') {
	    $oldvar = $mp3_dir;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::mp3_dir\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the directories you would to use to hold\nmp3 files. This is where all MP3 files\nwill be dumped to.\n" 13 56 "$mp3_dir");
	    $mp3_dir = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($mp3_dir eq "") {
		$mp3_dir = $oldvar;
	    }
	    $mp3_dir_mnu = "MP3 Directory ($mp3_dir)";

	} elsif ($mnuchoice eq 'WAVDIR') {
	    $oldvar = $wav_dir;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::wav_dir\" ";
	    $tmpvar .= qq(--inputbox "\nEnter the directories you would to use to hold\nwav files. This is where all wav files\nwill be held pre-encoding.\n" 13 48 "$wav_dir");
	    $wav_dir = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($wav_dir eq "") {
		$wav_dir = $oldvar;
	    }
	    $wav_dir_mnu = "WAV Directory ($wav_dir)";

	} elsif ($mnuchoice eq 'BITRATE') {
	    $oldvar = $bitrate;

	    $tmpvar = "$cdialog --title \"cdr::setup::bitrate\" --menu \"\nSelect how many Kibbles n Bits per second (KB/s) you\nwant to use for encoding MP3 files.\n\" 17 62 7 ";
	    $tmpvar .= qq("56" "I really like mono AM quality" );
	    $tmpvar .= qq("96" "I wanna encode something I got off the radio" );
	    $tmpvar .= qq("112" "I'm making a copy of a copy of a copy" );
	    $tmpvar .= qq("128" "I like MP3s and have a normal sized hard disk" );
	    $tmpvar .= qq("160" "I love quality, but conserve disk space" );
	    $tmpvar .= qq("256" "I just bought a hard disk to devote to MP3s" );
	    $tmpvar .= qq("320" "I have a massive RAID array for digital archiving");
	    $bitrate = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($bitrate eq "") {
		$bitrate = $oldvar;
	    }
	    
	    $bitrate_mnu = "Bitrate for encoding MP3 files ($bitrate KB/s)";

	} elsif ($mnuchoice eq 'NAMEFMT') {
	    $oldvar = $nameformat;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::nameformat\" ";
	    $tmpvar .= qq(--title "Select Track Name Format" --menu "\nSelect the filename format to be used for ripped tracks. Directories\nwill be created if they need to be (for artist and album directories).\n" 15 76 4 );
	    $tmpvar .= qq("flat" "<Artist>-<Track Name>" );
	    $tmpvar .= qq("tree1" "<Artist>/<Album>/<Track Number>-<Track Name>" );
	    $tmpvar .= qq("tree2" "<Artist>/<Album>/<Artist>-<Track Name>" );
	    $tmpvar .= qq("full" "<Artist>.<Album>/<Artist>.<Album>-<Track Number>-<Track Name>" );

	    $nameformat = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($nameformat eq "") {
		$nameformat = $oldvar;
	    }
	    $nameformat_mnu = "Track filename format ($nameformat)";
	} elsif ($mnuchoice eq 'M3UFILE') {
	    $oldvar = $m3ufile;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::m3ufile\" ";
	    $tmpvar .= qq(--title "Create M3U Files" --yesno "\nWould you like a CD track listing file created (an .M3U\nfile) when you choose to rip and encode an album in one\nstep? This file will be put in the directory with the\nMP3 files.\n" 10 59);
	    $m3ufile = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($? eq "0") {
		$m3ufile = "Enabled";
	    } elsif ($? eq "256") {
		$m3ufile = "Disabled";
	    }

	    $m3ufile_mnu = "Build M3U files for ripped albums ($m3ufile)";

	} elsif ($mnuchoice eq 'ID3TAG') {
	    $oldvar = $id3tag;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::id3tag\" ";
	    $tmpvar .= qq(--title "Create id3 tags" --yesno "\nWould you like cdr to create id3 tags for the mp3s\nas they are encoded?\n" 10 59);
	    $id3tag = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($? eq "0") {
		$id3tag = "Enabled";
	    } elsif ($? eq "256") {
		$id3tag = "Disabled";
	    }

	    $id3tag_mnu = "Create id3 tags for encoded mp3s ($id3tag)";
	} elsif ($mnuchoice eq 'ENC. SLOTS') {
	    $oldvar = $enc_slots;

	    $tmpvar = "$cdialog --backtitle \"cdr::setup::encoder slots\" ";
	    $tmpvar .= qq(--inputbox "\nWhat is the maximum number of encoders cdr\nshould run in parallel?\n" 13 48 "$enc_slots");
	    $enc_slots = `$tmpvar 3>&1 1>&2 2>&3 3>&-`;

	    if ($enc_slots eq "") {
		$enc_slots = $oldvar;
	    }
	    $enc_slots_mnu = "Number of parallel encoders ($enc_slots)";

	} elsif ($mnuchoice eq 'MAIN') {
	    $outfile = "$ENV{'HOME'}";
	    $outfile .= qq(/.cdrrc);
	    open CDRRC, "> $outfile";

	    print CDRRC "# .cdrrc -- Configuration file for cdr\n";
	    print CDRRC "# Try not to edit this file directly, use cdr to do it\n";
	    print CDRRC "cdrom=$cdrom\n";
	    print CDRRC "editor=$editor\n";
	    print CDRRC "cddb=$lookup\n";
	    print CDRRC "server=$cddbserver\n";
	    print CDRRC "port=$cddbport\n";
	    print CDRRC "mp3_dir=$mp3_dir\n";
	    print CDRRC "wav_dir=$wav_dir\n";
	    print CDRRC "bitrate=$bitrate\n";
	    print CDRRC "delwav=$delwav\n";
	    print CDRRC "nameformat=$nameformat\n";
	    print CDRRC "m3ufile=$m3ufile\n";
	    print CDRRC "id3tag=$id3tag\n";
	    print CDRRC "enc_slots=$enc_slots\n";

	    close CDRRC;

	    # we need to reset the values with the prefix
	    &init();

	    return;
	} else {
	    system "$cdialog --msgbox \"OK, that was wierd. Something just happened and I don't know what it was. Hit OK and go back to the main menu to try again.\" 7 47";
	}
    }
} # end of setup subroutine


sub get_cddb { my $cddb = &get_values("cddb"); return "Enabled" if($cddb eq 'NOT SET'); return $cddb; }
sub get_editor { my $editor = &get_values("editor"); return "pico" if($editor eq 'NOT SET'); return $editor; }
sub get_server { my $i = &get_values("server"); return "freedb.freedb.org" if($i eq 'NOT SET'); return $i; }
sub get_port { my $port = &get_values("port"); return "888" if($port eq 'NOT SET'); return $port; }
sub get_mp3_dir { my $mp3_dir = &get_values("mp3_dir"); return "/tmp" if($mp3_dir eq 'NOT SET'); return $mp3_dir; }
sub get_wav_dir { my $wav_dir = &get_values("wav_dir"); return "/tmp" if($wav_dir eq 'NOT SET'); return $wav_dir; }
sub get_delwav { my $del = &get_values("delwav"); return "Enabled" if($del eq 'NOT SET'); return $del; }
sub get_bitrate { my $rate = &get_values("bitrate"); return 160 if($rate eq 'NOT SET'); return $rate; }
sub get_nameformat { my $name = &get_values("nameformat"); return "tree2" if($name eq 'NOT SET'); return $name; }
sub get_m3ufile { my $m3u = &get_values("m3ufile"); return "Enabled" if($m3u eq 'NOT SET'); return $m3u; }
sub get_id3tag { my $tag = &get_values("id3tag"); return "Enabled" if($tag eq 'NOT SET'); return $tag; }
sub get_enc_slots { my $slots = &get_values("enc_slots"); return 1 if($slots eq 'NOT SET'); return $slots; }
sub get_cdrom { my $c = &get_values("cdrom"); $c = "/dev/cdrom" if($c eq 'NOT SET'); return $c; }


#
# get_values
# Main get routine. Processes configuration file and returns the requested
# value if it is there, otherwise return "NOT SET"
#
sub get_values {
    $fld = $_[0];

    $retval = 'NOT SET';

    $infile = "$ENV{'HOME'}";
    $infile .= qq(/.cdrrc);

    open CDRRC, $infile;
    while (<CDRRC>) 
    {
	if (/$fld/) 
	{
	    (undef, $retval) = split(/=/, $_);
	    chop $retval;
	}
    }
    close CDRRC;

    return $retval;
}


#
# widesong
# Fixes menu items that are wider than 75 characters
#
sub widesong {
    $tmpvar = $_[0];

    if(length($tmpvar) > 56) {
	$tmpvar = substr($tmpvar, 0, 53);
	$tmpvar = "$tmpvar...";
    }

    return $tmpvar;
}
