package ID3FS::Path::Node;

use strict;
use warnings;

sub new
{
    my $proto=shift;
    my $class=ref($proto) || $proto;
    my $self={};
    bless($self,$class);

    $self->left(shift);
    $self->op(shift);
    $self->right(shift);

    return $self;
}

sub set
{
    my($self, $name, $val)=@_;
    if(defined($val))
    {
	$self->{$name}=$val;
    }
    return $self->{$name};
}

sub left  { return shift->set("left",  shift); }
sub right { return shift->set("right", shift); }
sub op    { return shift->set("op",    shift); }

sub print
{
    my($self)=@_;
    my $op=$self->op();
    my $left=$self->left();
    my $right=$self->right();
    return "" unless($left || $right);
    my $str .= $self->print_node($left);
    $str .= (" " . $op->{name} . " ") if($op);
    $str .= $self->print_node($right);
    if($op || ($left && $right))
    {
	$str="(" . $str . ")";
    }
    return $str;
}

sub print_node
{
    my($self, $node)=@_;
    return "" unless(defined($node));
    return $node->print() if(ref($node) eq "ID3FS::Path::Node");
    return $node->{name};
}

sub to_sql
{
    my($self, $parent, $andlevel)=@_;
    $andlevel=1 unless(defined($andlevel));
    my ($leftandlevel, $rightandlevel);
    my ($leftstr, $rightstr);
    my $op=$self->op();
    my $left=$self->left();
    my $right=$self->right();
    return ("", $andlevel) unless($left || $right);
    ($leftstr, $leftandlevel) = $self->node_to_sql($left, $parent, $andlevel);
    $andlevel=$self->max($andlevel, $leftandlevel);
    if(defined($op) && (($op->{name} eq "AND") || ($op->{name} eq "NOT")))
    {
	$andlevel++;
    }
    ($rightstr, $rightandlevel) = $self->node_to_sql($right, $parent, $andlevel);
    my $str=$leftstr;
    $str .= (" " . $op->{name} . " ") if($op);
    $str .= $rightstr;
    if($op || ($left && $right))
    {
	$str="(" . $str . ")";
    }
    return($str, $self->max($leftandlevel, $rightandlevel));
}

sub node_to_sql
{
    my($self, $node, $parent, $andlevel)=@_;
    return ("", $andlevel) unless(defined($node));
    return $node->to_sql($parent, $andlevel) if(ref($node) eq "ID3FS::Path::Node");
    my $sql;
    if(defined($node->{parents_id}))
    {
	print "HIT PARENTS_ID: $node->{parents_id}\n";
	$sql= "(t$andlevel.parents_id='$node->{parents_id}'";
	$sql .= " AND fxt${andlevel}.tags_id='" . $node->{id} . "')";
    }
#    elsif($parent)
#    {
#	print "HIT \$parent\n";
#	$sql= "(t$andlevel.parents_id='$parent')";
#    }
    else
    {
	$sql= "(t$andlevel.parents_id=''";
	$sql .= " AND fxt${andlevel}.tags_id='" . $node->{id} . "')";
    }
    return ($sql, $andlevel);
}

sub used_tags
{
    my($self)=@_;
    my @used=(grep { defined; }  ($self->node_used_tags($self->left()),
				  $self->node_used_tags($self->right())));
    print "used_tags: ", join(", ", @used), "\n";
    return(@used);
}

sub node_used_tags
{
    my($self, $node)=@_;
    return (undef) unless(defined($node));
    return $node->used_tags() if(ref($node) eq "ID3FS::Path::Node");
    if(defined($node->{parents_id}))
    {
	return([ $node->{parents_id}, $node->{id} ]);
    }
    return $node->{id};
}


sub max
{
    my($self, $a, $b)=@_;
    return(($a > $b) ? $a : $b);
}

1;
