#
# Footnote Plugin Ver. 0.6
#      Copyright(C) 2003-2004 N.Yamamoto

package MT::Entry::Footnote;
use strict;
#use warnings;
use MT::Template::Context;
use MT::Util qw(decode_html);

MT::Template::Context->add_container_tag(Footnote => \&Footnote);
MT::Template::Context->add_container_tag(FootnoteSet => \&_FootnoteParse);
MT::Template::Context->add_container_tag(FootnoteGet => \&_FootnoteParse);
MT::Template::Context->add_container_tag(Footnotes => \&Footnotes);
MT::Template::Context->add_container_tag(FootnoteNumbers => \&FootnoteNumbers);
MT::Template::Context->add_tag(FootnoteNumber => \&FootnoteNumber);
MT::Template::Context->add_tag(FootnoteTotalNumber => \&FootnoteTotalNumber);
MT::Template::Context->add_tag(FootnoteCount => \&FootnoteCount);
MT::Template::Context->add_tag(FootnoteTotalCount => \&FootnoteTotalCount);
MT::Template::Context->add_tag(FootnoteString => \&FootnoteString);
MT::Template::Context->add_conditional_tag(IfFootnoteExist =>
					   \&IfFootnoteExist);

sub _init_footnote {
  my $ctx = shift;
  my $eid = $ctx->stash('entry')->id;
  my $feid = $ctx->stash('footnote_eid');
  if ( !($feid and $feid == $eid) ) {
    $ctx->stash('footnote_eid', $eid);
    $ctx->stash('footnote_total_count', 0);
    $ctx->stash('footnote_count', 0);
    $ctx->stash('footnote_strings', []);
  }
}

sub Footnote {
  my ( $ctx, $args ) = @_;
  my $builder = $ctx->stash('builder');
  my $tokens  = $ctx->stash('tokens');
  my $value
    = defined $args->{value} ? _tag_compile($ctx,$args->{value}) : undef;
  _init_footnote($ctx);

  if ( defined $value and $value ne '' ) {
    FootnoteString( $ctx, { value_compiled => $value } );
    $tokens = [ grep { $_->[0] ne 'FootnoteGet' } @$tokens ];
  } else {
    $tokens = [ grep { $_->[0] ne 'FootnoteSet' } @$tokens ];
  }
  my $str = $builder->build($ctx,$tokens)
    or $ctx->error($ctx->errstr);
  if ( my $reset = $args->{reset} ) {
    $ctx->stash('footnote_count', 0)
      if (_tag_compile($ctx,$reset) );
  }
  $str;
}

sub _FootnoteParse {
  my ( $ctx ) = @_;
  my $builder = $ctx->stash('builder');
  my $tokens  = $ctx->stash('tokens');
  _init_footnote($ctx);
  $builder->build($ctx,$tokens)
    or $ctx->error($ctx->errstr);
}

sub Footnotes {
  my ( $ctx ) = @_;
  my $res = '';
  my $builder = $ctx->stash('builder');
  my $tokens  = $ctx->stash('tokens');
  my $footnote = $ctx->stash('footnote_strings') || [];
  $ctx->stash('footnote_last_string', undef );

  while ( @$footnote ) {
    defined( my $out = $builder->build($ctx,$tokens))
      or return $ctx->error($ctx->errstr);
    $res .= $out;
    shift( @$footnote );
  }
  $res;
}

sub FootnoteNumbers {
  my ( $ctx, $args ) = @_;
  my $res = '';
  my $glue = '';
  my $builder = $ctx->stash('builder');
  my $tokens  = $ctx->stash('tokens');
  my $footnote = $ctx->stash('footnote_strings')->[0];

  while ( scalar(@$footnote) > 1 ) {
    defined( my $out = $builder->build($ctx,$tokens))
      or return $ctx->error($ctx->errstr);
    $res .= "$glue$out";
    $glue ||= $args->{glue} || '';
    splice(@$footnote,1,1);
  }
  $res;
}

sub FootnoteNumber {
  my $ctx = $_[0];
  my $footnote = $ctx->stash('footnote_strings')->[0];
  $footnote->[1][0] or 0;
}

sub FootnoteTotalNumber {
  my $ctx = $_[0];
  my $footnote = $ctx->stash('footnote_strings')->[0];
  $footnote->[1][1] or 0;
}

sub FootnoteTotalCount {
  my $ctx = $_[0];
  $ctx->stash('footnote_total_count') or 0;
}

sub FootnoteCount {
  my $ctx = $_[0];
  $ctx->stash('footnote_count') or 0;
}

sub FootnoteString {
  my ( $ctx, $args ) = @_;
  my $fc = $ctx->stash('footnote_count');
  my $tfc = $ctx->stash('footnote_total_count');
  my $footnote = $ctx->stash('footnote_strings');
  my $val = $args->{value_compiled}
    || ( $args->{value} ? _tag_compile($ctx,$args->{value}) : undef );

  if ( defined $val ) {
    $fc++; $tfc++;
    $val =~ s/\s+(\w)/ $1/g;
    $val =~ s/(\w)\s+/$1 /g;
    $val =~ tr/\r\n//d;
    $val =~ s|^\s*\((.*?)\)\s*$|$1|g;
    my ( $fn ) = grep { $_->[0] eq $val } @$footnote;
    if ( $fn ) {
      push( @$fn, [ $fc, $tfc ] );
    } else {
      push( @$footnote, [ $val, [ $fc, $tfc ] ] );
    }
    $ctx->stash('footnote_count',$fc);
    $ctx->stash('footnote_total_count', $tfc );
    $ctx->stash('footnote_last_string', $val );
    return '';
   } else {
    $ctx->stash('footnote_last_string') or $footnote->[0][0] or '';
  }
}

sub IfFootnoteExist {
  my $ctx = $_[0];
  my $feid = $ctx->stash('footnote_eid');
  if ( $feid and $feid == $ctx->stash('entry')->id
       and @{$ctx->stash('footnote_strings')} != 0 ) {
    return 1;
  } else {
    return 0;
  }
}

sub _tag_compile ($$) {
  my($ctx, $str) = @_;
  my $build = $ctx->stash('builder');

  if ( ($str =~ m/\<MT.*?\>/g) ||
       ($str =~ s/\[(MT(.*?))\]/<$1>/g) ) {
    my $tokens = $build->compile($ctx, $str)
      or die $build->errstr;
    defined($str = $build->build($ctx, $tokens))
      or die $build->errstr;
  }
  $str;
}

1;
