
package Text::Wigwam::Engine::Totem::Token::Terminator::Generic;

    use strict;
    use warnings;
    our $VERSION = '0.01';

    use base q/Text::Wigwam::Cast/;

    use Text::Wigwam::Const( qw/TERM/ );
    use Text::Wigwam::Engine::Totem::Const(
      qw/
        TEXT_BLOCK
        ROOT_BLOCK
        CODE_BLOCK
      /
    );

sub new { return bless { DRAW => $_[1] } }
sub exec {
    my ($tokn, $want, $Arg, $Api, $core) = @_;
     # Associate a terminator token with the appropriate
     # directive type, or ignore the terminator.
    $core->next_token;
#    if(
#        $want & TERM &&
#        !($Arg->type & (TEXT_BLOCK | ROOT_BLOCK ))
#    ){
    if( ($want & TERM) && !$Arg->type ){
        $Arg->end_list(1);
        return;
    }
     # Strict template code enforcement feature
    return $core->curr_token->exec( $want, $Arg, $Api, $core )
        unless $Api->get_options( qw/strict_tags/ );
#    return $Arg->exec($Api)
#      unless $Api->get_options( qw/strict_tags/ );
    $Api->exception(
        "Encountered an unexpected list terminator."
    );
    return $Arg->null_data( $want );
}

sub skip {
    my ($tokn, $list, $Arg, $Api, $core) = @_;
    $core->next_token;
    return if $Arg->type & (TEXT_BLOCK|ROOT_BLOCK);
    if( $list && !$Arg->type ){
        return TERM;
    }
     # Strict tag enforcement feature
    if( $list ){
        if( !$Api->get_options( qw/strict_tags/ ) ){
            $Api->debug( 'Ignored unexpected list terminator.' );
            return $core->curr_token->skip( $list, $Arg, $Api, $core );
        }
        $Api->exception(
            "Encountered an unexpected list terminator."
        );
    }
    return;
}

sub paint {
    my ($tokn, $Arg, $Api, $core) = @_;
    $core->next_token;
    $tokn->{PAINT} ||=
        Text::Wigwam::Engine::Totem::Paint::Token->new(
            $tokn->{DRAW}[0],
            $core->curr_addr,
            'directive',
        )
    ;

    return(
        Text::Wigwam::Engine::Totem::Paint::Group->new(
            [ $tokn->{PAINT} ]
        ),
        1,
    ) if (
        ($Arg->want & TERM) &&
        !$Arg->type
    );

     # If we make it this far, we've got a bogus terminator...

    if( $Arg->want & TERM ){
     # If we're pulling a list, just return the bogus token
        $Api->add_comment( "Unexpected terminator" );
        return(
          Text::Wigwam::Engine::Totem::Paint::Token->new(
              @{$tokn->{DRAW}},
              $core->curr_addr,
              'error',
          ),
          0,
        );
    }

     # If we're not pulling a list, we need to process the next
     # token instead, and piggy-back it to the bogus token.
    my ($text, $end) = $core->curr_token->paint(
        $Arg,
        $Api,
        $core,
    );
    $Api->add_comment( "Unexpected terminator" );
    return(
        Text::Wigwam::Engine::Totem::Paint::Group->new(
          [
            Text::Wigwam::Engine::Totem::Paint::Token->new(
                @{$tokn->{DRAW}},
                $core->curr_addr,
                'error',
            ),
            @$text,
          ],
        ),
        $end,
    );
}

1;
