/**
 * Copyright (c) 2010 Sylvain Gougouzian (sylvain@gougouzian.fr)
 * MIT (http://www.opensource.org/licenses/mit-license.php) licensed.
 * GNU GPL (http://www.gnu.org/licenses/gpl.html) licensed.
 *
 * jQuery moodular version: 2.3
 *
 * Requires: jQuery 1.3.2+ 	// http://www.jquery.com
 * Compatible : Internet Explorer 6+, Firefox 1.5+, Safari 3+, Opera 9+, Chrome 0.9+
 */
jQuery(function($){
	$.fn.moodular = function(options){
		var el = null;
		var opts = $.extend({}, $.fn.moodular.defaults, options);
		var ctrls = $.extend({}, $.fn.moodular.controls);
		var effects = $.extend({}, $.fn.moodular.effects);
		this.each(function(){
			el = new $moodular(this, opts, ctrls, effects);
			$(window).bind('resize', function () { el._resize(); });
		});
		return opts.api ? el : null;
	};
	$.moodular = function(e, opts, ctrls, effects){
		this.e = $(e);
		if (opts.random) {
			var elems = this.e.children($('> ' + opts.item));
			elems.sort(function() { return (Math.round(Math.random())-0.5); });
			this.e.remove($('> ' + opts.item));
			for(var i=0; i < elems.length; i++)
				this.e.append(elems[i]);
		}
		if (opts.continuous) $(e).html($(e).html() + $(e).html());
		this.aItems = null;
		this.nbItems = 0;
		this.current = 0;
		this.locked = false;
		this.dep = 0;
		this.timerMoving = null;
		this.opts = opts;
		this.controls = ctrls;
		this.effects = effects;
		this.direction = ((opts.direction == 'left') || (opts.direction == 'top') ? 'next' : 'prev');
		this.pos = ((opts.direction == 'left') || (opts.direction == 'right') ? 'left' : 'top');
		this.dir = ((opts.direction == 'right') || (opts.direction == 'bottom') ? -1 : 1);
		this.vertical = (this.pos == 'left' ? false : true);
		this._init();
	};
	var $moodular = $.moodular;
	$moodular.fn = $moodular.prototype = {
		moodular: '2.3'
	};
	$moodular.fn.extend = $moodular.extend = $.extend;
	$moodular.fn.extend({
		_init: function(){
			var self = this;
			this._resize();
			this.e.wrap('<div></div>');
			this.e.parent().css({
				'position' : 'relative',
				'overflow' : 'hidden',
				'width'	: this.e.width(),
				'height' : this.e.height()
			});
			this.e.css({
				'position' : 'absolute'
			});
			s = 0;
			$('> ' + this.opts.item, this.e).each(function() {
				if (this.vertical) {
					s += parseInt($(this).outerHeight(true));
				}
				else {
					s += parseInt($(this).outerWidth(true));
				}
			});
			this.e.css(this.vertical ? 'height' : 'width', s + 'px');
			this.aItems = $('> ' + this.opts.item, this.e);
			this.nbItems = this.aItems.length;
			if (!this.opts.continuous) this.nbItems = this.nbItems * 2;
			var control = this.opts.controls.split(' ');
			var i;
			for (i = 0; i < control.length; i++) {
				if ($.isFunction(this.controls[control[i]]))
					this.controls[control[i]](this);
			}
			var effect = this.opts.effects.split(' ');
			for (i = 0; i < effect.length; i++) {
				if ($.isFunction(this.effects.init[effect[i]]))
					this.effects.init[effect[i]](this);
			}
			if (this.opts.startOn) {
				this.speed = this.opts.speed;
				this.opts.speed = 1;
				this.moveTo(this.opts.startOn);
			}
			if (this.opts.auto) {
				setTimeout(function(){
					self._animate('next');
				}, self.opts.dispTimeout);
			}
		},
		_animate: function(dir, immediate){
			dir = (dir == undefined ? this.direction : dir);
			if (!this.locked) {
				this.locked = true;
				clearTimeout(this.timerMoving);
				this.dep = this.dep == 0 ? this.opts.scroll : this.dep;
				if (this.dir == -1) {
					if (dir == "next") {
						dir = "prev";
					}
					else if (dir == "prev") {
						dir = "next";
					}
				}
				if (dir != 'next') {
					this.dep *= -1;
				}
				var cont = true;
				if (!this.opts.continuous) {
					if (dir == 'next') {
						if (this.current >= ((this.nbItems / 2) - 1)) {
							cont = false;
							this.locked = false;
						}
					}
					else {
						if (this.current <= 0) {
							cont = false;
							this.locked = false;
						}
					}
				}
				if (cont) {
					this._beforeMoving(immediate);
				}
			}
		},
		_beforeMoving: function(immediate){
			var effect = this.opts.effects.split(' ');
			var i;
			for (i = 0; i < effect.length; i++) {
				if ($.isFunction(this.effects.before[effect[i]]))
					this.effects.before[effect[i]](this, (this.dep < 0 ? -1 : 1));
			}
			if (this.dep < 0 && this.opts.continuous) {
				var size = 0;
				for (i = 0; i < Math.abs(this.dep); i++) {
					var item = $('> ' + this.opts.item + ':last', this.e);
					size += parseInt(item.css(this.vertical ? 'height' : 'width'));
					$('> ' + this.opts.item + ':last', this.e).remove();
					this.e.prepend(item);
				}
				this.e.css(this.pos, -size);
			}
            
			this._move(immediate);
		},
		_move: function(immediate){
			var self = this;
			if ($.isFunction(this.opts.move)) {
				this.opts.move(this, function(){
					self._afterMoving();
				}, immediate);
			}
			else {
				var size = 0;
				var i;
				if (this.dep > 0) {
					for (i = 0; i < this.dep; i++) {
						if (this.vertical) {
							size += parseInt(this.aItems.eq(this._realpos(this.current) + i).outerHeight(true));
						}
						else {
							size += parseInt(this.aItems.eq(this._realpos(this.current) + i).outerWidth(true));
						}
					}
				}
				else {
					if (!this.opts.continuous && this.current <=0) {}
					else {
						for (i = 0; i < Math.abs(this.dep); i++) {
							if (this.vertical) {
								size += parseInt(this.aItems.eq(this._realpos(this.current) - i).outerHeight(true));
							}
							else {
								size += parseInt(this.aItems.eq(this._realpos(this.current) - i).outerWidth(true));
							}
						}
					}
				}
				if (this.e.css(this.pos) == 'auto') this.e.css(this.pos, 0);
				var dest = parseInt(this.e.css(this.pos)) + (this.dep > 0 ? -1 : 1) * size;
				if (!this.opts.continuous) {
					if (dest > 0) dest = 0;
					if (this.vertical) {
						if ((parseInt(this.e.height()) + dest) < parseInt(this.e.parent().height())) {
							dest = parseInt(this.e.parent().height()) - parseInt(this.e.height());
						}
					}
					else {
						if ((parseInt(this.e.width()) + dest) < parseInt(this.e.parent().width())) {
							dest = parseInt(this.e.parent().width()) - parseInt(this.e.width()) ;
						}
					}
				}
				if (this.vertical) {
					this.e.stop(true, true).animate({
						top: parseInt(dest) + 'px'
					}, this.opts.speed, this.opts.easing, function(){
						self._afterMoving();
					});
				}
				else {
					this.e.stop(true, true).animate({
						left: parseInt(dest) + 'px'
					}, this.opts.speed, this.opts.easing, function(){
						self._afterMoving();
					});
				}
			}
//            for (i = 0; i < this.opts.callbacks.length; i++) {
//				this.opts.callbacks[i](this);
//			}
		},
		_afterMoving: function(){
			var i;
			if (this.dep > 0 && this.opts.continuous) {
				for (i = 0; i < this.dep; i++) {
					var item = $('> ' + this.opts.item + ':first', this.e);
					$('> ' + this.opts.item + ':first', this.e).remove();
					this.e.append(item);
				}
				this.e.css(this.pos, 0);
			}
			var self = this;
			this.current = this.current + this.dep;
			if (this.current == -1) {
				if (this.opts.continuous)
					this.current = this.nbItems - 1;
				else
					this.current = 0;
			}
			else {
				if (this.current == this.nbItems) {
					this.current = 0;
				}
				else {
					this.current = this._realpos(this.current);
				}
			}
			this.dep = 0;
			this.locked = false;
			var effect = this.opts.effects.split(' ');
			for (i = 0; i < effect.length; i++) {
				if ($.isFunction(this.effects.after[effect[i]]))
					this.effects.after[effect[i]](this);
			}
			
			var control = this.opts.controls.split(' ');
			for (i = 0; i < control.length; i++) {
				if ($.isFunction(this.controls.callback[control[i]]))
					this.controls.callback[control[i]](this);
			}
			if (this.opts.startOn) {
				this.opts.speed = this.speed;
			}
			if (this.opts.auto) {
				this.timerMoving = setTimeout(function(){
					self._animate('next');
				}, this.opts.dispTimeout);
			}
		},
		_realpos: function(i){
			if (i < 0) i = (this.nbItems / 2) - i;
			return (i < (this.nbItems / 2) ? i : (i - (this.nbItems / 2)));
		},
		_resize: function () {
			var s = $('> ' + this.opts.item, this.e).css(this.vertical ? 'height' : 'width');
			$('> ' + this.opts.item, this.e).each(function() {
				if (this.vertical) {
					$(this).height($(this).height());
				}
				else {
					$(this).width($(this).width());
				}
			});
		},
		reanimate: function() {
			if (!this.opts.auto) {
				this.locked = false;
				this.opts.auto = true;
				var self = this;
				this.timerMoving = setTimeout(function(){
					self._animate('next');
				}, this.opts.dispTimeout);
			}
		},
		start: function(){
			if (!this.opts.auto) {
				this.locked = false;
				this.opts.auto = true;
				this._animate('next');
			}
			return false;
		},
		stop: function(){
			clearTimeout(this.timerMoving);
			this.opts.auto = false;
			return false;
		},
		next: function(){
			this._animate('next');
			return false;
		},
		prev: function(){
			this._animate('prev');
			return false;
		},
		getCurrent: function(){
			return this._realpos(this.current);
		},
		moveTo: function(i, immediate){
			if (i > (this.nbItems / 2)) {
				i = (this.nbItems / 2) - 1;
			}
			this.dep = parseInt(i) - parseInt(this.current);
			if (this.dep != 0) {
				this._animate('next', immediate);
			}
			return false;
		}
	});
	$.fn.moodular.defaults = {
		item: 'li',
		controls: '',
		effects: '',
		easing: '',
		auto: true,
		continuous: true,
		speed: 2000,
		direction: 'left',
		scroll: 1,
		startOn: 0,
		dispTimeout: 1000,
		callbacks: [],
		random: false,
		api: false
	};
	$.fn.moodular.controls = {
		callback: {}
	};
	$.fn.moodular.effects = {
		init: {},
		before: {},
		after: {}
	};
});

/**
 * Copyright (c) 2010 Sylvain Gougouzian (sylvain@gougouzian.fr)
 * MIT (http://www.opensource.org/licenses/mit-license.php) licensed.
 * GNU GPL (http://www.gnu.org/licenses/gpl.html) licensed.
 *
 * jQuery moodular controls by Sylvain Gougouzian http://sylvain.gougouzian.fr
 *
 * Requires: jQuery 1.3.2+ 	// http://www.jquery.com
 * 			jQuery moodular plugin
 *	 		jQuery Mouse Wheel Plugin v3.0.2 // Copyright (c) 2009 [Brandon Aaron] (http://brandonaaron.net)
 *			jQuery UI 1.7.2
 *
 * Compatible : Internet Explorer 6+, Firefox 1.5+, Safari 3+, Opera 9+, Chrome 0.9+
 */
jQuery(function($){
	$.extend($.fn.moodular.controls, {
		keys: function(moodular){
			$(document).keydown(function(event){
				if ((event.keyCode == 39) || (event.keyCode == 40)) {
					moodular._animate('next');
				}
				if ((event.keyCode == 37) || (event.keyCode == 38)) {
					moodular._animate('prev');
				}
			});
			return false;
		},
		click: function(moodular){
			for (var i = 0; i < moodular.nbItems; i++) {
				$('> ' + moodular.opts.item, moodular.e).css('cursor', 'pointer').attr('rel', moodular._realpos(i)).click(function(){
					moodular.locked = false;
					moodular.moveTo($(this).attr('rel'));
					return false;
				});
			}
		},
		stopOver: function (moodular) {
			moodular.e.parent().bind("mouseenter", function(){
				moodular.stop();
			}).bind("mouseleave", function () {
				if (!moodular.locked) { 
					moodular.reanimate();
				} else { 
					moodular.locked = false;
				}
			});
		},
		index: function(moodular){
			moodular.e.parent().parent().append('<ul class="moodular_itemList"></ul>');
			var h = "";
			for (var i = 0; i < (moodular.nbItems / 2); i++) {
				h += '<li class="moodular_itemList_li" rel="' + i + '">' + (i + 1) + '</li>';
			}
			$('.moodular_itemList', moodular.e.parent().parent()).html(h);
			$('li.moodular_itemList_li', moodular.e.parent().parent()).css('cursor', 'pointer').click(function(){
				if(!moodular.locked) {
					moodular.moveTo($(this).attr('rel'));
				} else { 
					moodular.locked = false;
				}
				return false;
			});
			$('.moodular_itemList_li:first').addClass('active');
		},
		tabs: function(moodular){
			if (moodular.opts.tabs) {
				$('a', moodular.opts.tabs).bind('click', function () {
					moodular.moveTo($('> ' + moodular.opts.item, moodular.e).index($($(this).attr('href'))));
				});
				if (window.location.hash.length) {
					moodular.moveTo($('> ' + moodular.opts.item, moodular.e).index($(window.location.hash)));
				}
			}
		},
		wheel: function(moodular){
			moodular.e.parent().parent().bind("mousewheel", function(event, delta){
				var dir = delta > 0 ? 'Up' : 'Down';
				if (dir == 'Up') {
					moodular.next();
				}
				else {
					moodular.prev();
				}
				return false;
			});
		},
		mouseover: function(moodular){
			moodular.opts.callbacks[moodular.opts.callbacks.length] = function(moodular){
				if (moodular.isMouseOver) {
					moodular._animate(mouseDirection(moodular));
				}
			};
			moodular.e.parent().parent().bind("mousemove", function(evt){
				moodular.mouseX = evt.pageX;
				moodular.mouseY = evt.pageY;
			});
			moodular.e.parent().parent().bind("mouseenter", function(evt){
				moodular.isMouseOver = true;
				moodular.mouseX = evt.pageX;
				moodular.mouseY = evt.pageY;
				moodular._animate(mouseDirection(moodular));
				return false;
			});
			moodular.e.parent().parent().bind("mouseleave", function(){
				moodular.isMouseOver = false;
				return false;
			});
		},
		touch: function(moodular){
			moodular.touchBPosX = null;
			moodular.touchBPosY = null;
			moodular.touchEPosX = null;
			moodular.touchEPosY = null;
			moodular.e.parent().bind('touchstart', function (event) {
				var e = event.originalEvent;
				moodular.touchBPosX = e.targetTouches[0].pageX;
				moodular.touchBPosY = e.targetTouches[0].pageY;
			}).bind('touchmove', function (event) {
				event.preventDefault();
				var e = event.originalEvent;
				moodular.touchEPosX = e.targetTouches[0].pageX;
				moodular.touchEPosY = e.targetTouches[0].pageY;
			}).bind('touchend', function(e) {
				if (moodular.vertical) {
					if (moodular.opts.direction == 'top') {
						if (moodular.touchEPosY < moodular.touchBPosY)
							moodular.next();
						else
							moodular.prev();
					}
					else {
						if (moodular.touchEPosY > moodular.touchBPosY)
							moodular.next();
						else
							moodular.prev();
					}
				}
				else {
					if (moodular.opts.direction == 'left') {
						if (moodular.touchEPosX < moodular.touchBPosX)
							moodular.next();
						else
							moodular.prev();
					}
					else {
						if (moodular.touchEPosX > moodular.touchBPosX)
							moodular.next();
						else
							moodular.prev();
					}
				}
				moodular.touchBPosX = null;
				moodular.touchBPosY = null;
				moodular.touchEPosX = null;
				moodular.touchEPosY = null;
				return false;
			});
		},
		slider: function (moodular) {
			moodular.e.parent().parent().append('<div id="' + moodular.id + '_slider"></div>');
			$("#" + moodular.id + "_slider", moodular.e.parent().parent()).slider({
				range: "max",
				min: 0,
				max: ((moodular.nbItems) / 2) - 1,
				value: 0,
				stop: function(event, ui) {
					moodular.moveTo(ui.value);
				}
			});
		}
	});

	$.extend($.fn.moodular.controls.callback, {
		index: function (moodular) {
			$('.moodular_itemList li.active').removeClass('active');
			$('.moodular_itemList li').eq(moodular._realpos(moodular.current)).addClass('active');
		},
		slider: function (moodular) {
			$("#" + moodular.id + "_slider", moodular.e.parent().parent()).slider('value', moodular.current);
		}
	});

	function mouseDirection(moodular){
		var offset = moodular.e.parent().parent().offset();
		if (moodular.vertical) {
			if ((moodular.mouseY >= parseInt(offset.top)) && (moodular.mouseY <= parseInt((parseInt(offset.top) + parseInt(moodular.e.parent().parent().height())) / 2))) {
				return 'prev';
			}
			else {
				return 'next';
			}
		}	
		else {
			if ((moodular.mouseX >= parseInt(offset.left)) && (moodular.mouseX <= parseInt((parseInt(offset.left) + parseInt(moodular.e.parent().parent().width())) / 2))) {
				return 'prev';
			}
			else {
				return 'next';
			}
		}
	}
});

/**
 * Copyright (c) 2009 Sylvain Gougouzian (sylvain@gougouzian.fr)
 * MIT (http://www.opensource.org/licenses/mit-license.php) licensed.
 * GNU GPL (http://www.gnu.org/licenses/gpl.html) licensed.
 *
 * jQuery moodular effects by Sylvain Gougouzian http://sylvain.gougouzian.fr
 *
 * Requires: jQuery 1.3.2+ 	// http://www.jquery.com
 *			jQuery corner plugin 2.01 // http://jquery.malsup.com/corner/
 *
 * Compatible : Internet Explorer 6+, Firefox 1.5+, Safari 3+, Opera 9+, Chrome 0.9+
 */

jQuery(function($) {
	$.extend($.fn.moodular.effects.init,{
		corner: function (moodular) {
			$.fn.corner.defaults.useNative = false;
			$('> ' + moodular.opts.item, moodular.e).corner("10px");
		},
		reflection: function (moodular) {
			moodular.e.parent().height(parseInt(moodular.e.parent().height()) * 1.33);
			$(moodular.opts.item + ' > img', moodular.e).load(function () {
				reflect(this);
				$(this).parent().height(parseInt($(this).parent().height()) * 1.33);
			});
		},
		fade: function (moodular) {
			$('> ' + moodular.opts.item, moodular.e).each(function(i){
				if (i > (moodular.nbItems / 2)) {
					$(this).remove();
				}
			});
			moodular.opts.scroll = 1;
			moodular.opts.move = function (c, b, immediate) {
				c.e.css({
					top: 0,
					left: 0
				});
                if(immediate){
                    $('.position_' + c.current, c.e).fadeOut(c.opts.speed); 
					$('.position_' + c._realpos(c.current + c.dep), c.e).fadeIn(c.opts.speed, function () { b(); }); 
                }
                else{
                    setTimeout(function () { 
                        clearTimeout(c.timerMoving);
                        for (i = 0; i < moodular.opts.callbacks.length; i++) {
                            moodular.opts.callbacks[i](moodular);
                        }
                        $('.position_' + c.current, c.e).fadeOut(c.opts.speed); 
                        $('.position_' + c._realpos(c.current + c.dep), c.e).fadeIn(c.opts.speed, function () { b(); }); 
                    }, c.opts.dispTimeout);
                }
			};
			$('> ' + moodular.opts.item, moodular.e).each(function (i){
				$(this).css('position', 'absolute').addClass('position_' + i);
			});
			$('> ' + moodular.opts.item, moodular.e).not(':first').hide();
		},
		zoom: function (moodular) {
			$('> ' + moodular.opts.item, moodular.e).each(function(i){
				if (i > (moodular.nbItems / 2)) {
					$(this).remove();
				}
			});
			moodular.opts.scroll = 1;
			moodular.opts.move = function (c, b) {
				c.e.css({
					top: 0,
					left: 0
				});
				setTimeout(function () { 
					clearTimeout(c.timerMoving);
					var $c = $('.position_' + c.current, c.e);
					$c.show();
					var w = $c.width();
					var wi = $('> img', $c).width();
					var h = $c.height();
					var hi = $('> img', $c).height();
					$c.hide();
					$c.fadeOut(c.opts.speed).animate({
						width: (2 * parseInt(w)) + 'px',
						height: (2 * parseInt(h)) + 'px',
						top: ( 0 - parseInt(h) / 2) + 'px',
						left: ( 0 - parseInt(w) / 2) + 'px'
					}, c.opts.speed, function () {
						$(this).css({
							top: 0,
							left: 0,
							width: w,
							height: h
						}).hide();
					}); 
					$('> img', $c).animate({
						width: (2 * parseInt(wi)) + 'px',
						height: (2 * parseInt(hi)) + 'px'
					}, c.opts.speed, function () {
						$(this).css({
							width: wi,
							height: hi
						});
					}); 
					$('.position_' + c._realpos(c.current + c.dep), c.e).fadeIn(c.opts.speed, function () { b(); }); 
				}, c.opts.dispTimeout);
			};
			$('> ' + moodular.opts.item, moodular.e).each(function (i){
				$(this).css('position', 'absolute').addClass('position_' + i);
			});
			$('> ' + moodular.opts.item, moodular.e).not(':first').hide();
		}
	});
	$.extend($.fn.moodular.effects.after,{
		fade: function (c) {
			c.e.css({
				top: 0,
				left: 0
			});
			$('> ' + c.opts.item, c.e).css({
				top: 0,
				left: 0
			}); 
		},
		zoom: function (c) {
			c.e.css({
				top: 0,
				left: 0
			});
			$('> ' + c.opts.item, c.e).css({
				top: 0,
				left: 0
			}); 
		}
	});
	$.extend($.fn.moodular.effects.before,{
		fade: function (c) {
			c.e.css({
				top: 0,
				left: 0
			});
			$('> ' + c.opts.item, c.e).css({
				top: 0,
				left: 0
			}); 
		},
		zoom: function (c) {
			c.e.css({
				top: 0,
				left: 0
			});
			$('> ' + c.opts.item, c.e).css({
				top: 0,
				left: 0
			}); 
		}
	});
	
	function reflect(img) {
		var $this = $(img);
		var w = parseInt($this.width());
		var h = parseInt($this.height());
		var r;
		if ($.browser.msie) {
			r = $("<img />").attr('src', $this.attr('src')).css({
				'width': w,
				'height': h,
				'margin-bottom': h - Math.floor(h * 0.33),
				'filter': "flipv progid:DXImageTransform.Microsoft.Alpha(opacity=50, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=33)"
			})[0];
		}
		else {
			r = $("<canvas />")[0];
			if (!r.getContext) { return; }
			var f = r.getContext("2d");
			try {
				$(r).attr({
					'width': w,
					'height': Math.floor(h * 0.33)
				});
				f.save();
				f.translate(0, h - 1);
				f.scale(1, -1);
				f.drawImage(img, 0, 0, w, h);
				f.restore();
				f.globalCompositeOperation="destination-out";
				var i = f.createLinearGradient(0, 0, 0, Math.floor(h * 0.33));
				i.addColorStop(0, "rgba(255, 255, 255, 0.5)");
				i.addColorStop(1, "rgba(255, 255, 255, 1.0)");
				f.fillStyle = i;
				f.rect(0, 0, w, Math.floor(h * 0.33));
				f.fill();
			}
			catch (e) {
				return;
			}
		}
		$(r).css('display', 'block');
		$this.parent().css({
			width: w,
			height: h + Math.floor(h * 0.33),
			overflow: "hidden"
		}).append($(r));
		return false;
	}
	function unreflect($this) {
		var html = $this.parent().html();
		$this.parent().parent().html(html);
		return false;
	}
});

/**
 * jQuery Roundabout - v1.1
 * http://fredhq.com/projects/roundabout/
 *
 * Moves list-items of enabled ordered and unordered lists long
 * a chosen path. Includes the default "lazySusan" path, that
 * moves items long a spinning turntable.
 *
 * Terms of Use // jQuery Roundabout
 * 
 * Open source under the BSD license
 *
 * Copyright (c) 2010, Fred LeBlanc
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above 
 *     copyright notice, this list of conditions and the following 
 *     disclaimer in the documentation and/or other materials provided 
 *     with the distribution.
 *   - Neither the name of the author nor the names of its contributors 
 *     may be used to endorse or promote products derived from this 
 *     software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 */

jQuery.extend({roundabout_shape:{def:'lazySusan',lazySusan:function(r,a,t){return{x:Math.sin(r+a),y:(Math.sin(r+3*Math.PI/2+a)/8)*t,z:(Math.cos(r+a)+1)/2,scale:(Math.sin(r+Math.PI/2+a)/2)+0.5}}}});jQuery.fn.roundabout=function(){var options=(typeof arguments[0]!='object')?{}:arguments[0];options={bearing:(typeof options.bearing=='undefined')?0.0:jQuery.roundabout_toFloat(options.bearing%360.0),tilt:(typeof options.tilt=='undefined')?0.0:jQuery.roundabout_toFloat(options.tilt),minZ:(typeof options.minZ=='undefined')?100:parseInt(options.minZ,10),maxZ:(typeof options.maxZ=='undefined')?400:parseInt(options.maxZ,10),minOpacity:(typeof options.minOpacity=='undefined')?0.40:jQuery.roundabout_toFloat(options.minOpacity),maxOpacity:(typeof options.maxOpacity=='undefined')?1.00:jQuery.roundabout_toFloat(options.maxOpacity),minScale:(typeof options.minScale=='undefined')?0.40:jQuery.roundabout_toFloat(options.minScale),maxScale:(typeof options.maxScale=='undefined')?1.00:jQuery.roundabout_toFloat(options.maxScale),duration:(typeof options.duration=='undefined')?600:parseInt(options.duration,10),btnNext:options.btnNext||null,btnPrev:options.btnPrev||null,easing:options.easing||'swing',clickToFocus:(options.clickToFocus!==false),focusBearing:(typeof options.focusBearing=='undefined')?0.0:jQuery.roundabout_toFloat(options.focusBearing%360.0),shape:options.shape||'lazySusan',debug:options.debug||false,childSelector:options.childSelector||'li',startingChild:(typeof options.startingChild=='undefined')?null:parseInt(options.startingChild,10),reflect:(typeof options.reflect=='undefined'||options.reflect===false)?false:true};this.each(function(i){var ref=jQuery(this);var period=jQuery.roundabout_toFloat(360.0/ref.children(options.childSelector).length);var startingBearing=(options.startingChild===null)?options.bearing:options.startingChild*period;ref.addClass('roundabout-holder').css('padding',0).css('position','relative').css('z-index',options.minZ);ref.data('roundabout',{'bearing':startingBearing,'tilt':options.tilt,'minZ':options.minZ,'maxZ':options.maxZ,'minOpacity':options.minOpacity,'maxOpacity':options.maxOpacity,'minScale':options.minScale,'maxScale':options.maxScale,'duration':options.duration,'easing':options.easing,'clickToFocus':options.clickToFocus,'focusBearing':options.focusBearing,'animating':0,'childInFocus':-1,'shape':options.shape,'period':period,'debug':options.debug,'childSelector':options.childSelector,'reflect':options.reflect});if(options.clickToFocus===true){ref.children(options.childSelector).each(function(i){jQuery(this).click(function(e){var degrees=(options.reflect===true)?360.0-(period*i):period*i;degrees=jQuery.roundabout_toFloat(degrees);if(!jQuery.roundabout_isInFocus(ref,degrees)){e.preventDefault();if(ref.data('roundabout').animating===0){ref.roundabout_animateAngleToFocus(degrees)}return false}})})}if(options.btnNext){jQuery(options.btnNext).bind('click.roundabout',function(e){e.preventDefault();if(ref.data('roundabout').animating===0){ref.roundabout_animateToNextChild()}return false})}if(options.btnPrev){jQuery(options.btnPrev).bind('click.roundabout',function(e){e.preventDefault();if(ref.data('roundabout').animating===0){ref.roundabout_animateToPreviousChild()}return false})}});this.roundabout_startChildren();if(typeof arguments[1]==='function'){var callback=arguments[1],ref=this;setTimeout(function(){callback(ref)},0)}return this};jQuery.fn.roundabout_startChildren=function(){this.each(function(i){var ref=jQuery(this);var data=ref.data('roundabout');var children=ref.children(data.childSelector);children.each(function(i){var degrees=(data.reflect===true)?360.0-(data.period*i):data.period*i;jQuery(this).addClass('roundabout-moveable-item').css('position','absolute');jQuery(this).data('roundabout',{'startWidth':jQuery(this).width(),'startHeight':jQuery(this).height(),'startFontSize':parseInt(jQuery(this).css('font-size'),10),'degrees':degrees})});ref.roundabout_updateChildPositions()});return this};jQuery.fn.roundabout_setTilt=function(newTilt){this.each(function(i){jQuery(this).data('roundabout').tilt=newTilt;jQuery(this).roundabout_updateChildPositions()});if(typeof arguments[1]==='function'){var callback=arguments[1],ref=this;setTimeout(function(){callback(ref)},0)}return this};jQuery.fn.roundabout_setBearing=function(newBearing){this.each(function(i){jQuery(this).data('roundabout').bearing=jQuery.roundabout_toFloat(newBearing%360,2);jQuery(this).roundabout_updateChildPositions()});if(typeof arguments[1]==='function'){var callback=arguments[1],ref=this;setTimeout(function(){callback(ref)},0)}return this};jQuery.fn.roundabout_adjustBearing=function(delta){delta=jQuery.roundabout_toFloat(delta);if(delta!==0){this.each(function(i){jQuery(this).data('roundabout').bearing=jQuery.roundabout_getBearing(jQuery(this))+delta;jQuery(this).roundabout_updateChildPositions()})}if(typeof arguments[1]==='function'){var callback=arguments[1],ref=this;setTimeout(function(){callback(ref)},0)}return this};jQuery.fn.roundabout_adjustTilt=function(delta){delta=jQuery.roundabout_toFloat(delta);if(delta!==0){this.each(function(i){jQuery(this).data('roundabout').tilt=jQuery.roundabout_toFloat(jQuery(this).roundabout_get('tilt')+delta);jQuery(this).roundabout_updateChildPositions()})}if(typeof arguments[1]==='function'){var callback=arguments[1],ref=this;setTimeout(function(){callback(ref)},0)}return this};jQuery.fn.roundabout_animateToBearing=function(bearing){bearing=jQuery.roundabout_toFloat(bearing);var currentTime=new Date();var duration=(typeof arguments[1]=='undefined')?null:arguments[1];var easingType=(typeof arguments[2]=='undefined')?null:arguments[2];var passedData=(typeof arguments[3]!=='object')?null:arguments[3];this.each(function(i){var ref=jQuery(this),data=ref.data('roundabout'),timer,easingFn,newBearing;var thisDuration=(duration===null)?data.duration:duration;var thisEasingType=(easingType!==null)?easingType:data.easing||'swing';if(passedData===null){passedData={timerStart:currentTime,start:jQuery.roundabout_getBearing(ref),totalTime:thisDuration}}timer=currentTime-passedData.timerStart;if(timer<thisDuration){data.animating=1;if(typeof jQuery.easing.def=='string'){easingFn=jQuery.easing[thisEasingType]||jQuery.easing[jQuery.easing.def];newBearing=easingFn(null,timer,passedData.start,bearing-passedData.start,passedData.totalTime)}else{newBearing=jQuery.easing[thisEasingType]((timer/passedData.totalTime),timer,passedData.start,bearing-passedData.start,passedData.totalTime)}ref.roundabout_setBearing(newBearing,function(){ref.roundabout_animateToBearing(bearing,thisDuration,thisEasingType,passedData)})}else{bearing=(bearing<0)?bearing+360:bearing%360;data.animating=0;ref.roundabout_setBearing(bearing)}});return this};jQuery.fn.roundabout_animateToDelta=function(delta){var duration=arguments[1],easing=arguments[2];this.each(function(i){delta=jQuery.roundabout_getBearing(jQuery(this))+jQuery.roundabout_toFloat(delta);jQuery(this).roundabout_animateToBearing(delta,duration,easing)});return this};jQuery.fn.roundabout_animateToChild=function(childPos){var duration=arguments[1],easing=arguments[2];this.each(function(i){var ref=jQuery(this),data=ref.data('roundabout');if(data.childInFocus!==childPos&&data.animating===0){var child=jQuery(ref.children(data.childSelector)[childPos]);ref.roundabout_animateAngleToFocus(child.data('roundabout').degrees,duration,easing)}});return this};jQuery.fn.roundabout_animateToNearbyChild=function(passedArgs,which){var duration=passedArgs[0],easing=passedArgs[1];this.each(function(i){var data=jQuery(this).data('roundabout');var bearing=jQuery.roundabout_toFloat(360.0-jQuery.roundabout_getBearing(jQuery(this)));var period=data.period,j=0,range;var reflect=data.reflect;var length=jQuery(this).children(data.childSelector).length;bearing=(reflect===true)?bearing%360.0:bearing;if(data.animating===0){if((reflect===false&&which==='next')||(reflect===true&&which!=='next')){bearing=(bearing===0)?360:bearing;while(true&&j<length){range={lower:jQuery.roundabout_toFloat(period*j),upper:jQuery.roundabout_toFloat(period*(j+1))};range.upper=(j==length-1)?360.0:range.upper;if(bearing<=range.upper&&bearing>range.lower){jQuery(this).roundabout_animateToDelta(bearing-range.lower,duration,easing);break}j++}}else{while(true){range={lower:jQuery.roundabout_toFloat(period*j),upper:jQuery.roundabout_toFloat(period*(j+1))};range.upper=(j==length-1)?360.0:range.upper;if(bearing>=range.lower&&bearing<range.upper){jQuery(this).roundabout_animateToDelta(bearing-range.upper,duration,easing);break}j++}}}});return this};jQuery.fn.roundabout_animateToNextChild=function(){return this.roundabout_animateToNearbyChild(arguments,'next')};jQuery.fn.roundabout_animateToPreviousChild=function(){return this.roundabout_animateToNearbyChild(arguments,'previous')};jQuery.fn.roundabout_animateAngleToFocus=function(target){var duration=arguments[1],easing=arguments[2];this.each(function(i){var delta=jQuery.roundabout_getBearing(jQuery(this))-target;delta=(Math.abs(360.0-delta)<Math.abs(0.0-delta))?360.0-delta:0.0-delta;delta=(delta>180)?-(360.0-delta):delta;if(delta!==0){jQuery(this).roundabout_animateToDelta(delta,duration,easing)}});return this};jQuery.fn.roundabout_updateChildPositions=function(){this.each(function(i){var ref=jQuery(this),data=ref.data('roundabout');var inFocus=-1;var info={bearing:jQuery.roundabout_getBearing(ref),tilt:data.tilt,stage:{width:Math.floor(ref.width()*0.9),height:Math.floor(ref.height()*0.9)},animating:data.animating,inFocus:data.childInFocus,focusBearingRad:jQuery.roundabout_degToRad(data.focusBearing),shape:jQuery.roundabout_shape[data.shape]||jQuery.roundabout_shape[jQuery.roundabout_shape.def]};info.midStage={width:info.stage.width/2,height:info.stage.height/2};info.nudge={width:info.midStage.width+info.stage.width*0.05,height:info.midStage.height+info.stage.height*0.05};info.zValues={min:data.minZ,max:data.maxZ,diff:data.maxZ-data.minZ};info.opacity={min:data.minOpacity,max:data.maxOpacity,diff:data.maxOpacity-data.minOpacity};info.scale={min:data.minScale,max:data.maxScale,diff:data.maxScale-data.minScale};ref.children(data.childSelector).each(function(i){if(jQuery.roundabout_updateChildPosition(jQuery(this),ref,info,i)&&info.animating===0){inFocus=i;jQuery(this).addClass('roundabout-in-focus')}else{jQuery(this).removeClass('roundabout-in-focus')}});if(inFocus!==info.inFocus){jQuery.roundabout_triggerEvent(ref,info.inFocus,'blur');if(inFocus!==-1){jQuery.roundabout_triggerEvent(ref,inFocus,'focus')}data.childInFocus=inFocus}});return this};jQuery.roundabout_getBearing=function(el){return jQuery.roundabout_toFloat(el.data('roundabout').bearing)%360};jQuery.roundabout_degToRad=function(degrees){return(degrees%360.0)*Math.PI/180.0};jQuery.roundabout_isInFocus=function(el,target){return(jQuery.roundabout_getBearing(el)%360===(target%360))};jQuery.roundabout_triggerEvent=function(el,child,eventType){return(child<0)?this:jQuery(el.children(el.data('roundabout').childSelector)[child]).trigger(eventType)};jQuery.roundabout_toFloat=function(number){number=Math.round(parseFloat(number)*1000)/1000;return parseFloat(number.toFixed(2))};jQuery.roundabout_updateChildPosition=function(child,container,info,childPos){var ref=jQuery(child),data=ref.data('roundabout'),out=[];var rad=jQuery.roundabout_degToRad((360.0-ref.data('roundabout').degrees)+info.bearing);while(rad<0){rad=rad+Math.PI*2}while(rad>Math.PI*2){rad=rad-Math.PI*2}var factors=info.shape(rad,info.focusBearingRad,info.tilt);factors.scale=(factors.scale>1)?1:factors.scale;factors.adjustedScale=(info.scale.min+(info.scale.diff*factors.scale)).toFixed(4);factors.width=(factors.adjustedScale*data.startWidth).toFixed(4);factors.height=(factors.adjustedScale*data.startHeight).toFixed(4);ref.css('left',((factors.x*info.midStage.width+info.nudge.width)-factors.width/2.0).toFixed(1)+'px').css('top',((factors.y*info.midStage.height+info.nudge.height)-factors.height/2.0).toFixed(1)+'px').css('width',factors.width+'px').css('height',factors.height+'px').css('opacity',(info.opacity.min+(info.opacity.diff*factors.scale)).toFixed(2)).css('z-index',Math.round(info.zValues.min+(info.zValues.diff*factors.z))).css('font-size',(factors.adjustedScale*data.startFontSize).toFixed(2)+'px').attr('current-scale',factors.adjustedScale);if(container.data('roundabout').debug===true){out.push('<div style="font-weight: normal; font-size: 10px; padding: 2px; width: '+ref.css('width')+'; background-color: #ffc;">');out.push('<strong style="font-size: 12px; white-space: nowrap;">Child '+childPos+'</strong><br />');out.push('<strong>left:</strong> '+ref.css('left')+'<br /><strong>top:</strong> '+ref.css('top')+'<br />');out.push('<strong>width:</strong> '+ref.css('width')+'<br /><strong>opacity:</strong> '+ref.css('opacity')+'<br />');out.push('<strong>z-index:</strong> '+ref.css('z-index')+'<br /><strong>font-size:</strong> '+ref.css('font-size')+'<br />');out.push('<strong>scale:</strong> '+ref.attr('current-scale'));out.push('</div>');ref.html(out.join(''))}return jQuery.roundabout_isInFocus(container,ref.data('roundabout').degrees)};


