require 5.002;
my $path = "$Config{'archlibexp'}/CORE/perl.h";
die "Cannot find '$path' have you installed $^X?\n" unless (-r $path);
print "$^X is installed in $Config{'archlibexp'} okay\n";
use Config;
use Cwd;
use Tk::MMtry;
warn "No VERSION" unless (defined $VERSION);

my %define = ();

$inc    = "";        
$xlib   = "";        
$define = '-DBASEEXT=\\"$(BASEEXT)\\"';
$gccopt = "";
@macro  = ();

#
# Convert perls Config info into -DXXXX for Tk
#

if (defined $Config{'gccversion'})
 {
  $ver = $Config{'gccversion'};
  if ($ver ge "2.6")
   { 
    # retain author's favourite warnings if using gcc
    $gccopt .= " -Wall -Wno-comment -Wno-unused -D__USE_FIXED_PROTOTYPES__";
    eval 
     {
      if ((getpwuid($<))[6] =~ /Nick\s+Ing-Simmons/)
       {
        # This is the author - catch as many bugs as possible
        $gccopt .= " -MMD -Werror";
        # $gccopt .= " -ansi -D__EXTENSIONS__" if ($^O eq 'solaris');
        # $gccopt .= " -Wmissing-prototypes" if (-f "/etc/shadow");
        @macro = ( macro => { INSTALLDIRS => 'perl' } );
       }
     }
   }
 }

$define{'USE_PROTO'} = 1         if ($Config{'prototype'});
$define{'HAVE_UNISTD_H'} = 1     if ($Config{'i_unistd'});
$define{'HAVE_SYS_SELECT_H'} = 1 if ($Config{'i_sysselct'});
$define{'NO_STDLIB_H'} = 1       unless ($Config{'i_stdlib'});
$define{'HAVE_SYS_TIME_H'} = 1   if ($Config{'i_systime'});
$define{'HAVE_LIMITS_H'} = 1     if ($Config{'i_limits'});
$define{'USE_BCOPY'} = 1         if (!$Config{'d_memmove'} && $Config{'d_bcopy'});

if (defined $Config{'selecttype'})
 {
   my $type = $Config{'selecttype'};
   $type =~ s/\s*\*\s*$//;
   $define{'SELECT_MASK'} = $type;
 }

if (!$Config{'i_unistd'} && defined $Config{'lseektype'})
 {
   my $type = $Config{'lseektype'};
   $type =~ s/\s*\*\s*$//;
   $define{'LSEEK_TYPE'} =$type;
 }


my $voidflags = $Config{'voidflags'};
my $voidused  = $Config{'defvoidused'}+0;

$define{'NOVOID'}  = 1 if (($voidflags & $voidused) != $voidused);
$define{'NOCONST'} = 1 unless ($Config{'d_const'});

if (try_compile("config/signedchar.c"))
 {
  $define{'ANSI_SIGNED_CHAR'} = 1;
 }
else
 {
  if (try_run("config/unsigned.c"))
   {
    $define{'CHAR_UNSIGNED'} = 1;
   }
 }

if (!try_compile("config/tod.c"))
 {
  my $d;
  my $def;
  foreach $d (qw(TZ NO_TZ DOTS))
   {
    if (try_compile("-DTIMEOFDAY_$d config/tod.c"))
     {
      $def = "TIMEOFDAY_$d";
      print STDERR "$d gettimeofday()\n";
      last;
     }
   }
  if (defined $def)
   {
    $define{$def} = 1;
   }
  else
   {
    print STDERR "Problem gettimeofday()\n";
   }
 }
else
 {
  print STDERR "Generic gettimeofday()\n";
 }

#
# Hunt down X Library - first a function
#
sub lX11
{
 my $user = shift;
 foreach (@_)
  {
   # allow any of libX11.a libX11.so.* etc.
   if (-d $_)
    {
     local ($lib);
     my $pattern = "$_/libX11.*";
     $pattern .= " $_/X11$Config::Config{lib_ext}" 
       if $Config::Config{osname} eq 'os2';
     foreach $lib (reverse(<$ {pattern}>))
      {
       if (-r $lib)
        {
         print "Using -L$_ to find $lib\n"; 
         return "-L$_" 
        }
      }
    }
  }
 print "No -lX11 in ",join(' ',@_),"\n" if (@_ && $user);
 return undef;
}

sub IX11
{
 foreach (@_)
  {
   if (-d $_ && -d "$_/X11" && -r "$_/X11/Xlib.h")
    {
     print "Using -I$_ to find $_/X11/Xlib.h\n";
     return "-I$_";
    }
  }
 return undef;
}

my @args = ();
my $arg;
foreach $arg (@ARGV)
 {
  if ($arg =~ /^(X11\w*)=(.*)$/)
   {
    ${"$1"} = $2;
   }
  else
   {
    $MakefileName = $1 if ($arg =~ /^MAKEFILE=(.*)$/);
    push(@args,$arg);
   }
 }
@ARGV = @args;

@xdirs = ();

if (defined $X11)
 {
  my $dir = $X11;
  if (-d $dir)
   {
    print "Looking for X in $dir\n";
    push(@xdirs,$dir);
   }
  else
   {
    die "X11=$dir is not a directory";
   }
 }
else
 {
  # Find the X Library through xmkmf!
  $xmkmf = undef;
  my @exts = ("", ".cmd", ".bat");
 LOOK:
  foreach $dir (split($Config::Config{path_sep},$ENV{'PATH'})) {
    foreach $ext (@exts) {
      if (-x "$dir/xmkmf$ext" && -r "$dir/xmkmf$ext") {
$xmkmf = "$dir/xmkmf$ext";
last LOOK;
      }
    }
  }
  $uiline = undef;
  if (defined $xmkmf) {
    open(XMKMF,$xmkmf) || die("Can't open $xmkmf: $!\n");
    while(<XMKMF>) {
      next unless /UseInstalled/o;
      warn ("Odd, two lines in the $xmkmf file that have UseInstalled on them:\n$uidir$_") if defined $uiline;
      $uidir = $_;
    }
    close(XMKMF);
    while (defined $uidir) {
      last unless ($uidir =~ s!^.*-I(\S+)/lib/X11/config!!o);
      $try = $1;
      $try =~ s/'x11root'/$ENV{X11ROOT}/;
      push(@xdirs,$try);
    }
  }
  print "$xmkmf suggests ",join(' ',@xdirs),"\n" if (@xdirs);
 }

undef $xlib;  # Make sure

if (defined $X11LIB)
 {
  $xlib = &lX11(1,$X11LIB) 
 }
if (!defined($xlib) && defined($X11))
 {
  $xlib = &lX11(1,"$X11/lib") 
 }
$xlib = &lX11(0,map("$_/lib",@xdirs)) unless (defined $xlib);

# Special case for sun-machines 
unless (defined $xlib)
 {
  if ($Config{'osname'} eq 'solaris' || $Config{'osname'} eq 'sunos')
   {
    $xlib = &lX11(0,'/usr/openwin/lib');
   }
 }

sub chooseX11
{
 # Aim to prefer X11R5 over X11R4 over X11
 (reverse(sort(@_)));
}

#
# If no luck there try "common" places 
#
unless (defined $xlib)
 {
  $xlib = &lX11(0,chooseX11(</usr/X11*/lib>),chooseX11(</usr/lib/X11*>),</usr/Xfree*/lib>,'/usr/X386/lib')
 }

#
# Try places perl looks for libraries
# This is now "last resort" as /lib and /usr/local/lib are so often
# full of dubious links
#
unless (defined $xlib)
 {
  $xlib = &lX11(0,split(/\s+/,$Config{'libpth'})) 
 }

die "Cannot find -lX11 anywhere" unless(defined $xlib);

($base) = $xlib =~ m#-L(.*)(?:/lib)$#x;
if (defined $X11INC)
 {
  $xinc = &IX11("$X11INC");
 }

$xinc = &IX11("$base/include") unless (defined $xinc);

unless (defined $xinc)
 {
  warn "Cannot find X include files via $base/include\n";
  $xinc = &IX11(map("$_/include",@xdirs),
                '/usr/openwin/include',
                chooseX11(</usr/X11*/include>),
                chooseX11(</usr/include/X11*>),
                </usr/Xfree*/include>,
                '/usr/X386/include',
                $Config{'usrinc'});
 }

die "Cannot find X include files anywhere" unless (defined $xinc);

$inc = ($xinc eq "-I/usr/include") ? "" : $xinc;

if ($Config{'osname'} eq 'solaris' && $xlib =~ /\bopenwin\b/ )
 {
  $define{'NEED_PRELOAD'} = 1; 
 }

sub WriteIfChanged
{
 my ($file,$string) = @_;
 my ($dir) = $file =~ m#^(.*)/[^/]+$#; 
 if (defined($dir) && !-d $dir)
  {
   mkdir($dir,0777) || die "Cannot mkdir $dir:$!";
  }
 my $ok = -f $file;
 if ($ok = open(IN,"$file"))
  { 
   my $old = join('',<IN>);
   close(IN);
   $ok = $old eq $string;
   print STDERR "$file has changed\n" unless ($ok);
  }
 unless ($ok)
  {
   open(OUT,">$file") || die "Cannot open $file:$!";
   print STDERR "Writing $file\n";
   print OUT $string;
   close(OUT);
  }
}

if (!defined($MakefileName) || $MakefileName eq 'Makefile')
 {
  my $config = "package Tk::Config;\nrequire Exporter;\n\@ISA = qw(Exporter);\n";
  my $sym;
  my @export = (); 
  foreach $sym (qw(VERSION inc define xlib xinc gccopt))
   {         
    my $val = ${$sym};
    $val =~ s/([\\'])/\\$1/g;
    $config .= "\$$sym = '$val';\n";
    push(@export,"\$$sym");
   }         
  $config .= "\@EXPORT = qw(".join(' ',@export).");\n1;\n";
  WriteIfChanged("Tk/Config.pm",$config);
  $config = "#ifndef _TKCONFIG\n#define _TKCONFIG\n";
  foreach $sym (sort keys %define)
   {
    $config .= "#define $sym $define{$sym}\n";
   }
  $config .= "#endif\n";
  WriteIfChanged("pTk/tkConfig.h",$config);
 }

1;
