/* $Id: lib.js,v 1.8 2009/03/06 03:06:39 bob Exp $ */

// Splintered striper 1.3
// reworking of Zebra Tables and similar methods which works not only for tables and even/odd rows,
// but as a general DOM means of assigning any number of classes to children of a parent element.
// Patrick H. Lauke aka redux / www.splintered.co.uk
// Distributed under the Creative Commons Attribution-ShareAlike license - http://creativecommons.org/licenses/by-sa/2.0/

// Converted over to using Prototype to allow for nested lists
// by Robert Bottomley, UC Riverside.

/*
 * What we want striped.
 */
function striperLoadEvent() {
/*           Parent             Child
 *           Selector           Classes */
	striper ('tbody.striped',   'odd,.');
	striper ('ul.striped',      'odd,.');
	striper ('ul.big_links',    '.');
	striper ('ol.striped',      'odd,.');
	striper ('dl.striped',      'odd,.');
}

/*
 * Summary:      Function that applies any number of classes to all child elements
 *               contained in all occurrences of a parent element (either with or without a specific class)
 * Parameters:   parentSelector - parent selector (same as CSS selectors)
 *               styleClasses - comma separated list of any number of style classes (using 2 classes gives the classic "zebra" effect)
 * Return:       none
 */
function striper(parentSelector, styleClasses)
{
	var i=0, currentParent, currentChild;

	// capability and sanity check
	if ((document.getElementsByTagName) && (parentSelector) && (styleClasses)) {
		// turn the comma separate list of classes into an array
		var styles = styleClasses.split(',');

		// get an array of all parent elements
		var parentItems = $$(parentSelector);

		// loop through all parent elements
		parentItems.each(function(currentParent) {
			var j=1, k=0;

			// get all child elements of the current parent element
			var childItems = currentParent.childElements();

			// loop through all child elements
			childItems.each(function(currentChild) {
				// based on the current element and the number of styles in the array, work out which class to apply
				k = (j+(styles.length-1)) % styles.length;
				j++;

				if (styles[k] != '.') {
					// add the class to the child element
					$(currentChild).addClassName(styles[k]);
				}

				// add mouseover rules for hover effect
				currentChild.onmouseover = function() {
					$(this).addClassName('ruled');
				}

				currentChild.onmouseout = function() {
					$(this).removeClassName('ruled');
				}
			});
		});
	}
}

// Activate Striper.
Event.observe (window, 'load', striperLoadEvent);


/*
 * Toggles the visibility of element of class xpander using the blind effect.
 */

function toggleXpander(item) {
	new Effect.toggle($($($(item).next('.xpander')).identify()),'blind');
	item.toggleClassName('xpander-on');

	if (item.innerHTML == 'Show')
		item.update('Hide');
	else
		item.update('Show');
}


// Look for elements of class "xpander" and hide them, then add a "Show"
// button before them.
//
Event.observe(window,'load', function () {
	$$('.xpander').each(function(item) {
		item.hide();
		item.insert({before: '<a class="xpander-control" href="#" onclick="javascript:toggleXpander(this); return false">Show</a>\n'});
	});
});

/*
 * AJAX call to get calendar info from events.ucr.edu.
 */
function requestCalInfo (id, params) {
    var options = {
        method: 'get',
        parameters: params,
        onFailure: function(XHR) { $(id).innerHTML = '<div class="error"><p>An error occurred during loading: '+XHR.statusText+'.</p></div>' }
    };
    var myAjax = new Ajax.Updater({success: id}, "/calendar.php", options);
}


// Tooltip Object
// Source: http://www.wildbit.com/labs/cooltips/ version 1.0
var Tooltip = Class.create();
Tooltip.prototype = {
	initialize: function(el, options) {
		this.el = $(el);
		this.initialized = false;
		this.setOptions(options);

		// Event handlers
		this.showEvent = this.show.bindAsEventListener(this);
		this.hideEvent = this.hide.bindAsEventListener(this);
		this.updateEvent = this.update.bindAsEventListener(this);
		Event.observe(this.el, "mouseover", this.showEvent );
		Event.observe(this.el, "mouseout", this.hideEvent );

		// Removing title from DOM element to avoid showing it
		this.content = this.el.title;
		this.el.title = "";

		// If descendant elements has 'alt' attribute defined, clear it
		this.el.descendants().each(function(el){
			if(Element.readAttribute(el, 'alt'))
				el.alt = "";
		});
	},
	setOptions: function(options) {
		this.options = {
			//backgroundColor: '#999', // Default background color
			//borderColor: '#666', // Default border color
			//textColor: '', // Default text color (use CSS value)
			textShadowColor: '', // Default text shadow color (use CSS value)
			maxWidth: 250,	// Default tooltip width
			align: "left", // Default align
			delay: 250, // Default delay before tooltip appears in ms
			mouseFollow: true, // Tooltips follows the mouse moving
			opacity: .75, // Default tooltips opacity
			appearDuration: .25, // Default appear duration in sec
			hideDuration: .25 // Default disappear duration in sec
		};
		Object.extend(this.options, options || {});
	},
	show: function(e) {
		this.xCord = Event.pointerX(e);
		this.yCord = Event.pointerY(e);
		if(!this.initialized)
			this.timeout = window.setTimeout(this.appear.bind(this), this.options.delay);
	},
	hide: function(e) {
		if(this.initialized) {
			this.appearingFX.cancel();
			if(this.options.mouseFollow)
				Event.stopObserving(this.el, "mousemove", this.updateEvent);
			new Effect.Fade(this.tooltip, {duration: this.options.hideDuration, afterFinish: function() { Element.remove(this.tooltip) }.bind(this) });
		}
		this._clearTimeout(this.timeout);

		this.initialized = false;
	},
	update: function(e){
		this.xCord = Event.pointerX(e);
		this.yCord = Event.pointerY(e);
		this.setup();
	},
	appear: function() {
		// Building tooltip container
		this.tooltip = Builder.node("div", {className: "tooltip", style: "display: none;" }, [
			Builder.node("div", {className:"xtop"}, [
				Builder.node("div", {className:"xb1"/*, style:"background-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb2"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb3"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb4"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/})
			]),
			Builder.node("div", {className: "xboxcontent"/*, style: "background-color:" + this.options.backgroundColor +
				"; border-color:" + this.options.borderColor +
				((this.options.textColor != '') ? "; color:" + this.options.textColor : "") +
				((this.options.textShadowColor != '') ? "; text-shadow:2px 2px 0" + this.options.textShadowColor + ";" : "")*/}, this.content),
			Builder.node("div", {className:"xbottom"}, [
				Builder.node("div", {className:"xb4"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb3"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb2"/*, style: "background-color:" + this.options.backgroundColor + "; border-color:" + this.options.borderColor + ";"*/}),
				Builder.node("div", {className:"xb1"/*, style:"background-color:" + this.options.borderColor + ";"*/})
			]),
		]);
		document.body.insertBefore(this.tooltip, document.body.childNodes[0]);

		Element.extend(this.tooltip); // IE needs element to be manually extended
		this.options.width = this.tooltip.getWidth();
		this.tooltip.style.width = this.options.width + 'px'; // IE7 needs width to be defined

		this.setup();

		if(this.options.mouseFollow)
			Event.observe(this.el, "mousemove", this.updateEvent);

		this.initialized = true;
		this.appearingFX = new Effect.Appear(this.tooltip, {duration: this.options.appearDuration, to: this.options.opacity });
	},
	setup: function(){
		// If content width is more then allowed max width, set width to max
		if(this.options.width > this.options.maxWidth) {
			this.options.width = this.options.maxWidth;
			this.tooltip.style.width = this.options.width + 'px';
		}

		// Tooltip doesn't fit the current document dimensions
		if(this.xCord + this.options.width >= Element.getWidth(document.body)) {
			this.options.align = "right";
			this.xCord = this.xCord - this.options.width + 20;
		}

		this.tooltip.style.left = this.xCord - 7 + "px";
		this.tooltip.style.top = this.yCord + 12 + "px";
	},
	_clearTimeout: function(timer) {
		clearTimeout(timer);
		clearInterval(timer);
		return null;
	}
};

Event.observe(window,'load', function () {
	// Tooltips on:
	$$(".tip").each(function(item) {
		new Tooltip(item);
	});
});

