package Statocles::Page::Document;
$Statocles::Page::Document::VERSION = '0.073';
# ABSTRACT: Render document objects into HTML

use Statocles::Base 'Class';
with 'Statocles::Page';
use Statocles::Template;
use Statocles::Store;

#pod =attr document
#pod
#pod The L<document|Statocles::Document> this page will render.
#pod
#pod =cut

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

#pod =attr title
#pod
#pod The title of the page.
#pod
#pod =cut

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

#pod =attr author
#pod
#pod The author of the page.
#pod
#pod =cut

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

#pod =attr date
#pod
#pod Get the date of this page by checking the document.
#pod
#pod =cut

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

#pod =attr tags
#pod
#pod The tag links for this document. An array of L<link objects|Statocles::Link>. The
#pod most important attributes are:
#pod
#pod     text    - The text of the link
#pod     href    - The page of the link
#pod
#pod =cut

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 $doc = $self->document;
    if ( $doc->store ) {
        my $document_path = $doc->store->path->child( $doc->path )->parent;
        push @{ $tmpl->include_stores }, Statocles::Store->new( path => $document_path );
    }
    my $rendered = $tmpl->render( %$vars, $self->vars, self => $doc, page => $self );
    return $rendered;
}

#pod =method content
#pod
#pod     my $html = $page->content( %vars );
#pod
#pod Generate the document HTML by processing template directives and converting
#pod Markdown. C<vars> is a set of name-value pairs to give to the template.
#pod
#pod =cut

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

#pod =method vars
#pod
#pod     my %vars = $page->vars;
#pod
#pod Get the template variables for this page.
#pod
#pod =cut

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

#pod =method sections
#pod
#pod     my @sections = $page->sections;
#pod
#pod Get a list of rendered HTML content divided into sections. The Markdown "---"
#pod marker divides sections.
#pod
#pod =cut

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;
}

#pod =method tags
#pod
#pod     my @tags = $page->tags;
#pod
#pod Get the list of tags for this page.
#pod
#pod =cut

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

#pod =method template
#pod
#pod     my $tmpl = $page->template;
#pod
#pod The L<template object|Statocles::Template> for this page. If the document has a template,
#pod it will be used. Otherwise, the L<template attribute|Statocles::Page/template> will
#pod be used.
#pod
#pod =cut

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

#pod =method layout
#pod
#pod     my $tmpl = $page->layout;
#pod
#pod The L<layout template object|Statocles::Template> for this page. If the document has a layout,
#pod it will be used. Otherwise, the L<layout attribute|Statocles::Page/layout> will
#pod be used.
#pod
#pod =cut

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

=encoding UTF-8

=head1 NAME

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

=head1 VERSION

version 0.073

=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
