#!/usr/bin/perl
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#NAME
#  mkprog - make a program
#
#SYNOPSIS
#  mkprog [options] name page...
#
#DESCRIPTION
#  This is a tool that helps make a program of tune sets out  of  collections
#  of  ABC  files.   This  is used in Makefiles to simplify the entries for a
#  program of music.
#
#  The name argument is a name for the program.  We first create a  directory
#  by  that name.  If there is a "program" or "events" directory, we create a
#  program/$name directory, otherwise we create the ./$name directory.
#
#  The rest of the args are the names of pages for tune sets.  The Makefile  should  contain
#  entries  for  each  of  the  pages, to create the page.abc, page.ps and
#  page.pdf files.  We run through the list doing a "make $page"  for  each
#  dance name. Then we link the resulting files into the program's directory.
#
#OPTIONS
#  Options can start with '+' (for "yes" or "enable") or  '-'  (for  "no"  or
#  "disable).   All the options are a single letter, and they may be combined
#  into a single string if you like.  The case doesn't matter.  Some  options
#  may  be  followed by a numeric argument, with a default used if there's no
#  number.  If we show only a '-' option, then '+' means the same thing.
#
#  +H[file]
#       Create an HTML5 program file.  If [file] is present, it will be  read
#       for usable information, and its suffix (if any) will be replaced with
#       ".html" to get the name of the output file. The page...  args will be
#       used  to produce an HTML listing of the program, with links to return
#       their music in assorted formats.
#
#  +I   Informative: Don't actually make files, just say what would be done.
#  -I   Do everything.  This is the default.
#
#  -P   "Print"  After making sure that all the files exist, they are sent to
#       the default printer.
#
#  -R   Reverse the print order, printing the last dance's files first.
#
#  +Sn  Sleep between prints.  The default is a 5-second sleep.
#  -S   Don't sleep between prints.
#
#  +T   Link .abc files to .txt files, for browsers that don't grok .abc.
#  -T   Don't link .abc files to .txt files.  [default]
#
#  -Vn  sets the verbose level to n.  Without a number, +V increments and -V
#       decrements the default verbose level, which is usually 1, but may be
#       higher for debugging purposes.
#
#AUTHOR John Chambers <jc@trillian.mit.edu>
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

$| = 1;
$exitstat = 0;	# Success so far ...
($P = $0) =~ s".*/"";
$V = $ENV{"V_$P"} || 1;

$Hopt  = 0;		# HTML output wanted
$Hfil  = '';	# HTML file name
$Hnam  = '';	# HTML base name
$Hopen = 0;		# True when Hfil is open for writing
$Iopt  = 0;		# Information only, don't make or print
$Popt  = 0;		# Print if true
$Ropt  = 0;		# Reverse the page order
$Sopt  = 5;		# Delay between lpr commands
$task = 'Make';	# Make or Prnt
$lnabc = 1;		# Link source file as .abc
$lntxt = 0;		# Link source file as .txt
$pdir  = '';	# Directory that receives the files.

$name = shift;
if (($flg,$opts) = ($name =~ /^([-+])(.*)$/)) {
	print "$0: Opts \"$opts\" (flg='$flg')\n" if $V>1;
	while (($opt,$opts) = ($opts =~ /^(.)(.*)$/)) {
		if (uc($opt) eq 'A') {
			$lnabc = $flg eq '+' ? 1 : 0;
			print("$0: lnabc=$lnabc (" . ($lnabc ? '' : "don't ") . "link source file to .abc)\n") if $V>0;
		} elsif (uc($opt) eq 'H') {
			$Hopt = ($flg eq '+') ? 1 : 0;
			$Hnam = $opts;		# Use the rest of the option as the HTML file name
			print "$0: Hopt=$Hopt Hnam='$Hnam' (HTML output)\n" if $V>0;
		} elsif (uc($opt) eq 'I') {
			$Iopt = ($flg eq '+') ? 1 : 0;
			print "$0: Iopt=$Iopt (information only)\n" if $V>0;
		} elsif (uc($opt) eq 'P') {
			++$Popt;
			print "$0: Popt=$Popt (print)\n" if $V>1;
		} elsif (uc($opt) eq 'R') {
			$Ropt = ($flg eq '-') ? 0 : 1;
			print "$0: Ropt=$Ropt (reverse order)\n" if $V>0;
		} elsif (uc($opt) eq 'S') {
			if ($opts =~ s/^(\d+)//) {
				$Sopt = $1;	# Sleep time after lpr command
			} else {
				$Sopt ++;	# Incr lpr sleep time
			}
			print "$0: Sopt=$Sopt (sleep between sets)\n" if $V>1;
		} elsif (uc($opt) eq 'T') {
			$lntxt = $flg eq '+' ? 1 : 0;
			print("$0: lntxt=$lntxt (" . ($lntxt ? '' : "don't ") . "link source file to .txt)\n") if $V>0;
		} elsif (uc($opt) eq 'V') {		# Is number included?
			if ($opts =~ s/^(\d+)//) {	# Set $V to that value
				$V = int($1);
			} else {		# Decrement or increment $V according to flag
				$V += ($flg eq '-') ? -1 : 1;
			}
			print "$0: V=$V (verbose level)\n" if $V>0;
		} else {
			print STDERR "$0: Unknown option '$opt' ignored.\n" if $V>0;
		}
		print "$0: opts \"$opts\" (flg='$flg')\n" if $V>1;
	}
	$name = shift;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Directory kludge: #
# We firt check to see if the named directory exists, in ./ or program/, and #
# if so, we use it.  If not, we have to create it.
# If we have a "program" subdirectory, we create the target #
# directory there.  Otherwise, we create it under the current directory.      #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
if (-d "$name") {
	print STDERR "$0: Directory \"$name\" exists.\n" if $V>1;
	$pdir = $name;
} elsif (-d "event/$name") {
	print STDERR "$0: Directory \"event/$name\" exists.\n" if $V>1;
	$pdir = "event/$name";
} elsif (-d "program/$name") {
	print STDERR "$0: Directory \"program/$name\" exists.\n" if $V>1;
	$pdir = "program/$name";
} else {
	print STDERR "$0: Directory \"$name\" not found ...\n" if $V>0;
	if (-d ($d = "event")) {
		print STDERR "$0: Make \"$d\" directory ...\n" if $V>0;
		if (mkdir("$d",0644)) {	# Attempt to create it under event/
			$pdir = $d;
			print STDERR "$0: Directory \"$pdir\" created.\n" if $V>0;
		} else {
			print STDERR "$0: Can't create \"$d\" [$?]\n" if $V>0;
		}
	} elsif (-d ($d = "program")) {
		print STDERR "$0: Make \"$d\" directory ...\n" if $V>0;
		if (mkdir("$d",0644)) {	# Attempt to create it under program/
			$pdir = $d;
			print STDERR "$0: Directory \"$pdir\" created.\n" if $V>0;
		} else {
			print STDERR "$0: Can't create \"$d\" [$?]\n" if $V>0;
		}
	}
	unless ($pdir) {	# Attempt to create it under current directory
		if (mkdir($name,0644)) {
			$pdir = $name;
			print STDERR "$0: Directory \"$pdir\" created.\n" if $V>0;
		} else {
			print STDERR "$0: Can't create \"$name\" [$?]\n" if $V>0;
		}
	}
	$pdir = "$name";
}
unless ($pdir) {
	print STDERR "$0: Don't know which directory to use.\n" if $V>0;
	exit 1;
}
unless (-d $pdir) {
	print "$P: Make dir $pdir/\n" if $V>0;
	mkdir $pdir, 0755;
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# HTML output:  We create the .html program file here.  The first thing to do #
# is to figure out what we should call it.  Then we open it and write some 
# HTML boilerplate.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
if ($Hopt) {
	print "$P: HTML Hopt='$Hopt'\n" if $V>0;
	if ($Hnam) {		# Did we get a base name on the command line?
		print "$P: HTML Hnam='$Hnam'\n" if $V>0;
	} elsif ($name) {	# Did we get a program name?
		print "$P: HTML name='$name'\n" if $V>0;
		$Hfil = $name . '_program';		# Build base name from the program name
		print "$P: HTML Hfil='$Hfil'\n" if $V>0;
	} else {
		print STDERR "$P: Can't figure out HTML file name.\n" if $V>0;
		$Hfil = 'program';	# Useful default name
	}
	if ($Hfil =~ s/\.\w+$/.html/) {		# Replace suffix with .html
		print "$P: HTML Hfil='$Hfil'\n" if $V>0;
	} else {				# No suffix
		$Hfil .= ".html";	# Add .html to program name
		print "$P: HTML Hfil='$Hfil'\n" if $V>0;
	}
	# Create the file:
	if ($Hfil) {
		print "$P: Open '$Hfil' for writing ...\n" if $V>0;
		if (open(HFIL, ">$Hfil")) {
			$Hopen = 1;
			&htmlHdr();
		} else {
			print STDERR "$P: ### Can't write \"$Hfil\" [$?]\n" if $V>0;
			$Hopen = 0;		# It was probably 0 anyway
		}
	}
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# Now we run through the list of dance pages, making sure each is up to date, #
# and linking each one's files into the program directory.                    #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
if ($Hopen) {				# Create HTML table for the dances
	print HFIL "<table border=$B>\n";
	print HFIL "<caption><big><b>$name Program</b></big></caption>\n";
	print HFIL "<tr>\n";	# Column headers
	print HFIL "\t<th>abc</th>\n";
	print HFIL "\t<th>pdf</th>\n";
	print HFIL "\t<th>Name</th>\n";
	print HFIL "</tr>\n";
}
while ($page = ($Ropt ? pop @ARGV : shift @ARGV)) {
	print "---	$task $page ...\n" if $V>1;	# Make sure each is up-to-date
#	if ($page =~ /(.*)\.([^.]+)$/) {	# We no longer accept the full file name here
#		print "Name \"$page\" suffix \"$1\"\n" if $V>1;
#		$page = $1;
#	} else {
#		print "Name \"$page\" treated as name\n" if $V>1;
#	}
	$abc = $lnabc ? "$page.abc" : '';
	$txt = $lntxt ? "$page.txt" : '';
	$ps  = "$page.ps";
	$pdf = "$page.pdf";
	if ($Hopen) {		# Create HTML file line for this dance
		print HFIL "<tr>\n";
		print HFIL "\t<td><a href='$page.abc'>abc</a></td>\n";
		print HFIL "\t<td><a href='$page.pdf'>pdf</a></td>\n";
		print HFIL "\t<td>$page</td>\n";
		print HFIL "</tr>\n";
	}
	@mkout = $Iopt ? `make -k $abc $ps $pdf` : ();
	print @mkout if $?;
	if ($?) {
		print STDERR "$P: Problems with $page.\n" if $V>0;
	}
	if (-f "$abc") {
	#	if (-f "$pdir/$abc") {
	#		print "$P: unlink('$pdir/$abc')\n" if $V>0;
	#		unlink("$pdir/$abc");
	#	}
		print "$P: Link $abc to $pdir ...\n" if $V>1;
		unlink("$pdir/$abc") if -f "$pdir/$abc" && $lnabc;
		unlink("$pdir/$txt") if -f "$pdir/$txt" && $lntxt;
		link("$abc","$pdir/$abc") if $lnabc;	# Link in the ABC source file
		link("$abc","$pdir/$txt") if $lntxt;	# Also provide the ABC as "plain text"
	} else {
		print "$P: ABC file '$abc' does not exist.\n" if $V>0;
		if (@files = glob("$page*.abc")) {
			print "\tThese files exist:\n" if $V>0;
			system 'ls', '-ld', @files;
		}
	}
	if (-f $ps) {
		unlink("$pdir/$ps") if -f "$pdir/$ps";
		print "$P: Link $ps to $pdir ...\n" if $V>1;
		link("$ps","$pdir/$ps");
		if ($Popt) {
			print "$P: Print $page ...\n" if $V>1;
			system "lpr $pdir/$ps" unless $Iopt;
			sleep $Sopt if $Sopt>0;
		}
	} else {
		print "$P: PS file '$ps' does not exist.\n" if $V>0;
		if (@files = glob("$page*.ps")) {
			print "\tThese files exist:\n" if $V>0;
			system 'ls', '-ld', @files;
		}
	}
	if ( -f $pdf) {
		unlink("$pdir/$pdf") if -f "$pdir/$pdf";
		print "$P: Link $pdf to $pdir ...\n" if $V>1;
		link($pdf,"$pdir/$pdf") unless $Iopt;
	} else {
		print "$P: PDF file '$pdf' does not exist.\n" if $V>0;
		if (@files = glob("$page*.pdf")) {
			print "\tThese files exist:\n" if $V>0;
			system 'ls', '-ld', @files;
		}
	}
}
print HFIL "</table>\n" if ($Hopen);	# End HTML table for the dances

&htmlFtr();
exit $exitstat;

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

sub htmlHdr { my $F='htmlHdr';
	print "$F: Write HTML header ...\n" if $V>0;
	print HFIL "<html>\n";
	print HFIL "<title>$name program</title>\n";
	print HFIL "<head>\n";
	print HFIL "</head>\n";
	print HFIL "<body>\n";
}

sub htmlFtr { my $F='htmlFtr';
	print "$F: Write HTML footer ...\n" if $V>1;
	print HFIL "</html>\n";
	close HFIL;
	$Hopen = 0;
}
