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

# epssplit: a program to write an eps file as several eps files
# (or one postscript file) so that they may be printed and glued
# back together.

# Copyright (C) 1998-1999 Jens G. Jensen
# Currently: jens@math.u-strasbg.fr

# 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: epssplit,v 1.8 1999/05/01 10:24:46 jens Exp $
# Cannibalized from epsmerge =>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.0.1';

# 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
			 [ '-o', '--output-file', '=s', undef, 'stdout', 'Filename of the to-be-generated eps file' ],
			 [ '-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, 1, 'Generates a \`showpage\' for output to printer' ],
			 [ '-mar', '--margin', '=s', \&check_length, 0, "Margin around image on each paper" ],
			 [ '-ps', '--postscript', ':b', \&check_bool, 'default', 'Generate postscript output' ],
			 [ '-sc', '--scale', '=s', \&check_posfloat, 'default', 'Scale input by this factor' ],
			 [ '-fs', '--fontsize', '=s', \&check_length, 12, 'Size of fonts for labels' ],
			 [ undef, '--border', '=s', \&check_length, 20, 'Border around image for cropmarks and labels' ],
			 # Formatting options
			 [ '-O', '--orientation', '=s', \&check_orientation, 'default', 'Portrait or Landscape' ],
			 [ '-x', undef, '=i', \&check_posint, 0, 'Number of pages for width' ],
			 [ '-y', undef, '=i', \&check_posint, 0, 'Number of pages for height' ],
			 ],
			\@ARGV,
			".epssplitrc"
			);

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

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

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

unless( @ARGV == 1 ) {
    print "Sorry, wrong number of arguments\n";
    $opts->usage();
    exit(1);
}

my $main = MainCell->new( shift );

# If the `ps' option wasn't specified, make the default depend on the filename
my $multi;
if( $opts->getopts('ps') eq 'default' ) {
  # special case: stdout gets non-E postscript
  $multi = $opts->getopts('o') =~ /\.eps$/i;
  $opts->setopts( ps => !$multi ); # make sure it's boolean
}
else {
  $multi = !$opts->getopts('ps'); # writing output in multi-file mode
}

# prepare for writing multiple eps files as output; the multiple-file
# naming thing is a hack (particularly since it requires support from
# MainCell), but it was even uglier in 0.6...

if( $multi ) {
  my $o = $opts->getopts('o');
  my ($name, $ext);
  if( $o =~ /^(.*)(\.e?ps)$/ ) {
    $name = $1; $ext = $2;
  }
  else {
    $name = $o; $ext = '.eps';
  }
  my @xy = @{$opts->getopts('format')};
  if( $xy[0] > 36 || $xy[1] > 36 ) {
    print STDERR "Warning: too many files; switching to single-file postscript output";
    $multi = 0;
    $opts->setopts('o' => $name . '.ps');
  }
  else {
    $opts->setopts('o' => $name);
  }
}

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( ! $main->is_done() ) {
  if( $multi ) {
    my ($x, $y) = $main->get_xy();
    my $lst = '0123456789abcdefghijklmnopqrstuvwxyz';
    # note that $x counts the column, $y the row
    my $fname = sprintf( "%s-%s%s%s", $opts->getopts('o'),
			 substr($lst, $y, 1),
			 substr($lst, $x, 1),
			 '.eps');
    # opening a new file on the same handle closes the previous
    unless( open(OUTFILE, ">$fname") )	{
      printf STDERR "Cannot open output file %s for writing\n", $fname;
      exit(5);
    }
    select OUTFILE;
  }
  $main->write();
}

exit(0);



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

sub print_license {
    print STDOUT <<LICENSE;
epssplit Copyright (C) Jens G Jensen 1998-1999.
epssplit 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;
}

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;
}

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

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

sub check_posfloat {
    $_ = shift;
    return $_ if /^\d+\.?\d*$/ || /^\d*\.\d+$/;
    return;
}

# 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;
}
