#!/usr/bin/perl
# ************************************************************ #
# NAME: psmulti
# PURPOSE: Script for combining multiple postscript images
#    in an n-up fashion.
#
# NOTES: 
# SCCS: @(#)psmulti.pl	2.6 5/26/92
# HISTORY:
#       murray - Feb 19, 1992: Created.
#       murray - Mar 23, 1992: Tidied up the overall structure
#           of the program.
# ************************************************************ #

# ##################################################################### #
# (C) 1992 D Murray Laing, D.M.Laing@uk.ac.edinburgh
#          c/o Department of Chemical Engineering,
#              University of Edinburgh,
#              Edinburgh,
#              Scotland
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License version 2 as
#    published by the Free Software Foundation.
# 
#    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.
# ###################################################################### #

# ============================================================ #
# Set Up PSMulti Search Paths
# ============================================================ #

@DefaultPSMultiLibPath=( "/usr/lib/psmulti" );

if ( defined $ENV{PSMULTILIBPATH} )
  { unshift(@INC,split(/:/,$ENV{PSMULTILIBPATH}));
    @PSPPIncludePath=split(/:/, $ENV{PSMULTILIBPATH});
  }
else
  { unshift(@INC,@DefaultPSMultiLibPath);
    @PSPPIncludePath=@DefaultPSMultiLibPath;
  }

%StandardBBox=( 'page', '/Default',
                'a5',     '20 20 401 574'   ,
                'a4',     '20 20 574 822'   ,
                'a3',     '20 20 822 1168'  ,
                'a2',     '20 20 1168 1664' ,
                'letter', '18 3 594 789'  ,
                'note',   '29 30 583 761' ,
                'legal',  '64 36 548 972'
              );

# ============================================================ #
#             Error Handling Routine
# ============================================================ #

if ( $0 =~ m|.*/([^/]*)| )
   { $ProgName=$1; }
else
   { $ProgName=$0; }

sub error
  {
    print STDERR "$ProgName: @_\n";
    exit 1;
  }

sub warning
  {
    print STDERR "$ProgName: @_\n";
  }

sub info
  {
     if ( defined $verbose ) { print STDERR "$ProgName: @_\n"; }
  }


# ============================================================ #
#                    Argument Processing
# ============================================================ #
  

# Global Multi Options #
$File="Default";

while( $#ARGV >= 0 )
  {
    $_=splice(@ARGV,0,1);
    
    # Debugging #
    if ( /^-v/ )  { $verbose="1"; }

    # Output File #
    elsif ( /^-o/ ) {$OutFile=splice(@ARGV,0,1); }

    # ---------------------------------------- #
    #        Global Multi Options
    # ---------------------------------------- #

    elsif ( /^-style$/ || /^-border$/ )
      { $Global{Style}=splice(@ARGV,0,1); }
    
    elsif ( /^-format$/ )   { $Global{Format}=splice(@ARGV,0,1); }

    elsif ( /^-nodecor/ ) { $NoDecor{$File} = "true"; }
    elsif ( /^-decor/ )   { $NoDecor{$File} = "false"; }


    elsif ( /^-pages/ ) 
      { if ( $ARGV[0] =~ /^\d+$/ )
          { $Global{Pages}=splice(@ARGV,0,1); }
        else
          { &error("Incorrect Pages Specification"); }
      }

    elsif ( /^-geom/ )
      { if ( $ARGV[0] =~ /^([0-9]+)x([0-9]+)$/ )
          { $Global{Columns}=$1; $Global{Rows} = $2; }
        else
          { &error("Incorrect Geometry Specification"); }
        shift ARGV;
      }

    elsif ( /^-rmajor/ ) { $Global{'RowMajor'}="true"; }
    elsif ( /^-cmajor/ ) { $Global{'RowMajor'}="false"; }
    elsif ( /^-ttob/ )   { $Global{'TtoB'}="true"; }
    elsif ( /^-btot/ )   { $Global{'TtoB'}="false"; }
    elsif ( /^-ltor/ )   { $Global{'LtoR'}="true"; }
    elsif ( /^-rtol/ )   { $Global{'LtoR'}="false"; }
  
    elsif ( /^-pbbox/ )
      {
        if ( defined $StandardBBox{"$ARGV[0]"} )
          { $Global{FPageBBox}=$StandardBBox{"$ARGV[0]"};
            shift @ARGV;
          }

        elsif ( $ARGV[0] =~ /^-?\d+$/ && $ARGV[1] =~ /^-?\d+$/ &&
                $ARGV[2] =~ /^-?\d+$/ && $ARGV[3] =~ /^-?\d+$/
              )
          { $Global{PageBBox}=join(' ',splice(@ARGV,0,4)); }

        else
          { &error("Incorrect Page BBox Specification" ); }
      }
    
    # ---------------------------------------- #
    #       Document Specific Options
    # ---------------------------------------- #

    # Margin #
    elsif ( /^-m(-?[0-9\.]+)/ )
       { $MarginX{$File}=$1; $MarginY{$File}=$1; }
    elsif ( /^-m$/ )
      { if ( $ARGV[0] =~ /^-?[0-9\.]+$/ && $ARGV[1] =~ /^-?[0-9\.]+$/ )
          { ($MarginX{$File}, $MarginY{$File})=splice(@ARGV,0,2); }
        else
          { &error("Incorrect Margin Specification"); }
      }

    # Scaling #
    
    elsif ( /^-s(-?[0-9\.]+)$/ ) { $ScaleX{$File}=$1; $ScaleY{$File}=$1; }
    elsif ( /^-s$/ )
      { ($ScaleX{$File},$ScaleY{$File})=splice(@ARGV,0,2); }

    elsif ( /^-maxpect/ )  { $ScaleX{$File}='/Ratio';
                             $ScaleY{$File}='/Ratio';
                           }
    elsif ( /^-maxxy/ )    { $ScaleX{$File}='/Max';
                             $ScaleY{$File}='/Max';
                           }
    elsif ( /^-maxx$/ )    { $ScaleX{$File}='/Max'; }
    elsif ( /^-maxy$/ )    { $ScaleY{$File}='/Max'; }

    # Justification #

    elsif( /^-j/ )
      { ($JustX{$File},$JustY{$File})=splice(@ARGV,0,2); }

    elsif( /^-centerx/ )  { $JustX{$File}='/Center'; }
    elsif( /^-centery/ )  { $JustY{$File}='/Center'; }
    elsif( /^-left/ )     { $JustX{$File}='/Left'; }
    elsif( /^-right/ )    { $JustX{$File}='/Right'; }
    elsif( /^-top/ )      { $JustX{$File}='/Top'; }
    elsif( /^-bottom/ )   { $JustX{$File}='/Bottom'; }

    
    elsif ( /^-maxxy/ )   { $MaxXY{$File} = "true"; }
    elsif ( /^-maxpect/ ) { $MaxXY{$File} = "false"; }

    elsif ( /^-eps/ )     { $EPSDoc{$File} = "true"; }
    elsif ( /^-neps/ )    { $EPSDoc{$File} = "false"; }
    
    elsif ( /^-ibbox/ )
      { if    ( defined $StandardBBox{"$ARGV[0]"} )
          { $ImageBBox{$File}= $StandardBBox{"$ARGV[0]"};
            shift ARGV;
          }
        elsif ( $ARGV[0] eq "dsc" )
          { $ImageBBox{$File}='dsc';
            shift ARGV;
          }
        elsif ( $ARGV[0] =~ /^-?\d+$/ && $ARGV[1] =~ /^-?\d+$/ &&
                $ARGV[2] =~ /^-?\d+$/ && $ARGV[3] =~ /^-?\d+$/
              )
          { $ImageBBox{$File}=join(' ',splice(ARGV,0,4)); }
        else
          { &error("Incorrect Image BBox Specification" ); }
      }
    
    elsif ( /^-l$/ )
      {
        if ( ! defined $Rotate{$File} )
          { $Rotate{$File}="-90"; }
        if ( ! defined $Global{LtoR} )
          { $Global{LtoR}='false'; }
        if ( ! defined $Global{RowMajor} )
          { $Global{RowMajor}='false'; }
      }
    
    elsif ( /^-p$/ )
      {
        if ( ! defined $Rotate{$File} )
          { $Rotate{$File}="0"; }
        if ( ! defined $Global{LtoR} )
          { $Global{LtoR}='true'; }
        if ( ! defined $Global{RowMajor} )
          { $Global{RowMajor}='true'; }
      }

    elsif ( /^-r(-?[0-9\.]+)/ ) { $Rotate{$File}=$1; }
    elsif ( /^-r/ )
      { if ( $ARGV[0] =~ /^-?[0-9\.]+$/ )
          { $Rotate{$File}=$ARGV[0]; }
        else
          { &error("Incorrect Rotation Specification"); }
      }

    # Arguments Related to Page Selection and Ordering #
    elsif ( /^-reverse/ )
      { $ReversePages{$File}=1; }
    elsif ( /^-noreverse/ )
      { $ReversePages{$File}=0; }

    elsif (/^-select/ )
      { $_=splice(@ARGV,0,1);
        if ( /^ordinal/ ) 
          { $SelectBy{$File}="PageOrdinal"; 
            $SelectPages{$File}=splice(@ARGV,0,1);
          }
        elsif (  /^label/ )
          { $SelectBy{$File}="PageLabel";
            $SelectPages{$File}=splice(@ARGV,0,1);
          }
        else 
          { $SelectBy{$File}="PageOrdinal";
            $SelectPages{$File}=$_;
          }

      }

    # Deal with a file #
    elsif ( /^-$/ )
      { if ( defined $StdinTmpFile )
          { $File = $StdinTmpFile; }
        else
          { require "file-util.pl";
            if ( ($File = &stdin_to_tmp("/tmp/$ProgName")) )
              { $StdinTmpFile=$File; }
            else
              { &error($@); }
          }
        push(@FileList, $File);
      }

    elsif ( -f )
      { if ( -r )
          { $File=$_;
            push(@FileList, $File);
          }
        else
          { &error("Cannot read file $File"); }
      }
    
    # Unknown Argument #
    else
      { &error("Unknown file/argument: $_"); }

  }


if( $#FileList < 0 )
  { require "file-util.pl";
    if ( ($StdinTmpFile=&stdin_to_tmp("/tmp/$ProgName")) )
      { push(@FileList, $StdinTmpFile); }
    else
      { &error($@); }
  }
    


if ( ! defined $Global{Format} )
  { $Global{Format}="standard"; }

eval "require \"format-$Global{Format}.pl\"" || &error($@);

# Clean Up Any Temporary Files #

unlink $StdinTmpFile if ( defined $StdinTmpFile && -f $StdinTmpFile );

1;
