# -------------------------------------------------------------------------------------
# lib::Template::If
# -------------------------------------------------------------------------------------
#
#    Author   : Jean-Michel Hiver                         (c) Jean-Michel Hiver, 2001.
#    Synopsis : Provides the implementation for the
#    <% if ... %> tag
#
# -------------------------------------------------------------------------------------
package lib::Template::If;
use lib::Template::AbstractTag;
use lib::Exception;
use lib::Template;
use strict;
use vars qw /@ISA/;
@ISA = qw /lib::Template::AbstractTag/;


##
# $obj->main;
# -----------
#   Processes the <% if name="something" %> ... <% end-if %> tag.
##
sub main
{
    my $self   = shift;
    my $result = $self->result;
    my $tokens = $self->tokens;
    
    # parses $tokens to extract the if condition
    my ($info, $if_data, $else_data) = $self->parse ($tokens);
    
    # which variable do we want to test ?
    my $varname = $info->{name};
    my $value   = $self->get ($varname);
    
    # if $value is an array then I want to have it in list context.
    $value = scalar @{$value} if (ref $value eq 'ARRAY');
    $value = scalar (keys %{$value}) if (ref $value eq 'HASH');

    # has the if a 'not' attribute ?
    $value = not $value if (defined $info->{not} and $info->{not});
    
    # if 'equals' is set, then we must compare $value to it
    my $data = "";
    if ($info->{eq}) { $data = ($value eq $info->{eq}) ? $if_data : $else_data }
    else             { $data = ($value) ? $if_data : $else_data }
    
    my $tmpl = $self->{class}->new ( data => $data, hash => $self->{hash} );    
    push @{$result}, $tmpl->parse;
}


##
# $obj->parse ($tokens);
# ----------------------
#   The parse method had to be rewritten so that the following syntax
#   is supported:
#
#   <% if name="something" %>
#    ...
#   <% else %>
#    ...
#   <% end-if %>
##
sub parse
{
    my $self = shift;
    my $tokens = shift;
    
    my $if_token = shift @{$tokens};
    my ($if_name, @result) = $self->parse_tag ($if_token);
    my $balance = 1;
    
    push @result, '';
    
    while ($balance)
    {
	(@{$tokens} > 0) or
	    throw (new lib::Exception ( code => 'IF_NOT_CLOSED',
					info => $self ) );
	
	my $token = shift @{$tokens};
	if ($self->is_tag ($token))
	{
	    my ($tag_name, $tag_info) = $self->parse_tag ($token);
	    if (defined $tag_name and $tag_name eq 'if')
	    {
		$balance++;
		$result[$#result] .= $token;
	    }
	    elsif (defined $tag_name and $tag_name eq 'else')
	    {
		if ($balance == 1)
		{
		    push @result, '';
		}
		else
		{
		    $result[$#result] .= $token;
		}
	    }
	    elsif (defined $tag_name and $tag_name eq 'end-if')
	    {
		$balance--;
		$result[$#result] .= $token unless ($balance == 0);
	    }
	    else
	    {
		$result[$#result] .= $token;
	    }
	}
	else
	{
	    $result[$#result] .= $token;
	}
    }
    
    return @result;
}


1;





