#!/usr/bin/env perl

package local::bin::AveMaria;

use v5.10;
use strict;
use Webservice::Rosary::API qw//;
use Util::H2O::More qw/ddd Getopt2h2o h2o o2d tr4h2o/;
use Dispatch::Fu;
use Time::HiRes qw/sleep/;
use Text::Fold qw/fold_text/;

binmode(STDOUT, ":utf8");

$|++; #autoflush

my $Rosary = Webservice::Rosary::API->new;

our $VERSION = 0.3;

use constant {
  EXIT_SUCCESS => 0,
  EXIT_ERROR   => 1,
};

my $subcommand = shift @ARGV;

sub do_help() {
  print STDERR <<EOF;
AveMaria - commandline Rosary client for DailyRosary.cf and TheRosaryAPI.cf  

There are 2 types of commands. One set of commands returns a URL for an MP3,
which may then be piped into another program to download it. The other set
of commands displays the specified Mystery (by day of the week or actual
name of the Mystery), so that the user may be guided through the specified
Mystery of the Rosary - from start to finish.

Usage - to print MP3 URL to STDIN:

  AveMaria today|yesterday|tomorrow|random

Example 1,

  > AveMaria today
  > https://dailyrosary.cf/audio-rosary-sorrowful-mysteries.mp3
   
Example 2,

  > curl -O \$(AveMaria random) -w "\\nDownloaded file: %{filename_effective}\\n"
    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                   Dload  Upload   Total   Spent    Left  Speed
  100 31.5M  100 31.5M    0     0  2374k      0  0:00:13  0:00:13 --:--:-- 5043k
  
  Downloaded file: audio-rosary-sorrowful-mysteries.mp3
  >

Usage - to Pray the Rosary in the commandline:

  AveMaria DAY_OR_MYSTERY [--pray] [-i] [-t] [--fully] [--sleep=0.N] 

  Valid DAY_OR_MYSTERY values:

    Joyful, Sorrowful, Luminous, Glorious, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, or Saturday

  Optional flags:

  --pray   : automatically prints prayers, character by character to the screen; default delay is 0.4 seconds.
   -i      : user must hit <RETURN> after each prayer (and description, if used with "--fully"
   -t      : user must hit <RETURN> after each description (requires --fully)
  --fully  : prints the full description of the current Mystery's Decade, including the Fruit of the Mystery
  --sleep  : affects the delay taken before each new character is printed (when used with --pray). Default is 0.4 seconds.

Example 3,

  Used without additional options, it just prints the name of the Mystery

  > AveMaria Monday
  > Monday - The Joyful Mysteries
  >

  > AveMaria Sorrowful
  > Friday - The Sorrowful Mysteries
  >

Example 4,

  > AveMaria Friday --pray -t --fully
  > .. clears screen, the plays the specified Mystery (Sorrowful in this case),
    while pausing only at the beginning of each Mystery after the description has
    been printed ...

Example 5,

  Run with absolutely no subcommands or flags, runs "--pray" for Today's Mystery,

  > AveMaria
  > .. clears screen, the plays the specified Mystery for Today ...

Feedback is Requested.

I have no idea how this is going to be used, and the way someone says the Rosary
tends to be highly personal; so please let me know what kind of "--pray" controls
would be helpful.

+Deus Gratias+
  
EOF
}

#>>>
dispatch { # Dispatch::Fu
  my ($Rosary, $subcommand, $ARGV) = xshift_and_deref @_;
  my @mp3     = qw/today yesterday tomorrow random/;
  my @day     = qw/sunday monday tuesday wednesday thursday friday saturday/;
  my @mystery = qw/joyful glorious sorrowful luminous/;
  return "mp3"  if (grep { m/^$subcommand$/i } @mp3);
  return "day" if (grep { m/^$subcommand$/i } @day);
  return "mystery" if (grep { m/^$subcommand$/i } @mystery);
  return "day";
} [ $Rosary, lc $subcommand, \@ARGV ],
  mp3     => sub { my ($Rosary, $subcommand, $ARGV) = xshift_and_deref @_; say $Rosary->mp3Link($subcommand, $ARGV); exit EXIT_SUCCESS },
  day     => \&PrayTheRosary,
  mystery => \&mystery,
  help    => \&do_help,
;
#<<<

sub mystery {
  my ($Rosary, $subcommand, $ARGV ) = xshift_and_deref @_; 
  my $Convert = h2o {
    luminous  => "thursday",
    sorrowful => "friday",
    joyful    => "saturday",
    glorious  => "sunday",
  };
  $subcommand = $Convert->$subcommand;
  return PrayTheRosary([$Rosary, $subcommand, $ARGV]);
}

sub _print($$) {
  my ($Text, $o) = @_;
  my @words = split //, $Text;
  foreach my $Word (@words) {
    printf "%s", $Word;
    sleep $o->sleep;
  }
  return;
}

sub PrayTheRosary {
  my ($Rosary, $subcommand, $ARGV) = xshift_and_deref @_; 
  my @days_of_week = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);
  my ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime();
  $subcommand ||= lc $days_of_week[$wday];
  $ARGV       = (@$ARGV) ? $ARGV : ['--pray'];
  my $o = Getopt2h2o $ARGV, { sleep => 0.04 }, qw/pray i t fully without sleep=s/;
  my $Mystery = $Rosary->day($subcommand, $ARGV);
  my $Full;
  if ($o->fully) {
    $Full = $Rosary->details(lc $Mystery->group_by);
  }
  my $Name    = sprintf "%s - The %s Mysteries", ucfirst $subcommand, $Mystery->group_by;
  unless ($o->pray) {
    say $Name;
    exit EXIT_SUCCESS;
  }
  # Iterate over the entire Rosary, in Perl
  my @Prayers       = qw/In_The_Name_1 I_Believe Our__Father_1 Hail__Mary_1 Hail__Mary_2 Hail__Mary_3 Glory_Be_1 Oh_My_Jesus_1/;
  my $Decade        = 0;
  my $Announce      = 0;
  my $Pater_Noster  = 1; # "Our Father, who art in Heaven ..."
  my $Ave_Maria     = 3; # "Hail Mary, full of Grace ..."
  my $Gloria_Patria = 1; # "Glory be to the Father, to the Son, and to the Holy Ghost ..."
  my $O_Mi_Jesu     = 1; # "O My Jesus, forgive us our sins ..." (aka, "The Fatima Prayer")
  foreach my $D (1..5) {
    push @Prayers, sprintf "Announce_%d",   ++$Announce;
    push @Prayers, sprintf "Our__Father_%d", ++$Pater_Noster;
    foreach my $I (1..10) {
      push @Prayers, sprintf "Hail__Mary_%d_%d", ++$Ave_Maria, $I;
    }
    push @Prayers, sprintf "Glory_Be_%d", ++$Gloria_Patria;
    push @Prayers, sprintf "Oh_My_Jesus_%d", ++$O_Mi_Jesu;
  }
  push @Prayers, qw/Holy_Queen Pray_For_Us_Most_Holy_Mother_of_God Oremus Final_Prayer Most_Holy_Rosary In_The_Name_2/;
  $Mystery = tr4h2o o2d $Mystery;
  $Mystery->{pray_for_us_most_holy_mother_of_god} = <<EOF;
V. Pray for us, Oh Holy Mother of God
R. That we may be made worth of the promises of Christ.
EOF
  $Mystery->{oremus} = "V. Let us Pray.";
  $Mystery->{most_holy_rosary} = "";
  $Mystery->{in_the_name_2} = sprintf "The Most Holy Rosary.\n%s" . $Mystery->{in_the_name_2};
  h2o $Mystery;
  my $count  = 0;
  my $decade = 0;
  foreach my $Prayer (map { lc } @Prayers) {
    my $Text = $Mystery->$Prayer; 
    $Text =~ s/\\r\\n|\\n/\n/g; 
    $Text =~ s/Lead/\nLead/; # us to Heaven
    sleep 0.75;              # slight pause
    print "\033[2J\033[H";   # clear terminal
    my $align = sprintf "%30s ", $Name;
    printf "%s[%-2d of %d]\n\n", $align, ++$count, scalar @Prayers;
    if ($o->fully and $Prayer =~ m/Announce/i) {
      my $details = $Full->[$decade++];
      _print $details->title, $o;
      print "\n\n";
      _print fold_text($details->text, 72), $o;
      print "\n\n";
      _print $details->fruit, $o;
      print "\n\n";
      if ($o->i or $o->p) {
        print "\n\n<RETURN> to continue ... ";
        my $next = <STDIN>
      }
    }
    _print $Text, $o;
    if ($o->i) {
      print "\n\n<RETURN> to continue ... ";
      my $next = <STDIN>
    }
  }
}

123

__END__
