

;(function($) {

	var cal = {
		called: false,
		init: function () {
			if (cal.called) {
				return;
			}
			cal.called = true;
			var events = getElementsByClassName('cal-event');
			var c = events.length;
			for (var i = 0; i < c; i++) {
				var elEvent = events[i];
				var elLinks = getElementsByClassName('cal-event-with-cat', 'a', elEvent);
				var elLink = elLinks[0];
				cal.addEvent(elLink, 'mouseover', cal.bind(cal.showDetails, [elEvent]));
				cal.addEvent(elLink, 'mouseout', cal.bind(cal.hideDetails, [elEvent]));
			}
		},
		showDetails: function (evt, elEvent) {
			cal.cancelEvent(evt);
			var els = getElementsByClassName('cal-event-details', 'div', elEvent);
			var elDetails = els[0];
			elDetails.style.display = 'block';
		},
		hideDetails: function (evt, elEvent) {
			cal.cancelEvent(evt);
			var els = getElementsByClassName('cal-event-details', 'div', elEvent);
			var elDetails = els[0];
			elDetails.style.display = 'none';
		},
		bind: function (method, args) {
			var scope = cal;
			return function () {
				var a = [];
				for (var i = 0, j = arguments.length; i < j; i++) {
					a[a.length] = arguments[i];
				}
				for (var i = 0, j = args.length; i < j; i++) {
					a[a.length] = args[i];
				}
				method.apply(scope, a);
			}
		},
		addEvent: function (obj, type, fn) {
			if (obj.addEventListener) {
				obj.addEventListener(type, fn, false);
			}
			else if (obj.attachEvent) {
				obj['e' + type + fn] = fn;
				obj[type + fn] = function() {
					obj['e' + type + fn](window.event);
				};
				obj.attachEvent('on' + type, obj[type + fn]);
			}
		},
		cancelEvent: function (e) {
			if (!e) var e = window.event;

			if (e.stopPropagation) e.stopPropagation();
			else e.cancelBubble = true;

			if (e.preventDefault) e.preventDefault();
			else e.returnValue = false;
		}
	};

	/*
	Developed by Robert Nyman, http://www.robertnyman.com
	Code/licensing: http://code.google.com/p/getelementsbyclassname/
	*/
	var getElementsByClassName = function (className, tag, elm){
		if (document.getElementsByClassName) {
			getElementsByClassName = function (className, tag, elm) {
				elm = elm || document;
				var elements = elm.getElementsByClassName(className),
					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
					returnElements = [],
					current;
				for(var i=0, il=elements.length; i<il; i+=1){
					current = elements[i];
					if(!nodeName || nodeName.test(current.nodeName)) {
						returnElements.push(current);
					}
				}
				return returnElements;
			};
		}
		else if (document.evaluate) {
			getElementsByClassName = function (className, tag, elm) {
				tag = tag || "*";
				elm = elm || document;
				var classes = className.split(" "),
					classesToCheck = "",
					xhtmlNamespace = "http://www.w3.org/1999/xhtml",
					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
					returnElements = [],
					elements,
					node;
				for(var j=0, jl=classes.length; j<jl; j+=1){
					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
				}
				try	{
					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
				}
				catch (e) {
					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
				}
				while ((node = elements.iterateNext())) {
					returnElements.push(node);
				}
				return returnElements;
			};
		}
		else {
			getElementsByClassName = function (className, tag, elm) {
				tag = tag || "*";
				elm = elm || document;
				var classes = className.split(" "),
					classesToCheck = [],
					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
					current,
					returnElements = [],
					match;
				for(var k=0, kl=classes.length; k<kl; k+=1){
					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
				}
				for(var l=0, ll=elements.length; l<ll; l+=1){
					current = elements[l];
					match = false;
					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
						match = classesToCheck[m].test(current.className);
						if (!match) {
							break;
						}
					}
					if (match) {
						returnElements.push(current);
					}
				}
				return returnElements;
			};
		}
		return getElementsByClassName(className, tag, elm);
	}

	/* for Mozilla/Opera9 */
	if (document.addEventListener) {
		document.addEventListener('DOMContentLoaded', cal.init, false);
	}

	/* for Internet Explorer */
	/*@cc_on @*/
	/*@if (@_win32)
		document.write('<script id=__ie_onload defer src=javascript:void(0)><\/script>');
		var script = document.getElementById('__ie_onload');
		script.onreadystatechange = function() {
			if (this.readyState == 'complete') {
				cal.init(); // call the onload handler
			}
		};
	/*@end @*/

	/* for Safari */
	if (/WebKit/i.test(navigator.userAgent)) { // sniff
		cal.timer = setInterval(function() {
			if (/loaded|complete/.test(document.readyState)) {
				cal.init(); // call the onload handler
			}
		}, 10);
	}

	cal.addEvent(window, 'load', function() { cal.init() });
})();
