/**
 * @author Nathan Kelly - http://www.nathan-kelly.com/
 * @copyright 2009 Nathan Kelly
 * @package nk-multi-gliders
 * @version 1.0.2
 * @url http://projects.nathan-kelly.com/nk-multi-gliders/
 * @dependencies 
 * 	prototype.js 1.6.0.2+ (http://www.prototypejs.org/)
 *	scriptaculous.js 1.8.1+ (http://script.aculo.us/)
 * @license
 *	Creative Commons Attribution 2.5 Australia License
 *	http://creativecommons.org/licenses/by/2.5/au/
 */

nk_init_multi_gliders = Class.create({
	initialize: function (o) {
		this.o = Object.extend({
			_rootClass:		'nk-glider-panels',
			_panelClass:	'nk-glider-panel',
			_navClass:		'nk-glider-nav',
			_toggleClass:	'nk-glider-toggle',
			_duration:		0.5,
			_frequency:		10,
			_autoGlide:		0,
			_autoRestart:	1,
			_restartDelay:	2,
			_initialPanel:	0,
			_overrideLinks:	0
		}, o || {});
		// thats it dont edit below unless you need to
		if ( !$$('.' + this.o._rootClass) ) { return; }		
		var roots = $$('.' + this.o._rootClass);		
		for ( var i = 0; i < roots.length; i++ ) {
			new nk_multi_gliders(roots[i], this.o);
		}
	}
});

nk_multi_gliders = Class.create({
	initialize: function (glider, o) {
		this.o 				= o;		
		this.scrolling		= false;
		this.scroller		= glider;
		// set options defaults
		this.duration		= this.o._duration;
		this.frequency		= this.o._frequency;
		this.autoGlide		= this.o._autoGlide;
		this.autoRestart	= this.o._autoRestart;
		this.restartDelay	= this.o._restartDelay * 1000;
		this.initialPanel	= this.o._initialPanel;
		this.overrideLinks	= this.o._overrideLinks;
		// start options overrides
		this.opts			= this.scroller.className.split(' ');
		// get opts from className array
		for ( i = 0; i < this.opts.length; i++ ) {
			if ( this.opts[i].match(/duration/) ) { this.duration = Number( this.opts[i].substring( this.opts[i].indexOf('-') + 1, this.opts[i].length ).replace('_', '.') ); }
			if ( this.opts[i].match(/frequency/) ) { this.frequency = Number( this.opts[i].substring( this.opts[i].indexOf('-') + 1, this.opts[i].length ).replace('_', '.') ) }
			if ( this.opts[i].match(/autoglide/) ) { this.autoGlide = 1; }
			if ( this.opts[i].match(/autorestart/) ) { this.autoRestart = 1; }
			if ( this.opts[i].match(/restartDelay/) ) { this.restartDelay = Number( this.opts[i].substring( this.opts[i].indexOf('-') + 1, this.opts[i].length ) * 1000 ) }
			if ( this.opts[i].match(/initialpanel/) ) { this.initialPanel = Number( this.opts[i].substring( this.opts[i].indexOf('-') + 1, this.opts[i].length ).replace('_', '.') ); }
			if ( this.opts[i].match(/override-links/) ) { this.overrideLinks = 1; }
		}
		// end options overrides
		this.navigation		= $(this.o._navClass + this.scroller.id.substring(this.scroller.id.lastIndexOf('-'), this.scroller.id.length) );
		this.firstPanel		= this.o._panelClass + this.scroller.id.substring(this.scroller.id.lastIndexOf('-'), this.scroller.id.length) + '-' + this.initialPanel;
		this.panels			= this.scroller.getElementsBySelector('.' + this.o._panelClass);
		this.controls		= this.navigation.getElementsBySelector('.' + this.o._toggleClass);
		this.itemised		= this.navigation.className.match(/itemised/) ? true : false;
		this.complex		= this.navigation.className.match(/complex/) ? true : false;
		this.panels.each( function (panel, index) {
			panel._index = index;
		});		
		this.events = {
			click: this.click.bind(this),
			clickPanel: this.clickPanel.bind(this)
		};
		if ( this.overrideLinks ) {
			this.panels.invoke( 'observe', 'click', this.events.clickPanel );
		}
		this.controls.invoke( 'observe', 'click', this.events.click );
		this.moveTo( this.firstPanel , this.scroller, {
			duration: this.duration
		});
		if ( this.autoGlide ) {
			this.start(1);
		}		
	},

	clickPanel: function (event) {
		// allows all elemnts of a panel to link to one location
		Event.stop(event);
		var element = Event.findElement(event, 'li');
		var href = element.down('a').href;
		window.location = href;
	},
	
	click: function (event) {				
		Event.stop(event);
		var element = Event.findElement(event, 'a');
		if ( this.scrolling ) {
			this.scrolling.cancel();
		}
		if ( this.itemised ) {
			this.moveTo( element.href.split("#")[1], this.scroller, {
				duration: this.duration
			});
		} else if ( this.complex ) {
			if ( element.id.match(/prev/) || element.id.match(/next/) ) {
				element.id.match(/prev/) ? this.movePrev() : this.moveNext();
			} else {
				this.moveTo( element.href.split("#")[1], this.scroller, {
					duration: this.duration
				});
			}		
		} else if ( element.id.match(/prev/) || element.id.match(/next/) ) {
			element.id.match(/prev/) ? this.movePrev() : this.moveNext();
		}
		if ( this.autoGlide && this.autoRestart ) {
			this.stop();
			if (this.restart != null) {
				clearTimeout(this.restart);
			}
			this.restart = setTimeout( this.update.bind(this), this.frequency * this.restartDelay );
		}
	},

	moveTo: function (element, container) {
		this.current = $(element);
		Position.prepare();
		var co = Position.cumulativeOffset(container), eo = Position.cumulativeOffset($(element));
		this.scrolling = new Effect.SmoothScroll( container, {
			duration: this.duration,
			x: ( eo[0] - co[0] ),
			y: ( eo[1] - co[1] )
		});
		if ( this.itemised || this.complex ) {
			var selected = this.controls.each( function (s) {
				$(s).up('li').removeClassName('current');
			});
			if ( this.complex ) {
				selected[this.current._index + 1].up('li').addClassName( 'current' );
			} else {
				selected[this.current._index].up('li').addClassName( 'current' );
			}
		}
		return false;
	},

	moveNext: function () {
		if ( this.current ) {
			var c = this.current._index;
			var n = ( this.panels.length - 1 == c ) ? 0 : c + 1;
		} else {
			var n = 1;
		}
		this.moveTo( this.panels[n].id, this.scroller, {
			duration: this.duration
		});
	},

	movePrev: function () {
		if (this.current) {
			var c = this.current._index;
			var p = ( c == 0 ) ? this.panels.length - 1 : c - 1;
		} else {
			var p = this.panels.length - 1;
		}
		this.moveTo( this.panels[p].id, this.scroller, {
			duration: this.duration
		});
	},

	stop: function () {
		clearTimeout( this.timer );
	},

	start: function () {
		this.update();
	},

	update: function () {
		if (this.timer != null) {
			clearTimeout(this.timer);
			this.moveNext();
		}
		this.timer = setTimeout( this.update.bind(this), this.frequency * 1000 );
	}
});

Effect.SmoothScroll = Class.create();
Object.extend( Object.extend( Effect.SmoothScroll.prototype, Effect.Base.prototype ), {
	initialize: function (element) {
		this.element = $(element);
		var options = Object.extend({
			x:    0,
			y:    0,
			mode: 'absolute'
		} , arguments[1] || {}  );
		this.start(options);
	},
	
	setup: function () {
		if ( this.options.continuous && !this.element._ext ) {
			this.element.cleanWhitespace();
			this.element._ext = true;
			this.element.appendChild( this.element.firstChild );
		}
		this.originalLeft = this.element.scrollLeft;
		this.originalTop = this.element.scrollTop;
		if ( this.options.mode == 'absolute' ) {
			this.options.x -= this.originalLeft;
			this.options.y -= this.originalTop;
		}
	},
	
	update: function (position) {
		this.element.scrollLeft = this.options.x * position + this.originalLeft;
		this.element.scrollTop  = this.options.y * position + this.originalTop;
	}
});

document.observe('dom:loaded', function () { new nk_init_multi_gliders(); });
