package ID3FS::Path;

use strict;
use warnings;
use ID3FS::PathElement::Artist;
use ID3FS::PathElement::Album;
use ID3FS::PathElement::Boolean;
use ID3FS::PathElement::File;
use ID3FS::PathElement::Tag;
use ID3FS::PathElement::Tagval;

our ($STATE_INVALID, $STATE_ROOT, $STATE_WANTMORE, $STATE_TAG, $STATE_TAGVAL,
     $STATE_BOOL, $STATE_ARTIST, $STATE_ALBUM, $STATE_FILE)=(0..8);

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

    $self->{db}=shift;
    $self->{path}=shift;
    $self->parse();
    print "STATE: ", $self->state(), "\n";
    return $self;
}

sub isdir
{
    my($self)=@_;
    if(($self->state() eq $STATE_FILE) ||
       ($self->state() eq $STATE_INVALID))
    {
	return 0;
    }
    return 1;
}

sub isvalid
{
    my($self)=@_;
    return($self->state() != $STATE_INVALID);
}

sub dest
{
    my($self)=@_;
    return "FIXME";
}

sub dirents
{
    my($self)=@_;
    return $self->{db}->tags(@{$self->{elements}});
#    elsif($self->state() == $STATE_WANTMORE)
#    {
#	return(qw(AND OR ALL));
#    }
}

sub parse
{
    my($self)=@_;
    @{$self->{components}}=split(/\//, $self->{path});
    shift @{$self->{components}}; # drop empty field before leading /
    print "PATH: $self->{path}\n";
    print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
    $self->state($STATE_ROOT);
    return if($self->{path} eq "/");
    my @parts=@{$self->{components}};
    my($tag, $tagval);
    $self->{elements}=[];
    while(my $name=shift @parts)
    {
	print "NAME: $name\n";
	if   ($self->state() == $STATE_INVALID)
	{
	    print "SM: INVALID: $name\n";
	    return;
	}
	elsif($self->state() == $STATE_ROOT)
	{
	    print "SM: ROOT: $name\n";
	    $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
	    if($tag)
	    {
		push(@{$self->{elements}}, $tag);
		$self->state($STATE_WANTMORE);
	    }
	    else
	    {
		$self->state($STATE_INVALID);
	    }
	}
	elsif($self->state() == $STATE_WANTMORE)
	{
	    print "SM: WANTMORE: $name\n";
	    $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
	    if($tag)
	    {
		push(@{$self->{elements}}, $tag);
#		$self->state($STATE_TAG);
	    }
	    else
	    {
		$self->state($STATE_INVALID);
	    }
#	    if(($name eq "AND") || ($name eq "OR"))
#	    {
#		$self->state($STATE_BOOL);
#		push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
#	    }
#	    elsif($name eq "ALL")
#	    {
#		$self->state($STATE_ARTIST);
#	    }
#	    else
#	    {
#		$self->state($STATE_INVALID);
#	    }
	}
	elsif($self->state() == $STATE_TAG)
	{
	    print "SM: TAG: $name\n";
	    $self->state($STATE_WANTMORE);
	    next;
	    my @valid_tagvals=$self->{db}->tag_values($tag);
	    print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
	    if(@valid_tagvals)
	    {
		if(grep { $name eq $_; } @valid_tagvals)
		{
		    print "TAGVAL VALID\n";
		    $self->state($STATE_TAGVAL);
		    push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
		}
		else
		{
		    print "ERROR: unknown tagval: $tagval\n";
		    $self->state($STATE_INVALID);
		}
	    }
	    else
	    {
		$self->state($STATE_INVALID);
	    }
	}
	elsif($self->state() == $STATE_TAGVAL)
	{
	    print "SM: TAGVAL: $name\n";
	}
	elsif($self->state() == $STATE_BOOL)
	{
	    print "SM: BOOL: $name\n";
	}
	elsif($self->state() == $STATE_ARTIST)
	{
	    print "SM: ARTIST: $name\n";
	}
	elsif($self->state() == $STATE_ALBUM)
	{
	    print "SM: ALBUM: $name\n";
	}
	elsif($self->state() == $STATE_FILE)
	{
	    print "SM: FILE: $name\n";
	}
	else
	{
	    print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
	    $self->state($STATE_INVALID);
	}
    }
}

sub state
{
    my($self, $newstate)=@_;
    $self->{state}=$newstate if(defined($newstate));
    return $self->{state};
}

1;
