package Win32::FreeStanding_Builder;

our %xsHash;
my $orig_dl_load_file;
my $DEBUG = 0;

sub dl_load_file($;$) {
    my $libref = &$orig_dl_load_file(@_);
    if ($libref) {
	# DLL loaded OK, so save the name in xsHash
	my ($file, $flags) = @_;
	if ($file =~ m#/(auto/.+$)#) {
	    $xsHash{$1} = $file;
	    warn "Saving $file as $1\n" if $DEBUG;
	}
    }
    return $libref;
}

BEGIN {
    package DynaLoader;
    
    # force dl_load_file() creation if not created
    boot_DynaLoader('DynaLoader') unless defined &dl_load_file;
    unless (defined &dl_load_file) {
	die "Dynamic loading not available in this perl ($^X).\n"
	  . "Please install ActivePerl and try again\n";
    }

    $orig_dl_load_file = \&dl_load_file;
    package Win32::FreeStanding_Builder;
    *{"DynaLoader::dl_load_file"} = \&dl_load_file;
}

use Win32::FreeStanding;
use Config;

# called from C++ code to handle runtime require/do
sub HandleDoRequireStatements {
    return 0 if @_ != 1;

    my $script = shift;
    my @script = split /\n/, $script;
    my $in_pod = 0;
    foreach my $line (@script) {
	if ($line =~ /^__(END|DATA)__/) {
	    return;
	}
	if ($line =~ /^=\w/) {
	    if ($line =~ /^=cut\b/) {
		$in_pod = 0;
	    }
	    else {
		$in_pod = 1;
	    }
	}
	# XXX kludgey
	if (!$in_pod and $line =~ /^\s*(do|require)\s+[\w:\.'"]+\s*(;|$)/) {
	    Win32::FreeStanding::safe_eval($line);
	    warn $@ if $@ and $DEBUG;
	    # ignore errors as the file may not exist yet if it is only
	    # created at runtime for the do/require
	    $@ = '';
	}
    }
    return;
}

# called from the outside
sub AddModule($) {
    my $module = shift;
    $module = "'$module'" if $module =~ /\./;
    Win32::FreeStanding::safe_eval("BEGIN { require $module; }");
}

# called from the outside
sub ClearDataHolders {
    # clear the holder of the extension as well as %INC
    %xsHash = ();
    %::INC = ();
}

# called from the outside
sub GetXShash {
    return %xsHash;
}

sub Files {
    my $dir = shift;
    my $fullpath = "$Config{sitelib}/$dir";
    print "Fullpath=$fullpath\n";
    opendir DIR, $fullpath or return;
    my @files = grep /\.pm$/ && -f "$fullpath/$_", readdir DIR;
    closedir DIR;
    for (@files) {
	s#(.*)\.pm$#$dir/$1#;
	s#/#::#g;
    }
    return @files;
}

sub AutoDependencies {
    my @list;
    push @list, 'Carp::Heavy'             if defined $INC{'Carp.pm'};
    push @list, 'DynaLoader'              if defined $INC{'XSLoader.pm'};
    push @list, 'Exporter::Heavy'         if defined $INC{'Exporter.pm'};

    push @list, 'CGI::Cookie'             if defined $INC{'CGI.pm'};
    push @list, 'shellwords.pl'           if defined $INC{'CGI.pm'};
    push @list, 'Fcntl'                   if defined $INC{'CGI.pm'};

    push @list, Files('Net/FTP')          if defined $INC{'Net/FTP.pm'};
    push @list, Files('MLDBM/Serializer') if defined $INC{'MLDBM.pm'};

    push @list, Files('URI')              if defined $INC{'URI.pm'};
    push @list, Files('URI/file')         if defined $INC{'URI.pm'};

    push @list, Files('LWP/Authen')       if defined $INC{'LWP.pm'};
    push @list, Files('LWP/Protocol')     if defined $INC{'LWP.pm'};

    foreach my $module (@list) {
	#print "Adding autodependency $module\n";
	AddModule($module) unless defined $INC{$module};
    }
}

BEGIN {
    package Win32::FreeStanding;
    *{"CORE::GLOBAL::exit"}	= \&Exit if defined &Exit;
}

1;
