#!/usr/bin/perl
# extreme whitespace v. 0.1
# performance typing.
# amy alexander/uebergeek/deprogramming.us
# updates available at http://deprogramming.us
# contact: deprogramming at deprogramming.us
# 
# copyright/left 2003 - released under the Gnu Public License 
# http://www.gnu.org/licenses/gpl.txt
#
# you'll probably need to download Time::HiRes and/or 
# Term::ReadKey from cpan.org if you don't have them already.
# sorry, doesn't seem to work on perl 5.8 - works on perl 5.6 and 5.6.1
# Term:ReadKey seems to have a bug under Perl 5.8.


use Getopt::Std;
use Time::HiRes(usleep);
use Term::ReadKey;
use Term::ANSIColor;

my %opts;
        
getopts('mh', \%opts);
if(defined $opts{h}) {
        print "usage: $0 [-m] [-h]\n";
        print "\t-m\tmonochrome mode - color keys deactivated.\n";
        print "\t-h\tdisplay this help message.\n";
        print "\t\tsee comments at end of script for runtime keystroke commands.\n";
        exit;
}

$|=1;

$starttime = time;
$startphrase = '                    ';
$startsleepval = 3000;

$phrase = $startphrase;
$sleepval = $startsleepval;
$dosleep = 1;

$SIG{'INT'}= sub {print color 'reset'; print "adios!\n\n"; exit(0); };

while (1) {
	# performance note:
	# comment out these next 3 lines if you want the text to never reset on its own. 
	# you can do that by just putting a # sign at the beginning of each line.
 	if (int(rand(1100)) == 2) {
		$phrase = $startphrase;
	}
	
	print "$phrase  ";
	if ($dosleep) {
		usleep ($sleepval);
	}
	ReadMode 3;
	$key = ReadKey(-1);
	$now = time;
	if ((defined($key)) and ($now > $starttime + 5) and ($key !~ /[0123JK]/)) {
		$phrase = $phrase.$key;	
	}
	breakcheck ();

	if (!keycheck()) { # first, check key to see if it's an effect. 
                           # if it's not, see if it's a color (except in monochrome mode.)
		unless(defined $opts{m}) {
			colcheck ();
		}
	}
	
	$oldkey = $key;
	

	ReadMode 0; # this may appear redundant, but has a subtle visual effect.
	


}

# end main loop

sub breakcheck {
	# checks the phrase to see if it's one that goes in or out of a "break"
	if ($phrase =~ /.*HH$/) {
	# type HH to go into rapid-rhythm mode... 
		$dosleep = 0;
		$sleepval = 300;
		$phrase = ' ';
	}
	elsif (($phrase =~ /.*\|$/) and !($dosleep)){
	# type | to come out of rapid-rhythm mode... 
		$dosleep = 1;
		$starttime = time;
	}

}


sub colcheck () {
	# checks for color-related keystrokes
	my @colors = qw(black red green yellow blue);
	if ($key eq '1') {
		if ($colchanging) {
			$colchanging = 0;
		}
		else {
			$colchanging = 1;
		}
	}

	elsif ($key eq '2') {
		if ($underline) {
			$underline = 0;
		}
		else {
			$underline = 1;
		}
	}

	elsif ($key eq '3') {
		print color 'reset';
		$colchanging = 0;
		$underline = 0;
	}


	if ($colchanging == 1) {
	     ($bg) =  spewpicker (1,@colors);
             print color "on_$bg";
	}

	if ($underline == 1) {
	     ($fg) = spewpicker (1,@colors);
             print color "$fg";
             print color "underline";
             print color "bold";
	}

}

sub keycheck () {
	# checks for keystrokes other than color
	if ($key eq 'K' ){
		$sleepval = $sleepval + 100;
		return 1;
	}

	elsif (($key eq 'J' ) and ($sleepval > 50)) {
		$sleepval = $sleepval - 50;
		return 1;
	}


	elsif ($key eq '-') {
		$phrase .=  '    ';
		return 1;
	}

	elsif ($key eq '>') {
		@phrase = split('',$phrase);
		$phrase = join(' ',@phrase);
		return 1;
	}


	elsif ($key eq ',') {
		$phrase = '';
		return 1;

	}


	elsif ($key eq '<') {
		$key = $oldkey;
		@phrase = split('',$phrase);
		$newphrase = join("\n ",@phrase);
		chomp $phrase;
		$phrase .= $key;
		$phrase .= $key;

	}


	elsif ($key eq '_') {
		if ($dosleep) {
			$phrase .=  reverse ($phrase);
		}
		return 1;
	}

	elsif ($key eq '0') {
		$phrase =  $startphrase . '';
		$starttime = $now;
		$sleepval = $startsleepval;
		return 1;
	}

	return 0;


}

sub spewpicker {
        my ($numspewings, @spewings) = @_;
        my $i;
        my @returnspewings = ();
        for ($i=1;$i<=$numspewings ;$i++) {
                my $pickme = int(rand(@spewings));
                push (@returnspewings, $spewings[$pickme]);

        }

        return @returnspewings;
}

# End of program
####################################################################################
# Extreme Whitespace
# 
###############
# General Info:
# Extreme Whitespace takes advantage of your text terminal's natural talent 
# as a realtime video instrument! 
# About all this script really does it is spew whitespace into your
# terminal for you to type into, with, against, around... 
#
##############
# Preparation:
# Linux: make sure lpd  - or other print spooler - is turned off! 
# (/etc/init.d/lpd stop as root.)
# Works well in Eterm (or in plain console mode). 
# But *very slow* in KDE "Konsole" shells.
# Gnome-terminal adds its own special scroll-scratching talents to the mix!
# (Try it under gnome-terminal with excessive use of the up arrow... )
#
# Setting a large font such as lucidasanstypewriter-bold-24 is nice but not essential.
# For example:  Eterm -F lucidasanstypewriter-bold-24
# 
# Mac OSX: sort of works in OSX Terminal, but it's kind of slow.
# 
# Windows: doesn't work right at all, even if you install the librariess.
# However, it works ok over a moderately fast network connection 
# to a unix server if you use PuTTy on Windows. 
# (Just be sure that lpd or other print spooler isn't  running on the server.)
# 
#############
# Directions:
# Run the script and start typing.
# Experiment with different typing rhythms! Don't miss out on
# natural special fx keys like Enter, arrow keys, and spacebar!
# Try different combos of those, as well as combos like the | key and _ ... 
# Also, try copy/pasting bits of text of various sizes from your other
# shells with your mouse.
# 
# Also can be used in automatic mode - pipe in any text 
# from your harddrive or the net for teletype eyecandy fun!
# 
# Other suggestions: 
# Type along with your favorite pop song for reverse karaoke fun!
# Text rapping!
# Raves!
#
####################
# Keystroke commands 
# You can learn them or just mess around:
# 0 - reset
#      (See "performance note" in the script above to disable automatic resetting.)
# 1 - color mode #1
# 2 - color mode #2
# 3 - reset color mode
#
# -  (hyphen)  pattern effect
# _  (underscore) palindrome/strobe effect: don't hold down too long or it crashes!
# >  extra whitespace effect: don't hold this down too long either!
#    ok to hit these two repeatedly though, for varying fx!
# 
# ,  something strange and potentially diagonal. 
#    combine with up and down arrows for videogame fun!
# <  another strange, sort of diagonal thing. but stranger and less diagonal than the ','
#    try combining with arrow and color keys, as well as other typing.
#
# J  faster.
# K  slower.
#
# HH - fast break mode (definitely check this out)
# | (pipe)  = back to normal speed mode
#
#
# Ctrl-C (or your normal kill sequence) to quit.
# 
#################################
# Video jamming the natural way! 
# No patches to build, no peripherals to buy, no DirectX/OpenGL hassles - 
# Just peck away! 
# 
####################################################################################