
package Text::Wigwam::Engine::Totem::Expression;

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

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

    use Text::Wigwam::Const( qw/TERM EXPR/ );

    use constant ADDR => 0;
    use constant ENGN => 1;
    use constant DRIP => 2;
    use constant SIZE => 3;

sub new {
    my ($class, $addr, $want, $size, $engn) = @_;
    return bless [
        $addr,
        $engn,
        Text::Wigwam::Engine::Totem::Drip->pseudo(
            $want & ~( TERM | EXPR )
        ),
        $size,
    ], ref($class) || $class;
}

sub size { $_[0]->[SIZE] }
sub doc { $_[0]->[ENGN]->doc }
sub engine { q/Totem/ }
sub execute {
    my ($expr, $Args) = @_;
    my ($addr, $Api, $drip) = @$expr;

    $Api->{core}->temp_addr( $addr );
    my $Arg = $Api->_new_arg(
        Text::Wigwam::Engine::Totem::Argument->new($drip)
    );

    my $val;
    if( ref $Args ) {
        $Api->push_global( args => $Args );
        $val = $Arg->exec_arg($Api);
        $Api->del_global( q/args/ );
    }
    else {
        $val = $Arg->exec_arg($Api);
    }

    $Api->_pop_arg;
    $Api->{core}->temp_addr;
    if( my ($efnam, $efval, $efscp, $subst, $fatal) = $Api->eflag_info ){
        if( $subst ){ $val = $$efval }
        elsif ( $fatal ){ return( ref($efval) ? $$efval : $efval, $val ) if wantarray }
    }
    return ( undef, $val ) if wantarray;
#    warn "Expression called in list context from ".join( ", " => caller() )
#      if wantarray;
    return $val;
}

sub render {
    my ($expr) = @_;
    my ($addr, $Api, $drip) = @$expr;
    $Api->{core}->temp_addr( $addr );
    my $Arg = $Api->_new_arg(
        Text::Wigwam::Engine::Totem::Argument->new($drip)
    );
    my $struct = $Arg->list($Api);
    $Api->_pop_arg;
    $Api->{core}->temp_addr;
    return $struct;
}

sub beautify {
    my ($expr, $beau) = @_;
    $beau ||= Text::Wigwam::Beautify::Text->new();
    $beau->add_comments( $expr->[ENGN]->get_comments )
      if $beau->can( q/add_comments/ );
    my $beaut = Text::Wigwam::Engine::Totem::Beautify->new($beau);
    return $beaut->spew_thing( $expr->render );
}

1;
