use File::Path;

for (@ARGV) {
    $skip_grass = 1 if /--skip_grass/;
    $run_tests = 1 if /--run_tests/;
}

$ranlib = 'ranlib';
$fopt = '-Wall -fpic -ggdb -DPACKAGE=\""grassmods"\"';

# these variables are expanded by the main 'configure':
$grass_dir     = '@GRASS_HOME@';
$grass_arch    = '@ARCH@';
$grass_inc_dir = "$grass_dir/dist.$grass_arch/include";
$grass_lib_dir = "$grass_dir/dist.$grass_arch/lib";
$x_lib_dir     = '@X_LIBS@';

@incdirs = ('/usr/include',"$grass_inc_dir");
$incs = '';
foreach (@incdirs) {
    $incs .= " -I$_";
}


opendir(DIR, $grass_lib_dir) or die "Can’t open $grass_lib_dir: $!";
@tmp = grep { /\.so$/ && -f "$grass_lib_dir/$_" } readdir(DIR);
closedir DIR;

for (@tmp) {
    next if /cvs/;
    s/lib/-l/;
    s/.so$//;
    push @grass_libs, $_;
}

$grass_libs = "-L$grass_lib_dir $x_lib_dir -lX11 " . join(' ',@grass_libs);


# make basic Grass module

unless ($skip_grass) {
    system "swig -Wall -I$grass_inc_dir -perl5 -o grass_wrap.c grass.i";

    open(MAKEFILE_PL, ">Makefile.PL")or die "Can’t open Makefile.PL: $!";
    print MAKEFILE_PL <<end_of_this0;
use ExtUtils::MakeMaker;
    
WriteMakefile(
		  NAME => 'Grass',
		  MAKEFILE => 'Makefile_grass',
		  LIBS      => '$grass_libs',
		  OBJECT => 'grass_wrap.o error.o',
		  INC => "-I$grass_inc_dir"
		  );
end_of_this0
    close MAKEFILE_PL;
    
    system "perl Makefile.PL";
    system "make -f Makefile_grass";
}
#exit;


# make command modules:

$curdir = `pwd`;
chomp $curdir;

# add more directories here:
$root = 'raster';
rmtree($root);
recurse_dirs('../..',$root);

$root = 'vector';
rmtree($root);
recurse_dirs('../..',$root);

sub recurse_dirs {
    my @dir = @_;

    my $dir = join '/',@dir;

    if (-f "$dir/main.c") {
	has_main_c(@dir);
    }

    opendir(DIR, $dir) or die "can't opendir $dir: $!";    
    my @contents = readdir(DIR);
    closedir DIR;
    
    for my $e (@contents) {

	next unless -d "$dir/$e";
	next if $e eq '.';
	next if $e eq '..';
	recurse_dirs(@dir,$e);
    }
}

sub has_main_c {
    my @dir = @_;
    my $src = join '/',@dir;
    shift @dir;
    my $dst = join '/',@dir;


# 1. step: make copies of source code
    mkpath($dst) unless -d $dst;
    my $name = pop @dir;
    $name =~ s/\./_/g;
    system "cp $src/*.c $dst";
    system "cp $src/*.h $dst";
    open(MAIN_C, "$dst/main.c")or die "Can’t open $dst/main.c: $!";
    open(NEW_C, ">$dst/$name.c")or die "Can’t open $dst/main.c: $!";
    my $main_done = 0;
    while (<MAIN_C>) {
	if (not $main_done and /\bmain\b/) {
	    s/\bmain\b/$name/;
	    $main_done = 1;
	}
	s/\bexit\b/return/;
	print NEW_C;
    }
    close NEW_C;
    close MAIN_C;
    unlink "$dst/main.c";
    

# 2. step: compile static library
    chdir $dst;
    $lib_name = $name;

    opendir(DIR, '.') or die "Can’t open .: $!";
    @c_files = grep { /\.c$/ && -f "$_" } readdir(DIR);
    closedir DIR;

    $o_files = $c_files = join(' ',@c_files);
    $o_files =~ s/\.c/.o/g;

    my $mod_name = $name;
    $mod_name =~ s/^(\w)/uc($1)/e;

    open(MAKEFILE_PL, ">Makefile.PL")or die "Can’t open Makefile.PL: $!";
    print MAKEFILE_PL <<end_of_this;
use ExtUtils::MakeMaker;

WriteMakefile(
	      NAME      => '${mod_name}::$name',
	      INC	=> '$incs',
	      DEFINE    => '$fopt',
	      clean     => {'FILES' => '$name\$(LIB_EXT)'},
	      );

sub MY::top_targets {
'
pure_all ::

all :: static

static :: $lib_name\$(LIB_EXT)

$lib_name\$(LIB_EXT): $c_files $o_files
	\$(AR) cr $lib_name\$(LIB_EXT) $o_files
	$ranlib $lib_name\$(LIB_EXT)
';
}
    
end_of_this
    close MAKEFILE_PL;
    
system "perl Makefile.PL";
system "make";
rmtree('blib');


# 3. step: create the wrapper code & module
my $mod_name = $lib_name;
$mod_name =~ s/r_//;
if ($mod_name =~ /^(\w)/) {
    my $first_char = uc($1);
    $mod_name =~ s/^\w/$first_char/;
}
$mod_name = "Grass::Raster::$mod_name";

open(SWIG_I, ">$lib_name.i")or die "Can’t open $lib_name.i: $!";
print SWIG_I <<end_of_this2;
\%module "$mod_name"
\%{
#include "grass/gis.h"
\%}

\%include $curdir/typemaps.i

\%rename(main) $lib_name;
int $lib_name (int argc, char **argv);
end_of_this2
    close SWIG_I;

system "swig -Wall -perl5 -o ${lib_name}_wrap.c $lib_name.i";


# 4. step: create the dynamic library
open(MAKEFILE_PL, ">Makefile.PL")or die "Can’t open Makefile.PL: $!";
print MAKEFILE_PL <<end_of_this3;
use ExtUtils::MakeMaker;

WriteMakefile(
	      NAME      => '$mod_name',
	      OBJECT    => '${lib_name}_wrap.o ${lib_name}.a',
	      INC	=> '$incs',
	      LIBS      => '$grass_libs',
	      );
    
end_of_this3
    close MAKEFILE_PL;

open(TEST_PL, ">test.pl")or die "Can’t open test.pl: $!";
print TEST_PL <<end_of_this4;
BEGIN { \$| = 1; }
END {print "not ok 1\\n" unless \$loaded;}
use Grass;
use $mod_name;
use POSIX;
\$loaded = 1;

print \$loaded ? "1 - ok\\n" : "1 - not ok\\n";

Grass::set_my_error_routine();
${mod_name}::main(2,['dummy','elevation=dem']);
end_of_this4
    close TEST_PL;
    
system "perl Makefile.PL";
system "make";
system "make test" if $run_tests;

chdir $curdir;
#exit;

}
