#!@PERL@
#
# set up the printcap file
# first, read the defaults, if any, from a previous session.

require "getopts.pl";
use FileHandle;


$opt_d = "";
my (@lines, $debug, $f);
$f = select STDOUT; $| = 1; select $f;

&Getopts( 'd' );
$debug = 1 if( $opt_d );

$setup = "./apsfilter.setup";
getvars( $setup );
if($debug){
	print STDERR "previous:\n" if $debug;
	foreach(keys %VAR){
		print STDERR "  $_=$VAR{$_}\n" if $debug;
	}
}
$VAR{"test"} = "testing";

@commprog=(
"/bin/cat -",
"BINDIR/psfilter",
"BINDIR/ifhp" );
@comments=(
"null filter",
"for PostScript Printers",
"for HP PCL or PJL Printers" );

# first, get the available printers
$gs = "@GS@";
@lines = `$gs -h`;
if( $? ){
	print STDERR "$gs failed - $!\n";
	exit 1;
}
# print STDERR "gs output: " . join("",@lines) . "\n" if $debug;

$found = 0;
@devices = ("PS_300 PS_600 PS_1200 (PS_resolution)\n");
foreach( @lines ){
	# print STDERR "found $found, line $_" if $debug;
	if( $found ){
		if( /^[ \t]/ ){
			s/^\s*//;
			push @devices, $_;
		} else {
			last;
		}
	} else {
		$found = 1 if( m/devices/ );
	}
}

print "XX devices:\nXX " . join("XX ", @devices ). "\n" if $debug;

# next, get the available sheet size
$a2ps = "@A2PS@";
@lines = `$a2ps --list-features`;
if( $? ){
	print STDERR "$a2ps failed - $!\n";
	exit 1;
}
# print STDERR "a2ps output: " . join("",@lines) . "\n" if $debug;

$found = 0;
@sheets = ();
foreach( @lines ){
	# print STDERR "found $found, line $_" if $debug;
	if( $found ){
		if( /^[ \t]/ ){
			s/^\s*//;
			push @sheets, $_;
		} else {
			last;
		}
	} else {
		$found = 1 if( m/media/ );
	}
}

print "XX sheets:\nXX " . join("XX ", @sheets ). "\n" if $debug;

@yn = ("yes or 1, no or 0");
@cm = ("color or mono");
$printcap = "printcap.template";
$conf = "apsfilter.conf";
##### - get the name of the printer



$reply = "";
help();
while( !$confirm ) {
	getvalues();
	printvalues();
	$VAR{"y"} = "yes";
	prompt( "do you want to use these values","y",@yn) or finish();
	fixyn("y");
	$confirm = $VAR{"y"};
}
delete($VAR{"y"});
setvars( $setup );


$pc = $printcap;
open( PC, ">$pc" ) or die "cannot open $pc - $!\n";
print PC <<EOF;
# apsfilter printcap template
#  The first part is a list of dummy printcap entries that
#  will be used by client programs
#  The final part is the printcap entry for the server
#
EOF

entry($VAR{"name"}."_raw",$VAR{"name"}, $VAR{"server"}, $VAR{"device"}, $VAR{"papersize"}, "raw","" );
entry($VAR{"name"}."_ascii",$VAR{"name"}, $VAR{"server"}, $VAR{"device"}, $VAR{"papersize"}, "ascii", $VAR{"color"} );
$name = entry($VAR{"name"}."_auto",$VAR{"name"}, $VAR{"server"}, $VAR{"device"}, $VAR{"papersize"}, "auto", $VAR{"color"} );
$name = entry($VAR{"name"},$VAR{"name"}, $VAR{"server"}, $VAR{"device"}, $VAR{"papersize"}, "auto", $VAR{"color"} );

$of = "";
if( $VAR{"commprog_index"} > 1 ){
	$of = "\n  :of=$VAR{commprog}"
}
print PC <<EOF;
#
# This is the server printcap entry
#
$VAR{"name"}|$VAR{"device"} on server $VAR{"server"}
  :server:sh:sf:direct_read:mx#0:ps=status
  :lp=$VAR{"output"}:sd=/usr/spool/lpd/$VAR{"name"}
  :if=BINDIR/apsfilter$of
EOF

close PC or die "cannot close $pc - $!\n";

$pc = $conf;
open( PC, ">$pc" ) or die "cannot open $pc - $!\n";
print PC <<EOF;
# apsfilter.conf - default values
#  PATH environment variables
# PATH = $ENV{PATH}
# a2ps = a2ps -q -R -1 -m -B
# 
# commprog=BINDIR/psfilter
# commprog=BINDIR/ifhp
rewindstdin = BINDIR/rewindstdin
$VAR{"name"}\.printer = $name
$VAR{"name"}\.allow_pcl = $VAR{"allow_pcl"}
$VAR{"name"}\.res = $VAR{"resolution"}
$VAR{"name"}\.commprog = $VAR{"commprog"}
EOF

close PC or die "cannot close $pc - $!\n";

print <<EOF;

Generated the $printcap and $conf files.
Please add the $printcap values to the /etc/printcap file
and copy the $conf to the print spool directory.
EOF

exit 0;

sub finish {
	setvars( $setup );
	exit 0;
}

sub getvars {
	my ($default) = @_;
	my (@lines, $var, $value );
	if( -f $default and -r $default ){
		if( !open( FILE, $default ) ){
			print STDERR "$0: cannot open '$default' - $!\n" if $debug;
			exit $JABORT;
		}
		while(<FILE>){
			chomp;
			print STDERR "getvars: read '$_'\n" if $debug;
			next if( /^\s*#/ );
			($var,$value) = /\s*(.*?)[=\s]+(.*)/;
			if( $value ){
				$VAR{$var} = $value;
			} else {
				delete($VAR{$var});
			}
			print STDERR "getvars: $var='$value'\n" if $debug;
		}
		if( !close(FILE) ){
			print STDERR "cannot close $default - $!\n" if $debug;
			exit $JABORT;
		}
	}
}

sub setvars {
	my ($default) = @_;
	my (@lines, $var, $value );
	if( !open( FILE, ">$default" ) ){
		print STDERR "$0: cannot open '$default' - $!\n" if $debug;
		exit $JABORT;
	}
	foreach( keys %VAR ){
		print STDERR "setvars: $_='$VAR{$_}'\n" if $debug;
		print FILE "$_=$VAR{$_}\n" or die "cannot write $default - $!\n";
	}
	if( !close(FILE) ){
		print STDERR "cannot close $default - $!\n" if $debug;
		exit $JABORT;
	}
}

sub prompt {
	my ($prompt, $key, @list ) = @_;
	my ($reply, $default);
	$reply = $default = "";
	$default = $VAR{$key} if( $VAR{$key} );
	print STDERR "prompt '$prompt' for '$key'\n" if $debug;
	while( !$reply ){
		print STDOUT "$prompt\?";
		if( @list ){
			print STDOUT "\n choices:\n";
			foreach(@list){
				print STDOUT "    $_";
			}
		}
		print STDOUT " default[$default]: ";
		$reply = <STDIN>;
		if( !defined( $reply ) ){
			return $reply;
		}
		chomp $reply;
		if( $reply eq "?" or $reply eq "help" ){
			help();
			$reply = "";
			next;
		}
		if( $reply eq "" and $default ){
			$reply = $default;
		}
		if( @list ){
			@match = grep(m/$reply/,@list);
			print STDERR "matches @match\n" if $debug;
			if( !@match ){
				print STDOUT "value '$reply' not in list\n";
				$reply = "";
			}
		}
	}
	$VAR{$key} = $reply;
	setvars( $setup ) if $reply;
	$reply;
}

sub entry{
	my ($pr_name, $pr, $host, $device, $papersize, $auto, $color ) = @_;
	my ($c, $name);
	$c = "";
	$c = "-$color" if( $color );
	$color = ", $color" if( $color );
	$name="aps-${device}-${papersize}-${auto}${c}";
	print PC <<EOF;
#
# $auto printer
#
$pr_name|$device, papersize $papersize, selection $auto$color
  :qq:lp=$pr\@$host:force_queuename=$name
EOF
	$name;
}

sub help {
print <<EOF;
This program will set up $printcap and $conf.
The $printcap file contains a printcap entry suitable for use with
LPRng,  and should be added to the /etc/printcap file for use.
The $conf file contains some default configuration information,
and should be put in the spool queue directory for the printer.

In order to set things up,  you will need to provide:
1. The name of the spool queue for the printer.
   This will be used to generate printcap entries)
2. The type of the printer (i.e. - laserjet, etc).
   This is used to set up the conversion programs
3. The paper size (letter, legal, etc) to be used on the printer
   This is used to set up the conversion programs
4. Whether the printer is color or mono (black/white)
   This is used to set up graphic to raster conversion programs
5. Whether the printer directly supports HP PCL.
   If your printer supports PCL,  then you should specify this as true.
   This sets up entries in the $conf file, to allow auto mode to send
   the file directly to the printer.
6. The host name of the server for the print spool queue.
   Used to set up the printcap entries for client (lpr, lpq, ...)
   programs.
7. The output device or remote printer name for the output queue.
   Used to set up the server printcap information.

If you answer '?' or 'help' to any prompt during this process,
you will get the above information repeated.
EOF
}

sub fixyn {
	my ($n) = @_;
	my ($v);
	$v = $VAR{$n};
	if( $v =~ /y/ or $v =~ /1/){
		$VAR{$n} = "1";
	} else {
		$VAR{$n} = "0";
	}
}
sub getvalues {
	prompt( "printer name","name" ) or finish();
	prompt( "device","device",@devices ) or finish();
	$device = $VAR{"device"};
	if( $device =~ /PS_([0-9]*)/ ){
		$VAR{"resolution"} = $1;
		print "device resoluton $1\n";
	} else {
		prompt("device resolution (e.g.- 300 for 300dpi)", "resolution") or finish();
	}
	prompt( "paper size","papersize",@sheets ) or finish();
	prompt( "color or mono","color",@cm ) or finish();
	prompt( "allow PCL","allow_pcl",@yn ) or finish();
	fixyn( "allow_pcl" );
	prompt( "host name of server for queue","server" ) or finish();
	print <<EOF;
	You now need to specify the server output device.
	This can be:
       a pathname to a device (/dev/lp)
       a remote printer name (pr\@hostname)
       a network port (host%port)
    If you specify a serial port, you will have to add :sy: serial
    port configuration options to the printcap entry.  If you have
    a bidirectional device or network connection,  then you may want
    to use a communications program to support interaction with the
    device.
EOF
	prompt( "output device","output") or finish();

	$output = $VAR{"output"};
    if( $output =~ /@/ ){
       $VAR{"commprog_index"} = 1;
	} else {
		print <<EOF;
	You now need to specify a program that will send the output
    to the printer.  This value will be put in the $conf file
    as the commprog entry.  By default, this value is '/bin/cat -'.
    If you have a network or serial printer printer, you can
    use the other filters.  These provide various levels of support
    for printer specific options;  see the appropriate documentation.
    The choices offered are:
EOF
		@list = ();
		for($i = 0; $i < @commprog; ++$i ){
			print sprintf("%d %-20s %s\n", $i+1,
				$commprog[$i], $comments[$i] );
			push(@list, $i+1 );
		}
		prompt("communications program","commprog_index",@list);
	}
	$VAR{"commprog"} = $commprog[ $VAR{"commprog_index"}-1 ];
	setvars( $setup );
}

sub printvalues {
	print "\n\nCurrent Values:\n";
	showv("name");
	showv("device");
	showv("resolution");
	showv("papersize");
	showv("color");
	showv("allow_pcl");
	showv("server");
	showv("output");
	showv("commprog");
	print "\n";
}

sub showv {
	my ($v) = @_;
	print sprintf("%-10s %s\n", $v, $VAR{$v} );
}
