#!/usr/bin/perl -w
# ===============================================================================
# oopstops	prefilter to sanitize PostScript jobs generated by OpenOffice 2.x
# -------------------------------------------------------------------------------
# 1.00 - 2007-03-17/Bl
#	First implementation
#
#  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.
#
# Description:
# ------------
#	OpenOffice as of version 2.x has built-in CUPS support, parses
#	the user selectable options in the printer's PPD and inserts the respecitve
#	PostScript code into the PostScript job. However, it does not insert all 
#	defined defaults nor the JCL settings, but it does honour the JobPatchFile
#	keyword. In addition, if a default setting in the PPD does not correspond
#	to one of the choices listed in the respective UI block, OpenOffice silently 
#	selects the first choice (NOTE: this cannot be corrected by this filter).
#	Moreover, the page related features are inserted into the page setup section
#	of the first page. This violates the page independence and prohibits successful
#	working of job attivutes like number-up or same-up.
#
#	We therefore modify the PostScript job as follows:
#	- any JobPatchFile features are discaarded, as they are re-inserted by the 
#	  pstops filter.
#	- the first page's page setup is moved to the end of the general setup section
#	  (in fact, the respective comments are moved instead).



use IO::Handle;

#
# Check the arguments
#
die ("ERROR: wrong number of arguments\n") if (scalar @ARGV < 5);

$jobid = $username = $title = $copies = $options = undef;
$jobid = shift;				# Job ID
$username = shift;			# Job requesting user name
$title = shift;				# Job title
$copies = shift;			# Number of requested copies
$options = shift;			# Textual representation of job attributes
$psfile = shift;			# read from file ?


#
# Normalize options string
#
$options =~ s/^\s+//;
$options =~ s/\s+$//;
$options = ' ' . $options . ' ';

#
# Check from where to read
#
if (defined $psfile)
{
	open (FILI, "<$psfile") || die ("ERROR: $psfile: $!\n");
}
else
{
	open (FILI, "<&STDIN") || die ("ERROR: STDIN: $!\n");
}

# STDOUT->autoflush (1);

#
# Parse the input until and including the page setup of the first page
# and relocate the setup features to the end of the setup section.
#
@feature = ();
$within_feature = 0;
$feature_name = '';
$saw_page = 0;
@pagehead = ();

while (<FILI>)
{
	if (/^\[\{/)
	{
		push (@feature, $_);
		$_ = <FILI>;
		if (/^%%BeginFeature:\s+\*(\S+)\s+/)
		{
			$feature_name = $1;
			push (@feature, $_);
			$within_feature = 1;
			next;
		}
		else
		{
			print STDOUT shift @feature;
			print STDOUT;
		}
		next;
	}
	if (/^%%EndFeature/)
	{
		if ($within_feature)
		{
			push (@feature, $_);
			$_ = <FILI>;
			if (/^\}\s+stopped\s+cleartomark/)
			{
				push (@feature, $_);
			}
			else
			{
				$next_line = $_;
			}
			if ($feature_name eq 'JobPatchFile')
			{
				@feature = ();		# discard the job patch file(s)
			}
			$within_feature = 0;
			print STDOUT $next_line if (defined $next_line && $next_line);
		}
		else
		{
			print STDOUT;
		}
		next;
	}
	next if (/^%%EndSetup/);
	if (/^%%Page:/)
	{
		$saw_page = 1;
		push (@pagehead, $_);
		next;
	}
	if (/^%%EndPageSetup/)
	{
		push (@pagehead, $_);
		if (scalar @feature > 0)
		{
			while (my $line = shift @feature)
			{
				print STDOUT $line;
			}
			$feature_name = '';
		}
		print STDOUT "%%EndSetup\n";
		while (my $line = shift @pagehead)
		{
			print STDOUT $line;
		}
		$saw_page = 0;
		last;
	}
	next if (/^<< \/NumCopies null /);		# skip the copies hack because of Ghostscript quirks
	if ($within_feature)
	{
		push (@feature, $_);
	}
	elsif ($saw_page)
	{
		push (@pagehead, $_);
	}
	else
	{
		print STDOUT;
	}
}

#
# Now copy the rest without further interpretation
#
while (<FILI>)
{
	print STDOUT;
}

close (FILI) if (defined $psfile);


