/*########################### MagicText v1.0## by Dave Cash <magictext@fieldsofgarlic.com># 2004-03-09#*/// the MagicText objectfunction MagicText (text, colors, background_color) {	this.string = text;	this.pixelColors = colors;	this.background_color = background_color;	this.interval = 10;	this.font = MTFbasic;	this.italic_slope = 0;	this.pixel_xdim = 6;	this.pixel_ydim = 6;	this.pixel_pad = 2;	this.x = 0;	this.y = 0;	this.debug = false;	this.id = 'MT' + parseInt(Math.random() * 54321);	this.text_drawn = false;	this.stylesheet_generated = false;	this.pixels = [];	this.pixelCount = 0;}// MagicText methods// TODO: need some positional methods, like .position('top|right|left|center|middle')// .position_beside('above|below|left|right', 'MTOBJECT')MagicText.prototype.pixel_dims = function (x, y, pad) {	this.pixel_xdim = x;	this.pixel_ydim = y;	this.pixel_pad = pad;}MagicText.prototype.xy = function (x, y) {	this.x = x;	this.y = y;}MagicText.prototype.xscale = function () { return this.pixel_pad + this.pixel_xdim + this.pixel_pad; }MagicText.prototype.yscale = function () { return this.pixel_pad + this.pixel_ydim + this.pixel_pad; }MagicText.prototype.box_width = function () { return ((this.xscale() * (this.font.width + 1)) * this.string.length) + (this.font.width * Math.abs(this.italic_slope)) - this.xscale() };MagicText.prototype.box_height = function () { return this.yscale() * this.font.height };// TODO: work out how to do proportional fonts and lowercaseMagicText.prototype.mapStringToPixels = function () {	this.string = this.string.toUpperCase();	map = new Array(this.font.height);	for (r = 0; r < this.font.height; r ++) {		map[r] = new Array();		pos = 0;		for (c = 0; c < this.string.length; c ++) {			character = this.string.charAt(c);			for (p = 0; p < this.font.chars[character][r].length; p ++) {				map[r][pos] = this.font.chars[character][r][p] + ((this.font.width + 1) * c);				pos++;			}		}	}	return map;}// TODO: see if it is possible to have this thing just be a relative-positioned, in-flow div instead of absolute-positionedMagicText.prototype.stylesheet = function () {	ts = this.debug ? '&lt;' : '<';	ts != '<' ? document.writeln('<pre>') : '';	document.writeln(ts + 'style type="text/css">\n\#' + this.id + 'box {\n\	background:' + this.background_color + ';\n\	position:absolute;\n\	top:' + this.y + 'px;\n\	left:' + this.x + 'px;\n\	height:' + (this.yscale() * 7) + 'px;\n\	width:' + this.box_width() + 'px;\n\}\n\.' + this.id + 'row {\n\	position:absolute;\n\	left:' + this.x + 'px;\n\	left:0px;\n\	width:' + this.box_width() + 'px;\n\	height:' + this.yscale() + 'px;\n\}\n\.' + this.id + 'pixel {\n\	position:absolute;\n\	width:' + this.pixel_xdim + 'px;\n\	height:' + this.pixel_ydim + 'px;\n\	margin:' + this.pixel_pad + 'px;\n\	font-size:1pt;\n\}\n\' + ts + '/style>\n');	ts != '<' ? document.writeln('</pre>') : '';	this.stylesheet_generated = true;}MagicText.prototype.draw = function () {	if (! this.stylesheet_generated) {		this.stylesheet();	}	ts = this.debug ? '&lt;' : '<';	this.pixelMap = this.mapStringToPixels();	ts != '<' ? document.writeln('<pre>') : '';	document.writeln(ts + 'div id="' + this.id + 'box">');	for (r in this.pixelMap) {		document.writeln('	' + ts + 'div class="' + this.id + 'row" id="r' + r + '" style="top:' + (r * this.yscale()) + 'px">');		for (c in this.pixelMap[r]) {			italic_adjustment = this.italic_slope >= 0 ? (this.font.height - r) * this.italic_slope : r * Math.abs(this.italic_slope);			document.writeln('		' + ts + 'div class="' + this.id + 'pixel" id="' + this.id + 'p' + this.pixelCount + '" style="left:' + (italic_adjustment + (this.pixelMap[r][c] * this.xscale())) + 'px;background:' + this.pixelColors[parseInt(Math.random() * this.pixelColors.length)] + '">' + ts + '/div>');			this.pixelCount++;		}		document.writeln('	' + ts + '/div>');	}	document.writeln(ts + '/div>');	ts != '<' ? document.writeln('</pre>') : '';	this.text_drawn = true;}MagicText.prototype.sparkle = function () {	if (! this.text_drawn) {		this.draw();	}	if (this.debug) {		return;	}	MTdo_sparkle( this.id, this.pixelCount, this.pixelColors, this.interval );}function MTdo_sparkle (id, pixelCount, colors, interval) {	random_id = id + 'p' + parseInt( Math.random() * ( pixelCount - 1 ) );	random_color = colors[parseInt(Math.random() * colors.length)];	if (document.all) {		document.all[random_id].style.backgroundColor = random_color;		setTimeout("MTdo_sparkle('" + id + "', '" + pixelCount + "', [ '" + colors.join("', '") + "' ], '" + interval + "')", interval);	}	else if (document.getElementById(random_id)) {		document.getElementById(random_id).style.backgroundColor = random_color;		setTimeout("MTdo_sparkle('" + id + "', '" + pixelCount + "', [ '" + colors.join("', '") + "' ], '" + interval + "')", interval);	}}