;;; This file contains the needed mechanism to make a title to the page, and
;;;  a menu at the top of it.
;;;
;;; License GPL
;;; Authors: Martin Quinson

;;; To use it, you have to declare a menu-list tag, explaining what is your
;;;  menu organization. For example, I have a file called customization.wml,
;;;  which contains the following:
;;;     <define-tag menu-list>
;;;       home/
;;;       academia/ 
;;;       academia/publications/
;;;       academia/fast/
;;;       academia/fast/download/
;;;       academia/fast/install/
;;;       academia/fast/use/:fast_use
;;;       hacking/
;;;     </define-tag>
;;;  Then, I load it in all my pages on the very first line:
;;;    #include "customize.wml"

;;;  Afterward, I call the macro in this file (banner.wml), indicating which
;;;   file we are building:

;;;   #include <banner.wml> title="Mt's Homepage" path="home/"

;;;  title will be used twice. In the html <title>, and at the top,
;;;    to make a beautiful box containing it on the page.

;;;  path is the filename, and should match one of the lines in menu-list.

;;; Please note that the name of the file and the name of the entry don't
;;; have to be the same. If they are different, append the filename (without
;;; the extension) to the name  of the entry, separated by a colon (:)


;;; STOP TO READ HERE IF YOU JUST WANT TO USE THIS FILE.
;;; READ FURTHER IF YOU WANT TO CHANGE ANYTHING

;;; Detail of the content:
;;;  - Tags:
;;;    header: The header at the top of the page.
;;;  - Perl functions:

;;;    menu_do: Main function. build the menu, and output it

;;;    menu_parse: take a space separated list of entries, and build an
;;;                internal perl structure of it
;;;    menu_add_item: Add an item (recursively) to the menu. 
;;;                   Returns the modified version
;;;                   Used in menu_parse

;;;    menu_output: outputs the visible part of #menu# from #path#
;;;                 ARGS: (path,menu)

;;;    menu_dump: debugging purpose
;;;               ARG: (menu)

;;; This is the name of the main file, ie, the one containing the header. 
;;;  This is used by several tags around there.
<define-tag mainfile whitespace=delete>
 <perl>
  $mypath="$(OUTPUTFILENAME)";
  ;;;$mypath = $path;
  ;;;$mypath =~ s|^([^/]*/)*([^/]+)/?$|$2|; 
  ;;;$mypath =~ s|^[^:]*:(.*)|$1|; 
  $mypath =~ s|.php$||;
  <perl:print>$mypath</perl:print>
 </perl>
</define-tag>


#include <php.wml>
#include <template.wml>
#include <gettext.wml>
<phpinit>

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; header tag
;;;  The header at the top of the page.
;;;   Arg: title.

<define-tag header endtag=required>
    <table width="100%" border=0 cellspacing=0 cellpadding=0 class="navOutline">
      <tr>
	<td>
	  <table width="100%" border="0" cellspacing="1" cellpadding="0">
	    <tr class="content">
	      <div class="navTitle" valign=middle>
	        <preserve title><set-var %attributes>
	          <get-var title />
		<restore title>
	      </div>
	    </tr>
	    <tr>
	      <td class="navBarColor" colspan="3">
                <perl>{<perl:assign>%body</perl:assign>}</perl>
	      </td>
	    </tr>
	  </table>
	</td>
      </tr>
    </table>
</define-tag>

<perl>
my $debug=0;

###########
# sub filename
#  Find the file name and the menu entry

sub filename {
  my $begin=shift;
  my ($title,$filename);

  $title=$filename=$begin;
  if ($title =~ m/:/) {
    $filename =~ s/^(.*):([^:]*)$/$2/;
    $title = $1;
  }
  if ($filename !~ m/\./) {
    $filename.="$(CUR_LANG_EXT).html";
  }
  return ($title,$filename);
} 

###########
# sub menu_add_item
#  Add an item (recursively) to the menu. Returns the modified version

sub menu_add_item {
  my $menu=shift;
  my $item=shift;
  my ($begin,$end)=($item,"");
  my ($title,$filename);
  if ($item =~ m,^([^/]*)/(.*)$,) {
      ($begin,$end)=($1,$2);
  }
  return $menu if ($item eq "");# stop the recursive call when nothing to do

  if (!defined($menu->{'size'})) {
      # new entry
      $menu->{'size'}=1;
      ($title,$filename)=filename($begin);
      $menu->{'title'}="$title";
      $menu->{'filename'}="$filename";
      $menu->{'0'}=menu_add_item($menu->{'0'},$end);
  } else {
      # old entry. Search if this already exists
      my $i=0;
      for ($i=0 ;
	   $i<$menu->{'size'} 
	     && defined($menu->{$i}) && defined($menu->{$i}->{'title'})
	     && $menu->{$i}->{'title'} ne $begin ;
	   $i++) {
	  #Nothing more to do for the search
      }

      if ($i==$menu->{'size'}
	  || !defined($menu->{$i}) 
	  || !defined($menu->{$i}->{'title'})) {
	  # Not found
	  $menu->{'size'}=$menu->{'size'} + 1;
	  ($title,$filename)=filename($begin);
	  $menu->{"$i"}->{'title'}="$title";
	  $menu->{"$i"}->{'filename'}="$filename";
          $menu->{"$i"}->{'size'}=0;
	  $menu->{$menu->{'size'}-1}=menu_add_item($menu->{$menu->{'size'}-1},
						   "$end");
      } else {
	  # found
	  $menu->{"$i"}=menu_add_item($menu->{"$i"},"$end");;
      }
  }
  return $menu;
}

################
# sub menu_parse
#  take a space separated list of entries, and build a menu of it.

sub menu_parse{
  my $list=shift;
  my $menu;

  $menu->{'size'}=0;
  foreach my $item (split(/\n\s*/,$list)) {
    $item =~ s/\s*$//;
    $menu=menu_add_item($menu,$item);
  }
  menu_dump($menu,0) if $debug;
  return $menu;
}

###############
# sub menu_dump
#  debugging purpose
sub menu_dump{
  my $menu=shift;
  my $level=shift||0;

  print "------ DUMP MENU (begin)\n" if $level == 0;
  for (my $i=0;$i<$level;$i++) {
      print "  ";
  }
  if (!defined($menu->{'size'})) {
      print "()\n <par>";
  } else {
      print $menu->{'title'}." (size=".$menu->{'size'}.").\n";
      for (my $i=0;$i< ($menu->{'size'}||0);$i++) {
	  menu_dump($menu->{"$i"},$level+1);
      }
  }
  print "------ DUMP MENU (end)\n" if $level == 0;
}

#################
# sub menu_output
#  outputs the visible part of #menu# from #path#

sub menu_output {
    my $path=shift;
    my $menu=shift;
    my $res="";
    my $post;

    return unless (defined($menu->{'size'}) || defined($menu->{'title'}))
	          && ($menu->{'size'} != 0 || $menu->{'title'} ne "");
    if ($menu->{'size'} != 0) {
	$res .= "<table border=0><tr>\n";    
    }
    for (my $i=0 ; $i<$menu->{'size'} ; $i++) {
        my $filename,$title;
	$filename=$menu->{$i}->{'filename'};	
	$title=$menu->{$i}->{'title'};
        $res .= "<td valign=top><table border=0>\n<tr><td class=menu>";
	$res .= "  <a href=\"".$filename."\" "
                ."class=\"";
	$post= "\">".$title."</a>  </td>";
	
	if ($i < $menu->{'size'}-1) {
	    $post .= "</tr>\n"; #<tr>
	}
	if (defined($menu->{$i}->{'title'})
	    && defined($path->[0])
	    && $menu->{$i}->{'title'} eq $path->[0]) {
	    if (defined($path->[1])) {
		$res .= "navBar$post"; 
	    } else {
		$res .= "highlightNav$post"; 
	    }
	    shift @$path;
	    $res .= "<tr><td>".menu_output($path,$menu->{$i},1)."</tr>";
	} else {
	    $res .= "navBar$post"; 
	}
	$res .= "</table></td>\n";#</tr> en tete
    }
    if ($menu->{'size'} != 0) {
	$res .= "</tr></table>";
    }
    return $res;
}

#############
# sub menu_build_path
#  build menu path from filename
sub menu_build_path {
    my $filename=shift;
    my $menu=shift;

    return "" unless (defined($menu->{'size'}) || defined($menu->{'title'}))
	&& ($menu->{'size'} != 0 || $menu->{'title'} ne "");
    ;;;warn ($menu->{'filename'} . " ... " . $filename);
    if ($menu->{'filename'} eq $filename) {
	;;;    warn $menu->{'title'};
       return $menu->{'title'};
    }
    for (my $i=0 ; $i<$menu->{'size'} ; $i++) {
        my $path=menu_build_path($filename, $menu->{$i});
	if ($path ne "") {
	    ;;;warn $menu->{'title'};
	    return $menu->{'title'} . "/" . $path;
        }
    }
    return "";
}

#############
# sub menu_do
#  build the menu, and output it

sub menu_do {
    my $path=shift;
    my $list=shift;

    my $menu=menu_parse($list);
 
    if ($path eq "") {
       $path=menu_build_path("$(OUTPUTFILENAME)", $menu);
       $path =~ s,^/,,;
    }
    ;;;warn $path;
    menu_output([split(/\//,$path)],$menu)
}
</perl>


{#banner#: \
<header title="$(title)"> \
<perl> \
  $menu=menu_do("$(path)","<menu-list>"); \
  <perl:print>$menu</perl:print> \
</perl> \
</header> \
:#banner#}

{#PAGETITLE#:
<perl>
my $tit;<perl:assign $tit>$(title)</perl:assign>
$tit =~ s/_/ /g;
;;; FIXME $tit = gettext $tit;
<perl:print>$tit</perl:print>
</perl>
:#PAGETITLE#}