#!/usr/local/bin/perl

use strict ;
use warnings ;

use CMS::Simple ;
use CMS::Simple::Filter::Markup ;

use HTML::Entities;
use File::Slurp ;
use Data::Dumper ;


my $cont_file = shift @ARGV || 'compshare.cont' ;


my @filters = (
# 	{
# 		name	=> 'html_escape',
# 		tags	=> [ qw( code ) ],
# 		code	=> \&html_escape,
# 	},
	{
		name	=> 'markup',
		tags	=> [ qw( text email image ) ],
		code	=> \&CMS::Simple::Filter::Markup::filter_markup,
	},
) ;


my $conf = {

	output_suffix => '.html',

	contents => {

#		page_header	=> 'header.cont',
#		page_footer	=> 'footer.cont',
#		book		=> 'compshare.cont',
	},

	filters	 => \@filters,

	default_template	=> 'base_page',

# this maps loaded contents to location in this page's data tree.
# the location will be multilevel later on

# the page key name is the base name for the output file

	pages => {

		chapters => {
			template	=> 'chapters',
		},

		index => {

			template	=> 'index',
		},
	},
} ;


load_book_content( $conf, $cont_file ) ;

#print Dumper $conf ;
#print Dumper $conf->{pages} ;

my $cms = CMS::Simple->new( $conf ) ;

$cms->build_all_pages() ;

exit ;


sub load_book_content {

	my( $conf, $cont_file ) = @_ ;

	my $cont_text = read_file( "contents/$cont_file" ) ;
	my $content = CMS::Simple::Parse::parse_content( $cont_text ) ;

	process_book_content( $conf, $content ) ;

#print Dumper $content ;

}

sub process_book_content {

	my( $conf, $book_cont ) = @_ ;

	my $book_title = $book_cont->{book}{title} ;

	my $chap_conts = $book_cont->{chapter} ;
	$chap_conts = [ $chap_conts ] unless ref $chap_conts eq 'ARRAY' ;

	my $chap_num = '01' ;

	foreach my $chap_cont ( @{$chap_conts} ) {

		$chap_cont->{number} = $chap_num++ ;
		$chap_cont->{book_title} = $book_title ;

		process_chap_content( $conf, $chap_cont ) ;
	}

	process_index_page( $conf, $chap_conts ) ;

#print Dumper $conf ;

}
		
sub process_index_page {

	my( $conf, $chap_conts ) = @_ ;

	my $index_cont = $conf->{pages}{index}{contents} ||= {} ;

	foreach my $chap_cont ( @{$chap_conts} ) {

		my $page_titles = $chap_cont->{page_title} ;

		push( @{$index_cont->{chapter}}, {

			chap_title	=> $chap_cont->{title},
			chap_num	=> $chap_cont->{number},
			page => $page_titles,
		} ) ;
	}

print Dumper $index_cont ;

}



sub process_chap_content {
		
	my( $conf, $chap_data ) = @_ ;

	my $chap_title = $chap_data->{title} ;

	my $chap_page_cont = $conf->{pages}{chapters}{contents} ||= {} ;

	push( @{$chap_page_cont->{chap_title}}, {
		number	=> $chap_data->{number},
		title	=> $chap_title
	} ) ;

	my $page_conts = $chap_data->{page} ;
	$page_conts = [ $page_conts ] unless ref $page_conts eq 'ARRAY' ;

	my $page_num = '01' ;

	foreach my $page_cont ( @{$page_conts} ) {

		$page_cont->{number} = $page_num++ ;

#print Dumper $page_cont ;

		process_page_content( $conf, $chap_data, $page_cont ) ;
	}
}


sub process_page_content {
		
	my( $conf, $chap_data, $page_data ) = @_ ;

	my $chap_title = $chap_data->{title} ;
	my $page_title = $page_data->{title} ;


#print "TITLE $page_title\n" ;

	my $chap_num = $chap_data->{number} ;
	my $page_num = $page_data->{number} ;

	my $page_name = "page-$chap_num$page_num" ;
	my $page_url = "$page_name.html" ;

	push( @{$chap_data->{page_title}}, {
		number	=> $page_num,
		title	=> $page_title,
		page_link	=> $page_url,
	} ) ;

	my $page = {

		name		=> $page_name,
		template	=> 'page',
	} ;

	my $header_cont = {

		header_title	=> {
			text	=> $page_title,
		},

		book_title	=> $chap_data->{book_title} || 'FOO',
		index_link	=> {
			text => 'index.html',
		},
		chap_link	=> 'chapters.html',
	} ;

	if ( $page_num > 1 ) {

		my $prev_page_num = sprintf "%02d", $page_num - 1 ;
		$header_cont->{prev_link} = {
			prev_page	=> "page-$chap_num$prev_page_num.html",
		} ;
	}

	if ( $page_num < 50 ) {

		my $next_page_num = sprintf "%02d", $page_num + 1 ;
		$header_cont->{next_link} = {
			next_page	=> "page-$chap_num$next_page_num.html",
		} ;
	}


#print Dumper $page_data ;

	my $items = process_page_items( $page_data ) ;

	my $page_cont = {
		page	=> {
			item => $items,
		},
	} ;

	set_page_header_data( $page_cont, $header_cont ) ;

	$page->{contents} = $page_cont ;
#print Dumper $page_cont ;

	$conf->{pages}{$page_name} = $page ;

}

sub process_page_items {

	my( $page_data ) = @_ ;

	my $items = $page_data->{item} ;
	$items = [ $items ] unless ref $items eq 'ARRAY' ;

	foreach my $item ( @{$items} ) {


		if ( ref $item ) {

			$item->{title} = {
				text	=> $item->{title},
			} ;
		}
		else {

			$item = {
				title => {
					text	=> $item,
				},
			} ;
		}

		process_subitems( $item ) ;
		process_code( $item ) ;
	}

#print Dumper $items ;

	return $items ;
}

sub process_subitems {

	my( $item ) = @_ ;

	my $subitems = $item->{subitem} ;

	return unless $subitems ;

	$subitems = [ $subitems ] unless ref $subitems eq 'ARRAY' ;

	$item->{subitems} = [
		map {

			subitem	=> {
				text => $_
			}
		}, @{$subitems}
	] ;
}

sub process_code {

	my( $item ) = @_ ;

	my $code = $item->{code} ;

	return unless $code ;

# append a newline if needed - scalar content loses a trailing newline

#print "CODE: [$code]\n" ;

	$code =~ s/(?<!\n)\z/\n/ ;
	$code =~ s/^/\n\n/ ;

	$code = encode_entities( $code, '<>&"') ;

	$item->{code} =  {
		text => $code
	} ;
}



sub set_page_header_data {

	my( $page_cont, $data ) = @_ ;

	for my $header ( qw( html_header page_header page_footer ) ) {

		@{$page_cont->{$header}}{keys %{$data}} = values %{$data} ;
	}
}

