package DTA::Controller::DTAE;
use Moose;
use namespace::autoclean;

BEGIN {extends 'Catalyst::Controller'; }

use utf8;
use Data::Page;
use File::Temp qw(tempfile);

=head1 NAME

DTA::Controller::DTAE - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=head1 METHODS

=head2 index

=cut

sub index :Private {
    my ( $self, $c ) = @_;

    my $cache = Cache::FileCache->new({
        cache_root         => $c->path_to( 'var', 'cache' )."",
        namespace          => 'dtae',
        default_expires_in => 60 * 60 * 24 * 7, # 1 week
    });
    my $books       = $cache->get( 'books' );
    my $sources     = $cache->get( 'sources' );
    my $pages_total = $cache->get( 'pages_total' );

    if ( $c->req->params->{regen} or !defined $books or !defined $sources ) {
        undef $sources;
        undef $books;
        $pages_total = 0;
        my $rs = $c->model('DTADB::Book')->search(
            {
                source => { -in => [qw(dtae wikisource gutenberg_org aedit gutenberg_de dwds1 hab avh gutzkow kosmos blumenbach mkhz1 mkhz2 correspondent sbb_funeralschriften avhkv eebo gwb gei ntsm tdef briefjeanpaul augsburgerallgemeine novellenschatz epoetics hamburg_corresp moritz_erfahrungsseelenkunde nrhz sanders-briefe fcsus dsdk) ] },
            },
            {
                prefetch => [ 'source', 'textpages' ],
                order_by => 'source, autor1_lastname, title',
                cache    => 1,
            },
        );

        while( my $book = $rs->next ) {
            my $pages = $book->textpages->count;
            my $source = $book->source->source;
            $sources->{ $source } += $pages;
            $pages_total += $pages;
        }
        $books = [ $rs->all ];
    }

    $cache->set( 'books', $books );
    $cache->set( 'sources', $sources );
    $cache->set( 'pages_total', $pages_total );

    $c->stash(
        page_name   => 'dtae',
        books       => $books,
        sources     => $sources,
        pages_total => $pages_total,
    );
}

=head2 m24

=cut

sub m24 :Local {
    my ( $self, $c ) = @_;

    my $cache = Cache::FileCache->new({
        cache_root         => $c->path_to( 'var', 'cache' )."",
        namespace          => 'dtae',
        default_expires_in => 60 * 60 * 24 * 7, # 1 week
    });
    my $books       = $cache->get( 'books' );
    my $sources     = $cache->get( 'sources' );
    my $pages_total = $cache->get( 'pages_total' );

    if ( $c->req->params->{regen} or !defined $books or !defined $sources ) {
        undef $sources;
        undef $books;
        $pages_total = 0;
        my $rs = $c->model('DTADB::Book')->search(
            {
                source => { -in => [qw(dtae wikisource gutenberg_org gutenberg_de hab gutzkow) ] },
            },
            {
                prefetch => [ 'source', 'textpages' ],
                order_by => 'source, autor1_lastname, title',
                cache    => 1,
            },
        );

        while( my $book = $rs->next ) {
            my $pages = $book->textpages->count;
            my $source = $book->source->source;
            $source = 'dtae' if $source !~ /wikisource|hab|gutenberg_org/;
            $sources->{ $source } += $pages;
            $pages_total += $pages;
            print STDERR $book->dirname, "\n";
        }
        $books = [ $rs->all ];
    }

    $cache->set( 'books', $books );
    $cache->set( 'sources', $sources );
    $cache->set( 'pages_total', $pages_total );

    $c->stash(
        page_name   => 'dtae',
        books       => $books,
        sources     => $sources,
        pages_total => $pages_total,
        template    => 'dtae/m24.tt',
    );
}

=head2 view_ext

=cut

sub view_ext : Local {
    my ( $self, $c, $id ) = @_;

    my $dirname = $id;

    my $page = $c->req->params->{p} || 1;
    $c->stash->{page} = $page;

    my $xmlfile = sprintf '%s/%s.xml/pages/%s.xml_%04d.xml', $c->config->{xmlrep}, $dirname, $dirname, $page;
    $c->stash->{xmlfile} = $xmlfile;

    open( my $fh, '<', $xmlfile ) or die $!;
    my $xml;
    {
        local $/;
        $xml = <$fh>;
    }
    close $fh;

    $c->stash->{pagexml} = $xml;

    $c->forward('page_xsl');

    $c->stash(
        template => 'book/view_ext.tt',
        book     => { metadaten => { dirname => $dirname } },
        page     => $page,
        pages    => [
            map { /([0-9]+)\.xml$/; $1 }
            glob sprintf( '%s/%s.xml/pages/*.xml', $c->config->{xmlrep}, $dirname )
        ],
        view => 'DTAE',
    );
}

=head2 page_xsl

=cut

sub page_xsl : Private {
    my ( $self, $c ) = @_;

    my $rawxml = $c->stash->{pagexml};
    $rawxml =~ s{(</c>)\s+(<hi )}{$1$2}g;
    $rawxml =~ s/\s+<c /<c /g;
    $rawxml =~ s/(rendition=")\s*/$1/g;
    $rawxml =~ s/\R*(<supplied[^>]*>)\R*/$1/g;
    $rawxml =~ s/\R*(<\/supplied>)\R*/$1/g;

    my ( $tempfh, $tempname ) = tempfile();
    print $tempfh $rawxml;
    close $tempfh;

    $c->stash->{xml}      = $tempname;
    $c->stash->{template} = 'dtaq.xsl';
    $c->forward('DTA::View::XSLT');
    unlink $tempname;
    my $html = $c->res->body;

    # clean footnote lookup
    %DTA::View::XSLT::fn_seen = ();

    # some fixes
    $html = fixhtml($html);

    utf8::decode($html);
    $c->stash->{xsl} = $html;
    $c->res->body(undef);
}

sub fixhtml {
    my $str = shift || '';
    utf8::decode($str);
    for ( $str ) {
        s{(<(?:div|p)[^>]*>)\s+}{$1}g;
        s{(<br(?: ?/)?>)\s+}{$1}g;
        s{</(div|p|h[1-6])>\s*(?:<br(?: ?/)?>)?\s*<((?:div|p|h[1-6])[^>]*)>}{</$1><$2>}g;
        s{(<br(?: ?/)?>)+}{<br />}g;
        s{(</(?:div|p|table|ul)>)<br(?: ?/)?>}{$1}g;
        s{(span\s+class="up">[^<]*</span>)\s*<br(?: ?/)?>\s*}{$1 }g;
        s{(<span[^>]*>)(<br(?:\s*/)?>)}{$2$1}g;
        s{(<span class="(?:g\s*|\s*g|\s*g\s*)">)(.*?)(</span>)(<[^>]+>)?([^<])}{ $1 . fix_emphasis( $2, $3, $4, $5 )  }egs;
    }
    utf8::encode($str);
    return $str;
}

sub fix_emphasis {
    my ( $em, $closing_span, $next_tag, $next_char ) = @_;
    no warnings 'uninitialized';
    my $ret = $em . $closing_span . $next_tag . $next_char;
    if ( $em =~ /(.*)(.)(?:<[^>]+>)?$/s && $3 ) {
        my ( $em_start, $em_last, $em_close ) = ( $1, $2, $3 );
        if ( $next_char =~ /[.,;:?!]/ ) {
            $ret = $em_start . $em_close . $closing_span . $em_last . $next_tag . $next_char;
        }
    }
    return $ret;
}

=head2 kochbuch

=cut

sub kochbuch :Local {
    my ( $self, $c ) = @_;

    my $books = $c->model('DTADB::Book')->search(
        {
            'me.dwds_unterkategorie1' => 'Kochbuch',
        },
        {
            order_by => 'me.year',
        },
    );

    $c->stash(
        list     => [ $books->all ],
        template => 'dtae/kochbuch.tt',
    );
}

=head2 avh

=cut

sub avh :Local {
    my ( $self, $c ) = @_;

    my $books = $c->model('DTADB::Book')->search(
        {
            'me.autor1_prename'  => 'Alexander von',
            'me.autor1_lastname' => 'Humboldt',
            'me.ready'           => { -in => [ 1, 2 ] },
            'source.source'      => { '!=' => undef },
        },
        {
            prefetch => [ 'source' ],
            order_by => 'me.year',
        },
    );
    $c->stash(
        list     => [ $books->all ],
        template => 'dtae/avh.tt',
    );
}

=head2 metadaten

=cut

# sub metadaten :Local {
#     my ( $self, $c ) = @_;
#     $c->res->redirect( $c->uri_for( '/dtae/submit/other' ) );
#     $c->detach;
# }

__PACKAGE__->meta->make_immutable;

1;
__END__

=head1 AUTHOR

Frank Wiegand

=head1 LICENSE

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

=cut
