use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.

#
# Options:
#
#	--with-gdkimblib
#	--with-gtkxmhtml
#	--with-gtktty
#	--with-gnome  
#	--with-gtkglarea

# Search for a gnomeConf.sh file (waiting for gnome-config) ...
# One can also 'source' in the shell the proper gnomeConf.sh file
# before running perl Makefile.PL.
if (!defined $ENV{GTKXMHTML_LIBS} || !defined $ENV{GNOMEUI_LIBS}) {
	foreach (qw{/opt/lib /usr/local/lib /usr/lib /usr/X11R6/lib /opt/gnome/lib }) {
		open(GNOMEC, "$_/gnomeConf.sh") || next;
		my $f= join('', <GNOMEC>);
		close GNOMEC;
		# simple sh2pl hack
		$f =~ s/$/;/gm;
		$f =~ s/^(\w+)=/\$ENV{\1}=/gm;
		eval $f;
		last;
	}
}

@defines = ();

$libs = `gtk-config --libs`;
$libs = "-L/usr/X11R6/lib -lgtk -lgdk -lglib -lX11 -lXext" if not defined $libs;

$inc = `gtk-config --cflags`;

$libs =~ s/\s+/ /g;
$inc =~ s/\s+/ /g;

$gtk_version = gtk_version();

if ($gtk_version =~ /^(\d+\.\d+)/) {
	$dver = $1 + 0.0;
} else {
	$dver = 0.0;
}

if (not defined $gtk_version) {
	print "Unknown Gtk version\n";
} else {
	print "Gtk version $gtk_version\n";
}

$typemap = ["xtypemap"];
$object = 'Gtk.o GtkDefs.o GtkTypes.o GdkTypes.o MiscTypes.o';
$pm = {'Gdk.pm' => '$(INST_LIBDIR)/Gtk/Gdk.pm',
	'Gtk.pm' => '$(INST_LIBDIR)/Gtk.pm',
	'GtkTypes.pm' => '$(INST_LIBDIR)/Gtk/Types.pm',
	'Atoms.pm' => '$(INST_LIBDIR)/Gtk/Atoms.pm',
	'GtkColorSelectButton.pm' => '$(INST_LIBDIR)/Gtk/ColorSelectButton.pm',
};

@clean = qw(GtkTypes.pm xtypemap GtkDefs.c GtkDefs.h Objects.xpl boxed.xsh extension.xsh inc.h objects.xsh);

%xs = ();
%typemaps = ();
%defs = ();
%boot = ();


do_package("gtk");

foreach (@ARGV) {
	if (/^--with-/) {
		do_package($');
	}
}


print "Invoking gendefs.pl with [",join(", ",sort {$defs{$a} <=> $defs{$b}} keys %defs), "]\n";

system('perl', 'gendefs.pl', sort {$defs{$a} <=> $defs{$b}} keys %defs);

foreach (split(' ', (do 'Objects.xpl'))) {
	add_xs($_);
}

$xfiles = {};

foreach (sort {$xs{$a} <=> $xs{$b}} keys %xs) {
	my($xs) = $_;
	s/\.xs$/.c/;
	$xfiles->{$xs} = $_;
	s/\.c$/.o/;
	$object .= " $_";
}

foreach (<*.xs>) {
	if (not exists $xfiles->{$_}) {
		s/\.xs$/.c/;
		push @clean, $_;
	}
}

open (EXT, ">extension.xsh");
print EXT "\n\n# Do not edit this file, as it is automatically generated by Makefile.PL\n\n";
print EXT "BOOT:\n{\n";

foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) {
	my($b) = $_;
	$b =~ s/::/__/g;
	$b = "boot_$b";
	print EXT "extern void $b(CV *cv);\n";
}
foreach (sort {$boot{$a} <=> $boot{$b}} keys %boot) {
	my($b) = $_;
	$b =~ s/::/__/g;
	$b = "boot_$b";
	print EXT "callXS($b, cv, mark);\n";
}

print EXT "}\n";
close(EXT);

open(I, ">inc.h");
print I "\n\n/* Do not edit this file, as it is automatically generated by Makefile.PL*/\n\n";


foreach (sort {$headers{$a} <=> $headers{$b}} keys %headers) {
	print I "#include $_\n";
}
close(I);


foreach (sort {$typemap{$a} <=> $typemap{$b}} keys %typemap) {
	push @$typemap, $_;
}

@L = (LIBS => [$libs]);

if (defined $inc and $inc !~ /^\s*$/) {
	@I = (INC => $inc);
} else {
	@I = (); #e.g, INC => -I/usr/other/include
}

WriteMakefile(
    'NAME'	=> 'Gtk',
    'VERSION_FROM'	=> 'Gtk.pm',
    'PM' => $pm,
    'TYPEMAPS' => $typemap,
    'XS' => $xfiles,
    'XSOPT' => '-noversioncheck',
    'DEFINE'	=> join(' ',@defines),
    'OBJECT' => $object,
	'XSPROTOARG' => '-noprototypes',
	clean => {FILES => join(' ', @clean)},


	@I,
	@L,
);


sub gtk_version {
	my($result);

	$result = `gtk-config --version`;
	chomp $result;
	
	if (not defined $result) {

		unlink("gtkvertmp.out");

		open(T, ">gtkvertmp.c");
		print T <<'EOT';

#include <stdio.h>
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
	FILE * f = fopen("gtkvertmp.out", "w");
	fprintf(f,"%d.%d.%d\n", gtk_major_version, gtk_minor_version, gtk_micro_version);
	fclose(f);
	return 0;
}

EOT
		close(T);

		use Config;

		$c = "$Config{cc} $Config{ccflags} $inc gtkvertmp.c $Config{ldflags} $libs $Config{libs} -o gtkvertmp";
		system("$c && ./gtkvertmp");

		unlink("gtkvertmp.c");
		unlink("gtkvertmp.o");
		unlink("gtkvertmp");

		open(T, "<gtkvertmp.out");
		$result = <T>;
		chomp $result;
		close(T);

		unlink("gtkvertmp.out");
	}
	
	return $result;
}


$add = 0;
sub add_xs
{
	foreach (@_) { $xs{$_} = $add++; }
}

sub remove_xs
{
	foreach (@_) { delete $xs{$_}; }
}

sub add_typemap
{
	foreach (@_) { $typemap{$_} = $add++; }
}

sub remove_typemap
{
	foreach (@_) { delete $typemap{$_}; }
}

sub add_defs
{
	foreach (@_) { $defs{$_} = $add++; }
}

sub remove_defs
{
	foreach (@_) { delete $defs{$_}; }
}

sub add_headers
{
	foreach (@_) { $headers{$_} = $add++; }
}

sub remove_headers
{
	foreach (@_) { delete $headers{$_}; }
}

sub add_boot
{
	foreach (@_) { $boot{$_} = $add++; }
}

sub remove_boot
{
	foreach (@_) { delete $boot{$_}; }
}


sub do_package
{
	my($p) = @_;
	if (-f "config/pkg-$p.pl") {
		if (-f "config/pkg-$p.typemap") {
			add_typemap "config/pkg-$p.typemap";
		}
		if (-f "config/pkg-$p.defs") {
			add_defs "config/pkg-$p.defs";
		}
		do "config/pkg-$p.pl";
	} else {
		print "Unknown package '$p'\n";
	}
}
