
package Text::Wigwam::Engine::Fusion::Token::Terminator::Code;

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

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

    use Text::Wigwam::Engine::Fusion::Const(
      qw/
        TEXT_BLOCK
        CODE_BLOCK
      /
    );
    use Text::Wigwam::Const( qw/TERM STRING/ );

    sub new { return bless { DRAW => $_[1], TYPE => 'tagentity' } }
    sub type { $_[0]->{TYPE} }
    sub exec {
        my( $tokn, $want, $Arg, $Api, $core ) = @_;
        if(
             $Arg->type == CODE_BLOCK
#         && !$Arg->type & TEXT_BLOCK
        ){
            bless $tokn, 'Text::Wigwam::Engine::Fusion::Token::Terminator::Fast'
              if $Api->get_options( qw/strict_tags/ );
            $core->next_token;
            $Arg->end_list(1);
        }
        if( $Arg->type & TEXT_BLOCK ){
             # If the calling directive is a block token,
             # ignore terminator & execute the next token.
            $core->next_token;
            return $core->curr_token->exec( $want, $Arg, $Api, $core );
#            return $Arg->exec($Api);
        }
         # The calling directive type matches the terminator
        if( $want & TERM ){
             # Generate an exception if strict tags...
            $Api->exception(
                 "Missing terminator: An unexpected code "
               . "terminator was encountered while executing "
               . "an argument for a terminated list "
               . "directive (" . $Arg->drip->token.")"
#               . " (type: ".$Arg->type." ".$core->curr_addr().")"
            ) if (
                $Api->get_options( qw/strict_tags/ ) &&
                !( $Arg->type & CODE_BLOCK )
            );
             # Terminate the list, but don't skip the token
            $Arg->end_list(1);
            return;
        }
         # Strict tag enforcement feature
        return $tokn->cast(
            $Arg,
            $Api,
            $want,
            STRING,
            undef
        ) unless $Api->get_options( qw/strict_tags/ ); # unless !$tokn->{STAG};
        $Api->exception(
            "Missing argument: An unexpected tag terminator ".
            "was encountered while executing an argument for ".
            $Arg->drip->token."."
        );
        return $tokn->cast( $Arg, $Api, $want, STRING, undef );
    }
    sub skip {
        my( $tokn, $list, $Arg, $Api, $core ) = @_;
        $core->next_token, return if $Arg->type & TEXT_BLOCK;
        unless( $Arg->type & TEXT_BLOCK ){
           if( $list ){
            $Api->exception(
               "Missing terminator token: An unexpected code terminator "
             . "was encountered while pulling "
             . "an argument for a terminated list directive "
             . "(".$Arg->drip->token.")."
            ) if !( $Arg->type & CODE_BLOCK ) && $Api->get_options( qw/strict_tags/ );
            return TERM;
           }
            # Strict template code enforcement feature
           $Api->exception(
               "Missing argument: An unexpected tag terminator ".
            "was encountered while pulling an ".
            "argument for ".$Arg->drip->token."."
           ) if $Api->get_options( qw/strict_tags/ );
           return;
        }
        return $core->next_token->skip( $list, $Arg, $Api, $core );
#        $core->next_token;    # Ignore implied terminator
#        return $core->curr_token->skip( $list, $Arg, $Api, $core );
    }
    sub paint {
        my( $tokn, $Arg, $Api, $core ) = @_;
        $tokn->{PAINT} ||= [
            Text::Wigwam::Engine::Fusion::Paint::Token->new(
                $tokn->{DRAW}[0],
                $core->curr_addr,
                'tagentity'
            )
        ];
        if( $Arg->type & CODE_BLOCK ){ # All is well
            $core->next_token;
            return(
              Text::Wigwam::Engine::Fusion::Paint::Group->new(
                [ @{$tokn->{PAINT}} ]
              ),
              1
            );
        }

        # If we make it this far, we've got a misplaced tag terminator

        if( $Arg->want & TERM ){
          if( $Arg->type & TEXT_BLOCK ){
           # This will probably never happen in the Fusion engine,
           # because a tag terminator within a text block would just
           # be dismissed as plain-text.
            $core->next_token;
            $Api->add_comment( "Misplaced tag terminator" );
          }
          return(
            Text::Wigwam::Engine::Fusion::Paint::Group->new(
            [
              Text::Wigwam::Engine::Fusion::Paint::Token->new(
                (($Arg->type & CODE_BLOCK) ?
                    $Api->get_options( qw/code_term/ )
                :
                    '#/*'),
                $core->curr_addr,
                'implied'
              )
            ]
            ),
            1
          );
        }

        $Api->add_comment( "Directive is missing an argument" );
        return(
          Text::Wigwam::Engine::Fusion::Paint::Group->new(
            [
            Text::Wigwam::Engine::Fusion::Paint::Token->new(
                'MissingArg',
                $core->curr_addr,
                'error'
            )
            ]
          ),
          1
        ); # Missing argument
    }

1;
