#!/usr/bin/perl

# This script updates the printer list of the driver XML file of
# Gutenprint (db/source/driver/gutenprint.xml in foomatic-db package)
# according to the file src/foomatic/foomatic-printermap of the source
# tarball of Gutenprint 5.0.x or later.
#
# Remarks:
#
# - Manually added printer entries will not be removed. They drop out
#   to the beginning of the printer list during the update. The same
#   happens to printers which are removed from the new foomatic-printermap
#
# - All printers of foomatic-printermap are put to the end of the list,
#   the order of foomatic-printermap is preserved.
#
# - The user will be informed by screen messages if the new
#   foomatic-printermap contains new printers which were neither in the
#   previous foomatic-printermap nor under the manually added printers.
#
# - A printer which was added manually before and is in foomatic-printermap
#   now will be removed from the list of manually added printers and added
#   to the list of printers from foomatic-printermap.

#use strict;

# Read out the program name with which we were called, but discard the path
$0 =~ m!/([^/]+)\s*$!;
my $progname = $1;
my $debug = 0;

my ($opt_f, $opt_g, $opt_h);
use Getopt::Std;
getopts("f:g:h") or $opt_h = 1;
if ($opt_h) {
    print "
foomatic-printermap-to-gutenprint-xml [ -f <foomatic-printermap> ] \
                              [ -g <gutenprint.xml> ]
 -f <foomatic-printermap>: File src/foomatic/foomatic-printermap of
                    Gutenprint source tarball (4.2.x or later). Default
                    is foomatic-printermap in the current directory

 -g <gutenprint.xml>: File gutenprint.xml whose printer list should be
                    updated. Default is the gutenprint.xml of the
                    Foomatic database currently in use.

This program updates the printer list of the driver XML file of
Gutenprint (db/source/driver/gutenprint.xml in foomatic-db package)
according to the file src/foomatic/foomatic-printermap of the source
tarball of Gutenprint 5.0.x or later.

";
    exit 0;
}

# Determine gutenprint.xml file
my $gutenprintxmlfile = $opt_g;
if (!$gutenprintxmlfile) {
    use Foomatic::Defaults;
    $gutenprintxmlfile = "$libdir/db/source/driver/gutenprint.xml";
}

# Determine foomatic-printermap file
my $foomaticprintermapfile = $opt_f;
if (!$foomaticprintermapfile) {
   $foomaticprintermapfile = "./foomatic-printermap";
}

# Read list of printer IDs from Gutenprint's foomatic-printermap
open PM, "< $foomaticprintermapfile" or
    die "Cannot read $foomaticprintermapfile!\n";
my @printermap = <PM>;
close PM;

(s/^\s*\S+\s+\S+\s+(\S+)\s*$/$1/) foreach @printermap;

#print $#printermap;

# Read gutenprint.xml
open GPX, "< $gutenprintxmlfile" or
    die "Cannot read $gutenprintxmlfile!\n";
my $gutenprintxml = join("", <GPX>);
close GPX;

# Remove printer list
#$gutenprintxml =~ s!(<\s*printers\s*>).*(\n\s*<\s*/\s*printers\s*>)!$1$2!s;

# Mark beginning of printer list from foomatic-printermap before deleting
# these printer entries
$gutenprintxml =~ s:\n  <!-- The following printers are listed in the current foomatic-printermap -->:XXXXXXXXXX:s;

# Remove only those printers which are in foomatic-printermap. We
# re-add them in the next step, this way we have all printers of
# foomatic-printermap together and in the order of
# foomatic-printermap, and we have all manually added printers in the
# beginning of the list, before the printers of foomatic-printermap
# are listed.
print STDERR "Removing old printer entries ";
foreach my $printer (@printermap) {
    print STDERR ".";
    $gutenprintxml =~ s:\s*<\!\-\-[^<>]*?\-\->\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or
	$gutenprintxml =~ s:\s*<printer>\s*<id>\s*$printer\s*</id>.*?</printer>::s or 
	print STDERR "\n\nNew printer: $printer\n\n";
}
print STDERR "\n\n";

# Insert comment to mark the part of the list set up manually
$gutenprintxml =~ s:(\n\s*<\s*printers\s*>)\n\s*<!--\s*Manually inserted printer entries\s*-->:$1:s;
$gutenprintxml =~ s:(\n\s*<\s*printers\s*>):$1\n  <!-- Manually inserted printer entries -->:s;

# Insert comment to mark the part of the list generated from
# foomatic-printermap
$gutenprintxml =~ s:\n  <!-- The following printers were deleted in the current foomatic-printermap -->::s;
$gutenprintxml =~ s:\n  <!-- The following printers are listed in the current foomatic-printermap -->::s;
$gutenprintxml =~ s:XXXXXXXXXX:\n  <!-- The following printers were deleted in the current foomatic-printermap -->:s;
$gutenprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n  <!-- The following printers are listed in the current foomatic-printermap -->$1:s;

# Insert printers of foomatic-printermap to the end of the list
print STDERR "Inserting printer entries of foomatic-printermap ";
foreach my $printer (@printermap) {
    print STDERR ".";
    $gutenprintxml =~ s:(\n\s*<\s*/\s*printers\s*>):\n    <printer>\n      <id>$printer</id>\n    </printer>$1:s;
}
print STDERR "\n\n";

open GPX, "> $gutenprintxmlfile" or
    die "Cannot write $gutenprintxmlfile!\n";
print GPX $gutenprintxml;
close GPX;

exit 0;
