#!/usr/bin/env python

# Matrix code for console by TeknoHog 2000 / 2002
# Maybe an immensely useful screensaver thingy.

# vert: 1. abbr. for vertical scrolling
#	2. French for 'green' (iirc)

# color doesn't work on all curses libraries (e.g. python1.5.2)
# so you only get b&w != matrix code :(

# absolute max length of single scroll as a fraction of screen height
# (mean value is 1/4 of this.. RTFSource for more)
maxscroll = 0.4

# max delay (seconds) per character for slowed scrolling
maxdelay = 0.01

# probability of whitespaces in code
spaceprob = 0.42

# prob. of highlighted characters
hiliteprob = 0.3333

# column separation, integer (1 = minimum = no space between columns)
colsep = 2

# now keep your eyes peeled for the lady in red dress.


import curses, time, random

screen = curses.initscr()
try: 
    curses.start_color()
    curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
    hascolor = curses.has_colors()
except:
    hascolor = 0

maxtuple = screen.getmaxyx()
maxx = maxtuple[1]
maxy = maxtuple[0]

# I tried chr(n) but it gives newlines and other nasty stuff...
characters = "1234567890+6*7=42|phi>?qwertyuiopåQWERTYUI§Ú­Ì«D±`Ä@·N¬°±z§ä¨ì·sªº©Ð«È¡A±z¤£·|¬°¤F©Ð«È·hÂ·ç°T¤£°Ê²£ °Ó¥ò³¡¦pªG±zªº¿ì¤½«Ç§Y±NªÅ¥X¨Ó¡A§Ú­ÌÄ@¬°±z¬D¿ï¥X²z·Qªº©Ð«È÷«á¦³¼Æ¤ëOPÅasdfghjklöäASDFGHJKLÖÄz#$%&/()=??ïëíìéè[]m,.ZXCVBNMzxcvbnm;:-_*!#$%&/(|<>'`)PRKLhew0mnînthë\/\/0m4ñ|nr3dDr3$$éè@£${}§½~¥¤§Ú­Ì±Mªù´£¨Ñ°Ó¥Î¿ì¤½«Ç¤§¯²¸îªA°È¡"

class Window:
    def __init__(self, maxy, x):
        self.x = x
        self.w = curses.newwin(maxy, 1, 0, x)
        self.blank = 0
        if hascolor:
            self.w.attron(curses.color_pair(1))

    def randattr(self):
        if random.random() < hiliteprob: self.w.attron(curses.A_BOLD)
        else: self.w.attroff(curses.A_BOLD)

    def randletter(self):
        n = int(random.randrange(0,len(characters)-1))
        return characters[n]

    def scroll(self):
        self.blank = not self.blank

        if self.blank:
            prob = spaceprob
        else:
            prob = 1 - spaceprob

        scrollen = int(random.random()*prob*maxy*maxscroll)

        for foo in range(0, scrollen):
	    time.sleep(random.random()*maxdelay) 
            self.randattr()
	    self.w.move(0, 0)
	    self.w.insertln()
	    self.w.addstr(0, 0, (not self.blank) * self.randletter() + self.blank * " ")
	    self.w.refresh()

columns = []
for x in range(0, maxx, colsep):	
    columns.append(Window(maxy, x))

col_len = len(columns)

screen.timeout(0)
screen.keypad(1)

try:
    while 1:
        n = random.randrange(0, col_len)
        
        c = screen.getch()

        if c == ord('q'):
            break

        columns[n].scroll()


except:
    curses.endwin()

curses.endwin()
