// =====================================================
// Wiggle stereograms with javascript, by Martin Sutherland 
// http://www.sunpig.com/martin/archives/2005/12/12/wiggle_stereoscopy_a_new_approach/
// http://www.sunpig.com/secondbest/2005/12/wigglestereoscopyfollowup.html
//
// Version 1.1 (27 December 2005)
// 
// References:
// Adding event handlers: see http://www.scottandrew.com/weblog/articles/cbs-events
// Event cache to prevent memory leaks: see http://novemberborn.net/javascript/event-cache
// =====================================================


// Array support for the push method in IE 5
Array.prototype.push = ArrayPush;
function ArrayPush(value){
	this[this.length] = value;
}

// =====================================================
// EVENT CACHE
// =====================================================

// Event Cache uses an anonymous function to create a hidden scope chain.
// This is to prevent scoping issues. */
var EventCache = function(){
	var listEvents = [];
	
	return {
		listEvents : listEvents,
	
		add : function(node, sEventName, fHandler, bCapture){
			listEvents.push(arguments);
		},
	
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				
				/* From this point on we need the event names to be prefixed with 'on" */
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				
				item[0][item[1]] = null;
			};
		}
	};
}();


// =====================================================
// EVENT HANDLERS
// =====================================================

// Add an event handler to an object.
function addEvent(obj, evType, fn, useCapture){
	var result;
	if (obj.addEventListener){
		obj.addEventListener(evType, fn, useCapture);
		result = true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent("on"+evType, fn);
		result = r;
	} else {
		return false;
	}

	EventCache.add(obj, evType, fn, useCapture);
	return result;
}

// Remove an event handler from an object
function removeEvent(obj, evType, fn, useCapture){
	if (obj.removeEventListener){
		obj.removeEventListener(evType, fn, useCapture);
		return true;
	} else if (obj.detachEvent){
		var r = obj.detachEvent("on"+evType, fn);
		return r;
	} else {
		return false;
	}
}

// =====================================================
// EVENT CACHE FLUSH
// =====================================================

// Attach an event handler to window.unload for flushing 
// the event cache.
addEvent(window, "unload", EventCache.flush);


// =====================================================
// THE WIGGLER
// =====================================================

var Wiggler = function () {

	// Private variables
	var alt = false;
	var wigglyDivs = [];
	var wiggleInterval = 120; // ms

	// Public methods
	return ({
		toggle: function() {
			for (var i=0; i<wigglyDivs.length; i++) {
				var d= wigglyDivs[i];
				d.firstChild.style.left = alt ? "-" + d.imWidth + "px"  : "0";
			}
			alt = !alt;
		},

		init: function() {
			var imgs = document.getElementsByTagName("img");
			for (var i=imgs.length-1; i>=0; i--) {
				var im = imgs[i];
				if (im.className.match(/\bwiggle\b/gi)) {
					// Create a new div that will serve as a container for the image.
					var dv = document.createElement("div");
					dv.imWidth = im.width/2;
					dv.style.display = "block";
					dv.style.border = "5px solid #000";
					dv.style.overflow = "hidden";
					dv.style.height = im.height + "px";
					dv.style.width = (im.width/2) + "px";
					dv.style.position = "relative";
					
					// Replace the image with the div
					im.parentNode.replaceChild(dv, im);
					
					// Re-append the image to the div
					dv.appendChild(im);
					im.style.position = "absolute";

					// Add the div to the array of wiggle divs
					wigglyDivs.push(dv);
				}
			}


			// Set a timer to wiggle 
			window.setInterval(Wiggler.toggle, wiggleInterval);
		}
	});
}();

addEvent(window, "load", Wiggler.init);


