#!/usr/bin/perl
package File::PatternMatch;

use vars qw($VERSION);
$VERSION = '0.056';

require Exporter;
@ISA = qw(Exporter);
our @EXPORT = qw(patternmatch);

use strict;
use Term::ExtendedColor qw(fg bg);

# Yes, this is extremely fugly.
our %patterns                        = (
  'S[0-9]{1}[2-9]{1}E[0-9]{1}[2-9]' => {
    256                             => fg('magenta23', 'New Episode'),
    dzen                            => "^fg(#ff0000)New Episode^fg()",
    none                            => "New Episode",
    weight                          => 20,
  },
  'S01E01'                          => {
    256                             => fg('red1', 'New Show'),
    dzen                            => "^fg(#ffff00)New Show^fg()",
    none                            => "New Show",
    weight                          => 100,
  },
  'S0\dE01'                         => {
    256                             => fg('bold', 'Season Premiere'),
    dzen                            => "^fg(#cccd05)Season Premiere^fg()",
    none                            => "Season Premiere",
    weight                          => 75,
  },
  'do(c|k?)u(ment.+)?|
  (discovery|history)\.(channel)?|
  national\.geographic|
  colossal\.'                        => {
    256                             => fg('green16', 'Documentary'),
    dzen                            => "^fg(#87d700)Documentary^fg()",
    none                            => "Documentary",
    weight                          => 80,
  },
  'EPL|WWE|UFC|UEFA|Rugby|La\Liga|
  Superleague|Allsvenskan|
  Formula\.Ford'                     => {
    256                             => fg(145, 'Sport'),
    dzen                            => "^fg(#afaf87)Sport^fg()",
    none                            => "Sport",
    weight                          => 5,
  },
  '(?i)swedish|-se-'                => {
    256                             => fg('cyan8', 'Swedish'),
    dzen                            => "^fg(#87ffd7)Swedish^fg(#121212)",
    none                            => "Swedish",
    weight                          => 30,
  },
  '(?i)jay\.leno'                   => {
    256                             => fg('purple15', 'Talk Show'),
    dzen                            => "^fg(87afff)Talk Show^fg()",
    none                            => "Talk Show",
  },
  'PsyCZ|MYCEL|UPE|HiEM|PSi|gEm'    => {
    256                             => "\e[38;5;192mPsychedelic\e[0m",
    dzen                            => "^fg(#d7ff87)Psychedelic^fg()",
    none                            => "Psychedelic",
    weight                          => 70,
  },
  '.+-(H3X|wAx|CMS|BFHMP3|WHOA|RNS|
  C4|CR|UMT|0MNi)(.+)?|FRAY(.+)?$'   => {
    256                             => "\e[38;5;094mHip-Hop\e[0m",
    dzen                            => "^fg(#309184)Hip-Hop^fg()",
    none                            => "Hip-Hop",
    weight                          => 85,
  },
  'LzY|qF|SRP|NiF'                  => {
    256                             => "\e[38;5;126mRock\e[0m",
    dzen                            => "^fg(#af0087)Rock^fg()",
    none                            => "Rock",
    weight                          => 50,
  },
  '-sour$'                          => {
    256                             => "\e[38;5;166mDnB\e[0m",
    dzen                            => "^fg(#d75f00)DnB^fg()",
    none                            => "DnB",
    weight                          => 50,
  },
  'VA(-|_-_).+'                     => {
    256                             => "\e[38;5;049mV/A\e[0m",
    dzen                            => "^fg(#00ffaf)V/A^fg()",
    none                            => "V/A",
    weight                          => 20,
  },
  '\(?_?-?CDS-?_?\)?'               => {
    256                             => "\e[38;5;244mSingle\e[0m",
    dzen                            => "^fg(#808080)Single^fg()",
    none                            => "Single",
    weight                          => 50,
  },
  '\(?_?-?CDM-?_?\)?'               => {
    256                             => "\e[38;5;233mMaxi\e[0m",
    dzen                            => "^fg(#1c1c1c)Maxi^fg()",
    none                            => "Maxi",
    weight                          => 50,
  },
  '\(?_?-?CDA-?_?\)?'               => {
    256                             => "\e[38;5;222mAlbum\e[0m",
    dzen                            => "^fg(#ffd787)Album^fg()",
    none                            => "Album",
    weight                          => 55,
  },
  '\(?_?-?DAB-?_?\)?'               => {
    256                             => "\e[38;5;211mDAB\e[0m",
    dzen                            => "^fg(#ff87af)DAB^fg()",
    none                            => "DAB",
    weight                          => 50,
  },
  '\(?_?-?CABLE-?_?\)?'             => {
    256                             => "\e[38;5;191mCable\e[0m",
    dzen                            => "^fg(#d7ff5f)Cable\e[0m",
    none                            => "Cable",
    weight                          => 5,
  },
  '\(?_?-?VLS|Vinyl-?_?\)?'         => {
    256                             => "\e[38;5;201mVinyl\e[0m",
    dzen                            => "^fg(#ff00ff)Vinyl^fg()",
    none                            => "Vinyl",
    weight                          => 70,
  },
  'Live_(on|at|in)'                 => {
    256                             => "\e[38;5;181mLive\e[0m",
    dzen                            => "^fg(#d7afaf)Live^fg()",
    none                            => "Live",
    weight                          => 45,
  },
  '-Recycled.+$'                    => {
    256                             => "\e[38;5;215Re-release\e[0m",
    dzen                            => "^fg(#ffaf5f)Re-release^fg()",
    none                            => "Re-release",
    weight                          => 55,
  },
  'TALiON|HB|DV8'                   => {
    256                             => "\e[38;5;41m\e[1mHardstyle\e[0m",
    dzen                            => "^fg(#f95504)Hardstyle^fg()",
    none                            => "Hardstyle",
    weight                          => 40,
  },
);

my(undef,undef,undef,undef,undef,$year) = localtime(time);
$year += 1900;

our %wanted = (
  'Fringe'                     => {
    dzen  => "^fg(#000000)^bg(#121212)",
    256   => "\e[48;5;052m\e[1m\e[38;5;196m",
    none  => "",
  },
  'House'                      => {
    dzen  => "^fg(#d5f418)^fg(#ffff00)",
    256   => fg('bold', fg('red1')),
    none  => "",
  },
  '(?:do(c|k)ument(a|รค)ry?|History\.Channel)'   => {
    dzen  => "^fg(#09b33f)",
    256   => "\e[38;5;197m",
    none  => "",
  },

  'pilot'     => {
    dzen      => "^fg(#c02d07)",
    256       => "\e[38;5;85m\e[1m",
    none      => "",
  },
  'S01E01'    => {
    dzen      => "^fg(#d7d75f)",
    256       => "\e[38;5;185m",
    none      => "",
  },
  'hdtv'      => {
    dzen      => "^fg(#cccdda)",
    256       => "\e[38;5;32m\e[3m",
    none      => "",
  },
  'pdtv'      => {
    dzen      => "^fg(#dacddd)",
    256       => "\e[38;5;29m\e[3m",
    none      => "",
  },
  'swedish'   => {
    dzen      => "^fg(#ffff00)",
    256       => "\e[38;5;220m\e[1m",
    none      => "",
  },
  'DIMENSION' => {
    dzen      => "^fg(#faeec4)",
    256       => "\e[38;5;240m\e[1m",
    none      => "",
  },
  'C4'        => {
    dzen      => "^fg(#facddc)",
    256       => "\e[38;5;130m\e[1m",
    none      => "",
  },
  'LOL'       => {
    dzen      => "^fg(#facddc)",
    256       => "\e[38;5;118m\e[1m",
    none      => "",
  },
  '720p'      => {
    dzen      => "^fg(#ffcccd)",
    256       => "\e[38;5;178m\e[1m",
    none      => "",
  },
  'Promo_CD'  => {
    dzen      => "^fg(#dddc26)",
    256       => "\e[38;5;173m",
    none      => "",
  },
  $year       => {
    dzen      => "^fg(#93c26b)",
    256       => "\e[1m",
    none      => "",
  },
);

our %end = (
  dzen  => "", # ^bg()^fg()
  256   => "\e[0m",
  none  => "",
);


sub patternmatch {
  my $fmt = shift // 'plain';
  chomp(my @files = @_);

  my %results;
  my $i = 0;
  for my $file(@files) {
    if( ($fmt == 256) or ($fmt eq 'extended') or ($fmt eq 'plain')) {
      $file = sprintf("%70.70s", $file);
#      $file = sprintf("%$ENV{COLUMNS}.$ENV{COLUMNS}s", $file);
    }

    for my $keyword(keys(%wanted)) {
      $file =~ s/($keyword)/$wanted{$keyword}->{$fmt}$1$end{$fmt}/gi;
    }

    for my $pattern(sort{$patterns{$a}{weight} <=> $patterns{$b}{weight}} keys(%patterns)) {
      if($file =~ /$pattern/x) {
        $results{$i}{$file} = $patterns{$pattern}{$fmt};
        next;
      }
    }
    $i++;
  }
  return(\%results);
}

1;

=head1 NAME

File::PatternMatch - parse media information from filenames

=head1 SYNOPSIS

  use File::PatternMatch;

  my @files = glob("$ENV{HOME}/music/*");

  my $plain = patternmatch(@files);

  my $extended_colors = patternmatch(256, @files);


=head1 DESCRIPTION

B<File::PatternMatch> takes a list of filenames and tries to parse relevant
information from them. If a filename contains the string 'S01E01' we can safely
assume it's a new TV show, the first episode from the first season, and thus we
label it 'New Show'.

There are filters for various music genres, tv shows and music videos.

The labels can be formatted in three ways (output formats):

=head2 plaintext

Raw, plain text.

=head2 colored

Colored using extended escape sequences (see L<Term::ExtendedColor>).

=head2 dzen2

Formatted using the L<dzen2(1)> notation.

=head1 EXPORTS

=head2 patternmatch()

Parameters: $output_format, @files

Returns:    \%results

B<patternmatch()> takes a list of filenames and tries to match them aginst
specific patterns. The result might look like:

  # Plain text
  2 => {
    'Prison.Break.S01E01-FOOBAR'  => 'New Show',
  },
  42 => {
    'Laleh-Prinsessor-FOOBAZ'     => 'Pop/Rock',
  },

  # Using extended color escape sequences
  2 => {
    'Prison.Break.S01E01-FOOBAR'  => "\e[38;5;160mNew Show\e[0m",
  },

  # Using dzen2 format
  2 => {
    'Prison.Break.S01E01-FOOBAR'  => '^fg(#ff0000)New Show^fg()',
  },

=head1 SEE ALSO

L<https://github.com/trapd00r/rel>

=head1 AUTHOR

  Magnus Woldrich
  CPAN ID: WOLDRICH
  m@japh.se
  http://japh.se

=head1 REPORTING BUGS

Report bugs and/or feature requests:

L<https://rt.cpan.org>

L<https://github.com/trapd00r/Foo-Bar/issues>

L<m@japh.se>

=head1 COPYRIGHT

Copyright 2011, 2018- Magnus Woldrich <m@japh.se>. This program is free
software; you may redistribute it and/or modify it under the same terms as
Perl itself.

=cut