#!/usr/bin/perl

$VERSION = "0.1";
$PROGVER = $VERSION;

$configfile = 'playlist.conf';
$type = 'MAIN';
 
sub readconfig ($$);
sub getdir($);
sub getbands(@);
sub getalbums(@);
sub createbasedirs();
sub createbanddir();
sub createalbumdir();
sub printplaylist();


readconfig($configfile, $type);
@mp3s = getdir($config{mp3dir});

print "\n\nDirectories Done\n";

%songs = getalbums(@mp3s);
#%bands = getbands(@mp3s);



createbasedirs();

printplaylist();

createbanddir();
createalbumdir();


sub readconfig($$)
{
  $configfile = shift;
  $type = shift;

  open(CONFIG, "< $configfile") or die "No Conf file: $configfile \n";
  while (<CONFIG>) {
    chomp;                  # no newline
    s/#.*//;                # no comments
    s/^\s+//;               # no leading white
    s/\s+$//;               # no trailing white
    next unless length;     # anything left?


    my ($var, $value) = split(/\s*=\s*/, $_, 2);
    $config{$var} = $value;
  }
  close(CONFIG);
}

sub getdir($)
{
  my($dir) = shift;
  my(@directorys, @mp3s, @files, $file, $mp3, $num);

  opendir(MP3, $dir);
  @files = readdir(MP3);
  closedir(MP3);
  
  print "\nGetting directories.\n\n";
  foreach $file (@files)
  {
    if($file =~ m/.musicdir.noscan/i)
    {
      return undef;
    }
    elsif(-d $dir . "/" . $file && $file ne "." && $file ne "..")
    {
      push(@directorys, $dir . "/" . $file);
      print ".";
    }
    elsif($file =~ m/\.mp3/i or $file =~ m/\.ogg/i)
    {
      push(@mp3s, $dir . "/" . $file);
    }
  }
  
  foreach $directory (@directorys)
  {
    print ".";
    @files = getdir($directory);
    push(@mp3s, @files);
  }
  return @mp3s;
}

sub getalbums(@)
{
  my(@mp3s) = @_;
  my($error, $sfile, $begin, $end, $num);
  my($band, $album, $num, $song) = "";
  
  open ERROR, ">/tmp/musicdir.err";
  foreach $file (@mp3s)
  {
    $error = 0;
    $num = "";
    $album = "";
    my($band) = "";
    my(@bands, $remove);
    $song = "";
    $sfile = $file;
    $sfile =~ s/.*\///;
    $sfile =~ s/\.mp3//i;
    $sfile =~ s/\.ogg//i;
    if($sfile =~ m/-[0-9][0-9]-/)
    #Files with format of Artist-Album-Num-Song.mp3 (with [] around any part that contains a '-'
    {
      $begin = $sfile;
      $begin =~ s/-[0-9][0-9]-.*//;
      
      $end = $sfile;
      $end =~ s/.*?-[0-9][0-9]-//;
      
      $num = $sfile;
      $num =~ /-([0-9][0-9])-/;
      $num = $1;
      
      if($begin =~ m/^\[/)
      {
        $band = $begin;
        $band =~ s/^\[//;
        $band =~ s/\]-.*//;
        $begin =~ s/.*?\]-//;
      }
      elsif($begin =~ m/.*?-.*/)
      {
        $band = $begin;
        $band =~ s/-.*//;
        $begin =~ s/.*?-//;
      }

      if($begin =~ m/^\[/)
      {
        $album = $begin;
        $album =~ s/^\[//;
        $album =~ s/\].*//;
      }
      else
      {
        $album = $begin;
      }
      
      if($end =~ m/^\[/)
      {
        $song = $end;
        $song =~ s/^\[//;
        $song =~ s/].*//;
      }
      else
      {
        $song = $end;
        $song =~ s/\.mp3//i;
        $song =~ s/\.ogg//i;
      }
    }
    else
    #Files with format of Artist-Song.mp3, [Artist]-Song.mp3, Artist-[Song].mp3 & [Artist]-[Song].mp3
    {
      if($sfile =~ m/^\[.*?\]-\[.*?\].*/)
      #[Artist]-[Song].mp3
      {
        $band = $sfile;
        $band =~ s/^\[//;
        $band =~ s/\]-.*//;
        
        $song = $sfile;
        $song =~ s/.*-\[//;
        $song =~ s/].*//;
      }
      elsif($sfile =~ m/^.*-\[.*?\].*/)
      #Artist-[Song].mp3
      {
        $band = $sfile;
        $band =~ s/-.*//;
        
        $song = $sfile;
        $song =~ s/.*-\[//;
        $song =~ s/].*//;
      }
      elsif($sfile =~ m/^\[.*?\]-.*/)
      #[Artist]-Song.mp3
      {
        $band = $sfile;
        $band =~ s/^\[//;
        $band =~ s/\]-.*//;
        
        $song = $sfile;
        $song =~ s/.*?-//;
      }
      elsif($sfile =~ m/.*?-.*?-.*?/)
      #More then 2 dashes and nothing is in [] - this file has an error in it's name
      {
        print ERROR $file . "\n";
        $error = 1;
      }
      elsif($sfile =~ m/.*?-.*?/)
      #Artist-Song.mp3
      {
        $band = $sfile;
        $band =~ s/-.*//;

        $song = $sfile;
        $song =~ s/.*?-//;
      }
      else
      #This file has NO dashes in it's name - there is an error in it's name.
      {
        print ERROR $file . "\n";
        $error = 1;
      }
      
    }
    
    if($band =~ m/&/)
    {
      while($band =~ m/&/)
      {
        $remove = $band;
        $remove =~ s/ &.*//;
        $band =~ s/.*?& //;
        push(@bands, $remove);
      }
      push(@bands, $band);
    }
    else
    {
      push(@bands, $band);
    }

    if($album =~ m/\{.*\}/)
    {
      $remixers = $album;
      $remixers =~ s/.*{//;
      $remixers =~ s/}.*//;
      while($remixers =~ m/&/)
      {
        $remove = $remixers;
        $remove =~ s/ &.*//;
        $remixers =~ s/.*?& //;
        push(@bands, $remove);
      }
      push(@bands, $remixers);
    }

    if($error == 0)
    {
      $songs{"album"}{lc($album)}{$num}{"band"} = $band;
      $songs{"album"}{lc($album)}{$num}{"song"} = $song; 
      $songs{"album"}{lc($album)}{$num}{"file"} = $file;
      $songs{"albumname"}{lc($album)} = $album;
      
      foreach $bandname (@bands)
      {
        push(@{$songs{"band"}{lc($bandname)}}, $file); 
        $songs{"bandname"}{lc($bandname)} = $bandname;
      }
    }
  }
  close ERROR;
  return %songs;
}

sub createbasedirs()
{
  $config{'dir'}{'mp3'}{'band'} = $config{musicdir} . "/" . $config{bandmp3dir};
  $config{'dir'}{'mp3'}{'album'} = $config{musicdir} . "/" . $config{albummp3dir};
  $config{'dir'}{'mp3'}{'boot'} = $config{musicdir} . "/" . $config{bootmp3dir};
  $config{'dir'}{'mp3'}{'bootalbum'} = $config{musicdir} . "/" . $config{bootmp3dir} . "/" . $config{albummp3dir};
  $config{'dir'}{'mp3'}{'remix'} = $config{musicdir} . "/" . $config{remixmp3dir};
  $config{'dir'}{'mp3'}{'remixalbum'} = $config{musicdir} . "/" . $config{remixmp3dir} . "/" . $config{albummp3dir};
  $config{'dir'}{'m3u'}{'band'} = $config{pldir} . "/" . $config{bandpldir};
  $config{'dir'}{'m3u'}{'album'} = $config{pldir} . "/" . $config{albumpldir};
  $config{'dir'}{'m3u'}{'boot'} = $config{pldir} . "/" . $config{bootpldir};
  $config{'dir'}{'m3u'}{'remix'} = $config{pldir} . "/" . $config{remixpldir};
  if(!(-e $config{'dir'}{'mp3'}{'band'}))
  {
    mkdir($config{'dir'}{'mp3'}{'band'}, 0755);
  }
  if(!(-e $config{'dir'}{'mp3'}{'album'}))
  {
    mkdir($config{'dir'}{'mp3'}{'album'}, 0755);
  }
  if(!(-e $config{'dir'}{'mp3'}{'boot'}))
  {
    mkdir($config{'dir'}{'mp3'}{'boot'}, 0755);
  }
  if(!(-e $config{'dir'}{'mp3'}{'bootalbum'}))
  {
    mkdir($config{'dir'}{'mp3'}{'bootalbum'}, 0755);
    symlink($config{'dir'}{'mp3'}{'bootalbum'},   $config{'dir'}{'mp3'}{'album'} . "/Bootleg\ Albums");
  }
  if(!(-e $config{'dir'}{'mp3'}{'remix'}))
  {
    mkdir($config{'dir'}{'mp3'}{'remix'}, 0755);
  }
  if(!(-e $config{'dir'}{'mp3'}{'remixalbum'}))
  {
    mkdir($config{'dir'}{'mp3'}{'remixalbum'}, 0755);
    symlink($config{'dir'}{'mp3'}{'remixalbum'}, $config{'dir'}{'mp3'}{'album'} . "/Remix\ Albums");
  }
  if(!(-e $config{'dir'}{'m3u'}{'band'}))
  {
    mkdir("$config{'dir'}{'m3u'}{'band'}", 0755);
  }
  if(!(-e $config{'dir'}{'m3u'}{'album'}))
  {
    mkdir("$config{'dir'}{'m3u'}{'album'}", 0755);
  }
  if(!(-e $config{'dir'}{'m3u'}{'boot'}))
  {
    mkdir("$config{'dir'}{'m3u'}{'boot'}", 0755);
  }
  if(!(-e $config{'dir'}{'m3u'}{'remix'}))
  {
    mkdir("$config{'dir'}{'m3u'}{'remix'}", 0755);
  }
}

sub createbanddir()
{
  print "\n\nBand Directories.\n\n";
  $banddir = $config{'dir'}{'mp3'}{'band'};

  foreach $band (keys %{$songs{"band"}})
  {
    if(scalar(@{$songs{"band"}{$band}}) >= $config{"dir_reqfiles"})
    {
      if(!(-e $config{'dir'}{'mp3'}{'band'} . "/" . $songs{'bandname'}{$band}))
      {
        mkdir "$config{'dir'}{'mp3'}{'band'}/$songs{'bandname'}{$band}", 0755;
      }
    
      foreach $file (sort @{$songs{"band"}{$band}})
      {
        $sfile = $file; 
        $sfile =~ s/.*\///;
        $newfile = "$config{'dir'}{'mp3'}{'band'}/$songs{'bandname'}{$band}/$sfile";
        print ".";
        symlink $file, $newfile;
      }
      print "\n";
    }
    else
    {
    $x = scalar(@{$songs{'band'}{$band}});
    print("\n$band - " . $x . "\n");
      foreach $file (sort @{$songs{"band"}{$band}})
      {
        print ".";
        $sfile = $file; 
        $sfile =~ s/.*\///;
        symlink $file, $config{'dir'}{'mp3'}{'band'} . "/" . $sfile;
      }
      print "\n";
    }


    foreach $file (sort @{$songs{"band"}{$band}})
    {
      if($file =~ m/\(bootleg\)/i or $file =~ m/\(live\)/i)
      {
        if(!(-e $config{'dir'}{'mp3'}{'boot'} . "/" . $songs{'bandname'}{$band}))
        {
          mkdir $config{'dir'}{'mp3'}{'boot'} . "/" . $songs{'bandname'}{$band}, 0755;
        }
        $sfile = $file; 
        $sfile =~ s/.*\///;
        $newfile = "$config{'dir'}{'mp3'}{'boot'}/$songs{'bandname'}{$band}/$sfile";
        print ".";
        symlink $file, $newfile;
      }
      elsif($file =~ m/\(remix\)/i or $file =~ m/\(bside\)/i)
      {
        if(!(-e $config{'dir'}{'mp3'}{'remix'} . "/" . $songs{'bandname'}{$band}))
        {
          mkdir "$config{'dir'}{'mp3'}{'remix'}/$songs{'bandname'}{$band}", 0755;
        }
        $sfile = $file; 
        $sfile =~ s/.*\///;
        $newfile = "$config{'dir'}{'mp3'}{'remix'}/$songs{'bandname'}{$band}/$sfile";
        print ".";
        symlink $file, $newfile;
      }
    }
  }
  print "\n\nDone.\n";
}

sub createalbumdir()
{
  print "\n\nAlbum Directories.\n\n";
  foreach $album (keys %{$songs{"album"}})
  {
    my(@albumfiles) = "";
    @save = 0;
    if($album ne "")
    {
      $bandsame = 1;
      $bandname = "";
      foreach $num (sort keys %{$songs{"album"}{$album}})
      {
        if($bandname eq "")
        {
          $bandname = $songs{"album"}{$album}{$num}{"band"};
        }
        elsif($bandname ne $songs{"album"}{$album}{$num}{"band"})
        {
          $bandsame = 0;
        }
        push(@albumfiles, $songs{"album"}{$album}{$num}{"file"});
      }

      if(scalar(@albumfiles) >= $config{"album_reqfiles"})
      {
        if($bandsame)
        {
          $albumname = "$bandname-$songs{'albumname'}{$album}";
        }
        else
        {
          $albumname = "Various Artists-$songs{'albumname'}{$album}";
        }

        if($album =~ m/\(bootleg\)/i or $album =~ m/\(live\)/i)
        {
          $maindir = $config{'dir'}{'mp3'}{'bootalbum'};
          $pldir = $config{'dir'}{'m3u'}{'boot'};
        }
        elsif($album =~ m/\(remix\)/i or $album =~ m/\(bside\)/i)
        {
          $maindir = $config{'dir'}{'mp3'}{'remixalbum'};
          $pldir = $config{'dir'}{'m3u'}{'remix'};
        }
        else
        {
          $maindir = $config{'dir'}{'mp3'}{'album'};
          $pldir = $config{'dir'}{'m3u'}{'album'};
        }

        if(!(-e $maindir . "/$albumname"))
        {
          mkdir("$maindir/$albumname", 0755);
          symlink "$pldir/$albumname.m3u", "$maindir/$albumname/$albumname.m3u";
#          symlink "$pldir/$albumname.pla", "$maindir/$albumname/$albumname.pla";
        }
        foreach $file (sort @albumfiles)
        {
          print "+";
          $sfile = $file;
          $sfile =~ s/.*\///;
          $newfile = "$maindir/$albumname/$sfile";
          symlink $file, $newfile;
        }
        print "\n";
      }
    }
  }
  print "\n\nDone.\n";
}

sub printplaylist()
{
  print "\n\nProducing album playlists.\n\n";
  print $config{pldir} . "\n";
  
  foreach $album (keys %{$songs{"album"}})
  {
    @print = 0;
    if($album ne "")
    {
      print ".";
      $bandsame = 1;
      $bandname = "";
      foreach $num (sort keys %{$songs{"album"}{$album}})
      {
        if($bandname eq "")
        {
          $bandname = $songs{"album"}{$album}{$num}{"band"};
        }
        elsif($bandname ne $songs{"album"}{$album}{$num}{"band"})
        {
          $bandsame = 0;
        }
        push(@print, $songs{"album"}{$album}{$num}{"file"});
      }
      if(scalar(@print) >= $config{"album_reqfiles"})
      {
        if($album =~ m/\(bootleg\)/i or $album =~ m/\(live\)/i)
        {
          $pldir = $config{'dir'}{'m3u'}{'boot'};
        }
        elsif($album =~ m/\(remix\)/i or $album =~ m/\(bside\)/i)
        {
          $pldir = $config{'dir'}{'m3u'}{'remix'};
        }
        else
        {
          $pldir = $config{'dir'}{'m3u'}{'album'};
        }

        if($bandsame == 1)
        {
          open M3UALBUMPL, ">" . $pldir . "/" . $bandname . "-" . $songs{"albumname"}{$album} . ".m3u";
#          open PLAALBUMPL, ">" . $pldir . "/" . $bandname . "-" . $songs{"albumname"}{$album} . ".pla";
        }
        else
        {
          open M3UALBUMPL, ">" . $pldir . "/Various Artists-" . $songs{"albumname"}{$album} . ".m3u";
#          open PLAALBUMPL, ">" . $pldir . "/Various Artists-" . $songs{"albumname"}{$album} . ".pla";
        }
        
        shift @print;
        foreach $line (@print)
        {
#          print PLAALBUMPL $line . "\n";
#          $line =~ s/\/usr\/local\/music//;
          $line =~ s/.*\///g;
          $line =~ s/\//\\/g;
          print M3UALBUMPL $line . "\n";
        }
      }
      
      #truncate print queue
    }
    close M3UALBUMPL;
#    close PLAALBUMPL;
  }
  print "\n\nProducing band playlists.\n\n";
  foreach $band (keys %{$songs{"band"}})
  {
    if(scalar(@{$songs{"band"}{$band}}) >= $config{"band_reqfiles"})
    {
      print ".";
      open M3UBANDPL, ">" . $config{'dir'}{'m3u'}{'band'} . "/" . $songs{"bandname"}{$band} . ".m3u";
#      open PLABANDPL, ">" . $config{'dir'}{'m3u'}{'band'} . "/" . $songs{"bandname"}{$band} . ".pla";
    
      foreach $song (sort @{$songs{"band"}{$band}})
      {
#        print PLABANDPL $song . "\n";
        $line =~ s/\/usr\/local\/music//;
        print M3UBANDPL $song . "\n";
      }
      close M3UBANDPL;
#      close PLABANDPL;
    }
  }
  print "\n\nDone.\n";
}
