// Matika S.r.l.
// Version: 1.0.7
// Date: December 18, 2008

if (!window.Element) {
	var Element = {};
}

Cookie = {
	set: function(key, value, params) {
		var c = [key + "=" + escape(value)];
	
		for (var i in params) {
			if (i == "expires") {
				var d = new Date();
				
				d.setTime(d.getTime() + (86400000 * params[i]));
				
				params[i] = d.toGMTString();
			}
			
			c.push(i + "=" + params[i]);
		}
		
		document.cookie = c.join(";");
	},
	get: function(key) {
		document.cookie.match(new RegExp(key + "=([^;]*);?", "gi"));
		
		return unescape(RegExp.$1);
	},
	erase: function(key) {
		this.set(key, "", {expires: -1});
	}
}

Enumerable = {
	$break: {},
	$continue: {},
	$function: function(x) {
		return x;
	},
	each: function(iterator) {
		var index = 0;
		
		try {
			this._each(function(value) {
				try {
					iterator(value, index++);
				} catch (e) {
					if (e != this.$continue) throw e;
				}
			});
		} catch (e) {
			if (e != this.$break) throw e;
		}
	},
	all: function(iterator) {
		var result = true;
		
		this.each(function(value, index) {
			result = result && !!(iterator || this.$function)(value, index);
			
			if (!result) {
				throw this.$break;
			}
		});
		
		return result;
	},
	any: function(iterator) {
		var result = true;
		
		this.each(function(value, index) {
			if (result = !!(iterator || this.$function)(value, index)) {
				throw this.$break;
			}
		});
		
		return result;
	},
	collect: function(iterator) {
		var results = [];
		
		this.each(function(value, index) {
			results.push(iterator(value, index));
		});
		
		return results;
	},
	find: function (iterator) {
	    var result;
		
	    this.each(function(value, index) {
			if (iterator(value, index)) {
				result = value;
				throw this.$break;
			}
		});
		
	    return result;
	},
	findAll: function(iterator) {
		var results = [];
		
		this.each(function(value, index) {
			if (iterator(value, index)) {
				results.push(value);
			}
		});
		
		return results;
	},
	toArray: function() {
		return this.collect(this.$function);
	}
}

Event = {
	KEY_RETURN: 13,

	guid: 1,
	key: function(e) {
		return e.keyCode;
	},
	element: function(e) {
		return e.target || e.srcElement;
	},
	add: function(obj, type, func) {
		if (window.addEventListener) {
			obj.addEventListener(type, func, false);
		} else {
			if (!func.$$guid) func.$$guid = this.guid++;
			if (!obj.events) obj.events = {};

			var funcs = obj.events[type];
			
			if (!funcs) {
				funcs = obj.events[type] = {};

				if (obj["on" + type]) {
					funcs[0] = obj["on" + type];
				}
			}
			
			funcs[func.$$guid] = func;
			obj["on" + type] = this.handle;
		}
	},
	remove: function(obj, type, func) {
		if (window.removeEventListener) {
			obj.removeEventListener(type, func, true);
		} else {
			if (obj.events && obj.events[type]) {
				delete obj.events[type][func.$$guid];
			}
		}
	},
	get: function(e) {
		if (!e) {
			e = ((this.ownerDocument || this.document || this).parentWindow || window).event;
		}
		
		this.fix(e);
		
		return e;
	},
	stop: function(e) {
		e.preventDefault();
		e.stopPropagation();
	},
	handle: function(e) {
		var funcs;
		var returnValue = true;
		
		e = Event.get(e);
		funcs = this.events[e.type];

		for (var i in funcs) {
			this.$$handleEvent = funcs[i];
			
			if (this.$$handleEvent(e) === false) {
				returnValue = false;
			}
		}
		
		return returnValue;
	},
	fix: function(e) {
		if (!e.preventDefault) {
			e.preventDefault = this.preventDefault;
		}
		
		if (!e.stopPropagation) {
			e.stopPropagation = this.stopPropagation;
		}
	},
	preventDefault: function() {
		this.returnValue = false;
	},
	stopPropagation: function() {
		this.cancelBubble = true;
	}
}

Form = {
	$: function(form) {
		return document.forms[form];
	},
	getElements: function(form) {
		form = this.$(form);
		var elements = [];

		for (tagName in this.serialize) {
			var tagElements = form.getElementsByTagName(tagName);
			
			for (var j = 0; j < tagElements.length; j++) {
				elements.push(tagElements[j]);
			}
		}
		
		return elements;
	},
	get: function(form, element) {		
		return this.$(form).elements[element];
	},
	getValue: function(form, element) {
		return this.get(form, element).value;
	},
	setValue: function(form, element, value) {
		this.get(form, element).value = value;
	},
	reset: function(form) {
		this.$(form).reset();
	},
	serialize: {
		input: function(element) {
			switch (element.type.toLowerCase()) {
			case "submit":
			case "hidden":
			case "password":
			case "text":
				return [element.name, element.value];
			case "checkbox":
			case "radio":
				if (element.checked) {
					return [element.name, element.value];
				}
			}
			
			return false;
		},
		select: function(element) {
			switch (element.type.toLowerCase()) {
			case "select-one":
			    var value = "";
				var index = element.selectedIndex;
				
			    if (index >= 0) {
					var opt = element.options[index];
					
					value = (!opt.value && !("value" in opt)) ? opt.text : opt.value;
			    }
				
			    return [element.name, value];
			default:
				var value = [];
				
				for (var i = 0; i < element.length; i++) {
					var opt = element.options[i];
					
					if (opt.selected) {
						value.push((!opt.value && !("value" in opt)) ? opt.text : opt.value);
					}
				}
				
				return [element.name, value];
			}
		},
		textarea: function(element) {
			return [element.name, element.value];
		}
	}
}

$ = function() {
	var elements = [];

	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		
		if (typeof element == "string") {
			element = document.getElementById(element);
		}
		
		if (arguments.length == 1) {
			return element;
		}	
 
		elements.push(element);
	}
	
	return elements;
}

$.Array = function(iterable) {
	if (!iterable) return [];
  
	if (iterable.toArray) {
		return iterable.toArray();
	} else {
		var results = [];
		
		for (var i = 0; i < iterable.length; i++) {
			results.push(iterable[i]);
		}
		
		return results;
	}
}

$.Name = function(obj, name) {
	return obj.getElementsByName(name);
}

$.TagName = function(obj, tagName) {
	return obj.getElementsByTagName(tagName.toUpperCase());
}

Object.extend = function(destination, source) {
	for (property in source) {
		destination[property] = source[property];
	}
	
	return destination;
}

Object.extend(Array.prototype, {
	_each: function(iterator) {
		for (var i = 0; i < this.length; i++) {
			iterator(this[i]);
		}
	},
	clear: function() {
		this.length = 0;
		
		return this;
	},
	first: function() {
		return this[0];
	},
	last: function() {		
		return this[this.length - 1];
	},
	indexOf: function(obj) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == obj) return i;
		}
		
		return -1;
	}
})

Object.extend(Array.prototype, Enumerable);

Object.extend(Element, {
	script: function(src, DOMMODE) {
		if (DOMMODE) {
			this.append($.TagName(document, "head")[0], "script", {
				type: "text/javascript",
				src: src});
		} else {
			try {
				document.write("<scr" + "ipt type=\"text/javascript\" src=\"" + src + "\"></scr" + "ipt>");
			} catch(e) {
				this.script(src, true);
			}
		}
	},
	style: function(src, DOMMODE) {
		if (DOMMODE) {
			this.append($.TagName(document, "head")[0], "link", {
				rel: "stylesheet",
				type: "text/css",
				href: src});	
		} else {
			try {
				document.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + src + "\">");
			} catch(e) {
				this.style(src, true);
			}
		}
	},
	create: function(objTagName, map) {
		var obj = document.createElement(objTagName.toUpperCase());

		for (var i in map) {
			if (i.indexOf("on") == 0) {
				Event.add(obj, i.substring(2), map[i]);
			} else {
				switch(i) {
				case "className":
					obj.className = map[i];
				break;
				default:
					obj.setAttribute(i, map[i]);
				}
			}
		}
		
		return obj;
	},
	createText: function(text) {
		return document.createTextNode(text);
	},
	append: function(objParent, tag, map) {
		var obj;
		
		if (typeof(tag) == "string") {
			obj = this.create(tag, map);
		} else {
			obj = tag;
		}
		
		objParent.appendChild(obj);
		
		return obj;
	},
	appendText: function(objParent, text) {
		objParent.appendChild(this.createText(text));
	},
	clone: function(obj, recursive) {
		return obj.cloneNode(recursive);
	},
	cloneWithEventHandlers: function(obj, recursive) {
		var clone = obj.cloneNode(false);
		
		for (var i in obj) {
			if (i.indexOf("on") == 0) {
				clone[i] = obj[i];
			}
		}
		
		if (recursive) {
			$.Array(obj.childNodes).each( function(node) {
				switch (node.nodeType) {
				case 3: //TEXT_NODE
					clone.appendChild(Element.createText(node.nodeValue));
				break;
				case 1: //ELEMENT_NODE
					clone.appendChild(Element.cloneWithEventHandlers(node, recursive));
				break;
				default:
					clone.appendChild(node); 
				}
			});
		}
		
		return clone;
	},
	remove: function(obj) {
		obj.parentNode.removeChild(obj);
	},
	hasAttribute: function(obj, attribute) {
		return (typeof obj[attribute] == "undefined") ? 0 : 1;
	},
	hide: function(obj, visibility) {
		if (visibility) {
			obj.style.visibility = "hidden";
		} else {
			obj.style.display = "none";
		}
	},
	show: function(obj, visibility) {
		if (visibility) {
			obj.style.visibility = "visible";
		} else {
			obj.style.display = "block";
		}
	},
	addClassName: function(obj, className) {
		obj.className = obj.className.insert(className);
	},
	removeClassName: function(obj, className) {
		obj.className = obj.className.remove(className);
	},
	getHeight: function(obj) {
		return obj.offsetHeight;
	},
	getWidth: function(obj) {
		return obj.offsetWidth;
	},
	setWidth: function(obj, size) {
		obj.style.width = size;
	},
	getLeft: function(obj) {
		var x = 0;
		
		if (obj.offsetParent) {
			while (obj.offsetParent) {
				x += obj.offsetLeft;
				obj = obj.offsetParent;
			}
		} else if (obj.x) {
			x += obj.x;
		}	
		
		return x;
	},	
	getTop: function(obj) {
		var y = 0;
		
		if (obj.offsetParent) {
			while (obj.offsetParent) {
				y += obj.offsetTop;
				obj = obj.offsetParent;
			}
		} else if (obj.y) {
			y += obj.y;
		}	
		
		return y;
	}
})

Object.extend(Function.prototype, {
	bind: function() {
		var __method = this, args = $.Array(arguments), obj = args.shift();
		
		return function() {
			return __method.apply(obj, args.concat($.Array(arguments)));
		}
	},
	bindAsEventListener: function(obj) {
		var __method = this;
		
		return function(event) {
			return __method.call(obj, Event.get(event));
		}
	}
})

Object.extend(String.prototype, {
	trim: function() {
		return this.replace(/\s+$|^\s+/g, "");
	},
	insert: function() {
		var w = this.split(" ");
		var i = arguments.length;
		
		while (i > 0) {
			i--;
			
			if (w.indexOf(arguments[i]) == -1) {
				w.unshift(arguments[i]);
			}
		}
		
		return w.join(" ");
	},
	remove: function() {
		var w = this.split(" ");
		
		for (var i=0; i < arguments.length; i++) {
			var index = w.indexOf(arguments[i]);
			
			if (index != -1) {
				w.splice(index, 1);
			}
		}
		
		return w.join(" ");
	}
})