#!/usr/bin/perl

eval 'exec /usr/bin/perl  -S $0 ${1+"$@"}'
    if 0; # not running under some shell

# A plug-in for GIMP for converting xfig files into gimp native
# format, i.e. xcf.  Note that fig has 1200ppi (fig resolution units
# per inch, while gimp has a default of 72.

# Written in 2003 (c) by Michael Jung <miju@phantasia.org>.
# This plugin may be distributed under the same terms as The Gimp itself.
# See http://www.gimp.org/ for more information on The Gimp.

require 5.004;

use strict;

use Gimp qw(:auto N_);
use Gimp::Fu;

sub perl_fig2xcf {
    # predefined color values
    my @col = (0x000000, 0x0000ff, 0x00ff00, 0x00ffff,
	       0xff0000, 0xff00ff, 0xffff00, 0xffffff,
	       0x00008e, 0x0000ae, 0x0000cf, 0x86cfff,
	       0x009200, 0x00b200, 0x00d300, 0x00928e,
	       0x00b2ae, 0x00d3cf, 0x8e0000, 0xae0000,
	       0xcf0000, 0x8e008e, 0xae00ae, 0xcf00cf,
	       0x863000, 0x9e4100, 0xbe6100, 0xff8286,
	       0xffa29e, 0xffc3be, 0xffe3df, 0xffd700);
    
    my ($fn, $bg, $sc) = @_;
    my ($f, $D, $col);
    my $C = 32;

    open FIG, "<$fn";
    while (<FIG>) {
	if (/^\d+ \d+\n/) {
	    $f .= $_."\x03";
	    next;
	}
	# get user colors
	if (my ($coli, $col) = (/^0 \d+ \#([a-z0-9]+)\n/)) {
	    $C++;
	    push @col, hex($col);
	}
	# prepare most objects and get depth
	if (s/^([1-35] \d [-]?\d+ \d+ [-]?\d+ [-]?\d+) (\d+) /$1 $2\x01 /) {
	    $D = ($D > $2 ? $D : $2);
	}
	# get text objects and depth
	if (s/^(4 \d [-]?\d+) (\d+) /$1 $2\x02 /) {
	    $D = ($D > $2 ? $D : $2);
	}
	$f .= $_;
    }

    # get a decent background color. fig2dev (ps) -> gif will lose one
    # point, unless exactly divisible. Only happens with multiples of
    # 51.
    foreach my $i (0..5) {
	foreach my $j (0..5) {
	    foreach my $k (0..5) {
		$col = ($i * 256**2 + $j * 256 + $k) * 51;
		goto NEXT if (join("", map($_ == $col, @col)) eq "");
	    }
	}
    }

  NEXT:
    # We now have a background color
    $col = sprintf("%06x",$col);
    $f =~ s/\x03/"0 $C #$col\n"/e;
    
    my $dest;
    my $destlayer;
    my $tmpfile = "/tmp/fig2xcf".time;
    my ($w, $h);

#    &Gimp::set_trace(TRACE_ALL);

    for (my $d = $D; $d >= 0; $d--) {
	# prepare fig file(s)
	my $fd = $f;
	$fd =~ s/ $d\x01/" $d"/eg;
	$fd =~ s/ $d\x02/" $d"/eg;
	if ($fd ne $f) {
	    foreach my $dd (0..$D) {
		$fd =~ s/[-]?\d+ [-]?\d+ ${dd}\x01 ([-]?\d+) [-]?\d+/"$C $C ".($D+1)." $1 -1"/eg;
		$fd =~ s/[-]?\d+ ${dd}\x02/"$C ".($D+1)/eg;
	    }
	    # convert fig(s) to gif(s)
	    open FILE, ">$tmpfile.fig";
	    print FILE $fd;
	    close FILE;
	    system "fig2dev -L gif -m $sc -b 1 -g #$col $tmpfile.fig $tmpfile.gif";

	    # first layer
	    if (!defined($dest)) {
		$dest = file_gif_load(RUN_NONINTERACTIVE, "$tmpfile.gif", "$tmpfile.gif");
		gimp_image_set_filename($dest,$fn);
		gimp_image_undo_disable($dest);
		gimp_convert_rgb($dest);
		$destlayer = gimp_image_get_active_layer($dest);
		gimp_layer_add_alpha($destlayer);
		gimp_layer_set_name($destlayer,"$d");
		$w = gimp_image_width($dest);
		$h = gimp_image_height($dest);
	    }
	    # all other layers
	    else {
		$destlayer = gimp_layer_new($dest, $w, $h, RGBA_IMAGE, "$d", 100, NORMAL_MODE);
		gimp_image_add_layer($dest,$destlayer,-1);
		gimp_image_set_active_layer($dest,$destlayer);
		gimp_selection_all($dest);
		gimp_edit_clear($destlayer);

		my $orig = file_gif_load(RUN_NONINTERACTIVE, "$tmpfile.gif", "$tmpfile.gif");
		gimp_convert_rgb($orig);
		my $origlayer = gimp_image_get_active_layer($orig);
		gimp_layer_add_alpha($origlayer);

		gimp_selection_all($orig);
		gimp_edit_copy($origlayer);
		gimp_edit_paste($destlayer, 1);
		my $destsel = gimp_image_floating_selection($dest);
		gimp_floating_sel_anchor($destsel);
	    }

	    # make background stuff transparent
	    my @gcol = (hex(substr($col,0,2)), hex(substr($col,2,2)), hex(substr($col,4,2)));
	    gimp_by_color_select($destlayer,\@gcol,0,REPLACE,0,0,0,0);
	    gimp_rect_select($dest,1,1,$w-2,$h-2,INTERSECT, 0,0); 
	    gimp_edit_clear($destlayer);
	}
    }

    gimp_image_undo_enable($dest);
    gimp_selection_none($dest);

    # add background
    $destlayer = gimp_layer_new($dest, $w, $h, RGB_IMAGE, "background", 100, NORMAL_MODE);
    gimp_image_add_layer($dest, $destlayer, 0);
    gimp_image_lower_layer_to_bottom($dest, $destlayer);
    gimp_image_set_active_layer($dest,$destlayer);
    gimp_palette_set_background($bg);
    gimp_bucket_fill($destlayer, BG_BUCKET_FILL, NORMAL_MODE, 100, 255, 0, 0, 0);
    gimp_image_resize($dest, $w-2, $h-2, -1, -1);

    # clean up
    unlink "$tmpfile.fig";
    unlink "$tmpfile.gif";

    return $dest;
}

# Register the plug-in:

register
    "fig2xcf",
    "Turns a fig file into xcf format",
    "Use this plugin to turn a Fig file into Gimp native format. ".
    "Preserves layers.",
    "Michael Jung", "(c) Michael Jung", "2002-12-28",
    N_"<Toolbox>/Xtns/Perl/fig2xcf",
    undef,
    [
     [PF_FILE, "file_name", "file", ""],
     [PF_COLOR, "background_color", "color for background", "white"],
     [PF_FLOAT, "magnification", "scale as passed to fig2dev", 1.0]
    ],
    \&perl_fig2xcf;

exit main;
