#!/usr/bin/perl
#
# Disc-Cover - using CDDB to create a cover for music cds. Default is
# to output a postscript file called 'artist_-_album.ps' provided the
# album is found in the CDDB database.
# Copyright (C) 1999 J.I. van Hemert
#
# 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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Author: J.I. van Hemert <jvhemert@cs.leidenuniv.nl>
#
# Physical mail:
# LIACS - Leiden University
# Niels Bohrweg 1
# 2333 CA Leiden
# The Netherlands
#
# Last Revision: 30-Nov-1999 17:43
#

################################
# Default configuration values #
################################

my ($config_tmp_dir) = '/tmp';
my ($config_output_format) = 'ps';
my ($flag_force_cddb_lookup) = 0;
my ($flag_verbose) = 1;
my ($config_device) = "/dev/cdrom";
my ($config_cddb_cache_directory) = "$ENV{HOME}/.cddb";
# my ($config_cddb_server) = "http://freedb.freedb.org/cgi-bin/cddb.cgi";
my ($config_cddb_server) = "http://cddb.cddb.org/~cddb/cddb.cgi";
my ($config_proxy_server) = ""; # something like: "http://proxy.some.server:8888/" blank=>none
my ($flag_extended_track_info) = 0;


#################################
# Non advisable to change these #
#################################

my ($bottomtextfront) = '';
my ($latex_global_oddsidemargin, $latex_global_evenside_margin, $latex_global_voffset, $latex_global_footskip, $latex_global_textheight) = ("0pt", "0pt", "-100pt", "0pt", "780pt");
my ($version) = '0.9.4';
my ($process_number) = $$;
my ($move_end_file) = 0;
my ($outputfile) = '';
my ($inputfile) = '';
my ($removetmpstuff) = 1;
my ($all_output_types) = 'tex dvi ps pdf cddb txt lbl';
my ($latex_global_additional_packages) = ''; # for instance: '\usepackage{times}';


########################
# Start of main progam #
########################

commandline();

use FreeDB;
$cddb = new FreeDB;
$cddb->cddb_server($config_cddb_server);
$cddb->cdrom_device($config_device);
$cddb->cache_directory($config_cddb_cache_directory);
if ($config_proxy_server ne "")
{
	$cddb->proxy_value($config_proxy_server);
}
if ($flag_force_cddb_lookup)
{
	$cddb->ignore_cache(1);
}

if ($inputfile eq "")
{
	if (!$cddb->fetch())
	{
		print "Error: could not fetch cdrom information.\n";
		end_program();
	}
}
else
{
	local $cddb_contents = '';
	open (CDDB_FILE, "$inputfile");
	while (<CDDB_FILE>)
	{
		$cddb_contents = $cddb_contents.$_;
	}
	close (CDDB_FILE);
	if (!$cddb->fetch($cddb_contents))
	{
		print "Error: could not fetch information.\n";
		end_program();
	}
}

($bottomtextfront) = $cddb->disc_info() if ($bottomtextfront eq "");


if ($outputfile eq "")
{
	$outputfile = $cddb->artist.' - '.$cddb->title;
	$outputfile =~ s/ /_/g;
	$outputfile =~ s/
//g;
	$outputfile =~ s#/#:#g;
}

if ($outputfile ne "-")
{
	if ($config_output_format eq 'pdf') { $outputfile =~ s/(\.pdf){0,1}$/.pdf/; }
	if ($config_output_format eq 'lbl') { $outputfile =~ s/(\.lbl){0,1}$/.lbl/; }
	if ($config_output_format eq 'txt') { $outputfile =~ s/(\.txt){0,1}$/.txt/; }
	if ($config_output_format eq 'tex') { $outputfile =~ s/(\.tex){0,1}$/.tex/; }
	if ($config_output_format eq 'dvi') { $outputfile =~ s/(\.dvi){0,1}$/.dvi/; }
	if ($config_output_format eq 'ps') { $outputfile =~ s/(\.ps){0,1}$/.ps/; }
	if ($config_output_format eq 'cddb') { $outputfile =~ s/(\.cddb){0,1}$/.cddb/; }
}

print "Output goes to \"$outputfile\"\n" if (($flag_verbose == 1) && ($outputfile ne "-"));

if ($config_output_format eq 'lbl')
{
	open OUT,">$outputfile";
        print OUT "cdlabelgen \\\n";
	printf OUT "-c \"%s\" \\\n", $cddb->artist;
	printf OUT "-s \"%s\" \\\n", $cddb->title;
	print OUT "-S 0.96 -e penguin.eps \\\n";
	print OUT "-i \"";
	while ($cddb->next_track)
	{
		printf OUT "%2d. %s  %02d:%02d%%\\\n", $cddb->current_track_number, $cddb->current_track_info, $cddb->current_track_time_in_seconds/60, $cddb->current_track_time_in_seconds%60;
	}
	printf OUT "%%CD length: %02d:%02d\"\n", $cddb->disc_length/60, $cddb->disc_length%60;
	close OUT;
}
elsif ($config_output_format eq 'txt')
{
	open OUT,">$outputfile";
	printf OUT "Artist: %s\n", $cddb->artist;
	printf OUT "Title:  %s\n", $cddb->title;
	while ($cddb->next_track)
	{
		if ($cddb->current_track_extended_info eq "")
		{
			printf OUT "%02d %s %02d:%02d %d\n", $cddb->current_track_number, $cddb->current_track_info, $cddb->current_track_time_in_seconds/60, $cddb->current_track_time_in_seconds%60, $cddb->current_track_offset;
		}
		else
		{
			printf OUT "%02d %s %s %02d:%02d %d\n", $cddb->current_track_number, $cddb->current_track_info, $cddb->current_track_extended_info, $cddb->current_track_time_in_seconds/60, $cddb->current_track_time_in_seconds%60, $cddb->current_track_offset;
		}
        }
	printf OUT "CD length: %02d:%02d %d\n",
          $cddb->disc_length/60, $cddb->disc_length%60, $cddb->disc_length*75;
	close OUT;
}
elsif ($config_output_format eq 'cddb')
{
	open OUT,">$outputfile";
	print OUT $cddb->cddb_string();
	close OUT;
}
elsif ($config_output_format eq 'tex')
{
	open OUT,">$outputfile";
	print OUT print_whole_cover();
	close OUT;
}
elsif ($config_output_format eq 'pdf')
{
	run_latex("pdflatex");
	$move_end_file = 1;
}
elsif ($config_output_format eq 'dvi')
{
	run_latex("latex");
	$move_end_file = 1;
}
elsif ($config_output_format eq 'ps')
{
	run_latex("latex");
	if (system ("(dvips \"$config_tmp_dir/disc-cover.$process_number.dvi\" -o \"$config_tmp_dir/disc-cover.$process_number.ps\" 2> /dev/null)") > 0)
	{
		print "Error: something went wrong while running dvips.\n\nSolution: run disc-cover with argument '-r' as argument, then\ncheck if a .dvi file is produced in \"$config_tmp_dir\".\n";
		end_program();
	}
	$move_end_file = 1;
}
else
{
	print "Error: this type of format \"".$config_output_format."\" does not exist\n\nSolution: use \"-t <option>\" where <option> is one of:\n$all_output_types.\n";
	end_program();
}

if ($move_end_file == 1)
{
	if ($outputfile eq "-")
	{
		if (!open OUT,"$config_tmp_dir/disc-cover.$process_number.$config_output_format")
		{
			print "Error: could not open the file \"$config_tmp_dir/disc-cover.$process_number.$config_output_format\".\n\nSolution: run disc-cover with argument '-r', then\ncheck if a .$config_output_format file is produced in \"$config_tmp_dir\".\n";
			end_program();
		}
		while (<OUT>)
		{
			print;
		};
		close OUT;
	}
	else
	{
		if (system ("mv -- \"$config_tmp_dir/disc-cover.$process_number.$config_output_format\" \"$outputfile\" 2> /dev/null") > 0)
		{
			print "Error: could not move the file \"$config_tmp_dir/disc-cover.$process_number.$config_output_format\"\nto \"$outputfile\".\n\nSolution 1: is the directory you are trying to write in writable?\nSolution 2: run disc-cover with argument '-r', then\ncheck if a .$config_output_format file is produced in \"$config_tmp_dir\".\n";
			end_program();
		}
	}
}
end_program();


#######################
# Clean exit function #
#######################

sub end_program
{
	if ($removetmpstuff == 1)
	{
		`rm -f \"/tmp/disc-cover.$process_number.ps\"`;
		`rm -f \"/tmp/disc-cover.$process_number.log\"`;
		`rm -f \"/tmp/disc-cover.$process_number.dvi\"`;
		`rm -f \"/tmp/disc-cover.$process_number.aux\"`;
		`rm -f \"/tmp/disc-cover.$process_number.tex\"`;
	}
	exit;
}

######################
# Commandline parser #
######################

sub commandline
{
	local ($readnext) = 0;
	
	foreach $i (@ARGV)
	{
		if ($readnext > 0)
		{
			if ($readnext == 1)
			{
				$bottomtextfront = $i;
			}
			if ($readnext == 2)
			{
				$outputfile = $i;
			}
			if ($readnext == 3)
			{
				 $config_device = $i;
			}
			if ($readnext == 4)
			{
				 $inputfile = $i;
			}
			if ($readnext == 5)
			{
				 $config_output_format = $i;
			}

			$readnext = 0;
		}
		else
		{
			if ($i =~ /^-e$/)
			{
				$flag_with_extended_track_info = 1;
			}
			if ($i =~ /^-r$/)
			{
				$removetmpstuff = 0;
			}
			if ($i =~ /^-t$/)
			{
				$readnext = 5;
			}
			if ($i =~ /^-F$/)
			{
				$flag_force_cddb_lookup = 1;
			}
			if ($i =~ /^-q$/)
			{
				$flag_verbose = 0;
			}
			if ($i =~ /^-a$/)
			{
				$readnext = 1;
			}
			if ($i =~ /^-o$/)
			{
				$readnext = 2;
			}
			if ($i =~ /^-D$/)
			{
				$readnext = 3;
			}
			if ($i =~ /^-f$/)
			{
				$readnext = 4;
			}
			if ($i =~ /-v$/)
			{
				print print_version_info();
				exit;
			}
			if ($i =~ /-h$/)
			{
				print print_help();
				exit;
			}

		}
	}
}

#################
# LaTeX filters #
#################

sub filter_input_for_latex_one_line_for_cddb_output
{
# Changes allmost all the noughty characters in a string returning a string
# safely parsed by LaTeX.

	local ($return) = @_;

	# recode $ as $$$
	$return =~ s/\$/\$\$\$/mg;
	# recode \ as $\backslash$
	$return =~ s/\\\\/\$\\backslash\$/mg;
	# recode \n as \\\\
	$return =~ s/\\n/\\\\/mg;
	# now recode $$ as \$
	$return =~ s/\$\$\$/\\\$/mg;
	# recode every x in _#%^&{} as \x{}
	$return =~ s/([_#%&\^~{}])/\\$1\{\}/mg;
	# recode every x in <>| as $x$
	$return =~ s/([<>\|])/\$$1\$/mg;


	return ($return);
}

sub filter_input_for_latex_one_line
{
# Changes all the noughty characters in a string returning a string
# safely parsed by LaTeX.

	local ($return) = @_;

	# recode $ as $$$
	$return =~ s/\$/\$\$\$/mg;
	# recode \ as $\backslash$
	$return =~ s/\\/\$\\backslash\$/mg;
	# now recode $$ as \$
	$return =~ s/\$\$\$/\\\$/mg;
	# recode every x in _#%^&{} as \x{}
	$return =~ s/([_#%&\^~{}])/\\$1\{\}/mg;
	# recode every x in <>| as $x$
	$return =~ s/([<>\|])/\$$1\$/mg;

	return ($return);
}

####################################
# Start of all the print functions #
####################################

sub print_cd_info_without_extended_track_info
{
# Prints latex code that declares the commands '\myartist \mytitle, \mylabel,
# and \mycontents to be used in the covers.

	if ( ( (($cddb->title eq 'Unknown') && ($cddb->artist eq 'Unknown')) || ($cddb->title eq '(unknown disc title)') ) && ($flag_verbose == 1))
	{
		print "Warning: No such cd found in CDDB database\n";
	}

	local ($return) = '
%%%%%%%%%%%
% CD INFO %
%%%%%%%%%%%
';

	$return .= '\newcommand{\mytitle}{'.filter_input_for_latex_one_line($cddb->title).'}'."\n";

	$return .= '\newcommand{\myartist}{'.filter_input_for_latex_one_line($cddb->artist).'}'."\n";

	$return .= '\newcommand{\mylabel}{'.filter_input_for_latex_one_line_for_cddb_output($bottomtextfront).'}'."\n";

	$return .= '\newcommand{\mycontents}'."\n";
	$return .= '{'."\n";
	if ($cddb->number_of_tracks <= 11)
	{

		$return .= '	\begin{center}\parbox{13cm}{'."\n";
		$return .= '	\begin{description}'."\n";
		while ($cddb->next_track)
		{
			$i = sprintf "\\item[%2i\.\]{{\\sf %s~\\dotfill %02i.%02i}}\n",
			$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
			$return .= $i;
		}
		$return .= sprintf "		\\item[]{\\sf \\hfill %02i.%02i}\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
		$return .= '	\end{description}}\end{center}'."\n";
	}
	else
	{
		if ($cddb->number_of_tracks <= 27)
		{
			if ($cddb->number_of_tracks >= 22)
			{
				$return .= '	{\footnotesize'."\n";
			}

			$return .= '	\begin{tabular}{rp{12.1cm}}'."\n";
			$return .= '		\\\\'."\n";
			while ($cddb->next_track)
			{
				$i = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
				$return .= $i;
			}
			$return .= sprintf "	\& \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
			$return .= '	\end{tabular}'."\n";

			if ($cddb->number_of_tracks >= 22)
			{
				$return .= '	}'."\n";
			}
		}
		else
		{
			if ($cddb->number_of_tracks <= 54)
			{
				$return .= '	{\footnotesize'."\n";
				
				$return .= '	\begin{tabular}{r@{\hspace{1em}}p{5.6cm}c@{}r@{\hspace{1em}}p{5.6cm}}'."\n";
				$return .= '		\\\\'."\n";
				for ($i = 0; $i < $cddb->number_of_tracks/2; $i++)
				{
					$cddb->current_track_number($i + 1);
					$t1 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$cddb->current_track_number($i + $cddb->number_of_tracks/2 + 1);
					$t2 = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$return .= $t1.'& &'.$t2;
				}
				$return .= sprintf "	\& \& \& \& \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
				$return .= '	\end{tabular}'."\n";
				$return .= '	}'."\n";
			}
			else
			{
				$return .= '	{\scriptsize'."\n";
				
				$return .= '	\begin{tabular}{@{}r@{\hspace{0pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{}}'."\n";
				$return .= '		\\\\'."\n";
				for ($i = 0; $i < $cddb->number_of_tracks/3; $i++)
				{
					$cddb->current_track_number($i + 1);
					$t1 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$cddb->current_track_number($i + $cddb->number_of_tracks/3 + 1);
					$t2 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$cddb->current_track_number($i + 2*$cddb->number_of_tracks/3 + 1);
					$t3 = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);

					$return .= $t1.' & '.$t2. ' & '.$t3;
				}
				$return .= sprintf "	 \& \& \& \& \&  \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
				$return .= '	\end{tabular}'."\n";
				$return .= '	}'."\n";
			}
		}
	}
	$return .= '}
%%%%%%%
'."\n";

	return ($return);
}

###########################

sub print_cd_info_with_extended_track_info
{
# Prints latex code that declares the commands '\myartist \mytitle, \mylabel,
# and \mycontents to be used in the covers.

	if ( ( (($cddb->title eq 'Unknown') && ($cddb->artist eq 'Unknown')) || ($cddb->title eq '(unknown disc title)') ) && ($flag_verbose == 1))
	{
		print "Warning: No such cd found in CDDB database\n";
	}

	local ($return) = '
%%%%%%%%%%%%%%%%%%%%%%
% CD INFO W/EXTENDED %
%%%%%%%%%%%%%%%%%%%%%%
';

	$return .= '\newcommand{\mytitle}{'.filter_input_for_latex_one_line($cddb->title).'}'."\n";

	$return .= '\newcommand{\myartist}{'.filter_input_for_latex_one_line($cddb->artist).'}'."\n";

	$return .= '\newcommand{\mylabel}{'.filter_input_for_latex_one_line_for_cddb_output($bottomtextfront).'}'."\n";

	$return .= '\newcommand{\mycontents}'."\n";
	$return .= '{'."\n";
	if ($cddb->number_of_tracks <= 11)
	{
			$return .= '	\begin{tabular}{rp{12.1cm}}'."\n";
			$return .= '		\\\\'."\n";
			while ($cddb->next_track)
			{
				$i = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
				$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
				$e = sprintf "\&{{\\footnotesize\\em %s}}\\\\\n", filter_input_for_latex_one_line($cddb->current_track_extended_info);
				$return .= $i;
				$return .= $e;
			}
			$return .= sprintf "	\& \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
			$return .= '	\end{tabular}'."\n";
	}
	else
	{
		if ($cddb->number_of_tracks <= 14)
		{
				$return .= '	{\footnotesize'."\n";

				$return .= '	\begin{tabular}{rp{12.1cm}}'."\n";
				$return .= '		\\\\'."\n";
				while ($cddb->next_track)
				{
					$i = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
					$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$e = sprintf "\&{{\\scriptsize\\em %s}}\\\\\n", filter_input_for_latex_one_line($cddb->current_track_extended_info);
					$return .= $i;
					$return .= $e;
				}
				$return .= sprintf "	\& \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
				$return .= '	\end{tabular}'."\n";

				$return .= '	}'."\n";
		}
		else
		{
			if ($cddb->number_of_tracks <= 28)
			{
				$return .= '	{\footnotesize'."\n";
				
				$return .= '	\begin{tabular}{r@{\hspace{1em}}p{5.6cm}c@{}r@{\hspace{1em}}p{5.6cm}}'."\n";
				$return .= '		\\\\'."\n";
				for ($i = 0; $i < $cddb->number_of_tracks/2; $i++)
				{
					$cddb->current_track_number($i + 1);
					$t1 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
					$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
					$e1 = sprintf "\&{{\\scriptsize\\em %s}}", filter_input_for_latex_one_line($cddb->current_track_extended_info);
					
					if ($cddb->current_track_number * 2 < $cddb->number_of_tracks)
					{
						$cddb->current_track_number($i + $cddb->number_of_tracks/2 + 2);
						$t2 = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
						$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$e2 = sprintf "\&{{\\scriptsize\\em %s}}\\\\\n", filter_input_for_latex_one_line($cddb->current_track_extended_info);
					}
					else
					{
						$t2 = ' & \\\\'."\n";
						$e2 = ' & \\\\'."\n";
					}

					
					$return .= $t1.'& &'.$t2;
					$return .= $e1.'& &'.$e2;
				}
				$return .= sprintf "	\& \& \& \& \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
				$return .= '	\end{tabular}'."\n";
				$return .= '	}'."\n";
			}
			else
			{
				if ($cddb->number_of_tracks <= 52)
				{
					$return .= '	{\scriptsize'."\n";
					
					$return .= '	\begin{tabular}{@{}r@{\hspace{0pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{}}'."\n";
					$return .= '		\\\\'."\n";
					for ($i = 0; $i < $cddb->number_of_tracks/3; $i++)
					{
						$cddb->current_track_number($i + 1);
						$t1 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
						$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$e1 = sprintf "\&{{\\tiny\\em %s}}", filter_input_for_latex_one_line($cddb->current_track_extended_info);

						$cddb->current_track_number($i + $cddb->number_of_tracks/3 + 1);
						$t2 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
						$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$e2 = sprintf "\&{{\\tiny\\em %s}}", filter_input_for_latex_one_line($cddb->current_track_extended_info);

						$cddb->current_track_number($i + 2*$cddb->number_of_tracks/3 + 1);
						$t3 = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
						$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$e3 = sprintf "\&{{\\tiny\\em %s}}\\\\\n", filter_input_for_latex_one_line($cddb->current_track_extended_info);

						$return .= $t1.' & '.$t2. ' & '.$t3;
						$return .= $e1.' & '.$e2. ' & '.$e3;
					}
					$return .= sprintf "	 \& \& \& \& \&  \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
					$return .= '	\end{tabular}'."\n";
					$return .= '	}'."\n";
				}
				else
				{
					$return .= '	{\scriptsize'."\n";
					
					$return .= '	\begin{tabular}{@{}r@{\hspace{0pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{\hspace{1em}}r@{\hspace{1pt}}p{3.8cm}@{}}'."\n";
					$return .= '		\\\\'."\n";
					for ($i = 0; $i < $cddb->number_of_tracks/3; $i++)
					{
						$cddb->current_track_number($i + 1);
						$t1 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
					$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$cddb->current_track_number($i + $cddb->number_of_tracks/3 + 1);
						$t2 = sprintf "{\\bf %i.}\&{{\\sf %s~\\dotfill %02i.%02i}}",
					$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);
						$cddb->current_track_number($i + 2*$cddb->number_of_tracks/3 + 1);
						$t3 = sprintf "{\\bf %i\.}\&{{\\sf %s~\\dotfill %02i.%02i}}\\\\\n",
					$cddb->current_track_number, filter_input_for_latex_one_line($cddb->current_track_info), ($cddb->current_track_time_in_seconds/60),($cddb->current_track_time_in_seconds %60);

						$return .= $t1.' & '.$t2. ' & '.$t3;
					}
					$return .= sprintf "	 \& \& \& \& \&  \\sf\\hfill %02i.%02i\\\\\n", ($cddb->disc_length/60), ($cddb->disc_length%60);
					$return .= '	\end{tabular}'."\n";
					$return .= '	}'."\n";
				}
			}
		}
	}
	$return .= '}
%%%%%%%
'."\n";

	return ($return);
}

############################
# Help and version dialogs #
############################

sub print_version_info
{
	return '
Disc-Cover version '.$version.' Copyright (C) 1999 J.I. van Hemert
This piece of software comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions, see the file COPYING for details.
For more information read the README that came with the
distribution.
';
}


sub print_help
{
	return print_version_info().'
Program switches:
 -a "<text>"   additonal text at the bottom of the front cover
 -D <device>   scan the cd in this device
 -e            enable extended track info
 -f <filename> use this cddb file as input instead of a cddb connection 
 -F            force checking with the cddb server
 -h            this help
 -o <filename> output to this filename (extension is added accordingly)
 -q            quiet mode, no warnings and no messages displayed
 -r            do not remove temporary files from '.$config_tmp_dir.' (for debugging)
 -t <type>     output format, possible values: '.$all_output_types.'
 -v            version and program information
';
}


#########################
# LaTeX print functions #
#########################

sub print_latex_head
{
	local ($return) = '\documentclass[]{article}';
	if ($config_output_format eq 'pdf')
	{
		$return = '\documentclass[pdftex]{article}';
	}

	$return .= '
\usepackage{rotating}
'.$latex_global_additional_packages.
'
\usepackage[latin1]{inputenc}
\usepackage{isolatin1}
\renewcommand{\thepage}{}
\oddsidemargin '.$latex_global_oddsidemargin.'
\evensidemargin '.$latex_global_evenside_margin.'
\voffset '.$latex_global_voffset.'
\footskip '.$latex_global_footskip.'
\textheight '.$latex_global_textheight.'
\hyphenpenalty=10000
\def\dotfill{\leaders\hbox to 2mm{\hfil.\hfil}\hfill}

%\newcommand{\mydate}{\the\year/\the\month/\the\day}

';

	return ($return);
}

sub print_latex_body
{
	return '\begin{document}

\newcommand{\myhead}[1]
{
\noindent
\begin{center}
{
\parbox{#1}{{\Large\mytitle}}

\rule{#1}{1pt}
\vspace{0.1cm}

\noindent
\parbox{#1}{{\hfill\large\emph{\myartist}}}
}
\end{center}
}

\noindent
\parbox{11cm}
{
{\small Printed with \emph{Disc-Cover} version '.$version.' on '.localtime(time()).'
For suggestions mail the author at {\tt jvhemert@cs.leidenuniv.nl} or for the
latest version check {\tt http://www.liacs.nl/\~{}jvhemert/disc-cover}}
}
\vspace{0.5cm}


%%%%%%%%%
% FRONT %
%%%%%%%%%

\noindent
\framebox{\parbox[c][12.0cm][t]{12.0cm}
{
\vspace{1cm}

\myhead{10cm}
\vfill
\begin{center}
\parbox{10cm}{{\footnotesize\sf\mylabel}}
\end{center}

}}

%%%%%%%%%


\vspace{1cm}


%%%%%%%%
% BACK %
%%%%%%%%


\newlength{\Test}
\settowidth{\Test}{\emph{\myartist}\hfill~{\mytitle}}
\ifthenelse{\lengthtest{\Test > 12.0cm}}
{
	\settowidth{\Test}{\small \emph{\myartist}\hfill~{\mytitle}}
	\ifthenelse{\lengthtest{\Test > 12.0cm}}
	{
		\settowidth{\Test}{\footnotesize \emph{\myartist}\hfill~{\mytitle}}
		\ifthenelse{\lengthtest{\Test > 12.0cm}}
		{
			\settowidth{\Test}{\scriptsize \emph{\myartist}\hfill~{\mytitle}}
			\ifthenelse{\lengthtest{\Test > 12.0cm}}
			{
				\newcommand{\sidetext}{\parbox{11.6cm}{\tiny \emph{\myartist}\hfill~{\mytitle}}}
			}
			{
				\newcommand{\sidetext}{\parbox{11.6cm}{\scriptsize \emph{\myartist}\hfill~{\mytitle}}}
			}
		}
		{
			\newcommand{\sidetext}{\parbox{11.6cm}{\footnotesize \emph{\myartist}\hfill~{\mytitle}}}
		}
	}
	{
		\newcommand{\sidetext}{\parbox{11.6cm}{\small \emph{\myartist}\hfill~{\mytitle}}}
	}
}
{
	\newcommand{\sidetext}{\parbox{11.6cm}{\emph{\myartist}\hfill~{\mytitle}}}
}

\noindent
\framebox{\parbox[c][11.6cm][t]{3mm}
{
	\begin{turn}{90}\sidetext\end{turn}
}}\framebox{\parbox[c][11.6cm][t]{13.6cm}
{
	\vspace{-0.1cm}
	\myhead{13cm}
	\vspace{-0.2cm}
	\mycontents

}}\framebox{\parbox[c][11.6cm][t]{3mm}
{
	\begin{turn}{-90}\sidetext\end{turn}
}}

%%%%%%%%

\end{document}
';
}


sub print_whole_cover
{
	if ($flag_with_extended_track_info)
	{
		return (print_latex_head().print_cd_info_with_extended_track_info().print_latex_body());
	}
	else
	{
		return (print_latex_head().print_cd_info_without_extended_track_info().print_latex_body());
	}
}

sub run_latex
{
	my ($latex_command) = $_[0];

	open OUT,">$config_tmp_dir/disc-cover.$process_number.tex";
	print OUT print_whole_cover() ;
	close OUT;

	if (system ("(cd $config_tmp_dir ; echo q | $latex_command \"disc-cover.$process_number.tex\" > /dev/null)") > 0)
	{
		print "Error: something went wrong while running LaTeX.\n\nSolution: check if the necessary LaTeX packages are installed:\nrotating, isolatin1 and inputenc.\n";
		end_program();
	}
}



=pod MANUAL PAGE

=head1 NAME

disc-cover - create front and back covers for audio CDs


=head1 SYNOPSIS

disc-cover  [-hrqevF] [-a text] [-f filename] [-o filename] [-t txt|dvi|tex|ps|pdf|cddb|lbl] [-D device]


=head1 DESCRIPTION

disc-cover creates front and back covers for audio CDs. The CD has to be
present in the CD-ROM drive. disc-cover searches the CDDB database for an entry
corresponding to the CD's CDDB ID. It starts by looking for a local CDDB entry
in ~/.cddb. If no local CDDB entry matches the CD, disc-cover continues to
search the online CDDB database at www.cddb.com. It then formats the CDDB entry
to produce a Latex, Dvi, Postscript or PDF file, which contains the front and
back covers on a single page. Other formats supported include a simple text
output, a CDDB compatible format and an output format that can be used with
cdlabel- gen (http://www.red-bean.com/~bwf/software/cdlabelgen/), another cover
builder.


=head1 LAYOUT

The front cover shows artist, album title and when available extended disc
info. In addition to those, the back cover lists the individual tracks,
preceded by a track number and followed by their running time. The total running
time of the CD is given at the bottom of the back cover. The sides of the back
cover contain the artist and CD title.


=over 4

=head1 OPTIONS

=item B<-a> I<text>

Add text to the bottom of the front cover. Default is to put extended disc
information here.

=item B<-D> I<device>

Specify the CD-ROM device.

=item B<-e>

This flag enables extended track information. If it is available this extended
information will be added below the track names. It is mostly used in
compilation cds for artist information. Sometimes this extened track
information has been used for lyrics, needles to say this will not fit at the
back of one cd cover and will therefor destroy the layout. That is why is an
option instead of default behavior.

=item B<-f> F<filename>

Use filename as input instead of searching the local and online CDDB database.

=item B<-F>

Don't search the local CDDB database for the CD. Force online CDDB lookup.

=item B<-h>

Print help message and exit.

=item B<-o> F<filename>

The -o switch allows to specify the name of the output file. By default the
filename will be Artist_Title.xxx, where xxx is txt, tex, dvi, ps or pdf
depending on the file format. See -t option for supported file formats. Using
"-o -" will send the output to standard out.

=item B<-q>

Run in quiet mode. No warnings or messages are displayed.

=item B<-r>

By default disc-cover deletes all temporary files it created before it exits. This behavior can be overwritten by specifying the -r option.

=item B<-t> I<txt|tex|dvi|ps|pdf|cddb|lbl>

The -t switch allows to specify the output format. By default disc-cover will
create a Postscript file. Other formats supported include ASCII text (txt),
LaTeX (tex), DVI (dvi), PDF (pdf), cddb database format (cddb) and a cdlabelgen
compatible format (lbl).

=item B<-v>

Print version and program information and exit.

=back

=head1 BUGS

=over 4

=item -

Whenever a title is too long it will destroy the layout.

=item -

Whenever there is more than one file in the cddb cache directory disc-cover
will issue a warning and just use the first one it found.


=head1 AUTHORS

disc-cover is written and maintained by J.I. van Hemert <jvhemert@cs.leidenuniv.nl>

The program is licensed under the GNU Public License.

=cut

# Eof disc-cover

