#!/usr/bin/env perl
use strict;
use warnings;

# Use local libraries
use lib map { "$ENV{HOME}/sandbox/$_/lib" } qw( MIDI-Drummer-Tiny MIDI-Util Music-Duration-Partition );

use MIDI::Drummer::Tiny;
use Music::Duration::Partition;

my $max = shift || 8;
my $bpm = shift || 100;

my $d = MIDI::Drummer::Tiny->new(
    file => "$0.mid",
    bpm  => $bpm,
);

$d->score->synch(
    \&pulse,
    \&beat,
);

$d->write;

sub pulse {
    for my $n (1 .. $max) {
        $d->note($d->quarter, $d->pedal_hh) for 1 .. $max;
    }
}

sub beat {
    my $mdp = Music::Duration::Partition->new(
        size    => 4,
        pool    => [qw(qn en sn)],
        weights => [5, 10, 5],
    );

    my $j = 0;

    for my $n (1 .. $max) {
        $d->note(
            $d->quarter,
            $_ == 1 ? $d->crash1 : '',
            $_ % 2 ? $d->kick : $d->snare
        ) for 1 .. 4;

        my $motif = $mdp->motif;

        my $patch;
        for my $i (0 .. @$motif - 1) {
            if ($j % 2 == 0) {
                $patch = $d->snare         if $i == 0;
                $patch = $d->snare         if $i == 1;
                $patch = $d->hi_tom        if $i == 2;
                $patch = $d->hi_mid_tom    if $i == 3;
                $patch = $d->low_mid_tom   if $i == 4;
                $patch = $d->low_tom       if $i == 5;
                $patch = $d->hi_floor_tom  if $i == 6;
                $patch = $d->low_floor_tom if $i == 7;
            }
            else {
                $patch = $d->snare         if $i == 0;
                $patch = $d->hi_tom        if $i == 1;
                $patch = $d->snare         if $i == 2;
                $patch = $d->hi_mid_tom    if $i == 3;
                $patch = $d->snare         if $i == 4;
                $patch = $d->low_mid_tom   if $i == 5;
                $patch = $d->snare         if $i == 6;
                $patch = $d->low_tom       if $i == 7;
                $patch = $d->snare         if $i == 8;
                $patch = $d->hi_floor_tom  if $i == 9;
                $patch = $d->snare         if $i == 10;
                $patch = $d->low_floor_tom if $i == 11;
            }

            $d->note($motif->[$i], $patch);
        }

        $j++;
    }
    $d->note($d->whole, $d->crash1, $d->kick);
}
