package Statocles::Page::Document;
# ABSTRACT: Render document objects into HTML
$Statocles::Page::Document::VERSION = '0.064';
use Statocles::Base 'Class';
with 'Statocles::Page';
use Statocles::Template;


has document => (
    is => 'ro',
    isa => InstanceOf['Statocles::Document'],
    required => 1,
);


has '+title' => (
    lazy => 1,
    default => sub { $_[0]->document->title },
);


has author => (
    is => 'rw',
    isa => Str,
    lazy => 1,
    default => sub { $_[0]->document->author || '' },
);


has '+date' => (
    lazy => 1,
    default => sub {
        my ( $self ) = @_;
        $self->document->date || Time::Piece->new;
    },
);


has _tags => (
    is => 'rw',
    isa => LinkArray,
    default => sub { [] },
    coerce => LinkArray->coercion,
    init_arg => 'tags',
);

has '+_links' => (
    default => sub { $_[0]->document->links },
);

has '+_images' => (
    default => sub { $_[0]->document->images },
);


sub _render_content_template {
    my ( $self, $content, $vars ) = @_;
    my $tmpl = $self->site->theme->build_template( $self->path, $content );
    my $rendered = $tmpl->render( %$vars, $self->vars, self => $self->document, page => $self );
    return $rendered;
}


sub content {
    my ( $self, %vars ) = @_;
    my $content = $self->document->content;
    my $rendered = $self->_render_content_template( $content, \%vars );
    return $self->markdown->markdown( $rendered );
}


around vars => sub {
    my ( $orig, $self ) = @_;
    return (
        $self->$orig,
        doc => $self->document,
    );
};


has _rendered_sections => (
    is => 'rw',
    isa => ArrayRef,
    predicate => '_has_rendered_sections',
);

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

    if ( $self->_has_rendered_sections ) {
        return @{ $self->_rendered_sections };
    }

    my @sections =
        map { $self->markdown->markdown( $_ ) }
        map { $self->_render_content_template( $_, {} ) }
        split /\n---\n/,
        $self->document->content;

    $self->_rendered_sections( \@sections );
    return @sections;
}


sub tags {
    my ( $self, $new_tags ) = @_;
    if ( $new_tags ) {
        return $self->_tags( $new_tags );
    }
    return @{ $self->_tags };
}


around template => sub {
    my ( $orig, $self, @args ) = @_;
    if ( $self->document->has_template ) {
        return $self->site->theme->template( @{ $self->document->template } );
    }
    return $self->$orig( @args );
};


around layout => sub {
    my ( $orig, $self, @args ) = @_;
    if ( $self->document->has_layout ) {
        return $self->site->theme->template( @{ $self->document->layout } );
    }
    return $self->$orig( @args );
};

1;

__END__

=pod

=head1 NAME

Statocles::Page::Document - Render document objects into HTML

=head1 VERSION

version 0.064

=head1 DESCRIPTION

This page class takes a single L<document|Statocles::Document> and renders it as HTML.

=head1 ATTRIBUTES

=head2 document

The L<document|Statocles::Document> this page will render.

=head2 title

The title of the page.

=head2 author

The author of the page.

=head2 date

Get the date of this page by checking the document.

=head2 tags

The tag links for this document. An array of L<link objects|Statocles::Link>. The
most important attributes are:

    text    - The text of the link
    href    - The page of the link

=head1 METHODS

=head2 content

    my $html = $page->content( %vars );

Generate the document HTML by processing template directives and converting
Markdown. C<vars> is a set of name-value pairs to give to the template.

=head2 vars

    my %vars = $page->vars;

Get the template variables for this page.

=head2 sections

    my @sections = $page->sections;

Get a list of rendered HTML content divided into sections. The Markdown "---"
marker divides sections.

=head2 tags

    my @tags = $page->tags;

Get the list of tags for this page.

=head2 template

    my $tmpl = $page->template;

The L<template object|Statocles::Template> for this page. If the document has a template,
it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
be used.

=head2 layout

    my $tmpl = $page->layout;

The L<layout template object|Statocles::Template> for this page. If the document has a layout,
it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
be used.

=head1 AUTHOR

Doug Bell <preaction@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2016 by Doug Bell.

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

=cut
