From b2c3e20920c2595f800eb1cb1bd28b0ad03377e2 Mon Sep 17 00:00:00 2001
From: bill-auger <mr.j.spam.me@gmail.com>
Date: Tue, 21 Mar 2023 13:56:40 -0400
Subject: [PATCH 3/5] implement animation stepping

---
 cowsay | 47 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/cowsay b/cowsay
index dc49542..aa356df 100755
--- a/cowsay
+++ b/cowsay
@@ -45,7 +45,7 @@ if (($^O eq "MSWin32") or ($^O eq "Windows_NT")) {	## Many perls, eek!
     'W'		=>	40,
 );
 
-getopts('bde:f:ghlLnNpstT:wW:y', \%opts);
+getopts('abde:f:ghlLnNpstT:wW:y', \%opts);
 
 &display_usage if $opts{'h'};
 &list_cowfiles if $opts{'l'};
@@ -76,18 +76,49 @@ else {
 	my $anim_duration = 3000000;
 	my $n_anim_files = @anim_files;
 	my $sleep_ivl = $anim_duration / $n_anim_files;
-	my $clear_string = `clear`;
+	$clear_string = `clear`;
+	$frame_n = 0;
+	$key = '';
 
-	for my $full (@anim_files) {
-		do $full;
-		die "$progname: $@\n" if $@;
+	# step through animation
+	if ($opts{'a'}) {
+		use Term::ReadKey;
 
-		print $clear_string;
-		&print_cow;
-		usleep($sleep_ivl);
+		while (not $key =~ /q/) {
+			if    ($key =~ /,/  and $frame_n > 0                ) { --$frame_n; }
+			elsif ($key =~ /\./ and $frame_n < $n_anim_files - 1) { ++$frame_n; }
+			$full = $anim_files[$frame_n];
+			&print_frame;
+			&read_key;
+		}
+	# play complete animation
+	} else {
+		for $full (@anim_files) {
+			&print_frame;
+			usleep($sleep_ivl);
+		}
 	}
 }
 
+sub read_key {
+	$key = '';
+
+	while (not $key =~ /,|\.|q/) {
+		ReadMode('cbreak');
+		$key = ReadKey(0);
+		ReadMode('normal');
+	}
+}
+
+sub print_frame {
+	do $full;
+	die "$progname: $@\n" if $@;
+
+	print $clear_string;
+	&print_cow;
+	if ($opts{'a'}) { print "frame[$frame_n]: $full\n"; }
+}
+
 sub print_cow {
 	print @balloon_lines;
 	print $the_cow;
-- 
2.40.0

