﻿/*
* greystork.js - Custom functions for greystork.com.
*
* :tabSize=2:indentSize=2:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the 
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/


// Create GreyStork.com's global object.
var GreyStork = (function() {

	// Begin definition of private members for GreyStork object.
	var documentLoaded = false;
	
	// Color index counters for rainbowtext tags.
	var redidx = 0;
	var greenidx = 0;
	var blueidx = 0;

	// Create a rainbowized node from a plain text node.
	function rainbowizeNode(node) {

		var container;
		
		if (node.nodeValue) {
			var chars = node.nodeValue;

			var reds = ["60", "64", "68", "6C", "70", "74", "78", "7C", "80"];
			var greens = ["60", "68", "70", "78", "80", "88", "90", "98", "A0",
									 "A8", "B0", "B8", "C0"];
			var blues = ["60", "68", "70", "78", "80", "88", "90", "98", "A0",
									 "A8", "B0", "B8", "C0", "C8", "D0", "D8", "E0"];

			var chridx = 0;

			var color;
			var element;
			var textNode;
			var chr;
			
			container = document.createElement("span");

			while (chridx < chars.length) {
				chr = chars.charAt(chridx);
				++chridx;

				if (chr !== " ") {
					redidx++;
					if (redidx >= reds.length) {
						reds.reverse();
						redidx = 1;
					}

					greenidx++;
					if (greenidx >= greens.length) {
						greens.reverse();
						greenidx = 1;
					}

					blueidx++;
					if (blueidx >= blues.length) {
						blues.reverse();
						blueidx = 1;
					}

					color = "#" + reds[redidx] + greens[greenidx] + blues[blueidx];
				}
				element = document.createElement("rbchar");
				textNode = document.createTextNode(chr);
				element.appendChild(textNode);
				element.style.color = color;
				container.appendChild(element);
			}
		}
		return container;
	}

	// Process text in rainbowtext tags recursively.
	function rainbowizeElement(element) {

		var node;
		var newNode;

		if (element.childNodes && element.childNodes.length > 0) {
			for (var nodeidx = 0; nodeidx < element.childNodes.length; ++nodeidx) {
				node = element.childNodes[nodeidx];

				switch (node.nodeType) {

					case 1: // Element
						rainbowizeElement(node);
						break;

					case 3: // Mozilla Text
						newNode = rainbowizeNode(node);
						if (newNode)
							element.replaceChild(newNode, node);
						break;
				}
			}
		}
		else if (element.nextSibling) { // IE Text
			node = element.nextSibling;
			newNode = rainbowizeNode(node);
			node.replaceNode(newNode);
		}
	}

	// Find all rainbowtext tags and apply rainbow color effect.
	function transformRainbowTags() {

		var rainbowTag;
		var rainbowTags = document.getElementsByTagName("rainbowtext");

		for (var tagidx = 0; tagidx < rainbowTags.length; ++tagidx) {
			rainbowTag = rainbowTags[tagidx];
			rainbowizeElement(rainbowTag);
		}
	}

	// Find all images with an altsrc attribute and lazy-load alternate sources.
	function lazyloadAltImages() {

		var curImgUrl;
		var altImgUrl;
		var image;
		var images = document.getElementsByTagName("img");

		for (var imgidx = 0; imgidx < images.length; ++imgidx) {
			image = images[imgidx];
			if (image.attributes.altsrc) {
				curImgUrl = image.src;
				altImgUrl = image.attributes.altsrc.value;
				if (curImgUrl != altImgUrl)
					image.src = altImgUrl;
			}
		}
	}
	// End definition of private members for GreyStork object.

	// Constructor defining public members of GreyStork object.
	return {

		// Perform tasks upon document load.
		documentLoadHandler: function() {

			if (!documentLoaded) {
				documentLoaded = true;
				transformRainbowTags();
				lazyloadAltImages();
			}
		}
	}; // End constructor of GreyStork object.
} ()); // Invoke object constructor.
