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

BEGIN {extends 'Catalyst::Controller'; }

use utf8;
use Data::Page;
use JSON;
use List::MoreUtils qw(first_index);

=head1 NAME

DTA::Controller::List - Catalyst Controller

=head1 DESCRIPTION

Catalyst Controller.

=cut

my @fields = (
    {
        name  => 'author1',
        label => 'AutorIn 1',
        field => sub {
            my $book = shift;
            my $ret = '';
            if ( $book->autor1_lastname || $book->autor1_prename ) {
                $ret = $book->autor1_lastname;
                $ret .= ", " . $book->autor1_prename if $book->autor1_prename;
            }
            elsif ( $book->publisher ) {
                $ret = $book->publisher;
                # http://odo.dwds.de/mantis/view.php?id=24242
                $ret =~ s/ #[0-9X]+//g;
                $ret .= ' (Hg.)';
            }
            return $ret;
        },
        style => 'width:150px',
    },
    {
        name  => 'author2',
        label => 'AutorIn 2',
        field => sub {
            my $book = shift;
            my $ret = $book->autor2_lastname;
            $ret .= ", " . $book->autor2_prename if $book->autor2_prename;
            return $ret;
        },
        style => 'width:150px',
    },
    {
        name  => 'author3',
        label => 'AutorIn 3',
        field => sub {
            my $book = shift;
            my $ret = $book->autor3_lastname;
            $ret .= ", " . $book->autor3_prename if $book->autor3_prename;
            return $ret;
        },
        style => 'width:150px',
    },
    {
        name  => 'shorttitle',
        label => 'Kurztitel',
        field => sub { shift->short_title },
    },
    {
        name  => 'title',
        label => 'Titel',
        field => sub { shift->title },
    },
    {
        name  => 'subtitle',
        label => 'Untertitel',
        field => sub { shift->subtitle },
    },
    {
        name  => 'voltitle',
        label => 'Bandbezeichnung',
        field => sub { shift->band_alphanum },
    },
    {
        name  => 'volnum',
        label => 'Bandnummer',
        field => sub {
            my $book = shift;
            return $book->band_zaehlung || '-';
        },
    },
    {
        name  => 'seriestitle',
        label => 'Reihentitel',
        field => sub { shift->reihentitel },
    },
    {
        name  => 'edition',
        label => 'Ausgabe',
        field => sub { shift->dta_auflage },
    },
    {
        name  => 'place',
        label => 'Ort',
        field => sub { shift->dta_pub_location },
    },
    {
        name  => 'publisher',
        label => 'Verlag/Drucker',
        field => sub {
            my $verlag = shift->dta_pub_verlag || '';
            for ( $verlag ) {
                s/Realschulbuchhandlung/Realschul\x{ad}buchhandlung/;
                s/Vereinsbuchhandlung/Vereinsbuch\x{ad}handlung/;
                s/Erziehungsanstalt/Erziehungs\x{ad}anstalt/g;
                s/Schulbuchhandlung/Schulbuch\x{ad}handlung/g;
            }
            return $verlag;
        },
        style => 'width:100px',
    },
    {
        name  => 'year',
        label => 'Jahr',
        field => sub { shift->year },
        style => 'width:50px',
    },
    {
        name  => 'schriftart',
        label => 'Schriftart',
        field => sub { shift->schriftart },
        style => 'width:100px',
    },
    {
        name  => 'category',
        label => 'Kategorie',
        field => sub {
            my $cat = shift->dwds_kategorie1 || '';
            for ( $cat ) {
                s/Gebrauchsliteratur/Gebrauchs\x{ad}literatur/;
            }
            return $cat;
        },
    },
    {
        name  => 'subcategory',
        label => 'Unterkategorie',
        field => sub {
            my $cat = shift->dwds_unterkategorie1 || '';
            for ( $cat ) {
                #s/(wissenschaft|geschichte)/\x{ad}$1/g;
            }
            return $cat;
        },
    },
    {
        name  => 'library',
        label => 'Bibliothek',
        field => sub {
            my $place = shift->bookplace;
            if ( $place && $place->location ) {
                return $place->location->name;
            }
            return '';
        },
    },
    {
        name  => 'indtasince',
        label => 'im DTA seit',
        field => sub {
            my $book = shift;
            return $book->date_ingest;
        },
    },
    {
        name => 'digimethod',
        label => 'DTA-Teilkorpus',
        field => sub {
            my $book = shift;
            my $source = $book->source->source;
            # root/api/tei-header.tt
            return ( $source =~ /^(?:china|kt|don)/ or $book->dirname =~ /^(?:goethe_reineke_1794|mesmer_magnetismus_1781|hoffmannswaldau_grabschriften_1662|nimwegen_friede_1679|humboldt_kosmos01_1845|humboldt_kosmos02_1847|humboldt_kosmos03_1850|humboldt_kosmos04_1858|humboldt_kosmos0501_1862)$/ ) ? 'Kernkorpus' : $source;
        },
    },
);

=head1 METHODS

=head2 index

=cut

sub index :Path :Args(0) {
    my ( $self, $c ) = @_;

    my $mode = $c->req->params->{mode} || '';
    $mode = 'list' if ($mode ne 'table' and $mode ne 'full');

    my $rs = $c->model('DTADB::Book')->search(
        {
            'me.ready' => { -in => [ 1, 2 ] },
        },
        {
            prefetch => [ 'source', { 'bookplace' => 'location' } ],
            order_by => [ 'autor1_lastname NULLS LAST', 'autor1_prename', 'title', 'band_zaehlung' ],
            cache    => 1,
        },
    );

    my $list;

    my @default_columns = grep { $_->{name} =~ /^(?:author1|title|year)$/ } @fields;
    my @columns = ();
    if ( $mode eq 'table' ) {
        $list = $rs->search();
        my @wanted_columns = ref $c->req->params->{columns} eq 'ARRAY' ? @{ $c->req->params->{columns} }
                           : $c->req->params->{columns}                ? $c->req->params->{columns}
                           :                                             ();
        foreach my $col ( @wanted_columns ) {
            foreach my $field ( @fields ) {
                if ( $field->{name} eq $col ) {
                    push @columns, $field;
                    last;
                }
            }
        }
    }
    else {
        my $epp = 30;
        $epp = 100 if $mode eq 'list';
        my $p = $c->req->params->{p} || 1;

        my $pager = Data::Page->new;
        $pager->total_entries( scalar @{[$rs->all]} );
        $pager->entries_per_page( $epp );
        $pager->current_page( $p );

        $list = $rs->search( undef, {
            page => $p,
            rows => $epp,
        });

        $c->stash(
            pager => $pager,
        );
    }

    @columns = @default_columns if @columns == 0;
    $c->stash(
        columns         => \@columns,
        default_columns => \@default_columns,
        fields          => \@fields,
        list            => [ $list->all ],
        fullwidth       => 1,
        mode            => $mode,
        template        => 'web/list/index.tt',
    );
}

=head2 browse

=cut

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

    my $cond = {
        'me.ready' => { -in => [ 1, 2 ] },
    };

    my $attrs = {
        prefetch => [ 'source', { 'bookplace' => 'location' } ],
        order_by => [ 'autor1_lastname NULLS LAST', 'autor1_prename', 'title', 'band_zaehlung' ],
        cache    => 1,
    };

    if ( $c->req->params->{genre} ) {
        $cond->{'me.dwds_kategorie1'} = $c->req->params->{genre};
        unshift @{$attrs->{order_by}}, 'me.dwds_unterkategorie1';
    }

    my $century = $c->req->params->{century};
    if ( defined $century and $century =~ /^(1[6789]|20)$/ ) {
        $cond->{'me.year'} = [ \"~ E'@{[$century - 1]}\[0-9][0-9]'", { -like => '%'.($century*100).'%' } ];
    }

    my $books = $c->model('DTADB::Book')->search( $cond, $attrs );

    if ( $c->req->params->{genre} && $c->req->params->{genre} eq 'Zeitung' ) {
        $c->stash->{list} = [ sort _sort_zeitungen $books->all ];
    }
    else {
        $c->stash->{list} = [ $books->all ];
    }

    $c->stash(
        template => 'web/list/browse.tt',
    )
}

my @months = (
    qr/\b(?:Januar|0?1\.)/,
    qr/\b(?:Februar|0?2\.)/,
    qr/\b(?:März|0?3\.)/,
    qr/\b(?:April|0?4\.)/,
    qr/\b(?:Mai|0?5\.)/,
    qr/\b(?:Juni|0?6\.)/,
    qr/\b(?:Julii?|0?7\.)/,
    qr/\b(?:August|0?8\.)/,
    qr/\b(?:September|0?9\.)/,
    qr/\b(?:Oktober|10\.)/,
    qr/\b(?:November|11\.)/,
    qr/\b(?:Dezember|12\.)/,
);
my $month_re = join '|' => map { "(?:$_)" } @months;

sub _sort_zeitungen {
    my $a_title = $a->dta_bibl_angabe;
    my $b_title = $b->dta_bibl_angabe;

    # Nummernangaben verwirren
    s/Nr\. \d+// for $a_title, $b_title;

    # nur Jahresangabe
    if ( $a_title !~ /\[?\d{1,2}\.\]?\s?$month_re\s?(\d{4})/ ) {
        ( $a_title ) = ($a_title =~ /(\d{4})/g)[-1];
    }
    if ( $b_title !~ /\[?\d{1,2}\.\]?\s?$month_re\s?(\d{4})/ ) {
        ( $b_title ) = ($b_title =~ /(\d{4})/g)[-1];
    }

    my ( $day_a, $month_a, $year_a ) = $a_title =~ /(\[?\d{1,2}\.\]?)?\s?($month_re)?\s?(\d{4})/;
    my ( $day_b, $month_b, $year_b ) = $b_title =~ /(\[?\d{1,2}\.\]?)?\s?($month_re)?\s?(\d{4})/;

    $_ ||= 0 for $month_a, $month_b;
    my $mon_a = first_index { $month_a =~ $_ } @months;
    my $mon_b = first_index { $month_b =~ $_ } @months;

    $_ ||= 0 for $day_a, $day_b;
    for ( $mon_a, $mon_b ) {
        $_ = 0 if $_ == -1;
    }
    s/[\.\[\]]//g for $day_a, $day_b, $month_a, $month_b;


    my $date_a = sprintf "%04d%02d%02d", $year_a, $mon_a, $day_a;
    my $date_b = sprintf "%04d%02d%02d", $year_b, $mon_b, $day_b;

   # use Data::Dumper; warn Dumper [ "$date_a: $year_a $mon_a $day_a", "$date_b: $year_b $mon_b $day_b" ];
    return $date_a <=> $date_b;
}

=head2 timeline

=cut

sub timeline :Local {
    my ( $self, $c ) = @_;
    $c->stash(
        template => 'web/list/timeline.tt',
    );
}

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

    my $list = $c->model('DTADB::Book')->search(
        {
            'me.ready' => { -in => [ 1, 2 ] },
        },
        {
            prefetch => [ 'source' ],
        },
    );

    my @data;
    while ( my $book = $list->next ) {
        my ($year) = $book->year =~ /(\d{4})/;

        my %icons = (
            Belletristik       => 'http://www.deutschestextarchiv.de/static/timeline/dull-blue-circle.png',
            Gebrauchsliteratur => 'http://www.deutschestextarchiv.de/static/timeline/dull-green-circle.png',
            Wissenschaft       => 'http://www.deutschestextarchiv.de/static/timeline/dull-red-circle.png',
            default            => 'http://www.deutschestextarchiv.de/static/timeline/gray-circle.png',
        );

        my $title = sprintf "%s: %s", ($book->autor1_lastname || $book->publisher || 'o. A.'), $book->title;

        push @data, {
            start       => $year,
            title       => $title,
            link        => $c->uri_for('/book/show', $book->dirname)."",
            description => sprintf('<div style="margin-bottom:10px"><a href="book/show/%2$s">%s</a></div><div style="text-align:center"><a href="book/show/%2$s"><img src="http://media.dwds.de/dta/images/%2$s/%2$s_%3$04d_250px.jpg"/></a></div>', $book->dta_bibl_angabe, $book->dirname, $book->startseite),
            icon        => ( exists $icons{$book->dwds_kategorie1} ? $icons{$book->dwds_kategorie1} : $icons{default} ),
        },
    }

    my %out = (
        dateTimeFormat => 'iso8601',
        events => \@data
    );
    $c->res->content_type( 'application/json; charset=utf-8' );
    $c->res->body( encode_json \%out );
}

__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
