#!/usr/bin/python
"""
 random_walk_1.cgi

 A CGI script to generate an image of a random walk
 using the python PIL library.

 version 1 : just generate the image and send it out.

 Testing it from the command line :
   # comment out the "Content-Type" line first
   $ ./random_walk_1.cgi > rw1.png
 Running it over the web :
   visit http://....../random_walk_1.cgi with a web browser.

 Jim Mahoney | cs.marlboro.edu | Sep 2012 | MIT License
"""
from PIL import Image, ImageDraw
from random import randint
from sys import stdout
from math import sin, cos, pi

def random_direction_step(distance):
    """ Return random direction (dx,dy) with (dx**2 + dy**2) ~ distance**2 """
    angle = 2 * pi * randint(0,99)/100
    return int(distance * cos(angle)), int(distance * sin(angle))

def make_image(args={}):
    """ Return PIL Image of a random walk. """
    default_args = {
        'image_mode': 'RGB',
        'background_color': (248, 250, 252), # (red,green,blue) from 0 to 255
        'width': 400,  # of image
        'height': 400, # of image
        'step_length': 20, # in pixels
        'max_steps': 200,  # stop walk at image edge or after max_steps
        'color_change_per_step': 10,  # maximum (dR, dG, dB)
        }
    for key in default_args.keys():
        if not args.has_key(key):
            args[key] = default_args[key]
    image = Image.new(args['image_mode'], 
                      (args['width'], args['height']), 
                      args['background_color'])
    draw = ImageDraw.Draw(image)
    start_point = (args['width']/2, args['height']/2)
    color = (randint(0,255), randint(0,255), randint(0,255))    
    for i in range(args['max_steps']):
        delta = random_direction_step(args['step_length'])
        end_point = (start_point[0] + delta[0],
                     start_point[1] + delta[1])
        draw.line((start_point, end_point), fill=color)
        dcolor = args['color_change_per_step']
        color = tuple([(color[i] + randint(-dcolor, dcolor)) % 255 \
                           for i in (0,1,2)])
        if end_point[0] < 0 or end_point[0] > args['width'] or \
           end_point[1] < 0 or end_point[1] > args['height']:
            break
        start_point = end_point
    return image

print "Content-Type: image/png\n"
print make_image().save(stdout, 'PNG')


