/* some basic wob functions

	most - if not all - of them require prototype
*/
/**
 * Greps all <a> tags with attribute rel="external" and
 * inserts a target="_blank" into the DOM tree.
 */
document.observe("dom:loaded", function() {
    $$('a[rel="external"]').each(function(link) {
        if(link.readAttribute('href') != '' && link.readAttribute('href') != '#') {
            link.writeAttribute('target','_blank');
        }
    });
});
/**
 * Class that handles all Main Navigation Stuff,
 * instanciated on dom:loaded as "mainNavHandler"
 *
 */
var mainNavHdl = Class.create({
	/**
	 * Constructor
	 */
	initialize: function(){
		this.openElement = null;
		
		$('nav').observe('mouseover', function(e) {
			var elem = e.findElement('div > a');
			// alert(typeof(elem));
			if (elem == undefined) { // not over an <a>: return
				e.stop(); return;
			}
			var parent = elem.up('div');
			if (parent.hasClassName('contact')) { // over contact button: return
				parent.down('a img').src = parent.down('a img').src.replace(/_off\./i,'_on.');
				if (this.openElement !== null) {
					this.closeCurrentFlyout();
				}
				e.stop(); return;
			}
			var elemToOpen = parent.down('div');
			if (elemToOpen !== this.openElement) {
				if (this.openElement !== null) {
					this.closeCurrentFlyout();
				}
				elemToOpen.setStyle({ display: 'block' });
				parent.down('a img').src = parent.down('a img').src.replace(/_off\./i,'_on.');
				this.openElement = parent; // the parent keeps the class name
			}
			e.stop();
		}.bind(this));
		
		$('nav').observe('mouseout', function(e) {
			var elem = e.findElement('div > a');
			if (elem !== undefined) {
				var parent = elem.up('div');
				if (parent.hasClassName('contact')) { // over contact button: return
					parent.down('a img').src = parent.down('a img').src.replace(/_on\./i,'_off.');
					// e.stop(); return;
				}
			}
			if (this.openElement === null) { // nothing open: return
				e.stop();
				return;
			}
			if (this.within(this.openElement, Event.pointerX(e), Event.pointerY(e))) return;
			if (this.openElement !== null) {
				this.closeCurrentFlyout();
			}
		}.bind(this));
	},
	/**
	 * closes the flyout stored in this.openElement
	 *
	 */
	closeCurrentFlyout: function() {
		this.openElement.down('div').setStyle({ display: 'none' });
		this.openElement.down('a img').src = this.openElement.down('a img').src.replace(/_on\./i,'_off.');
		this.openElement = null;
	},
	/**
	 * helper method that re-implements deprecated Prototype method Position:within
	 *
	 */
	within : function(element, x, y){
		element = $(element);
		this.topleft = Element.cumulativeOffset(element);
		this.bottomright = [
			this.topleft[0] + element.offsetWidth,
			this.topleft[1] + element.offsetHeight,
		];
		return (y >= this.topleft[1] &&
			y <  this.bottomright[1] &&
			x >= this.topleft[0] &&
			x <  this.bottomright[0]);
	}
}); // End Class mainNavHdl
document.observe('dom:loaded',function() {
	var mainNavHandler = new mainNavHdl();
});


/**
 * Class that handles a horizontal Carousel
 *
 * Needs prototype and script.aculo.us
 *
This class expects this html structure:

<div id="carousel">
	<div class="nav"><img width="20" height="20" alt="Previous" src="/_gfx/prev_on.gif"/></div>
	<div class="itemholder"><div class="itemslider">
		<div class="item">Item 1</div>
		<div class="item">Item 2</div>
		<div class="item">Item 3</div>
		<div class="item">Item 4</div>
		<div class="item">Item 5</div>
		<div class="item">Item 6</div>
	</div></div>
	<div class="nav"><img width="20" height="20" alt="Next" src="/_gfx/next_on.gif"/></div>
</div>

Important css Stuff:

div.itemholder {
	overflow: hidden;
	position: relative;
}
div.itemslider {
	width: 5000px; # enough to keep all items
}
div.item { float: left; } # prehaps you should add a clearfix somewhere

- The Navigation images need "_on" and "_off" in their name. Nav Images should be initially "_on".
- If you also have mouseover Images, they have to be suffixed "_over" and activate mouseover/out
	observing by setting horizCarouselHdl::doHover to (bool) true.
- The width of items - and therefore the mumber of px to move on click - is calculated by the class.
- The number of visible items has to be set in the constructor
- The duration of a move may be set.
- This class should be instanciated only if id "carousel" exists.
 */
var horizCarouselHdl = Class.create({
	/**
	 * Constructor
	 */
	initialize: function(){
		this.doHover = true;
		this.duration = 0.75
		this.visibleItems = 3;
		this.currentFirstItem = 1;
		this.carousel = $('carousel');
		this.prev = this.carousel.down('div.nav img',0);
		this.next = this.carousel.down('div.nav img',1);
		this.slider = this.carousel.down('div.itemslider');
		this.numItems = this.carousel.select('div.item').length;
		// attach observers
		this.prev.observe('click', this.clickedPrev.bind(this));
		this.next.observe('click', this.clickedNext.bind(this));
		if (this.doHover) {
			this.prev.observe('mouseover', this.hover.bind(this));
			this.next.observe('mouseover', this.hover.bind(this));
			this.prev.observe('mouseout', this.hover.bind(this));
			this.next.observe('mouseout', this.hover.bind(this));
		}
		this.toggleBtnState(this.prev);
		if (this.numItems <= this.visibleItems) {
			this.toggleBtnState(this.next);
		}
	},

	/**
	 * prev Button clicked
	 *
	 * move slider accordingly (if there are more items in that direction) and update buttons
	 */
	clickedPrev: function() {
		if (this.prev.readAttribute('carousel') == 'off') return;
		var width = this.carousel.select('div.item')[this.currentFirstItem-1].getWidth();
		new Effect.Move(this.slider, { x: (width), y: 0, mode: 'relative', queue: 'end', duration: this.duration });
		this.currentFirstItem -= 1;
		if ( (this.currentFirstItem + this.visibleItems) == (this.numItems) ) {
			this.toggleBtnState(this.next);
		}
		if (this.currentFirstItem == 1 ) {
			this.toggleBtnState(this.prev);
		}
	},
	/**
	 * next Button clicked
	 *
	 * move slider accordingly (if there are more items in that direction) and update buttons
	 */
	clickedNext: function() {
		if (this.next.readAttribute('carousel') == 'off') return;
		var width = this.carousel.select('div.item')[this.currentFirstItem].getWidth();
		new Effect.Move(this.slider, { x: (width)*(-1), y: 0, mode: 'relative', queue: 'end', duration: this.duration });
		this.currentFirstItem += 1;
		if ( (this.currentFirstItem + this.visibleItems) == (this.numItems+1)) {
			this.toggleBtnState(this.next);
		}
		if (this.currentFirstItem == 2) {
			this.toggleBtnState(this.prev);
		}
	},
	/**
	 * handle mouseover/out on nav images
	 *
	 */
	hover: function(e) {
		var elem = e.findElement();
		if (elem.readAttribute('carousel') == 'off') return;
		switch (e.type) {
			case 'mouseover':
				elem.src = elem.src.replace(/_(on)\./i,'_over.');
				break;
			case 'mouseout':
			default:
				elem.src = elem.src.replace(/_(over)\./i,'_on.');
		}
	},
	/**
	 * toggles the state of a passed navigation botton,
	 * depending on whatever the attribute 'charousel' is set.
	 *
	 * If the attribute is not found, it's added with value 'on'.
	 *
	 */
	toggleBtnState: function(btn) {
		btn = $(btn);
		// attribute 'carousel' not set -> add it
		if (null == btn.readAttribute('carousel')) {
			btn.writeAttribute('carousel','on');
		}
		switch(btn.readAttribute('carousel')) {
			case 'on':
				btn.writeAttribute('carousel','off');
				btn.src = btn.src.replace(/_(on|over)\./i,'_off.');
				break;
			case 'off':
				btn.writeAttribute('carousel','on');
				btn.src = btn.src.replace(/_(off)\./i,'_on.')
			default:
		}
		return;
	}
}); // end class
document.observe('dom:loaded',function() {
	if ($('carousel')) var newsHomeHandler = new horizCarouselHdl();
});



