#!/usr/local/bin/perl -w

use strict ;

use Carp ;
use YAML ;

my @slides ;

my %book_values ;
my ( $chap_title, $chap_abbrev ) ;

my $page_num = 0 ;		# number as read in
my $slide_num = 0 ;		# slide within a chapter
my $chap_num  = 0 ;

my %part2sub = (

	'book'		=> \&process_book,
	'title'		=> \&process_title,
	'chapter'	=> \&process_chapter,
	'code'		=> \&process_code,
	'code2'		=> \&process_code2,
	'*'		=> \&process_bullet,
	'**'		=> \&process_bullet2,
	'haiku'		=> \&process_haiku,
	'html'		=> \&process_html,
) ;


read_parse_pages() ;

make_index() ;

make_slides() ;

#print Dump \@slides ;

exit ;

sub read_parse_pages {

	local( $/ ) = "PAGE_END\n" ;

	while ( my $page = <> ) {

		chomp( $page ) ;

		next unless $page =~ /\S/ ;

		push @slides, parse_page( $page ) ;
	}

	$book_values{'TOTAL_PAGES'} = $page_num ;
}

sub parse_page {

	my ( $page_text ) = @_ ;

	my $slide = {
		'PAGE_NUM'	=> ++$page_num,
		'SLIDE_NUM'	=> ++$slide_num,
		'CHAP_NUM'	=> $chap_num,
	} ;

	foreach my $part ( split( /(?=^(?:\w+|\*+|):)/m, $page_text ) ) {

		next unless $part =~ /\S/ ;

 		my ( $part_type, $part_body ) = split /:/, $part, 2 ;

		my $part_sub = $part2sub{ lc $part_type } or die
 			"unknown slide part '$part_type'\n$page_text" ;

 		$part_sub->( $slide, $part_body ) ;
	}

	return $slide ;
}


sub process_book {

	my( $slide, $book_text ) = @_ ;

	$book_values{'BOOK_NAME'} = $book_text ;
}

sub process_chapter {

	my( $slide, $chapter_text ) = @_ ;

	( $chap_title, $chap_abbrev ) = split( /\n/, $chapter_text ) ;

	$chap_title =~ tr/\n / /s ;
	$slide->{'CHAPTER'} = $chap_title ;

	if ( $chap_abbrev ) {
		$chap_abbrev =~ tr/\n / /s ;
		$slide->{'CHAP_ABBREV'} = $chap_abbrev ;
	}

	$chap_num++ ;
	$slide_num = 1 ;
	$slide->{'SLIDE_NUM'} = $slide_num ;
	$slide->{'CHAP_NUM'} = $chap_num ;
}

sub process_title {

	my( $slide, $title_text ) = @_ ;

	$title_text =~ tr/\n / /s ;

	$slide->{'TITLE'} = $title_text ;

	$slide->{'CHAPTER'} = $chap_title ;
	$slide->{'CHAP_ABBREV'} = $chap_abbrev ;
}

sub process_bullet {

	my( $slide, $bullet_text ) = @_ ;

	my ( $bullet, @paras ) = split /\n{2,}/, $bullet_text ;
#	escape_entities( $_ ) for $bullet, @paras;
	escape_entities( $_ ) for @paras;
		
	push( @{$slide->{'html_parts'}},
		apply_template( 'bullet', { 'TEXT' => $bullet } ),
		map apply_template( 'para', { 'TEXT' => $_ } ), @paras ) ;
}

sub process_bullet2 {

	my( $slide, $bullet_text ) = @_ ;

	my ( $bullet, @paras ) = split /\n{2,}/, $bullet_text ;
#	escape_entities( $_ ) for $bullet, @paras;
	escape_entities( $_ ) for @paras;
	
	push( @{$slide->{'html_parts'}}, "<UL>\n",
		apply_template( 'bullet2', { 'TEXT' => $bullet } ),
		map( apply_template( 'para', { 'TEXT' => $_ } ), @paras ),
		"</UL>\n",
	) ;
}

sub process_code {

	my( $slide, $code_text ) = @_ ;

	$code_text =~ s/^\n// ;
	escape_entities( $code_text ) ;

	$code_text =~ s/<blue>/<font color="#0000ff">/gi ;

	push( @{$slide->{'html_parts'}},
		apply_template( 'code', { 'TEXT' => $code_text } ) ) ;
}

#  sub process_code2 {

#  	my( $slide, $code_text ) = @_ ;

#  	$code_text =~ s/^\n// ;
#	escape_entities( $code_text ) ;

#  	push( @{$slide->{'html_parts'}},
#  		apply_template( 'code2', { 'TEXT' => $code_text } ) ) ;
#  }

sub escape_entities {

print caller() if $_[0] =~ /IMG/ ;

	$_[0] =~ s/&/&amp;/g ;
	$_[0] =~ s/</&lt;/g ;
	$_[0] =~ s/>/&gt;/g ;
}

sub process_haiku {

	my( $slide, $haiku_text ) = @_ ;

	$haiku_text =~ tr/\n / /s ;

	my @lines = split m{:}, $haiku_text ;

	push( @{$slide->{'html_parts'}},
		apply_template(
			'haiku',
			{ LINE1 => $lines[0],
			  LINE2 => $lines[1],
			  LINE3 => $lines[2] }
		)
	) ;
}

sub process_html {

	my( $slide, $html_text ) = @_ ;

	push( @{$slide->{'html_parts'}}, $html_text ) ;
}

sub make_slides {

	foreach my $slide ( @slides ) {

		my $page_num = $slide->{'PAGE_NUM'} ;

		if ( $page_num > 1 ) {

			my $prev_slide = $slides[$page_num - 2] ;
			$slide->{'PREV_FILE'} = $prev_slide->{'slide_file'} ;
			$slide->{'PREV_TITLE'} = $prev_slide->{'TITLE'} ;
		}

		if ( $page_num < $book_values{'TOTAL_PAGES'} ) {

			my $next_slide = $slides[$page_num] ;
			$slide->{'NEXT_FILE'} = $next_slide->{'slide_file'} ;
			$slide->{'NEXT_TITLE'} = $next_slide->{'TITLE'} ;
		}


		my $header = apply_template( 'header', $slide ) ;
		my $footer = apply_template( 'footer', $slide ) ;

		my $slide_file = "slides/$slide->{'slide_file'}" ;

		write_file( $slide_file,
			$header,
			"<UL>\n",
			@{$slide->{'html_parts'}},
			"</UL>\n",
			$footer,
		) ;
	}
}

sub make_index {

	my $name = $book_values{'BOOK_NAME'} || 'Empty' ;

	my $index_html = <<HTML ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Index of $name</TITLE>
</HEAD>
<H2>Index of $name</H2>
<P>
<UL STYLE="list-style-type:none">
HTML

	my $toc_html = <<HTML ;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Table of Contents for $name</TITLE>
</HEAD>
<H2>Table of Contents for $name</H2>
<P>
<UL STYLE="list-style-type:none">
HTML

	foreach my $slide ( @slides ) {

		my $chap_num = $slide->{'CHAP_NUM'} ;
		my $slide_num = $slide->{'SLIDE_NUM'} ;

		my $slide_file = sprintf( "slide-%02d%02d.html",
					  $chap_num,
					  $slide_num ) ;

		$slide->{'slide_file'} = $slide_file ;

		if ( $slide_num == 1 ) {

			my $chapter = $slide->{'CHAPTER'} || '' ;

			$index_html .= "</UL>\n" if $chap_num > 1 ;

			$index_html .= <<HTML ;
  <LI>$chap_num. <A href="$slide_file">$chapter</A>
    <UL STYLE="list-style-type:none">
HTML


			$toc_html .= <<HTML ;
  <LI>$chap_num. <A href="$slide_file">$chapter</A>
HTML

		}

		$index_html .= <<HTML ;
    <LI>$chap_num.$slide_num <A href="$slide_file">$slide->{'TITLE'}</A>
HTML

	}

	$index_html .= <<HTML ;
</UL>
</HTML>
HTML

	$toc_html .= <<HTML ;
</UL>
</HTML>
HTML


	write_file( 'slides/index.html', $index_html ) ;
	$book_values{'INDEX'} = 'index.html' ;

	write_file( 'slides/toc.html', $toc_html ) ;
	$book_values{'TOC'} = 'toc.html' ;
}

my %templates ;

sub apply_template {

	my( $tmpl_name, $add_values ) = @_ ;

	my $template = $templates{ $tmpl_name } ;

	unless( $template ) {

		$template = read_file( "templates/$tmpl_name.tmpl" ) ;

		$templates{ $tmpl_name } = $template ;
	}

	my %tmpl_values = ( %book_values, %{$add_values} ) ;

	$template =~ s/<%(\w+?)%>/$tmpl_values{$1} || ''/ge ;

	$template =~ s[<A HREF="">(.+?)</A>][$1]i ;

	return $template ;
}

sub read_file {

	my( $file_name ) = shift ;

	my( $buf ) ;

	local( *FH ) ;

	open( FH, $file_name ) || croak "can't open $file_name $!" ;

	return <FH> if wantarray ;

	read( FH, $buf, -s FH ) ;
	return $buf ;
}

sub write_file {

	my( $file_name ) = shift ;

	local( *FH ) ;

	open( FH, ">$file_name" ) || croak "can't create $file_name $!" ;

	print FH @_ ;
}
