// colourblender.js
// Waj 2006-08

//treat following as const
var R = 0, G = 1, B = 2;
var Rmask = 255 << 16, Gmask = 255 << 8, Bmask = 255;

//general colour-blending globals
var currObj;
var currCol = new Array(0, 0, 0);
var nextCol = new Array(3);
var deltCol = new Array(3);
var defCol = "0xFFFFFF", colSeq = new Array(defCol);
var phaseInd = 0, stepPoint = 0;
var timer;
var numSteps = 8;
var freq = 16;


function StartColourEffect(obj, seq) //trigger or toggle blending effect
{
	//remove any previous timeout
	if(currObj)	clearTimeout(timer);

	if(!obj) return;

	//clear default list
	while(colSeq.length) colSeq.pop();

	//assign set sequence or default
	if(seq.length) for(var i=0; i<seq.length; i++) colSeq.push(seq[i]);
	else colSeq.push(defCol);

	currObj = obj;

	//get current colour
	var currColval = 0;

	if(!currObj.style.backgroundColor) //if not defined, define as default
		currObj.style.backgroundColor = "#" + defCol.substring(2);

	if(currObj.style.backgroundColor.indexOf("rgb") != -1) //FF-style, e.g. rgb(240, 49, 196)
	{
		var spl = new Array();
		spl = currObj.style.backgroundColor.split(" ", 3);
		if(spl.length == 3)
		{
			currCol[R] = parseInt(spl[R].substring(4, spl[R].length - 1));
			currCol[G] = parseInt(spl[G].substring(0, spl[G].length - 1));
			currCol[B] = parseInt(spl[B].substring(0, spl[B].length - 1));
		}
	}
	else //other browsers' style, e.g. #FF04B9
	{
		currColval = parseInt(currObj.style.backgroundColor.substr(1), 16);
		currCol[R] = (currColval & Rmask) >> 16;
		currCol[G] = (currColval & Gmask) >> 8;
		currCol[B] = currColval & Bmask;
	}

	phaseInd = 0;
	stepPoint = 0;

	ChangeColour();
}

function ChangeColour() //get next colour and start blending
{
	if(!colSeq || !colSeq.length || !currObj) return;

	//sequence ended
	if(phaseInd == colSeq.length)
	{
		clearTimeout(timer);
		return;
	}

	//set next colour
	var nextColval = parseInt(colSeq[phaseInd]);
	nextCol[R] = (nextColval & Rmask) >> 16;
	nextCol[G] = (nextColval & Gmask) >> 8;
	nextCol[B] = nextColval & Bmask;

	//get colour change step (delta)
	deltCol[R] = (nextCol[R] - currCol[R]) / numSteps;
	deltCol[G] = (nextCol[G] - currCol[G]) / numSteps;
	deltCol[B] = (nextCol[B] - currCol[B]) / numSteps;

	//phaseInd = (phaseInd + 1) % colSeq.length;
	phaseInd ++;
	stepPoint = 0;

	Blend();
}

function Blend() //make small colour change to object
{
	currCol[R] += deltCol[R];
	currCol[G] += deltCol[G];
	currCol[B] += deltCol[B];

	//convert decimal rgb value to hex, pad to 6 chars and format
	var newCol = parseHex((currCol[R] << 16) + (currCol[G] << 8) + currCol[B]);
	while(newCol.length < 6) newCol = "0" + newCol;
	newCol = "#" + newCol;
	currObj.style.backgroundColor = newCol;

	if(++ stepPoint >= numSteps) //reached target colour?
	{
		currCol[R] = nextCol[R];
		currCol[G] = nextCol[G];
		currCol[B] = nextCol[B];
		ChangeColour();
	}
	else timer = setTimeout("Blend()", freq);
}

function parseHex(dec) //convert decimal to hexadecimal
{
	if(dec <= 0) return "0";
	var div = Math.floor(dec);
	var rem = 0, res = "";
	var hex = "0123456789ABCDEF";
	do
	{
		rem = div % 16;
		res = hex.charAt(rem) + res;
		div = Math.floor(div / 16);
	}
	while(div);
	return res;
}