$(window).load(renderRibbon);


var iddqd = [73, 68, 68, 81, 68];
var codePosition = 0;
var lifeTimeout;

$(document).keydown( function(e) {
	if( e.keyCode == iddqd[codePosition] )
	    codePosition++;
	else {
	    codePosition = 0;
	    if( e.keyCode == iddqd[0]);
		codePosition++;
	}

	if( codePosition >= iddqd.length ) {
	    codePosition = 0;
	    if(lifeTimeout == null)
		startLife();
	    else {
		stopLife();
		generateLifeBoard();
		startLife();
	    }
	}
    });

var lifePaper;
var boardSize = 32;
var board;
var nextBoard;
var lifeStepCount;

function startLife() {
    if(lifeTimeout != null)
	return;

    if(lifePaper == null) {
	lifePaper = new Raphael('life', '100%', '100%');
	$(window).resize(drawLifeBoard);
    }

    if(nextBoard == null)
	generateLifeBoard();

    drawLifeBoard();
    lifeTimeout = setTimeout('lifeUpdate()', 1000);
}

function startLifeFrom(initialState) {
    nextBoard = initialState;
    lifeStepCount = 0;
    startLife();
}

function restartLife() {
    stopLife();
    startLifeFrom(JSON.parse(localStorage.getItem("lifeInitialState")));
}

function stopLife() {
    clearTimeout(lifeTimeout);
    lifeTimeout = null;
}

function lifeUpdate() {
    if(lifeTimeout == null)
	return;

    board = nextBoard;
    stepLifeBoard();
    lifeTimeout = setTimeout('lifeUpdate()', 1000);
}

function stepLifeBoard() {
    nextBoard = new Array();

    for(var i=0; i<boardSize; i++) {
	nextBoard[i] = new Array();
	for(var j=0; j<boardSize; j++) {
	    nextBoard[i][j] = checkBoardLocation(i, j);
	}
    }
    lifeStepCount++;
    drawLifeBoard();
}

function checkBoardLocation(xloc, yloc) {
    var neighbors = 0;

    for(var i=xloc-1; i<xloc+2; i++) {
	for(var j=yloc-1; j<yloc+2; j++) {
	    var checkx = (i<boardSize)? i:0;
	    var checky = (j<boardSize)? j:0;
	    if(checkx < 0) checkx = boardSize-1;
	    if(checky < 0) checky = boardSize-1;

	    if((board[checkx][checky] == 1) && ((checkx != xloc) || (checky != yloc)))
		neighbors ++;
	}
    }

    if((board[xloc][yloc] == 1) && ((neighbors == 2) || (neighbors == 3)))
	return 1;
    else if((board[xloc][yloc] == 0) && (neighbors == 3))
	return 1;
    return 0;
}

function generateLifeBoard() {
    lifeStepCount = 0;
    nextBoard = new Array();
    
    for(var i=0; i<boardSize; i++) {
	nextBoard[i] = new Array();
	for(var j=0; j<boardSize; j++) {
	    nextBoard[i][j] = (Math.random() > 0.5)? 1:0;
	}
    }
    localStorage.setItem("lifeInitialState", JSON.stringify(nextBoard));
}

function drawLifeBoard() {
    lifePaper.clear();

    var width = $('#life').width() / boardSize;
    var height = $('#life').height() / boardSize;

    for(var i=0; i<boardSize; i++) {
	for(var j=0; j<boardSize; j++) {
	    if(nextBoard[i][j] == 1) {
		var myx = i*width;
		var myy = j*height;
		var c = lifePaper.rect(myx, myy, width, height);
		c.attr({fill: "#0f6", stroke: "#333"});
	    }
	}
    }
}



function renderRibbon() {
var ribbonPaper = new Raphael('ribbon', 60, 90);
/* Ribbon By MesserWoland: http://commons.wikimedia.org/wiki/User:MesserWoland
   http://en.wikipedia.org/wiki/File:Blue_ribbon.svg
*/
var ribbon = ribbonPaper.path("M 209.84498,99.421775 C 209.84498,99.421775 180.2475,53.2607 140.93998,24.191715 C 113.26587,18.01428 104.7521,21.870695 73.934973,44.016181 C 31.269173,74.676239 30.718596,86.539236 30.718596,95.110666 C 47.073576,158.46056 65.919781,172.1301 79.494751,181.73315 C 79.494751,181.73315 78.563161,181.30931 78.563161,181.30931 C 78.563161,181.30931 89.844986,105.13606 209.84498,99.421775 zM 129.83931,14.658889 C 142.86031,27.317249 184.94458,49.695029 180.95505,82.361677 C 285.25474,260.40859 206.52771,584.53919 140.30568,811.549 C 140.30568,811.549 114.64465,902.16035 121.26685,919.96504 C 127.88906,937.76972 124.72054,936.02558 176.04261,977.56986 C 221.517,1014.3805 276.5678,1084.9015 284.84556,1119.0272 L 349.87542,511.57628 C 349.87542,511.57628 352.14883,257.85944 350.49328,207.41281 C 348.83773,156.96619 332.28223,93.218125 247.84914,59.092472 C 208.27404,43.097241 158.13347,20.319221 129.83931,14.658889 z M 209.84498,99.421775 C 209.84498,99.421775 204.30748,67.696689 164.99996,38.627704 C 137.32585,32.450269 112.23743,36.306684 81.420301,58.45217 C 38.754501,89.112228 37.134591,112.73788 37.134591,121.30931 C 53.489571,184.6592 65.919781,172.1301 79.494751,181.73315 C 79.494751,181.73315 78.563161,181.30931 78.563161,181.30931 C 78.563161,181.30931 89.844986,105.13606 209.84498,99.421775 z M 164.99996,38.627704 C 176.23576,50.815529 189.36948,73.949197 201.52753,102.4463 C 275.92692,276.83013 187.13459,561.30931 129.99173,779.88074 C 129.99173,779.88074 107.84888,858.45217 113.56316,875.59503 C 119.27745,892.73788 138.56316,912.73788 182.84888,952.73788 C 222.08864,988.18023 265.70602,1014.1665 272.84888,1047.0236 L 332.84888,512.73788 C 332.84888,512.73788 339.99173,268.45217 338.56316,219.88074 C 337.13459,171.30931 322.84888,105.59502 249.99173,72.737884 C 215.84245,57.337226 189.41494,44.077631 164.99996,38.627704 zM 69.647841,151.4245 C 69.647841,151.4245 46.223361,118.76408 26.856664,85.316659 C 26.856664,94.760639 20.954428,197.07039 20.954428,197.07039 C 20.954428,197.07039 15.052201,269.47423 59.318941,326.13809 C 103.58567,382.80196 258.51926,595.29145 555.10641,807.78096 C 555.10641,807.78096 627.40876,862.87083 648.06657,864.44482 C 648.06657,864.44482 684.95552,699.17521 677.57773,639.36335 C 677.57773,639.36335 591.99537,606.30943 336.72384,393.81993 C 81.452311,181.33043 69.647841,151.4245 69.647841,151.4245 z M 78.563161,181.30931 C 78.563161,181.30931 55.884591,151.66645 37.134591,121.30931 C 37.134591,129.88074 31.420301,222.73788 31.420301,222.73788 C 31.420301,222.73788 25.70602,288.45217 68.563161,339.88074 C 111.4203,391.30931 261.4203,584.16645 548.56316,777.0236 C 548.56316,777.0236 618.56316,827.0236 638.56316,828.45217 C 638.56316,828.45217 674.27745,678.45217 667.13459,624.16645 C 667.13459,624.16645 584.27745,594.16645 337.13459,401.30931 C 89.991731,208.45217 78.563161,181.30931 78.563161,181.30931 z  ").attr({fill: "100-#4671d5-#1240ab", stroke: "none", href: "http://www.efc.ca/pages/free-speech/blue-ribbon.html"});
ribbon.scale(0.08, 0.08);
ribbon.translate(-320, -520);

var shadow = ribbon.clone();
shadow.attr({stroke: "none", fill: "#000", translation: "1,2"});
ribbon.insertAfter(shadow);
}

