//ColorGradientText 1.0
//
//Author: Alexandr Kot ( alexandr.kot ?at?  gmail *dot* com , http://vril.vn.ua/ )
//
// ColorGradientText is the script that implements advanced text decoration, such as color gradients and animation, using JavaScript and Dynamic HTML.
// With the ColorGradientText you can easily add striking decoration to your web pages:
// *	You can decorate your HTML text with the color gradient
// *	Attractive JavaScript animation
// *	Several text blocs on one page can be decorated independently of one another
// *	No significant changes in HTML code required.
// *	Users can view your decorated text whether they use Internet Explorer, FireFox, Netscape or some other browser. 
// *	Text can be freely indexed by search engines
// *	Absolutely free


// Examples:
// Example 1: 
// This example implements the static colored text. First letter is red, last letter is yellow.
//<html>
//	<head>
//		<title>Example 1</title>
//		<script src="ColorGradientText.js"></script>
//		<style>
//			body{background-color:#000000; color:#FFFFFF; font-size:36px;}
//		</style>
//	</head>
//	<body onload="ColorGradientText('color_me' , false , 255 , 0, 0  , 255 , 255 , 0 ,  0 );" >
//		<p id="color_me">Color me.</p> 
//	</body>
//</html>
//
// Example 2: 
// This example implements the animated text. First letter is red, last letter is yellow, timeout is 80 milliseconds
//<html>
//	<head>
//		<title>Example 2</title>
//		<script src="ColorGradientText.js"></script>
//		<style>
//			body{background-color:#000000; color:#FFFFFF; font-size:36px;}
//		</style>
//	</head>
//	<body onload="ColorGradientText('color_me' , true , 255 , 0, 0  , 255 , 255 , 0 ,  80 );" >
//		<p id="color_me">Color me.</p> 
//	</body>
//</html>
//
// Example 3: 
// This example implements the set animated texts.
//<html>
//	<head>
//		<title>Example 3</title>
//		<script src="ColorGradientText.js"></script>
//		<style>
//			body{background-color:#000000; color:#FFFFFF; font-size:36px;}
//		</style>
//	</head>
//	<body onload="ColorGradientText('color_me' , true , 255 , 0, 0  , 255 , 255 , 0 ,  80 );ColorGradientText('color_me_too' , false , 0 , 255, 0  , 00 , 255 , 255 ,  40 );" >
//		<p id="color_me">Color me.</p> 
//		<p id="color_me_too">Color me too.</p> 
//	</body>
//</html>

var arrayColorsHolder             = new Array();  //arrayColorsHolder             contains the arrays of color values.             
var arrayAnimationDirectionHolder = new Array();  //arrayAnimationDirectionHolder keeps the state of iteration's direction through the arrayColorsHolder array.
var arrayAnimationCountersHolder  = new Array();  //arrayAnimationCountersHolder variable keeps the counters through the iterations. 


// AnimationIterator(strElementName , fForvard , r1 , g1 , b1 , r2, g2, b2 , nMilliSecondsTimeout) 
//
// Recurs the animation or colors the specified element only one time.
//
// Do not call this function directly.
//
// Parameters:
// 		strElementName - String that specifies the name of element to be coloured
// 		fForvard       - Boolean that specifies the direction of animation. 
//							Possible values:
//             					true  ->	from left  to right
//	             				false ->	from right to left
//      r1 - Integer that specifies the red channel's value of the first letter's color. 
//							Possible values: from 0 to 255
//      g1 - Integer that specifies the green channel's value of the first letter's color. 
//							Possible values: from 0 to 255
//      b1 - Integer that specifies the blue  channel's value of the first letter's color. 
//							Possible values: from 0 to 255 
//      r2 - Integer that specifies the red channel's value of the last letter's color. 
//							Possible values: from 0 to 255
//      g2 - Integer that specifies the green channel's value of the last letter's color. 
//							Possible values: from 0 to 255
//      b2 - Integer that specifies the blue  channel's value of the last letter's color. 
//							Possible values: from 0 to 255 
//      nMilliSecondsTimeout - Integer that specifies the number of milliseconds.
//							Possible values: 
//                               Less than 0 -> AnimationIterator executes only one time
//                               More than 0 -> AnimationIterator recurs the animation after a specified number of milliseconds has elapsed
function AnimationIterator(strElementName , fForvard , r1 , g1 , b1 , r2, g2, b2 , nMilliSecondsTimeout) 
{
	var currentElement = null;
	var nAnimationCounter = 0;
	var nFinalElement = arrayColorsHolder[strElementName].length - 1;
	var fInnerDirection = null;
	
	//Define the moving direction
	if(fForvard)
	{
		fInnerDirection = !arrayAnimationDirectionHolder[strElementName];
	}
	else
	{
		fInnerDirection = arrayAnimationDirectionHolder[strElementName];
	}
	
	nAnimationCounter = arrayAnimationCountersHolder[strElementName];
	for(var j = 0; j <= nFinalElement ; j++ )
	{
		//Get element within the text container
		currentElement = document.getElementById(strElementName + '_animated_child_' + j);
		
		
		if(currentElement) // if current element exists
		{
			//set span's color 
			currentElement.style.color = 'rgb(' + 
				arrayColorsHolder[strElementName][nAnimationCounter]['red']   + ','+ 
				arrayColorsHolder[strElementName][nAnimationCounter]['green'] + ','+
				arrayColorsHolder[strElementName][nAnimationCounter]['blue']  +
				')';
			
			 // Rule of painting.  -- BEGIN 
			if(fInnerDirection)
			{
				if(nAnimationCounter < nFinalElement )
				{
					nAnimationCounter ++ ;
				}
				else
				{
					fInnerDirection = ! fInnerDirection;
				}
			}
			else
			{
				if(nAnimationCounter > 0 )
				{
					nAnimationCounter --;
				}
				else
				{
					fInnerDirection = ! fInnerDirection;
				}
			} 
			// Rule of painting.  -- END 
		}
		else
		{
			window.status = 'Text container "' + strElementName + '" is modified or not initialized';
			return;
		}
	}		
	
	// Rule of painting.  -- BEGIN 
	if(arrayAnimationDirectionHolder[strElementName])
	{
		if(arrayAnimationCountersHolder[strElementName] < nFinalElement )
		{
			arrayAnimationCountersHolder[strElementName] ++ ;
		}
		else
		{
			arrayAnimationDirectionHolder[strElementName] = ! arrayAnimationDirectionHolder[strElementName];
		}
	}
	else
	{
		if(arrayAnimationCountersHolder[strElementName] > 0 )
		{
			arrayAnimationCountersHolder[strElementName] --;
		}
		else
		{
			arrayAnimationDirectionHolder[strElementName] = ! arrayAnimationDirectionHolder[strElementName];
		}
	}
	// Rule of painting.  -- END 
	
	//Launch the next iteration 
	if(nMilliSecondsTimeout > 0 )
	{
		window.setTimeout('AnimationIterator("' + 
		strElementName + 
		'", '+ fForvard.toString() + 
		', ' + r1.toString() + 
		', ' + g1.toString() + 
		', ' + b1.toString() + 
		', ' + r2.toString() + 
		', ' + g2.toString() + 
		', ' + b2.toString() + 	
		', ' + nMilliSecondsTimeout.toString() + 	 
		' )', nMilliSecondsTimeout);
	}
}


// ColorGradientText(strElementName , fForvard , r1 , g1 , b1 , r2, g2, b2 , nMilliSecondsTimeout) 
//
// Fill the specified element with the color gradient.
//
// Parameters:
// 		strElementName - String that specifies the name of element to be coloured
// 		fForvard       - Boolean that specifies the direction of animation. 
//							Possible values:
//             					true  ->	from left  to right
//	             				false ->	from right to left
//      r1 - Integer that specifies the red channel's value of the first letter's color. 
//							Possible values: from 0 to 255
//      g1 - Integer that specifies the green channel's value of the first letter's color. 
//							Possible values: from 0 to 255
//      b1 - Integer that specifies the blue  channel's value of the first letter's color. 
//							Possible values: from 0 to 255 
//      r2 - Integer that specifies the red channel's value of the last letter's color. 
//							Possible values: from 0 to 255
//      g2 - Integer that specifies the green channel's value of the last letter's color. 
//							Possible values: from 0 to 255
//      b2 - Integer that specifies the blue  channel's value of the last letter's color. 
//							Possible values: from 0 to 255 
//      nMilliSecondsTimeout - Integer that specifies the number of milliseconds.
//							Possible values: 
//                               Less than 0 -> AnimationIterator executes only one time
//                               More than 0 -> AnimationIterator recurs the animation after a specified number of milliseconds has elapsed
//

function ColorGradientText(strElementName , fForvard ,  r1 , g1 , b1 , r2, g2, b2 , nMilliSecondsTimeout)
{
	 
	var textContainer = document.getElementById(strElementName);
	if(textContainer === null)
	{
		window.status += 'Text container "' + strElementName + '" is not defined.';
		return;
	}

	var strText  = textContainer.innerText || textContainer.textContent ;
	if(!strText)
	{
		window.status += 'Text container "' + strElementName + '" is empty.';
		return;
	}

	arrayColorsHolder            [strElementName] = new Array();
	
	var nLetersCount = strText.length;
	
	// Define steps for creating color gradient
	var steps = new Array ();
	steps['red']   = (r2 - r1) / nLetersCount ;
	steps['green'] = (g2 - g1) / nLetersCount ;
	steps['blue']  = (b2 - b1) / nLetersCount ;

	// Generate array of color values
	for( var  i = 0; i < strText.length ; i++ )
	{
		arrayColorsHolder[strElementName][i]          = new Array();
		arrayColorsHolder[strElementName][i]['red']   = Math.round(r1 + steps['red']*i)  ;
		arrayColorsHolder[strElementName][i]['green'] = Math.round(g1 + steps['green']*i);  
		arrayColorsHolder[strElementName][i]['blue']  = Math.round(b1 + steps['blue']*i) ; 			
	}
	
	// Set initial values for harmonic oscillations emulator
	arrayAnimationDirectionHolder[strElementName] = true;
	arrayAnimationCountersHolder [strElementName] = 0;
	
	//Split original string. Result of this operation is the chain of span elements.
	var strResultString = '';
	for(var j = 0; j < strText.length ; j++ )
	{
		
		strResultString += '<span id="'+
				strElementName + '_animated_child_' + j +
				'"  >' + strText.charAt(j)  +'</span>';
				
	}			
	
	//Fill container by <span>s 
	document.getElementById(strElementName).innerHTML = strResultString;
	 
	//Start the animation
	AnimationIterator(strElementName ,  fForvard , r1 , g1 , b1 , r2, g2, b2 , nMilliSecondsTimeout)
}	