;;; 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/:down.php
;;;       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"
;;;  Spaces can be used (protected by '\')
;;;  PHP files MUST HAVE their extention writen, and NOT html files

;;;  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.
;;;  Update (Vince) : path is not used anymore.
;;;                   ========================
;;;    The line from the menu is selected from the name of the macro
;;;    OUTPUTFILENAME set in the Makefile (it's the name of the output
;;;    without the html extention)
;;;  TODO : use the automatique variable WML_SRC_FILENAME or WML_SRC_BASENAME
;;;    (take care of php)

;;; 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)

wml::Utils::perl
#use wml::Utils::perl

;;; 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|; 
  <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.

<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 $class=shift;
    my $res="";
    my $post;
    my $cur_path=shift @$path;

    if (!defined($class)) {
        $class= " class=\"MainFolder\"";
    }

    return unless (defined($menu->{'size'}) || defined($menu->{'title'}))
	          && ($menu->{'size'} != 0 || $menu->{'title'} ne "");
    if ($menu->{'size'} != 0) {
	$res .= "\n <div $class><ul>\n";    
    }
    for (my $i=0 ; $i<$menu->{'size'} ; $i++) {
        my $filename,$title;
	$filename=$menu->{$i}->{'filename'};	
	$title=$menu->{$i}->{'title'};
	
	# Add the cruft to mark open and closed folders
	if ($menu->{$i}->{'size'} > 0) {
	    if (defined($title)
		&& defined($cur_path)
	        && $title eq $cur_path) {
	      
		$class = " class=\"OpenedFolder\"";
	    } else {
		$class = " class=\"ClosedFolder\"";
	    }
	} else {
		$class = " class=\"NoFolder\"";
	}
        $res .= "  <li $class>    \n";

	# Add the link to this page
	$res .= "<a href=\"".$filename."\" ";
	my ($class2)="OutPath";
	my ($next_path)=$path;	

	if (defined($title)
	    && defined($cur_path)
	    && $title eq $cur_path) {
	    $class2 = defined($path->[0]) ? "OnPath" : "SelectedPath";
	} else {
	    my(@tlb)=();
	    $next_path=\@tbl;
	}
	$res .= "class=\"$class2\">".$title."</a>";
	$res .= menu_output($next_path,$menu->{$i},$class);
	$res .= "\n  </li>\n";
    }
    if ($menu->{'size'} != 0) {
	$res .= "</ul></div>\n";
    }
    unshift @$path, $cur_path;
    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 ||
	$menu->{'filename'} eq $filename.".html") {
	;;;    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,^/,,;
    }
    ;;; $path;
    menu_output([split(/\//,$path)],$menu)
}
</perl>



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

{#INTAG_TITLE#:
{#PAGETITLE#}
:#INTAG_TITLE#}

{#TITLE_LINE#:
<div class="TitleLine">
$(title)
</div>
:#TITLE_LINE#}

{#MENU#:
<div class="MainMenu">
<perl>
  $menu=menu_do("$(path)","<menu-list/>");
  <perl:print>$menu</perl:print>
</perl>
</div>
:#MENU#}


{#IN_HEADER#:
<div id="menu">
{#TITLE_LINE#}
{#MENU#}
</div>
:#IN_HEADER#}

wml::Utils::mailto
#use wml::Utils::mailto
;;; <sources-dir>: directory where html source pages are generated
;;;    (ie $(SOURCES_DIR) if defined or ".")

;;;
;;; Tag sources-dir
;;;
;;; directory where html source pages are generated
<define-tag sources-dir whitespace=delete>
<ifneq "$(SOURCES_DIR)" "." "$(SOURCES_DIR)/" />
</define-tag>

{#IN_FOOTER#:
<div class="validators">
  <p class="xhtml">
    <a href="http://validator.w3.org/check/referer"><img
          src="Icons/valid-xhtml11"
          alt="Valid XHTML 1.1!" height="31" width="88" />
    </a>

;;;    <form method="post" enctype="multipart/form-data" 
;;;       action="http://validator.w3.org/check">
;;;    <input type="file" id="uploaded_file" name="uploaded_file"
;;;     size="50" value="/home/vdanjean/public_html/<mainfile>.html" />
;;;    <input type="submit" value="Validate this file" />
;;;    </form>
  </p>
  <p class="css">
    <a href="http://jigsaw.w3.org/css-validator/check/referer">
      <img src="Icons/vcss" alt="Valid CSS!" height="31" width="88"/>
    </a>
  </p>
</div>
<div class="infos">
<div class="modifs">
      Last modification : <:= &isotime(time()) :>
</div>
;;;<div class="mailto">
;;;  <mailto email="<my-email />" />
;;;</div>
<div class="source">
      View <a href="<sources-dir /><mainfile />.wml.html">source</a>.
</div>
</div>
:#IN_FOOTER#}