#!/usr/bin/perl -w
# -----------------------------------------------------------------------------

use strict;

$| = 1;

my $myself = $0;
$myself =~ s|^.*/||;

die "$0: must run from top-level goffice directory.\n"
    unless -r "goffice/goffice.h";
my $dst = "goffice/cut-n-paste/foocanvas";

my $foodir = $ARGV[0];
$foodir = "../foocanvas" unless defined $foodir;
die "$0: must specify foocanvas directory on command line.\n"
    unless -d $foodir;

-d $dst or mkdir $dst or
    die "$0: cannot mkdir $dst: $!\n";

&copy_subsystem ("libfoocanvas");

# -----------------------------------------------------------------------------

sub copy_subsystem {
    my ($sys) = @_;

    my $srcdir = "$foodir/$sys";
    my $dstdir = "$dst";

    -d $dstdir or mkdir "$dstdir" or
	die "$0: cannot mkdir $dstdir: $!\n";

    my @sources;

    my $have_cvsignore = (-r "$srcdir/.cvsignore");
    push @sources, ".cvsignore" if $have_cvsignore;

    local (*SRC,*DST);
    open (SRC, "<$srcdir/Makefile.am") or
	die "$0: Cannot read $srcdir/Makefile.am: $!\n";
    open (DST, ">$dstdir/Makefile.am.new") or
	die "$0: Cannot write $dstdir/Makefile.am.new: $!\n";
    print STDERR "Creating $dstdir/Makefile.am...";
    while (<SRC>) {
	next if /^pkgconfig/ ... !/\\\s*$/;

	s|/libfoocanvas-1.0/libfoocanvas|/libgoffice-@GOFFICE_API_VER@/goffice/cut-n-paste/foocanvas/|;
	s|\$\(LIBFOOCANVAS_CFLAGS\)|\$\(GOFFICE_CFLAGS\)|;
	s/lib_LTLIBRARIES/noinst_LTLIBRARIES/;

	if (/^[a-zA-Z0-9_]+_(HEADERS|la_SOURCES)\s*=/ ... !/\\\s*$/) {
	    my $line = $_;
	    $line =~ s/^.*=|^\s+|\s*\\|\s+$|\$\(libfoocanvasinclude_HEADERS\)//g;
	    push @sources, split (' ', $line) if $line ne '';
	}

	next if /^(libfoocanvas_a_LIBADD|EXTRA_DIST)\s*=/ ... !/\\\s*$/;
	next if /^\s*\\$/;

	if (/echo.*\#include\s*"\$\*.h"/) {
	    my $config = $_;
	    $config =~ s|".*"|<goffice/goffice-config.h>|;
	    $_ = $config . $_;
	}

	print DST;
    }

    close (*SRC);
    close (*DST);
    &update_file ("$dstdir/Makefile.am");

    if (!$have_cvsignore) {
	open (DST, ">$dstdir/.cvsignore.new") or
	    die "$0: Cannot write $dstdir/.cvsignore.new: $!\n";
	print STDERR "Creating $dstdir/.cvsignore...";
	print DST "Makefile.in\n";
	print DST "Makefile\n";
	print DST ".deps\n";
	print DST ".libs\n";
	close (*DST);
	&update_file ("$dstdir/.cvsignore");
    }

    foreach my $file (@sources) {
	local (*SRC,*DST);
	open (SRC, "<$srcdir/$file") or
	    die "$0: Cannot read $srcdir/$file: $!\n";
	open (DST, ">$dstdir/$file.new") or
	    die "$0: Cannot write $dstdir/$file.new: $!\n";

	print STDERR "Creating $dstdir/$file...";

	print DST "/* File import from foocanvas to libgoffice by $myself.  Do not edit.  */\n\n";

	if ($file =~ /\.c$/) {
	    print DST "#undef GTK_DISABLE_DEPRECATED\n"
		unless $file =~ /^(foo-canvas-rect-ellipse|foo-canvas-util|foo-canvas|libfoocanvastypes)\.c$/;

	    print DST "#include <goffice/goffice-config.h>\n";
	    print DST "#include <glib/gi18n.h>\n";
	    print DST "#include <gsf/gsf-impl-utils.h>\n";
	}

	while (<SRC>) {
	    chomp;
	    s/\s+$//;
	    next if (/^\s*\* \$[I][d]: .* [E][x][p] \$$/);
	    next if (/^\s*\#\s*include\s*[<\"]config\.h[>\"]/);
	    if (m{^\s*\#\s*include\s*[<\"]libfoocanvas/(.*)[>\"]}) {
		print DST "#include \<goffice/cut-n-paste/foocanvas/$1\>\n";
		next;
	    }
	    # Turn C++ comments into C comments.
	    if (m|^\s*//|) {
		s|//|/*|;
		s|$|*/|;
	    }

	    if (/g_object_class_install_property/ ... /;/) {
		s/G_PARAM_READABLE \| G_PARAM_WRITABLE/G_PARAM_READWRITE/;
		s/(G_PARAM_READ)/GSF_PARAM_STATIC | $1/;
	    }

	    print DST "$_\n";
	}
	close (*SRC);
	close (*DST);

	# Jody has a patch for foo-canvas.c:
	&patch_file("$dstdir/$file.new") if $file eq "foo-canvas.c";

	&update_file ("$dstdir/$file");
    }
}

# -----------------------------------------------------------------------------

sub update_file {
    my ($old) = @_;
    my ($new) = "$old.new";

    if (!-r $old) {
	rename $new, $old or
	    die "$0: Cannot rename $new to $old: $!\n";
	print STDERR " -- done.\n";
    } else {
	system ("cmp '$old' '$new' >/dev/null");
	if ($? == 0) {
	    print STDERR " -- unchanged.\n";
	    unlink $new;
	} else {
	    rename $new, $old or
		die "$0: Cannot rename $new to $old: $!\n";
	    print STDERR " -- done.\n";
	}
    }
}

# -----------------------------------------------------------------------------

sub patch_file {
    my ($file) = @_;
    local (*PATCH);

    open (PATCH, "| patch --silent $file");
    print PATCH <<'EOF';
--- foo-canvas.c	27 Dec 2004 21:58:03 -0000
+++ foo-canvas.c	21 Jan 2005 03:08:31 -0000
@@ -2289,7 +2289,7 @@
  * keep as much as possible of the canvas scrolling region in view.
  */
 static void
-scroll_to (FooCanvas *canvas, int cx, int cy)
+scroll_to (FooCanvas *canvas, int cx, int cy, gboolean redraw)
 {
 	int scroll_width, scroll_height;
 	int right_limit, bottom_limit;
@@ -2320,9 +2320,6 @@
 	} else if (cx < 0) {
 		cx = 0;
 		canvas->zoom_xofs = 0;
-	} else if (cx > right_limit) {
-		cx = right_limit;
-		canvas->zoom_xofs = 0;
 	} else
 		canvas->zoom_xofs = 0;
 
@@ -2369,11 +2366,13 @@
 	}
 
 	/* Signal GtkLayout that it should do a redraw. */
+	if (redraw) {
 	if (changed_x)
 		g_signal_emit_by_name (GTK_OBJECT (canvas->layout.hadjustment), "value_changed");
 	if (changed_y)
 		g_signal_emit_by_name (GTK_OBJECT (canvas->layout.vadjustment), "value_changed");
 }
+}
 
 /* Size allocation handler for the canvas */
 static void
@@ -2399,7 +2398,7 @@
 
 	scroll_to (canvas,
 		   canvas->layout.hadjustment->value,
-		   canvas->layout.vadjustment->value);
+		   canvas->layout.vadjustment->value, TRUE);
 
 	g_signal_emit_by_name (GTK_OBJECT (canvas->layout.hadjustment), "changed");
 	g_signal_emit_by_name (GTK_OBJECT (canvas->layout.vadjustment), "changed");
@@ -3044,7 +3043,7 @@
 
 	foo_canvas_w2c (canvas, wxofs, wyofs, &xofs, &yofs);
 
-	scroll_to (canvas, xofs, yofs);
+	scroll_to (canvas, xofs, yofs, TRUE);
 
 	canvas->need_repick = TRUE;
 
@@ -3093,7 +3092,7 @@
 
 	scroll_to (canvas,
 		   canvas->layout.hadjustment->value,
-		   canvas->layout.vadjustment->value);
+		   canvas->layout.vadjustment->value, TRUE);
 }
 
 
@@ -3164,7 +3163,7 @@
 		gdk_window_show (window);
 	}
 
-	scroll_to (canvas, x1, y1);
+	scroll_to (canvas, x1, y1, FALSE);
 
 	/* If we created a an overlapping background None window, remove it how.
 	 *
@@ -3198,7 +3197,7 @@
 {
 	g_return_if_fail (FOO_IS_CANVAS (canvas));
 
-	scroll_to (canvas, cx, cy);
+	scroll_to (canvas, cx, cy, TRUE);
 }
 
 /**
EOF
    close (PATCH);
}
