﻿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 (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; 
					try {
						return object.filters.alpha.Opacity;
					}
					catch (e) { }
				};
			}
			else {
				getOpacity = function() { return 100; };
			}
			return getOpacity(object);
		}
		else {
			return 100;
		}

	}

	function setOpacity(object, opacity) {
		if (object) {
			if (object.filters) {
				setOpacity = function(object, opacity) {
					// object.filters['DXImageTransform.Microsoft.Alpha'].Opacity = opacity; 
					try {
						object.filters.alpha.Opacity = opacity;
					}
					catch (e) { }

				};
			}
			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)); }
	}
})();
