#!/bin/perl -w

use strict;
use XML::Twig;

my $h2_nb=0;
my $h3_nb=0;
my $h4_nb=0;

my $title;
my $info;
my @toc;
my %example;


my $t= XML::Twig->new( twig_roots => { h2 => \&h2_first_pass },);

if( $ARGV[0]) { $t->parsefile( $ARGV[0]); }      # process the twig
else          { $t->parse( \*STDIN);      }


$t= XML::Twig->new
         ( twig_handlers =>
             { h1          => \&h1,
               author      => sub { $info  = "<p>by <b>" . $_->text . "</b>";         },	
               date        => sub { $info .= "<br />updated <i>".$_->text."</i></p>"; },	
               h2          => \&h2,
               h3          => \&h3,
               h4          => \&h4,
               example     => \&example,
               br          => \&process_empty,
               hr          => \&process_empty,
               td          => \&td,
               section     => \&section,
               tutorial    => \&tutorial,
               method      => \&method,
               pre         => \&pre,
             },
          );

if( $ARGV[0]) { $t->parsefile( $ARGV[0]); }      # process the twig
else          { $t->parse( \*STDIN);      }



sub h2_first_pass
  { my( $t, $h2)= @_;
    $h2_nb++;
    my $filename= filename( $h2_nb);
    my $section_title= "$h2_nb. " . $h2->text;
    push @toc, { file => $filename, title => $section_title};
  }

sub h1
  { my( $t, $h1)= @_;
    $h2_nb=0;
    $title= $h1->text;
  }

sub h2
  { my( $t, $h2)= @_;
    $h2_nb++;
    $h3_nb=0;
    $h2->prefix( "$h2_nb. ");
  }

sub h3
  { my( $t, $h3)= @_;
    $h3_nb++;
    $h4_nb=0;
    $h3->prefix( "$h2_nb.$h3_nb ");
  }

sub h4
  { my( $t, $h4)= @_;
    $h4_nb++;
    $h4->prefix( "$h2_nb.$h3_nb.$h4_nb ");
  }

sub pre
  { my( $t, $pre)= @_;
    $pre->remove_cdata;
  }

sub example
  { my( $t, $example)= @_;
    # first get the included file
    my $file= $example->text;
    open( EXAMPLE, "<$file") or die "cannot open file $file: $!";
    local undef $/;
    my $text= <EXAMPLE>;

    my $parser= $t->{twig_parser};
    my $table= XML::Twig::Elt->new( 'table', $text);

    my $p= $example->parent;
    $table->paste( 'after', $p);

    $table->insert( 'tr', 'td', 'pre');
    $table->set_att( border => 1);
    $table->set_att( width => "100%");
    $table->set_att( bgcolor => "#00FFFF");


    $example->set_gi( 'a');
    $example->set_att( href => $file);

    if( $example->att( 'class') && ($example->att( 'class') eq 'code') )
      { $example{$file}= $example->att( 'desc');
        $example->del_att( 'desc');
        $example->del_att( 'class');
      }
    
  }

sub process_empty
  { my( $t, $empty)= @_;
    my $html_empty= XML::Twig::Elt->new( PCDATA, "<" . $empty->gi . ">");
    $html_empty->paste( 'before', $empty);
    $empty->cut;
  }

sub td
  { my( $t, $td)= @_;
    $td->set_text( '&nbsp;') unless( $td->text);
  }

sub method
  { my( $t, $method)= @_;
    $method->set_gi( 'tt');
    my $a= $method->insert( 'a');
    my $class= $method->att( 'class');
		if( $class=~ /^twig/)
		  { $class= ucfirst $class; }
		elsif( $class=~ /^elt/)
		  { $class= 'Twig_' . ucfirst $class; }
    my $item= $method->text;
    $method->del_att( 'class');
    $a->set_att( href => "../twig_dev.html#METHODS_XML_$class\_$item");
  }



sub section
  { my( $t, $section)= @_;
    my $filename="yapc_twig_s$h2_nb.html";
    warn "creating section $h2_nb\n";
    open( SECTION, ">$filename") or die "cannot open $filename: $!";
    select SECTION;

    my $body= $section->insert( 'body');
    $body->set_att( bgcolor => "#FFFFFF");
    my $head= XML::Twig::Elt->new( 'head');
    $head->paste( $section);
    my $title= XML::Twig::Elt->new( 'title', "Processing XMl efficiently with XML::Twig - Section $h2_nb");
    $title->paste( $head);
    $head->insert_new_elt( last_child => meta => { content => "main", name => "template"});

    my $top_links= links( $h2_nb);
    my $bottom_links= $top_links->copy;

    $top_links->paste( $body);
    my $hr= XML::Twig::Elt->new( hr => '#EMPTY');
    $hr->paste( after => $top_links);
    
    $bottom_links->paste( 'last_child', $body);
    $hr= XML::Twig::Elt->new( hr => '#EMPTY');
    $hr->paste( before => $bottom_links);


    $section->set_gi( 'html');

    $section->print;

    $t->purge;
    close SECTION;
  }

sub tutorial
  { my $filename="index.html";
    open( INDEX, ">$filename") or die "cannot open $filename: $!";
    select INDEX;
    print "<html>\n<head><title>$title</title></head>\n";
    print "<body bgcolor=\"#FFFFFF\"><h1>$title</h1>\n";
    print $info;
    print "<hr />\n";

    print "<h2>Table of Content</h2>\n<ul>";
    foreach my $toc(@toc) 
      { print '<li><a href="' . $toc->{file} . '">'. $toc->{title} . "</a></li>\n"; } 
    print "</ul>\n";

    print "<h2>Code Examples</h2>\n<p>";
    foreach my $file ( sort keys %example)
      { print "<a href=\"$file\">$file</a>: $example{$file}<br />\n"; }
    print "</p>\n";
    
    print "</body></html>";
    close INDEX;
  }

sub filename
  { my $section= shift;
    return "yapc_twig_s$section.html";
  }

sub links
  { my $section  = shift;
    my $current  = $section-1;
    my $previous = $current-1;
    my $next     = $current+1;

    my $table= XML::Twig::Elt->new( 'table');
    $table->set_att( width => "100%" );
    my $tr= $table->insert( 'tr');
   
    my $td= $tr->insert( 'td');
    $td->set_atts( { align => "left", width => "33%" });
    unless( $previous == -1)
      { my $a= $td->insert( 'a');
        $a->set_att( href => $toc[$previous]->{file});
        my $img= $a->insert( 'img');
        $img->set_atts( { src => "previous.gif", alt => "Previous", border => "0" });
        my $text= XML::Twig::Elt->new( PCDATA, { '#ASIS' => 1}, "<br />" . $toc[$previous]->{title});
        $text->paste( 'last_child', $a);
      }
    else
      { my $nbsp= XML::Twig::Elt->new( PCDATA, "");
        $nbsp->paste( $td);
      }

    $td= XML::Twig::Elt->new( 'td', { '#ASIS' => 1}, '<a href="index.html">'.
                     '<img src="home.gif" border="0" alt="Table of Content" />' .
                     '<br />Table of Content</a>'); $td->set_asis;
    $td->set_atts( { align => "center", width => "34%" });
    $td->paste( 'last_child', $tr);

   
    $td= XML::Twig::Elt->new( 'td');
    $td->set_atts( { align => "right", width => "33%" });
    unless( $next > $#toc)
      { my $a= $td->insert( 'a');
        $a->set_att( href => $toc[$next]->{file});
        my $img= $a->insert( 'img');
        $img->set_atts( { src => "next.gif", alt => "Next", border => "0"});
	my $text= XML::Twig::Elt->new( '#PCDATA' => {'#ASIS' => 1}, "<br />" . $toc[$next]->{title});
	$text->paste( 'last_child', $a);
      }
    else
      { my $nbsp= XML::Twig::Elt->new( PCDATA, {'#ASIS' => 1}, "");
        $nbsp->paste( $td);
      }
    $td->paste( 'last_child', $tr);

    return $table;
  }
