#!/bin/sh

#* Copyright (C) 2003-2006  Rick Richardson
#*
#* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#*
#* Authors: Rick Richardson <rick.richardson@comcast.net>

VERSION='$Id: foo2qpdl-wrapper.in,v 1.15 2007/06/11 00:48:32 rick Exp $'

#
# Printer Notes:
#
# Samsung CLP-300
# Samsung CLP-600
# Samsung CLX-3160
# Xerox Phaser 6110
#

PROGNAME="$0"
BASENAME=`basename $PROGNAME`
PREFIX=/usr
SHARE=$PREFIX/share/foo2qpdl
PATH=$PATH:/sw/bin:/opt/local/bin

#
#	Log the command line, for debugging and problem reports
#
if [ -x /usr/bin/logger ]; then
    logger -t "$BASENAME" -p lpr.info -- "$BASENAME $@" </dev/null
fi

usage() {
	cat <<EOF
Usage:
	$BASENAME [options] [ps-file]

	Foomatic printer wrapper for the foo2qpdl printer driver.
	This script reads a Postscript ps-file or standard input
	and converts it to a Samsung QPDL stream (CLP-600).

Normal Options:
-c                Print in color (else monochrome)
-d duplex         Duplex code to send to printer [$DUPLEX]
                    1=off, 2=longedge, 3=shortedge
-m media          Media code to send to printer [$MEDIA]
                    1=standard, 2=transparency, 3=glossy, 257=envelope,
                    259=letterhead, 261=thickstock, 262=postcard, 263=labels
-p paper          Paper code [$PAPER]
                    0=letter, 5=legal, 7=executive, 9=A4, 11=A5, 13=B5
                    20=env#10, 27=envDL 28=envC5 34=envB5 37=envMonarch
-n copies         Number of copies [$COPIES]
-r <xres>x<yres>  Set device resolution in pixels/inch [$RES]
-s source         Source code to send to printer [$SOURCE]
                    1=upper, 2=lower, 4=manual, 7=auto
		    Code numbers may vary with printer model.
-t                Draft mode.  Every other pixel is white.
-2/-3/-4/-6/-8/-10/-12/-14/-15/-16/-18
                  Print with N-up (requires psutils)
-o orient         For N-up: -op is portrait, -ol is landscape, -os is seascape.

Printer Tweaking Options:
-u <xoff>x<yoff>  Set offset of upper left printable in pixels [varies]
-l <xoff>x<yoff>  Set offset of lower right printable in pixels [varies]
-L mask           Send logical clipping values from -u/-l in ZjStream [3]
                  0=no, 1=Y, 2=X, 3=XY
-P                Do not output START_PLANE codes.  May be needed by some
                  monochrome-only printers.
-X padlen         Add extra zero padding to the end of BID segments [16]
-z model          Model: 0=CLP-300 1=CLP-600

Color Tweaking Options:
-g gsopts         Additional options to pass to Ghostscript, such as
                  -dDITHERPPI=nnn, etc.  May appear more than once. []
-G profile.icm    Convert profile.icm to a Postscript CRD using icc2ps and
                  adjust colors using the setcolorrendering PS operator.
                  $SHARE/icm/ will be searched for profile.icm.
-I intent         Select profile intent from ICM file [$INTENT]
                  0=Perceptual, 1=Colorimetric, 2=Saturation, 3=Absolute
-G gamma-file.ps  Prepend gamma-file to the Postscript input to perform
                  color correction using the setcolortransfer PS operator.

Debugging Options:
-S plane          Output just a single color plane from a color print [all]
                  1=Cyan, 2=Magenta, 3=Yellow, 4=Black
-D lvl            Set Debug level [$DEBUG]
-V                $VERSION
EOF

	exit 1
}

#
#       Report an error and exit
#
error() {
	echo "$BASENAME: $1" >&2
	exit 1
}

dbgcmd() {
	if [ $DEBUG -ge 1 ]; then
	    echo "$@" >&2
	fi
	"$@"
}

#
#	N-up-ify the job.  Requires psnup from psutils package
#
nup() {
    case "$NUP" in
    [2368]|1[0458])
	tr '\r' '\n' | psnup $NUP_ORIENT -d2 -$NUP -m.3in -p$paper -q
	;;
    [49]|1[26])
	tr '\r' '\n' | psnup $NUP_ORIENT -d2 -$NUP -m.5in -p$paper -q
	;;
    *)
	error "Illegal call to nup()."
	;;
    esac
}

#
#       Process the options
#

# Try to use a local copy of GhostScript 8.54, if available.  Otherwise,
# fallback to whatever the Linux distro has installed (usually 7.07)
#
# N.B. := operator used here, when :- would be better, because "ash"
# doesn't have :-
if gs8 -v >/dev/null 2>&1; then
        GSBIN=${GSBIN:-gs8}
else
        GSBIN=${GSBIN:-gs}
fi

CMDLINE="$*"
DEBUG=0
DUPLEX=1
COLOR=
COLORMODE=default
MODEL=0
QUALITY=1
QUALITY=wts
MEDIA=0
COPIES=1
PAPER=0
RES=1200x600
SOURCE=1
NUP=
CLIP_UL=
CLIP_LR=
CLIP_LOG=
BC=
AIB=
NOPLANES=
COLOR2MONO=
GAMMAFILE=default
INTENT=0
GSOPTS=
EXTRAPAD=
SAVETONER=
NUP_ORIENT=
GSDEV=-sDEVICE=pbmraw
# What mode to use if the user wants us to pick the "best" mode
case `$GSBIN --version` in
7*)	DEFAULTCOLORMODE=10
	DEFAULTCOLORMODE=1
	;;
*)	DEFAULTCOLORMODE=1
	;;
esac
while getopts "1:23456789o:b:cC:d:g:l:u:L:m:n:p:q:r:s:tz:ABS:D:G:I:PX:Vh?" opt
do
	case $opt in
	b)	GSBIN="$OPTARG";;
	c)	COLOR=-c;;
	d)	DUPLEX="$OPTARG";;
	g)	GSOPTS="$GSOPTS $OPTARG";;
	m)	MEDIA="$OPTARG";;
	n)	COPIES="$OPTARG";;
	p)	PAPER="$OPTARG";;
	q)	QUALITY="$OPTARG";;
	r)	RES="$OPTARG";;
	s)	SOURCE="$OPTARG";;
	t)	SAVETONER="-t";;
	z)	MODEL="$OPTARG";;
	l)	CLIP_LR="-l $OPTARG";;
	u)	CLIP_UL="-u $OPTARG";;
	L)	CLIP_LOG="-L $OPTARG";;
	A)	AIB=-A;;
	B)	BC=-B;;
	C)	COLORMODE="$OPTARG";;
	S)	COLOR2MONO="-S$OPTARG";;
	D)	DEBUG="$OPTARG";;
	G)	GAMMAFILE="$OPTARG";;
	I)	INTENT="$OPTARG";;
	P)	NOPLANES=-P;;
	X)	EXTRAPAD="-X $OPTARG";;
	[234689])	NUP="$opt";;
	[57])	error "Can't find acceptable layout for $opt-up";;
	1)	case "$OPTARG" in
		[024568])	NUP="1$OPTARG";;
		*)	error "Can't find acceptable layout for 1$OPTARG-up";;
		esac
		;;
	o)	case "$OPTARG" in
		l*)	NUP_ORIENT=-l;;
		s*)	NUP_ORIENT=-r;;
		p*|*)	NUP_ORIENT=;;
		esac;;
	V)	echo "$VERSION"; foo2qpdl -V; exit 0;;
	h|\?)
		if [ "$CMDLINE" != "-?" -a "$CMDLINE" != -h ]; then
		    echo "Illegal command:"
		    echo "	$0 $CMDLINE"
		    echo
		fi
		usage;;
	esac
done
shift `expr $OPTIND - 1`

#
# If there is an argument left, take it as the file to print.
# Else, the input comes from stdin.
#
if [ $# -ge 1 ]; then
    if [ "$LPJOB" = "" ]; then
	: # LPJOB="$1"
    fi
    exec < $1
fi

#
case "$QUALITY" in
0)
    GSOPTS="-dCOLORSCREEN $GSOPTS"
    ;;
1)
    GSOPTS="-dCOLORSCREEN $GSOPTS"
    ;;
2)
    GSOPTS="-dMaxBitMap=500000000 $GSOPTS"
    ;;
wts)
    GSOPTS="-dCOLORSCREEN $GSOPTS"
    ;;
esac

#
#	Validate model code
#
case "$MODEL" in
0|1)	;;
*)	error "Unknown model code $MODEL";;
esac

#
#	Validate media code
#
case "$MEDIA" in
0|plain)	MEDIA=0;;
1|thick)	MEDIA=1;;
2|thin)		MEDIA=2;;
3|bond)		MEDIA=3;;
4|color)	MEDIA=4;;
5|card)		MEDIA=5;;
6|labels)	MEDIA=6;;
7|envelope)	MEDIA=7;;
8|preprinted)	MEDIA=8;;
9|cotton)	MEDIA=9;;
10|recycled)	MEDIA=10;;
[0-9]*)		;;
*)		error "Unknown media code $MEDIA";;
esac

#
#	Validate source (InputSlot) code
#
case "$SOURCE" in
1|auto)		SOURCE=1;;
2|manual)	SOURCE=2;;
3|multi)	SOURCE=3;;
4|tray1)	SOURCE=4;;
[0-9]*)		;;
*)		error "Unknown source code $SOURCE";;
esac

#
#	Validate Duplex code
#
case "$DUPLEX" in
1|off|none)	DUPLEX=1;;
2|long*)	DUPLEX=2;;
3|short*)	DUPLEX=3;;
[0-9]*)		;;
*)		error "Unknown duplex code $DUPLEX";;
esac

#
#	Validate Resolution
#
case "$RES" in
600x600)	;;
1200x600)	;;
1200x1200)	;;
*)		error "Illegal resolution $RES";;
esac

#
#	Figure out the paper dimensions in pixels/inch, and set the
#	default clipping region.  Unfortunately, this is a trouble
#	area for ZjStream printers.  Various versions of ZjS print
#	engines react differently when asked to print into their
#	unprintable regions.
#
set_clipping() {
    ulx=$1; uly=$2
    lrx=$3; lry=$4

    # Set clipping region if it isn't already set
    if [ "$CLIP_UL" = "" ]; then
	case "$RES" in
	600x600)	ulx=`expr $ulx / 2`;;
	2400x600)	ulx=`expr $ulx \* 2`;;
	esac
	CLIP_UL="-u ${ulx}x${uly}"
    fi
    if [ "$CLIP_LR" = "" ]; then
	case "$RES" in
	600x600)	lrx=`expr $lrx / 2`;;
	2400x600)	lrx=`expr $lrx \* 2`;;
	esac
	CLIP_LR="-l ${lrx}x${lry}"
    fi
}

case "$PAPER" in
Custom*)
		#%%BeginFeature: *CustomPageSize True
		#216
		#360
		#0
		#0
		#0
		#pop pop pop pop pop

		TMPFILE=/tmp/cus$$
		cat >$TMPFILE
		exec <$TMPFILE

		XDIM=`head -n 1000 $TMPFILE | sed -n '/CustomPageSize/{n;p;}'`
		case "$XDIM" in
		""|0*)
		    rm -f $TMPFILE
		    error "Custom page size XDIM != 1-99999"
		    ;;
		esac
		XDIM=`dc -e "$XDIM 1200* 72/p"`

		YDIM=`head -n 1000 $TMPFILE | sed -n '/CustomPageSize/{n;n;p;}'`
		case "$YDIM" in
		""|0*)
		    rm -f $TMPFILE
		    error "Custom page size YDIM != 1-99999"
		    ;;
		esac
		YDIM=`dc -e "$YDIM 600* 72/p"`
		PAPER=21;        paper=letter;
                set_clipping 2 100     2 100
		;;
0|letter)	PAPER=0;	paper=letter;    XDIM="10200"; YDIM="6600"
		set_clipping 150 100	150 100
		;;
1|legal)	PAPER=1;	paper=legal;     XDIM="10200"; YDIM="8400"
		set_clipping 150 100	150 100
		;;
3|executive)	PAPER=3;	paper=executive; XDIM="8700";  YDIM="6300"
		set_clipping 150 100	150 100
		;;
2|a4|A4)	PAPER=2;	paper=a4;        XDIM="9920";  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set_clipping ;  YDIM="7016"
		set_clipping 150 100	150 100
		;;
16|a5|A5)	PAPER=16;	paper=a5;        XDIM="6992";  YDIM="4960"
		set