;;; TAG download: makes automatically a link to something downloadable
;;;     Args:
;;;       file = name of the downloadable file (without version number and
;;;              extension)
;;;       name = The text of the ancor. Defaults to <file>-<version>.<ext>
;;;       ext = The extension. Defaults to <dlext> 
;;;       dir = Where to search the file. Defaults to <dldir> or "."
;;;       mandatory = non null if we should fail when it's not present
;;;    
;;;
;;;       note: if ext is given, then it''s used. In other case, if <dlext>
;;;             exists and contain some non whitespace chars, it is used. 
;;;             if not, empty string is used
;;;
;;;     Result: 
;;;       It looks in the given dir for the most advanced version of the file,
;;;       and build a link to it. (indicate between parenthesis the size)

;;; TODO: Il va falloir changer l'argument "mandatory" en "ifnotfound", afin
;;;       de préciser ce qu'il faut faire quand le fichier est introuvable.
;;;       Il y a trois comportements possibles:
;;;          - echec ŕ la compilation (ce qu'on a maintenant avec mandatory
;;;            ŕ vrai) 
;;;          - ignorer, ne rien mettre (ce qu'on avait avant les dernieres
;;;            modifs) 
;;;          - mettre le nom du fichier puis "not available" apres (ce qu'on
;;;            a maintenant)

<define-tag dlext></define-tag>
<define-tag dldir></define-tag>

<define-tag download endtag=none>
  <preserve file name ext dir mandatory /><set-var %attributes />
  <if <string-eq <get-var file /> "" />
      <compound>
         <warning "Argument 'file' mandatory in tag 'download'" />
	 <warning "(name=<get-var name />; ext=<get-var ext />; dir=<get-var dir />)" />
         <exit 1 />
      </compound>
  />
  <perl>{ 
       my $file;<perl:assign $file><get-var file /></perl:assign>;
       my $name;<perl:assign $name><get-var name /></perl:assign>;
       my $ext;<perl:assign $ext><get-var ext /></perl:assign>;
       my $dir;<perl:assign $dir><get-var dir /></perl:assign>;
       my $mandatory;<perl:assign $mandatory><get-var mandatory /></perl:assign>;

       # Sannity checks on args, and defauls where needed
       chomp($dir);
       $dir =~ s/\n//g;
       chomp($file);

       unless (defined($ext) && ($ext =~ m,\S,)) {
	   <perl:assign $ext><dlext /></perl:assign>;
       }

       my($subdir, $ok);
       $subdir=$file;
       $subdir =~ s|^(.*)/([^/]*)$|$1|;
       if ("$subdir" ne "$file") {
	  if ($dir ne "") {
	    $dir=$dir . "/";
          }
	  $dir=$dir  . $subdir;
	  $file=$2;
	  $dir =~ s,//*,/,g;
       }

       ;;;<perl:print>dir=$dir file=$file subdir=$subdir</perl:print>
       ;;;print STDERR "dir=$dir file=$file subdir=$subdir\nfin\n";


       unless (defined($dir) && $dir =~ m,\S,) {
	   <perl:assign $dir><dldir /></perl:assign>;
	   $dir = "." unless (defined($dir) && $dir =~ m,\S,);
       }
       
       ($ver,$ok) = get_available_version($file,$ext,$dir,$mandatory);
       if ($ok) {
           $full="$file$ver$ext";
           $name=$full unless (defined($name) && $name =~ m,\S,);

           <perl:print><a href="$dir/$full">$name</a></perl:print>

           # get the size
           $size= (stat("$dir/$full"))[7];
           if ($size > 1024*1024*1024) {
	       $size=sprintf "%.2f Gb", $size / (1024*1024*1024);
           } elsif ($size > 1024*1024) {
	       $size=sprintf "%.1f Mb", $size / (1024*1024);
           } elsif ($size > 1024) {
	       $size=sprintf "%.0f kb", $size / 1024;
           } else {
	       $size = $size."b";
           }
           <perl:print> ($size)</perl:print>
        } else {
           $name="$file$ext" unless (defined($name) && $name =~ m,\S,);
	   <perl:print><a href="">$name</a> (<em>not available</em>)</perl:print>
	}
  }</perl>
  <restore file name ext dir mandatory />
</define-tag>


<perl>
# get the last version available of this file
sub get_available_version {
    my $file = shift 
	|| die "file should be defined in get_available_version\n";
    my $ext = shift;
    my $dir = shift || ".";
    my $mandatory = shift || 0;

    if ($dir ne "") {
	    $dir=$dir . "/";
    }
    ;;;print STDERR "file=$file\next=$ext\ndir=$dir\npwd=".`pwd`."dirfileext=$dir$file$ext\n";

    if ( -e "$dir$file$ext" ) {
       return ("", 1);
    }
    
    opendir(DIR, $dir) || die "can't opendir $dir from ".qx(pwd).": $!";
    my @versions = map { m/^$file(.*)$ext$/; $_=$1} 
                        grep { -f "$dir/$_" && /^$file(.*)$ext$/ } 
                              readdir(DIR);
    closedir DIR;
    if (scalar @versions == 0) {
       die "in tag 'download', file $dir/$file*$ext not found\n"
  	   if $mandatory;
       return ("",0); # if not
    }

    my @sorted = sort { 
	#print "a=$a ; b=$b<br />\n";
	@a=split(/\./,$a);
	@b=split(/\./,$b);
	my $val=undef;
	for ($i=0 ; $i<*scalar @a && !defined($val); $i++) {
	    if (scalar @b < $i) {
		$val = -1;
	    }
	    #print "a[$i](=".$a[$i].
	    #  ") <=> b[$i](=".$b[$i].") = ".
	    ($a[$i] <=> $b[$i])."<br />\n";
	    if ($a[$i] ne $b[$i]) {
		$val = ($a[$i] <=> $b[$i]);
	    } 
	}
	$val=0 unless defined($val);
	$val;
    } @versions;
    return ($sorted[scalar @sorted -1],1);
}
</perl>