// Right -- these functions are heavily based on www.devenezia.com/javascript/article.php/MouseTrails.html

// The only thing worth commenting in this script is this: any substr(4) calls are used to
// take the '15' from the 'ibox15' id of the div, as ids can't start with numbers in strict XHTML.

var _DEBUG = true; // although I've taken most of the debug comments out by now
var _FADESPEED = 20;
var _CASCADESPEED = 80;
var _STEPS = 20;
var _NUMBEROFIBOXES = 24;

var _CASCADING = false;

// I'm using this to prevent multiple clicks on the grid in quick succession, ie
// spawning simultaenous cascades. While these can look OK, they can also look horrible.
// Technically, _CASCADING shouldn't be in capitals, as it's a variable and not a constant.

var rndColors = new Array();

function initPulse() {
	var rules = new Array('.panel div','.subcontent','.header div','.square div','.contentfooter div','.menuiconcolour div','.menutextcolour div','.rightmenuiconcolour div','.rightmenutextcolour div');

	// we'll use this array in a few places, ultimately -- this is one of the next things to optimise,
	// as well as the colourPop() and update() functions.
	for (r = 0; r<rules.length; r++) {
		rc = rgb2hex(findStyleRule(rules[r]).style.backgroundColor);
		if (!inArray(rc, rndColors) && rc != '#ffffff') { // I've decided I don't like white iboxes
			rndColors.push(rc);
		}
	}
	
	if (rndColors.length == 1) {
		if (rndColors[0] == '#d8e0f3') {
			rndColors.push('#ffefb5'); // That's the yellow I use in the default scheme...
		}
		else {
			rndColors.push('#d8e0f3'); // ... and that's the light blue I use on my logo.
		}
	}
	
	var rnd = Math.floor(Math.random()*rndColors.length);
//	var _INITIALCOLOR = rndColors[rnd];
	var _INITIALCOLOR = rndColors[0];
	for (b = 1; b<=_NUMBEROFIBOXES; b++) {
		iboxes[b].initialcolor = _INITIALCOLOR;
		iboxes[b].currentcolor = _INITIALCOLOR;
		document.getElementById('ibox' + b).style.backgroundColor = _INITIALCOLOR;
	}
	
	function inArray(it,ar) {
		for (a=0; a<ar.length; a++) {
			if (it==ar[a]) {
				return true;
			}
		}
		return false;
	} 
	
	
	
}

function ibox() {
	this.initialcolor = '';
	this.finalcolor = '';
	this.finalcolorindex = 0;  // I think that if we're really going to streamline this, 
								// we can do away with finalcolor and just use finalcolorindex.
	this.currentcolor = '';
	this.timer = '';
	this.steps = _STEPS;
}

iboxes = new Array();

for (b = 1; b<=_NUMBEROFIBOXES; b++) {
	iboxes[b] = new ibox();
}

function cascade(c,r) {

	if (r || !_CASCADING) {

		c = c.substr(4);
		c = parseInt(c);
		
		if (!r) {
			var r = Math.ceil(Math.random() * (rndColors.length - 1));			
		}
		_CASCADING = true;

		ipulse('ibox' + c, r);
	
		if (c < _NUMBEROFIBOXES) {
			var command = 'cascade(\'ibox' + (c+1) + '\',' + r + ')';
			window.setTimeout(command,_CASCADESPEED);
		}		
	}
}

function ipulse(x,r) {
	x = x.substr(4);
	
	if ((iboxes[x].finalcolorindex + r) >= rndColors.length) {
		rr = ((iboxes[x].finalcolorindex + r) % rndColors.length);
		iboxes[x].finalcolorindex = rr;
	}
	else {
		iboxes[x].finalcolorindex += r;
	}
	iboxes[x].finalcolor = rndColors[iboxes[x].finalcolorindex];

	pulse(x,'#ffffff',iboxes[x].initialcolor);
}

function pulse(x,t,f) {

	iboxes[x].steps --;
	var step = iboxes[x].steps;
			
	//debug (t);
	var to = t.substr(1);
	var from = f.substr(1);

	var r0 = parseInt (from.substr(0,2), 16);
	var g0 = parseInt (from.substr(2,2), 16);
	var b0 = parseInt (from.substr(4,2), 16);

	var r1 = parseInt (to.substr(0,2), 16);
	var g1 = parseInt (to.substr(2,2), 16);
	var b1 = parseInt (to.substr(4,2), 16);

	var r = Math.floor(r1 * ((_STEPS-step)/_STEPS) + r0 * (step/_STEPS));
	var g = Math.floor(g1 * ((_STEPS-step)/_STEPS) + g0 * (step/_STEPS)); 
	var b = Math.floor(b1 * ((_STEPS-step)/_STEPS) + b0 * (step/_STEPS)); 
	
	var color = htmlColorString(r,g,b);

	document.getElementById('ibox' + x).style.backgroundColor = color;
	iboxes[x].currentcolor = color;
		
	if (iboxes[x].currentcolor == iboxes[x].finalcolor) {
		// The ibox has faded to the right color, so stop pulsing.
		iboxes[x].steps = _STEPS;
		iboxes[x].initialcolor = iboxes[x].finalcolor;
		if (x == _NUMBEROFIBOXES) {
			// If the very last ibox has finished pulsing, the cascade is over...
			_CASCADING = false;
		}
	}
	else if (iboxes[x].steps == 0  || iboxes[x].currentcolor == t) {
		// The ibox has faded to white, so start fading to the final color...
		iboxes[x].steps = _STEPS;
		pulse(x,iboxes[x].finalcolor,'#ffffff');
	}
	else {
		var command = 'pulse(\'' + x + '\',\'' + t + '\',\'' + f + '\')';
		iboxes[x].timer = window.setTimeout(command, _FADESPEED);
	}	
	
}

function htmlColorString(r,g,b) {
	var r = r.toString(16);
	var g = g.toString(16);
	var b = b.toString(16);
	if (r.length == 1) r = '0' + r;
	if (g.length == 1) g = '0' + g;
	if (b.length == 1) b = '0' + b;
	
	return '#' + r + g + b;
	
}

function debug(d) {
	if (_DEBUG) {
		window.status += d;
	}
}

function hi(x) {
	if (!_CASCADING) {
		x = x.substring(4);
		iboxes[x].initialcolor = '#ffffff';
		document.getElementById('ibox' + x).style.backgroundColor = '#ffffff';
		// Hmm... I really want this hi/lo stuff to fade in and out... that might get a bit complicated
	}
}

function lo(x) {
	if (!_CASCADING) {
		x = x.substring(4);
		iboxes[x].initialcolor = iboxes[x].currentcolor;
		document.getElementById('ibox' + x).style.backgroundColor = iboxes[x].currentcolor;
	}
}

function rgb2hex(rgb) {
	// this duplicates some of htmlColorString() -- could possibly streamline this
	var reg = /rgb\((\d+), *(\d+), *(\d+)\)/;
	var matches = rgb.match(reg);
	var r = parseInt(matches[1]).toString(16);
	var g = parseInt(matches[2]).toString(16);
	var b = parseInt(matches[3]).toString(16);
	if (r.length == 1) r = '0' + r;
	if (g.length == 1) g = '0' + g;
	if (b.length == 1) b = '0' + b;
	
	return '#' + r + g + b;
	
}
