var Hashtable = (function() {
	var prefix = ' $';
	function isNull(object) {return !object && ('object' == typeof object);}
	function isNumber(object) {return 'number' == typeof object;}
	function isUndefined(object) {return 'undefined' == typeof object;}
	function Element(key, value) {
		this.key = key;
		this.value = value;
		this.next = null;
	}
	function Hashtable() {
		var table = {data : []},
		    entries = 0;

		this.get = function(key) {var index, tableData = table.data;
			if(!isNull(key) && !isUndefined(key)
			 && isNumber(index = table[prefix + key]))
			{
				var node = tableData[index];
				while(node && (node.key !== key)) {node = node.next;}
				if(node) {return node.value;}
			}
		};
		this.put = function(key, value) {var index, prefixedKey, tableData = table.data;
			if(isNull(key) || isUndefined(key) || isUndefined(value)) {return;}
			if(isNumber(index = table[prefixedKey = prefix + key])) {
				var node = tableData[index], previousNode = null;
				while(node && (node.key !== key)) {
					previousNode = node;
					node = node.next;
				}
				if(node) {
					var oldValue = node.value;
					node.value = value;
					return oldValue;
				} else {
					previousNode.next = new Element(key, value);
				}
			}
			else {
				table[prefixedKey] = tableData.length;
				tableData[tableData.length] = new Element(key, value);
			}
			++entries;
		};
		this.remove = function(key) {var index, prefixedKey, tableData = table.data;
			if(!isNull(key) && !isUndefined(key)
			 && isNumber(index = table[prefixedKey = prefix + key]))
			{
				var node = tableData[index], previousNode = null, returnValue;
				while(node && (node.key !== key)) {
					previousNode = node;
					node = node.next;
				}
				if(!node) {return;}
				returnValue = node.value;
				if(previousNode) {previousNode.next = node.next;}
				else {tableData[index] = node.next;}
				if(!tableData[index]) {
					for(var length = tableData.length - 1; index < length; ++index) {
						tableData[index] = tableData[index + 1];
						--table[prefix + tableData[index].key];
					}
					delete tableData[index];
					delete table[prefixedKey];
				}
				--entries;
				return returnValue;
			}
		};
	}
	Hashtable.prototype.containsKey = function(key) {
		return !isUndefined(this.get(key));
	};
	return Hashtable;
})();
var fade = (function() {
	var global = this,
			objects = new Hashtable();

	function getOpacity(object) {
		if(global.getComputedStyle) {
			getOpacity = function(object) {
				return parseFloat(
					global.getComputedStyle(object, null).getPropertyValue('opacity')
				) * 100;
			};
		} else if(object.filters) {
			getOpacity = function(object) {
//				return object.filters['DXImageTransform.Microsoft.Alpha'].Opacity;
				return object.filters.alpha.Opacity;
			};
		} else {
			getOpacity = function() {return 100;};
		}
		return getOpacity(object);
	}

	function setOpacity(object, opacity) {
		if(object.filters) {
			setOpacity = function(object, opacity) {
//				object.filters['DXImageTransform.Microsoft.Alpha'].Opacity = opacity;
 				object.filters.alpha.Opacity = opacity;
			};
		} else if(object.style && object.style.setProperty) {
			setOpacity = function(object, opacity) {
				object.style.setProperty('opacity', opacity / 100, '');
			};
		} else {
			setOpacity = function() {};
		}
		setOpacity(object, opacity);
	}

	return function(object, targetOpacity, rate, delta) {
		var opacity = getOpacity(object);

		function stepFade() {var onTarget;
			opacity += delta;
			onTarget = (0 < delta) ?
				opacity >= targetOpacity
			: opacity <= targetOpacity;
			if(onTarget) {
				opacity = targetOpacity;
				objects.remove(object);
			}
			setOpacity(object, opacity);
			if(!onTarget) {objects.put(object, setTimeout(stepFade, rate));}
		}
		/* Deze function vertrouwd op sluiting, door de inner function hierboven.
		 * Als dit niet lukt, wordt deze stilletjes afgebroken.
		 */
		stepFade.toString = function() {return ';';};

		/* Als het object in behandeling is wordt deze gestopt. */
		if(objects.containsKey(object)) {clearTimeout(objects.get(object));}
		/* Maximum Opacity in gekko is 99. 		*/
		if(100 == targetOpacity) {--targetOpacity;}
		if(opacity > targetOpacity) {delta = -delta;}
		if(delta && rate) {objects.put(object, setTimeout(stepFade, rate));}
	}
})();

//onmouseover="fade(this,100,40,5)" style="filter: alpha(opacity=20);-moz-opacity:.2;opacity:.2;"
//onmouseout="fade(this,50,40,5)" style="filter: alpha(opacity=20);-moz-opacity:.2;opacity:.2;"
