merge ARTIST and TAG states
[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_TAG, $STATE_TAGVAL,
14      $STATE_BOOLEAN, $STATE_ALBUMS, $STATE_TRACKLIST,
15      $STATE_FILE)=(0..7);
16
17 sub new
18 {
19     my $proto=shift;
20     my $class=ref($proto) || $proto;
21     my $self={};
22     bless($self,$class);
23
24     $self->{db}=shift;
25     $self->{path}=shift;
26     $self->parse();
27     print "STATE: ", $self->state(), "\n";
28     return $self;
29 }
30
31 sub isdir
32 {
33     my($self)=@_;
34     if(($self->state() == $STATE_FILE) ||
35        ($self->state() == $STATE_INVALID))
36     {
37         return 0;
38     }
39     return 1;
40 }
41
42 sub isfile
43 {
44     my($self)=@_;
45     return 1 if($self->state() == $STATE_FILE);
46     return 0;
47 }
48
49 sub isvalid
50 {
51     my($self)=@_;
52     return($self->state() != $STATE_INVALID);
53 }
54
55 sub dest
56 {
57     my($self)=@_;
58     if($self->state() == $STATE_FILE)
59     {
60         return $self->{db}->filename(@{$self->{elements}});
61     }
62     return "ERROR"; #should never happen?
63 }
64
65 sub dirents
66 {
67     my($self)=@_;
68     my @dents=();
69     given($self->state())
70     {
71         when($STATE_TAG)
72         {
73             @dents=(qw(AND ALLTRACKS), # FIXME: NOT and OR
74                     $self->{db}->artists(@{$self->{elements}}));
75         }
76         when($STATE_BOOLEAN)
77         {
78             @dents=$self->{db}->tags(@{$self->{elements}});
79         }
80         when($STATE_ROOT)
81         {
82             @dents=("ALL", $self->{db}->tags(@{$self->{elements}}));
83         }
84         when($STATE_ALBUMS)
85         {
86             @dents=("TRACKS", $self->{db}->albums(@{$self->{elements}}));
87         }
88         when($STATE_TRACKLIST)
89         {
90             @dents=$self->{db}->tracks(@{$self->{elements}});
91         }
92         default
93         {
94             print "DIRENTS: UNHANDLED STATE: $_\n";
95         }
96     }
97     return(@dents);
98 }
99
100 sub parse
101 {
102     my($self)=@_;
103     @{$self->{components}}=split(/\//, $self->{path});
104     shift @{$self->{components}}; # drop empty field before leading /
105     print "PATH: $self->{path}\n";
106 #    print "COMPONENTS: ", join(' | ', @{$self->{components}}), "\n";
107     $self->state($STATE_ROOT);
108     return if($self->{path} eq "/");
109     my @parts=@{$self->{components}};
110     my($tag, $tagval);
111     $self->{elements}=[];
112     while(my $name=shift @parts)
113     {
114         print "NAME: $name\n";
115         given($self->state())
116         {
117             when($STATE_INVALID)
118             {
119                 print "SM: INVALID: $name\n";
120                 return;
121             }
122             when($STATE_ROOT)
123             {
124                 print "SM: ROOT: $name\n";
125                 if($name eq "ALL")
126                 {
127                     $self->state($STATE_TAG);
128                 }
129                 else
130                 {
131                     $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
132                     if($tag)
133                     {
134                         push(@{$self->{elements}}, $tag);
135                         $self->state($STATE_TAG);
136                     }
137                     else
138                     {
139                         $self->state($STATE_INVALID);
140                     }
141                 }
142             }
143             when($STATE_TAG)
144             {
145                 print "SM: TAG: $name\n";
146                 given($name)
147                 {
148                     when("AND")
149                     {
150                         $self->state($STATE_BOOLEAN);
151 #                       push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
152                     }
153                     when("ALLTRACKS")
154                     {
155                         $self->state($STATE_TRACKLIST);
156                     }
157                     when("OR")
158                     {
159                         $self->state($STATE_BOOLEAN);
160 #                       push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
161                     }
162                     when("NOT")
163                     {
164                         $self->state($STATE_TAG);
165 #                       push(@{$self->{elements}}, ID3FS::PathElement::Boolean->new($name));
166                     }
167                     my $artist=ID3FS::PathElement::Artist->new($self->{db}, $name);
168                     if($artist)
169                     {
170                         push(@{$self->{elements}}, $artist);
171                         $self->state($STATE_ALBUMS);
172                     }
173                     else
174                     {
175                         $self->state($STATE_INVALID);
176                     }
177                 }
178             }
179
180 #           when(255) #FIXME - dead code
181 #           {
182 #               my @valid_tagvals=$self->{db}->tag_values($tag);
183 #               print "TAGVALUES: $name: ", join(', ', @valid_tagvals), "\n";
184 #               if(@valid_tagvals)
185 #               {
186 #                   if(grep { $name eq $_; } @valid_tagvals)
187 #                   {
188 #                       print "TAGVAL VALID\n";
189 #                       $self->state($STATE_TAGVAL);
190 #                       push(@{$self->{elements}}, ID3FS::PathElement::Tagval($name));
191 #                   }
192 #                   else
193 #                   {
194 #                       print "ERROR: unknown tagval: $tagval\n";
195 #                       $self->state($STATE_INVALID);
196 #                   }
197 #           }
198             when($STATE_TAGVAL)
199             {
200                 print "SM: TAGVAL: $name\n";
201             }
202             when($STATE_BOOLEAN)
203             {
204                 print "SM: BOOLEAN: $name\n";
205                 my $tag=ID3FS::PathElement::Tag->new($self->{db}, $name);
206                 if($tag)
207                 {
208                     push(@{$self->{elements}}, $tag);
209                     $self->state($STATE_TAG);
210                 }
211                 else
212                 {
213                     $self->state($STATE_INVALID);
214                 }
215             }
216             when($STATE_ALBUMS)
217             {
218                 print "SM: ALBUM: $name\n";
219                 if($name eq "TRACKS")
220                 {
221                     $self->state($STATE_TRACKLIST);
222                 }
223                 else
224                 {
225                     my $album=ID3FS::PathElement::Album->new($self->{db}, $name);
226                     push(@{$self->{elements}}, $album);
227                     if($album)
228                     {
229                         push(@{$self->{elements}}, $album);
230                         $self->state($STATE_TRACKLIST);
231                     }
232                     else
233                     {
234                         $self->state($STATE_INVALID);
235                     }
236                 }
237             }
238             when($STATE_TRACKLIST)
239             {
240                 print "SM: TRACKLIST: $name\n";
241                 my $track=ID3FS::PathElement::File->new($self->{db}, $name);
242                 push(@{$self->{elements}}, $track);
243                 if($track)
244                 {
245                     push(@{$self->{elements}}, $track);
246                     $self->state($STATE_FILE);
247                 }
248                 else
249                 {
250                     $self->state($STATE_INVALID);
251                 }
252             }
253             when($STATE_FILE)
254             {
255                 print "SM: FILE: $name\n";
256                 # Can't have anything after a filename
257                 $self->state($STATE_INVALID);
258             }
259             default
260             {
261                 print "SM: ERROR: UNKNOWN STATE: $self->{state}\n";
262                 $self->state($STATE_INVALID);
263             }
264         }
265     }
266 }
267
268 sub state
269 {
270     my($self, $newstate)=@_;
271     $self->{state}=$newstate if(defined($newstate));
272     return $self->{state};
273 }
274
275 1;