package App::Followme::PodData;

use 5.008005;
use strict;
use warnings;
use integer;
use lib '../..';

use base qw(App::Followme::FileData);

use Pod::Simple::XHTML;
use File::Spec::Functions qw(abs2rel catfile rel2abs splitdir);

use App::Followme::FIO;
use App::Followme::Web;

our $VERSION = "1.91";

#----------------------------------------------------------------------
# Read the default parameter values

sub parameters {
    my ($self) = @_;

    return (
            extension => 'pm,pod',
            title_template => '<h2></h2>',
            package => '',
            pod_directory => '',
           );
}

#----------------------------------------------------------------------
# Extract the content between body tags in a web page

sub extract_body {
    my ($self, $html) = @_;

    my @section = split(/<\s*\/?body[^>]*>/i, $html);
    s/^\s+// foreach @section;

    return $section[1];
}

#----------------------------------------------------------------------
# Parse content as html to get values for data

sub fetch_content {
    my ($self, $content_block) = @_;

    my %content;
    $content{body} = $content_block;

    if ($self->{title_template}) {
        my $title_parser = sub {
                my $title = web_only_text(@_);
                $title =~ s/\s+/_/g;
                return lc($title);
            };

        my $section = web_titled_sections($self->{title_template},
                                          $content_block,
                                          $title_parser);

        my %mapping = ('title' => 'name',
                       'description' => 'description',
                       'summary' => 'description',
                       );

        while (my ($cname, $sname) = each %mapping) {
            $content{$cname} = $section->{$sname};
        }

        foreach my $cname (qw(title)) {
            my @tokens = web_split_at_tags($content{$cname});
            $content{$cname} = web_only_text(@tokens);
        }
    }


    return %content;
}

#----------------------------------------------------------------------
# Convert Pod into html

sub fetch_as_html {
    my ($self, $text) = @_;

    my ($h_level) = $self->{title_template} =~ /\d+/;
    $h_level = 1 unless defined $h_level;

    my $psx = Pod::Simple::XHTML->new();

    $psx->html_charset('UTF-8');
    $psx->html_encode_chars('&<>"');
    $psx->html_h_level($h_level);
    $psx->perldoc_url_prefix($self->{site_url});

    my $html;
    $psx->output_string(\$html);
    $psx->parse_string_document($text);

     return $self->extract_body($html);
}

#----------------------------------------------------------------------
# Split into text from file into section blocks.

sub fetch_sections {
    my ($self, $text) = @_;

    my %section;
    $section{body} = $self->fetch_as_html($text);
    $section{metadata} = '';

    return \%section;
}

#----------------------------------------------------------------------
# Find the directory containing the pod files

sub find_pod_directory {
    my ($self)= @_;

    my @package_path = split(/::/, $self->{package});
    pop(@package_path);

    my $package_folder = catfile(@package_path);
    my @folders = (split(/\s*,\s*/, $self->{pod_directory}), @INC);

    for my $folder (@folders) {
        my $pod_folder = catfile($folder, $package_folder);
        if (-e $pod_folder) {
            return $pod_folder;
        }
    }

    return;
}

#----------------------------------------------------------------------
# Initialize the pod parser

sub initialize_parser {
    my ($self, $html) = @_;

    my $psx;
    my ($h_level) = $self->{title_template} =~ /\d+/;
    $h_level = 1 unless defined $h_level;

    $psx = Pod::Simple::XHTML->new();

    $psx->html_charset('UTF-8');
    $psx->html_encode_chars('&<>"');
    $psx->html_h_level($h_level);
    $psx->perldoc_url_prefix($self->{site_url});
    $psx->output_string(\$html);

    return $psx;
}

#----------------------------------------------------------------------
# Initialize pod parser and find pod directory

sub setup {
    my ($self, %configuration) = @_;

    my $directory = $self->find_pod_directory();
    die "Couldn't find folder for $self->{package}" unless defined $directory;
    $self->{base_directory} = $directory;

    return;
}

1;
__END__
=encoding utf-8

=head1 NAME

App::Followme::PodData - Convert Pod files to html

=head1 SYNOPSIS

    use App::Followme::PodData;
    my $data = App::Followme::PodData->new();
    my $html = App::Followme::Template->new('example.htm', $data);

=head1 DESCRIPTION

This module converts Perl files with POD markup into html and extracts the
metadata from the html.

=head1 METHODS

All data are accessed through the build method.

=over 4

=item my %data = $obj->build($name, $filename);

Build a variable's value. The first argument is the name of the variable. The
second argument is the name of the file the metadata is being computed for. If
it is undefined, the filename stored in the object is used.

=back

=head1 VARIABLES

The Pod metadata class can evaluate the following variables. When passing
a name to the build method, the sigil should not be used.

=over 4

=item $body

All the contents of the file, minus the title if there is one. Markdown is
called on the file's content to generate html before being stored in the body
variable.

=item $description

A one line sentence description of the content.

=item $title

The title of the page is derived from contents of the top header tag, if one is
at the front of the file content, or the filename, if it is not.

=back

=head1 CONFIGURATION

The following parameters are used from the configuration:

=over 4

=item extension

The extension of files that are converted to web pages. The default value
is pod.

=item pod_directory

The directory containing the pod files

=back

=head1 LICENSE

Copyright (C) Bernie Simon.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 AUTHOR

Bernie Simon E<lt>bernie.simon@gmail.comE<gt>

=cut
