#!/usr/athena/bin/perl 
# -*- perl -*-

# epsmerge: A Perl script to merge several encapsulated postscript files
# into one single EPS file.

# Copyright (C) 1998-1999 Jens G. Jensen
# Currently: jens@arcade.mathematik.uni-freiburg.de

# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
# Or see http://www.gnu.org/copyleft/gpl.html

# $Id: epsmerge,v 1.13 1999/01/30 15:42:30 jens Exp $

require 5;
use strict;
use MainCell;
use Options;


my $Official_Version = '1.2.2';

# See the POD in Options.pm for what all this stuff is.
my $opts = Options->new([
			 # Special options
			 [ '-h', '--help', ':b', undef, 0, "" ],
			 [ '-v', '--version', ':b', undef, 0, "" ],
			 # General options
			 [ undef, '--header', '=s', undef, '', 'A label specifier for the generated eps file' ],
			 [ undef, '--labels', '=s', undef, '', 'Label specifier for the included eps files' ],
			 [ '-fn', '--font', '=s', undef, 'Times-Roman', 'The name of the font used to print labels' ],
			 [ '-o', '--output-file', '=s', undef, 'stdout', 'Filename of the to-be-generated eps file' ],
			 [ '-O', '--orientation', '=s', \&check_orientation, 'P', 'Landscape or Portrait?' ],
			 [ '-p', '--paper', '=s', \&check_paper, check_paper('A4'), 'Paper size (e.g., A4, A3, letter)' ],
			 [ '-ph', '--paper-height', '=s', \&check_length, '', 'Physical height of output' ],
			 [ '-pw', '--paper-width', '=s', \&check_length, '', 'Physical width of output' ],
			 [ undef, '--print', ':b', \&check_bool, 0, 'Generates a \`showpage\' for output to printer' ],
			 [ undef, '--script', '=s', undef, '', 'A perl script for generating labels' ],
			 [ '-ps', '--postscript', ':b', \&check_bool, 0, 'Generate postscript output' ],
			 # Formatting options
			 [ '-x', undef, '=i', \&check_posint, 0, 'How many images per row' ],
			 [ '-y', undef, '=i', \&check_posint, 0, 'How many images per column' ],
			 [ '-lmar', undef, '=s', \&check_length, '20', 'Size of left margin' ],
			 [ '-rmar', undef, '=s', \&check_length, '20', 'Size of right margin' ],
			 [ '-tmar', undef, '=s', \&check_length, '20', 'Size of top margin' ],
			 [ '-bmar', undef, '=s', \&check_length, '20', 'Size of bottom margin' ],
			 [ '-xcs', undef, '=s', \&check_length, '20', 'Horizontal spacing between images' ],
			 [ '-ycs', undef, '=s', \&check_length, '20', 'Vertical spacing between images' ],
			 [ '-rmo', undef, ':b', \&check_bool, 1, 'Arrange in row-major-order (first rows then cols)' ],
			 [ '-par', undef, ':b', \&check_bool, 0, 'Preserve aspect ration' ],
			 [ '-prs', undef, ':b', \&check_bool, 0, 'Preserve relative sizes of images' ],
			 ],
			\@ARGV,
			".epsmergerc"
			);

if( $opts->getopts('h') ) {
    print_usage();
    exit(0);
}

if( $opts->getopts('v') ) {
    print_version();
    exit(0);
}

$opts->setopts(v => $Official_Version);

unless( @ARGV ) {
    print "No files given.\n";
    &print_usage;
    exit(1);
}


my $multi = 0;			# writing output in multi-file mode
my @indx;			# index part of filename for multi-file
my $xy;				# number of files output per page
$opts->setopts( pages => 1 );	# non-E postscript default

# See if we switch to multi-file mode
# (bare block sets limited scope for many intermediate vars)
{
    my ($x, $y, $o) = $opts->getopts('x', 'y', 'o');
    $xy = $x * $y;
    if( $xy && $xy < @ARGV ) {
	if( $o eq 'stdout' && !$opts->getopts('ps') ) {
	    print STDERR "Can't write multiple files to stdout; see docs for details\n";
	    exit(1);
	}
	use integer;
	my $q = (@ARGV + $xy-1) / $xy; # how many pages
	if( $opts->getopts('ps') ) {
	    $opts->setopts( pages => $q );
	    last;
	}
	$multi = 1;
	my ($i, $m);
	for( $i = 1, $m = 10; $m < $q; ++$i, $m *= 10) { }
	# $m is now log10($q) rounded up
	my ($name, $ext);
	if( $o =~ /^(.*)(\.e?ps)$/ ) {
	    $name = $1; $ext = $2;
	}
	else {
	    $name = $o; $ext = '.eps';
	}
	$name .= '-';
	my @tmp = split //, $name;
	@indx = ( scalar @tmp, $i );
	$o = $name . ( '0' x $i ) . $ext;
	$opts->setopts( o => $o );
    }
    else {
	$xy = @ARGV;
    }
}


if( !$multi && $opts->getopts('o') ne 'stdout' ) {
    unless( open(OUTFILE, ">" . $opts->getopts('o')) ) {
	printf STDERR "Cannot open output file %s for writing\n", $opts->getopts('o');
	exit(5);
    }
    select OUTFILE;
}

while( @ARGV ) {
    if( $multi ) {
	# opening new OUTFILE closes previous OUTFILE
	unless( open(OUTFILE, ">" . $opts->getopts('o')) ) {
	    printf STDERR "Cannot open output file %s for writing\n", $opts->getopts('o');
	    exit(5);
	}
	select OUTFILE;
    }
    my @parms = splice @ARGV, 0, $xy;
    MainCell->new( \@parms )->write();
    if( $multi ) {
	# update filename
	my $o = $opts->getopts('o');
	++ substr( $o, $indx[0], $indx[1] );
	$opts->setopts( o => $o );
    }
}

exit(0);



sub print_usage {
    print STDOUT <<USAGE;
Usage: epsmerge [option1 value-1] ... [optionr valuer] [--] file1 file2 ... filen\n
where each option is followed by a value as follows:
	-o	name of file to send output to (default stdout)
	-O	orientation: p (portrait) or l (landscape)
	-x	number of files to format in each row
	-y	number of files to format in each column
	-par	yes/no; preserve aspect ratio
	-prs	yes/no; preserve relative sizes
	-p	the type of paper (if any) used for ouput
	--print yes/no; force a showpage operator into the output file
	-lmar   specify left margin (likewise -rmar -tmar -bmar)
	-xcs	specify spacing in x direction (likewise -ycs)
	-rmo	yes/no; row major order. Files typeset in rows first.
For further information and options see the epsmerge documentation.
USAGE
}

sub print_version {
    print STDOUT "epsmerge $Official_Version: merge encapsulated postscript files.\n";
}

sub print_license {
    print STDOUT <<LICENSE;
epsmerge Copyright (C) Jens G Jensen 1998-1999.
epsmerge is distributed "AS IS" under the GNU General Public License in the
hope that it may be useful; see the file COPYING for details.
LICENSE
}

# Value checker functions

sub check_length {
    $_ = shift;
    no integer;
    if( /^(-?\d*\.?\d*)cm$/ ) {
	return 28.346457 * $1;
    }
    if( /^(-?\d*\.?\d*)mm$/ ) {
	return 2.8346457 * $1;
    }
    if( /^(-?\d*\.?\d*)in$/ ) {
	return 72 * $1;
    }
    return $_ if /^-?\d*\.?\d*$/;
    return undef;
}

sub check_bool {
    $_ = shift;
    return 1 if(/^1$/ || /^y(es)?$/i || /^t(rue)?$/i);
    return 0 if(/^0$/ || /^no?$/i || /^f(alse)?$/i || /^nil$/i);
    return undef;
}

sub check_posint {
    $_ = shift;
    return $_ if /^[1-9]\d*$/;
    return undef;
}

sub check_orientation {
    $_ = shift;
    return 'P' if /^p/i;
    return 'L' if /^l/i;
    return undef;
}

# Converts a name (if recognized) into a ref to an array with dimensions
sub check_paper {
    my $sizeref = {
	'a2' => [ 1190, 1684 ],
	'a3' => [ 842, 1190 ],
	'a4' => [ 595, 842 ],
	'a5' => [ 420, 595 ],
	'b4' => [ 709, 1001 ],
	'b5' => [ 499, 709 ],
	'letter' => [ 612, 792 ],
	'tabloid' => [ 792, 1224 ],
	'ledger' => [ 1224, 792 ],
	'legal' => [ 612, 1008 ],
	'executive' => [ 540, 720 ],
    }->{ lc( shift ) };
    return $sizeref;
}
