#!/usr/bin/perl
#
# Create the stored music lists
#
# $Id: mklist,v 1.6 2002/05/26 17:43:34 dds Exp $
#
# Use -t option to create a track listing
#
# (C) Copyright 2000-2002 Diomidis Spinellis
# 
# Permission to use, copy, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation.
# 
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# 

open(PLAYLIST, '>/vol/db/playlist') || die;
open(HTML, '>/vol/db/playlist.html') || die;
open(TEX, '>/vol/db/playlist.tex') || die;
htmlhead();
texhead();


# Process bookmarks
htmlcontents("Bookmarks", 1);
$html .= "<dl compact>\n";
print TEX '
\section{Bookmarks}
\begin{tabular}{rl}
';
open(FILE, 'find /vol/db/bookmarks -type f -print | sort |') || die "find: $!\n"; ;
while (<FILE>) {
	chop;
	$name = $fname = $_;
	$name =~ s,.*/,,;
	open(BK, $fname);
	while (<BK>) {
		chop;
		next if (/^#/);
		$num = $1 if (/^NU (\d+)/);
		$bk = $1 if (/^BK (\d+)/);
	}
	close(BK);
	$name = fix($fname);
	$html .= "<dt><em>$num</em><dd>$name\n";
	print TEX "{\\em $num} & $name \\\\\n";
	$bookmark{$bk} = $num;
}
$html .= "</dl>\n";
print TEX "\\end{tabular}\n";

# Process index files and create full track list
htmlcontents("Disks", 1);
print TEX "\\section{Disks}\n";
open(FILE, 'find /vol/music -name index.txt -print | sort |') || die;
while (<FILE>) {
	chop;
	$dir = $idxname = $_;
	$dir =~ s,/index.txt$,,;
	open(IDX, $idxname) || die;
	while (<IDX>) {
		chop;
		next if (/^#/);
		if (/^DN (.*)/) {
			$dn = $1;
			pathheader($dir, $dn, 1, "#DN$dn");
			print PLAYLIST "# $dn\n";
			print PLAYLIST "# $b\n" if ($b = $bookmark{$dn});
		}
		if (/^TN (\d+)\001(.*)/) {
			print PLAYLIST "# $b\n" if ($b = $bookmark{$1});
			print PLAYLIST "# $1\n$dir/$2\n";
		}
	}
	close(IDX);
}

# Process collections

if ($ARGV[0] eq '-t') {
	# Process tracks
	htmlcontents("Tracks", 1);
	print TEX "\\section{Tracks}\n";
	open(FILE, 'find /vol/music -name index.txt -print | sort |') || die;
	while (<FILE>) {
		chop;
		$dir = $idxname = $_;
		$dir =~ s,/index.txt$,,;
		# Try to read track info from info.txt
		undef %trackname;
		if (open(INFO, $q = "$dir/info.txt")) {
			while (<INFO>) {
				chop;
				if (/^TR (.*)/) {
					($tn, $infoname, $fname) = split(/\001/);
					$trackname{$fname} = $infoname;
				}
			}
			close(INFO);
		}
		open(IDX, $idxname) || die;
		while (<IDX>) {
			chop;
			next if (/^#/);
			if (/^DN (.*)/) {
				$html .= "<a name=\"DN$1\"> </a>";
			}
			if (/^TN (\d+)\001(.*)/) {
				$tracknum = $1;
				$trackfname = $2;
				if (defined($trackname{$trackfname})) {
					$trackname = $trackname{$trackfname};
				} else {
					$id3 = id3name("$dir/$trackfname");
					$tryname = $trackfname;
					$tryname =~ s/track-?//i;
					$simplename = fix($tryname);
					$trackname = (length($id3) > length($simplename)) ? $id3 : $simplename;
				}
				$trackname =~ s,/,:,g;	# Not to confuse pathheader
				# URL in Windows format
				pathheader("$dir/$trackname", $tracknum, 0, "file:////spiti/$dir/$fname");
			}
		}
		close(IDX);
	}
} # process tracks


$html .= "</body></html>\n";

print HTML "<h1>Contents</h1>";
print HTML $contents;
print HTML "<p><hr><p>\n";
print HTML $html;

print TEX '
\end{document}
';

# Create the text version of the list
system(q{lynx -dump /vol/db/playlist.html -width=1024 | sed -n 's/\[[^]]*\]//g;s/  */ /g;/Disks/,/Tracks/p' >/vol/db/playlist.txt});

# Print an HTML head
sub
htmlhead
{
	print HTML '<!doctype html public "-//IETF//DTD HTML//EN">
<!-- WARNING: Automatically generated file.  Do not modify. -->
<HTML>
<HEAD>
<TITLE>MP3 Playlist</TITLE>
<META NAME="AUTHOR" CONTENT="Diomidis Spinellis">
<META HTTP-EQUIV="Content-type" CONTENT="text/html">
</HEAD>
<BODY> 
';
}

# Convert a filename to a readable name
sub
fix
{
	my($name) = @_;

	$name =~ s,.*/,,;
	$name =~ s/\.mp3$//;
	$name =~ s/([A-Z])/ $1/g;
	$name =~ s/_/ /g;
	$name =~ s/(\d+)/ $1/g;
	$name =~ s/\bcd\b/CD/g;
	$name =~ s/  */ /g;
	$name =~ s/^ //;
	return ($name);
}

# Convert a pathname into headers
# Return the last element of the path
sub
pathheader
{
	my($path, $number, $fixlast, $url) = @_;
	my($i, $l, $name);

	$path =~ s,/vol/music/,,;
	@elements = split(/\//, $path);
	for ($i = 0; $i <= $#elements; $i++) {
		if ($elements[$i] ne $oelements[$i]) {
			$level = $i + 2;
			if ($i < $#elements) {
				$name = fix($elements[$i]);
				if ($level == 2) {
					print TEX "\n\\subsection*{" . texprotect($name) . "}\n";
					print TEX "\n\\addcontentsline{toc}{subsection}{" . texprotect($name) . "}\n";
					htmlcontents($name, 2);
				} elsif ($level == 3) {
					print TEX "\n\\subsubsection*{" . texprotect($name) . "}\n";
					print TEX "\n\\addcontentsline{toc}{subsubsection}{" . texprotect($name) . "}\n";
					htmlcontents($name, 3);
				} else {
					print TEX "\\hspace*{" . ($level - 4) * 0.3 . "cm}" . texprotect($name) . "\\\\\n";
					$html .= ('&nbsp;' x (($level - 4) * 3)) . htmlprotect($name) . "<br>";
				}
			}
		}
	}
	@oelements = @elements;
	$last = $fixlast ? fix($elements[$#elements]) : $elements[$#elements];
	$html .= ('&nbsp;' x ($level * 3));
	print TEX "\\hspace*{" . ($level - 4) * 0.3 . "cm}";
	print TEX  texprotect($last) . ": {\\em $number}\\\\\n";
	$number = "<a href=\"$url\">$number</a>" if (defined($url));
	$html .=  htmlprotect($last) . ": <em>$number</em><br>\n";
	return ();
}

# Return the ID3 name of a given file
sub
id3name
{
	my($fname) = @_;
	
	$fname =~ s/'/'\\''/g;
	open(ID3, "id3 -lR '$fname'|") || die;
	while (<ID3>) {
		if (/^Title: (.*)/) {
			$name = $1;
			close(ID3);
			$name =~ s/  */ /g;
			return ($name);
		}
	}
	return ('');
}

sub
texhead
{
	print TEX '
\documentclass[10pt,twocolumn]{article}
\textwidth 17cm
\oddsidemargin -0.54cm
\evensidemargin -0.54cm
\textheight 23cm
% Margins are 1in more than specified so margin = 4cm / 2 - 1in
\topmargin -0.44cm
\headheight 0pt
\headsep 0pt

\usepackage{times}

\begin{document}

\title{Music Selection Guide}

\maketitle
\newpage
\tableofcontents
\clearpage
';
}

# Protect special TeX characters
sub
texprotect
{
	my($line) = @_;

	$line =~ s/\#/\\\#/g;
	$line =~ s/\$/\\\$/g;
	$line =~ s/\%/\\\%/g;
	$line =~ s/\&/\\\&/g;
	$line =~ s/\~/\\\~/g;
	$line =~ s/\_/\\\_/g;
	$line =~ s/\^/\\\^/g;
	$line =~ s/\{/\\\{/g;
	$line =~ s/\}/\\\}/g;
	return ($line);
}

# Protect special HTML characters
sub
htmlprotect
{
	my($line) = @_;

	$line =~ s/\&/\&amp;/g;
	$line =~ s/\</\&lt;/g;
	$line =~ s/\>/\&gt;/g;
	return ($line);
}

# Add a title to the HTML table of contents at a given level
sub
htmlcontents
{
	my($title, $level) = @_;

	$anchor++;
	$title = htmlprotect($title);
	$html .= "<h$level><a name=\"c$anchor\">$title</a></h$level>\n";
	$contents .= ('&nbsp;' x (($level - 1) * 3)) . '<a href="#c' . $anchor . '"><font size=' . (2 - $level) . ">$title</font></a><br>\n";
}
