#!/usr/bin/perl -w

#     Copyright 2006 Nickolay Kondrashov
# 
#    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

use strict;

use Text::Iconv;

my $CONFIG_PATH = "/etc/cups/pstitleiconv.conf";
### CONFIGURATION ##############################

# set default configuration parameters
my $FROMCODE='ascii';
my $TOCODE='utf-8';

# read config file contents
my $CONFIG_CONTENTS;
{
	local $/;
	open( CONFIG, $CONFIG_PATH ) or
		die "ERROR: Failed to open config file $CONFIG_PATH: $!\n";
	$CONFIG_CONTENTS = <CONFIG>;
	close( CONFIG ) or
		die "ERROR: Failed to close config file $CONFIG_PATH: $!\n";
}

# eval config file contents
eval $CONFIG_CONTENTS;
if( $@ ) {
	die "ERROR: Failed to evaluate config file contents: $@\n"
}

### SUBS #######################################

sub try_decode_ps_hex_string
{
	my( $string ) = @_;
	if( $string =~ m/^<[0-9a-fA-F \t]*>$/ ) {
		$string =~ tr/ \t<>//d;	# remove whitespace and brackets
		$string = pack( 'H*', $string );
	}
	return $string;
}

sub encode_ps_hex_string
{
	my( $string ) = @_;
	return '<'. uc( unpack( 'H*', $string ) ). '>';
}

sub convert_title
{
	my( $converter, $original_title ) = @_;
	warn "DEBUG: decoding title: $original_title\n";
	my $decoded_title = try_decode_ps_hex_string( $original_title );
	warn "DEBUG: converting title: $decoded_title\n";
	my $converted_title = $converter->convert( $decoded_title );
	unless( defined $converted_title ) {
		warn "WARNING: failed to convert title, leaving as is.\n";
		return $original_title;
	}
	warn "DEBUG: encoding title: $converted_title\n";
	my $encoded_title = encode_ps_hex_string( $converted_title );
	warn "DEBUG: encoded title: $encoded_title\n";
	return $encoded_title;
}

### MAIN #######################################

my( $printer, $jobid, $username, $title, $copies, $options, $filename ) = @_;

my $fh;

if( defined $filename ) {
	open( $fh, $filename ) or
		die "ERROR: Failed to open $filename: $!\n";
} else {
	$fh = *STDIN;
}

my $converter = new Text::Iconv( $FROMCODE, $TOCODE );

my $rec_depth = 0;
my $got_title = 0;

while( <$fh> ) {
	if( m/^\%!/ ) {
		if( $rec_depth == 0 ) {
			warn "DEBUG: found beginning of postscript code: $_\n";
		} else {
			warn "DEBUG: found beginning of embedded (e)ps code: $_\n";
		}
		$rec_depth++;
	} elsif( m/^\%\%EOF/ ) {
		$rec_depth--;
		if( $rec_depth == 0 ) {
			warn "DEBUG: found end of postscript code: $_\n";
		} elsif( $rec_depth > 0 ) {
			warn "DEBUG: found end of embedded (e)ps code: $_\n";
		} else {
			warn "WARNING: found unexpected end of ps code: $_\n";
		}
	} elsif(
		$rec_depth == 1 &&
		! $got_title &&
		s/^\%\%Title: ([^\r\n]*)(\r?\n?)$/
			"\%\%Title: ".
			convert_title( $converter, $1 ).
			$2
		/e
	) {
		warn "DEBUG: title converted\n";
		$got_title = 1;
	}
	print;
}

close $fh;
