partially implement booleans
[id3fs.git] / lib / ID3FS / Path.pm
1 package ID3FS::Path;
2
3 use strict;
4 use warnings;
5 use feature 'switch';
6 use ID3FS::PathElement::Artist;
7 use ID3FS::PathElement::Album;
8 use ID3FS::PathElement::Boolean;
9 use ID3FS::PathElement::File;
10 use ID3FS::PathElement::Tag;
11 use ID3FS::PathElement::Tagval;
12
13 our ($STATE_INVALID, $STATE_ROOT, $STATE_WANTMORE, $STATE_TAG, $STATE_TAGVAL,
14      $STATE_BOOLEAN, $STATE_ARTIST, $STATE_ALBUM, $STATE_FILE)=(0..8);
15
16 sub new
17 {
18     my $proto=shift;
19     my $class=ref($proto) || $proto;
20     my $self={};
21     bless($self,$class);
22
23     $self->{db}=shift;
24     $self->{path}=shift;
25     $self->parse();
26     print "STATE: ", $self->state(), "\n";
27     return $self;
28 }
29
30 sub isdir
31 {
32     my($self)=@_;
33     if(($self->state() eq $STATE_FILE) ||
34        ($self->state() eq $STATE_INVALID))
35     {
36         return 0;
37     }
38     return 1;
39 }
40
41 sub isvalid
42 {
43     my($self)=@_;
44     return($self->state() != $STATE_INVALID);
45 }
46
47 sub dest
48 {
49     my($self)=@_;
50     return "FIXME";
51 }
52
53 sub dirents
54 {
55     my($self)=@_;
56     given($self->state())
57     {
58         when($STATE_TAG)
59         {
60             return(qw(AND ARTISTS ALBUMS TRACKS));
61         }
62         when($STATE_BOOLEAN)
63         {
64             return $self->{db}->tags(@{$self->{elements}});
65         }
66         when($STATE_ROOT)
67         {
68             my @dents=("ALL", $self->{db}->tags(@{$self->{elements}}));
69             return @dents;
70         }
71         default
72         {
73             print "DIRENTS: UNHANDLED STATE: $_\n";
74         }
75     }
76 }
77
78 sub parse
79 {
80     my($self)=@_;
81     @{$self->{components}}=split(/\//, $self->{path});
82     shift @{$self->{components}}; # drop empty field before leading /
83     print "PATH: $self->{path}\n";
84     print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
85     $self->state($STATE_ROOT);
86     return if($self->{path} eq "/");
87     my @parts=@{$self->{components}};
88     my($tag, $tagval);
89     $self->{elements}=[];
90     while(my $name=shift @parts)
91     {
92         print "NAME: $name\n";
93         given($self->state())
94         {
95             when($STATE_INVALID)
96             {
97                 print "SM: INVALID: $name\n";
98                 return;
99             }
100             when($STATE_ROOT)
101             {
102                 print "SM: ROOT: $name\n";
103                 if($name eq "ALL")
104                 {
105                     $self->state($STATE_ARTIST);
106                 }
107                 else
108                 {
109                     $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
110                     if($tag)
111                     {
112                         push(@{$self->{elements}}, $tag);
113                         $self->state($STATE_TAG);
114                     }
115                     else
116                     {
117                         $self->state($STATE_INVALID);
118                     }
119                 }
120             }
121             when($STATE_TAG)
122             {
123                 print "SM: TAG: $name\n";
124                 given($name)
125                 {
126                     when("AND")
127                     {
128                         $self->state($STATE_BOOLEAN);
129 #                       push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
130                     }
131 #                   when("ARTISTS") { ; }
132 #                   when("ALBUMS")  { ; }
133 #                   when("TRACKS")  { ; }
134 #                   when("OR")  { ; }
135 #                   when("NOT") { ; }
136                     default
137                     {
138                         $self->state($STATE_INVALID);
139                     }
140                 }
141             }
142
143             when($STATE_WANTMORE)
144             {
145                 print "SM: WANTMORE: $name\n";
146                 $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
147                 if($tag)
148                 {
149                     push(@{$self->{elements}}, $tag);
150 #                   $self->state($STATE_TAG);
151                 }
152                 else
153                 {
154                     $self->state($STATE_INVALID);
155                 }
156                 my @valid_tagvals=$self->{db}->tag_values($tag);
157                 print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
158                 if(@valid_tagvals)
159                 {
160                     if(grep { $name eq $_; } @valid_tagvals)
161                     {
162                         print "TAGVAL VALID\n";
163                         $self->state($STATE_TAGVAL);
164                         push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
165                     }
166                     else
167                     {
168                         print "ERROR: unknown tagval: $tagval\n";
169                         $self->state($STATE_INVALID);
170                     }
171                 }
172                 else
173                 {
174                     $self->state($STATE_INVALID);
175                 }
176             }
177             when($STATE_TAGVAL)
178             {
179                 print "SM: TAGVAL: $name\n";
180             }
181             when($STATE_BOOLEAN)
182             {
183                 print "SM: BOOLEAN: $name\n";
184                 my $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
185                 if($tag)
186                 {
187                     push(@{$self->{elements}}, $tag);
188                     $self->state($STATE_TAG);
189                 }
190                 else
191                 {
192                     $self->state($STATE_INVALID);
193                 }
194             }
195             when($STATE_ARTIST)
196             {
197                 print "SM: ARTIST: $name\n";
198             }
199             when($STATE_ALBUM)
200             {
201                 print "SM: ALBUM: $name\n";
202             }
203             when($STATE_FILE)
204             {
205                 print "SM: FILE: $name\n";
206             }
207             default
208             {
209                 print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
210                 $self->state($STATE_INVALID);
211             }
212         }
213     }
214 }
215
216 sub state
217 {
218     my($self, $newstate)=@_;
219     $self->{state}=$newstate if(defined($newstate));
220     return $self->{state};
221 }
222
223 1;