

(function($) {

function dynamItCarousel(o) {
	this.slider = null;
	this.prev = o.prev;
	this.next = o.next;

	this.width = o.width;
	this.offset = o.offset;
	this.inview = o.inview;
	this.position = o.position;
	this.index = o.index;
	this.disabled = o.disabled;

	this.slideshow = o.slideshow;
	this.slideshowtimeout = o.slideshowtimeout;
	this.sstimeout = null;
	this.wraparound = o.wraparound;

	this.indexnav = o.indexnav;
	this.onbefore = o.onbefore;
	this.onafter = o.onafter;
	this.oninit = o.oninit;
	
	this.useraction = '';

	// touch handling
	this.touchX = null;
	this.touchY = null;
	this.touchIsSwipe = null;
	this.touchSwipeDirection = null;

}


$.extend(dynamItCarousel.prototype, {

	init: function(o, inst) {
		inst.slider = o;

		$(inst.prev).click( function() {
			inst.slideCarousel(-1);
			inst.useraction = 'prev';
			return false;
		});

		$(inst.next).click( function() {
			inst.slideCarousel(1);
			inst.useraction = 'next';
			return false;
		});

		if(inst.indexnav) {
			$(inst.indexnav).children().click( function() {
				var i = $(inst.indexnav).children().index(this);
				inst.navCarousel(i);
				inst.useraction = 'indexnav_' + i;
				return false;
			});
		}

		if(inst.slideshow) {
			var tmp = inst;
			inst.sstimeout = setTimeout( function() {
				tmp.slideCarousel(1);
			}, inst.slideshowtimeout );
		}

		var left = parseInt( $(inst.slider).css('left') );
		if( left != 0 && inst.index * inst.width != left ) {
			inst.position = -1 * left;
			inst.index = -1 * parseInt( left / inst.width );
		}
		
		if( inst.wraparound ) {
			var last = $(inst.slider).children('li').length - 1;
			$(inst.slider).children('li').eq(0).clone().appendTo(inst.slider);
			$(inst.slider).children('li').eq(last).clone().prependTo(inst.slider);
			inst.index++;
			inst.doSetCarousel(inst.position + inst.width);
		}
		
		if( inst.oninit )
			inst.oninit( inst, inst.index );


		o.addEventListener('touchstart', function(event) { 
			event.preventDefault();
			if(event.targetTouches.length == 1) {
				inst.touchIsSwipe = true;
				inst.touchX = event.targetTouches[0].pageX;
				inst.touchY = event.targetTouches[0].pageY;
			} else if(event.targetTouches.length > 1) {
				inst.touchIsSwipe = false;
			}
		}, false);

		o.addEventListener('touchmove', function(event) { 
			event.preventDefault();
			if(inst.touchIsSwipe && event.targetTouches.length == 1) {
						event.preventDefault();
				var dx = event.targetTouches[0].pageX - inst.touchX;
				var dy = event.targetTouches[0].pageY - inst.touchY;

				if( Math.abs(dx) > 1.5*Math.abs(dy) ) {

					var dir = (dx > 0) ? 'right' : 'left';
					// verify same direction
					if( inst.touchSwipeDirection == null || inst.touchSwipeDirection == dir ) {
						inst.touchX = event.targetTouches[0].pageX;
						inst.touchY = event.targetTouches[0].pageY;
						inst.touchSwipeDirection = dir;
					} else {
						inst.touchIsSwipe = false;
					}
	
	
				} else {
					inst.touchIsSwipe = false;
				}

			} else if(event.targetTouches.length > 1) {
				inst.touchIsSwipe = false;
			}
		}, false);


		o.addEventListener('touchend', function(event) { 
			if(inst.touchIsSwipe) {
				if(inst.touchSwipeDirection == 'left') {
					// swipe left executed
					inst.slideCarousel(1);
					inst.useraction = 'next';
					return false;
				} else if(inst.touchSwipeDirection == 'right') {
					// swipe right executed
					inst.slideCarousel(-1);
					inst.useraction = 'prev';
					return false;
				}
			}

			inst.touchX = null;
			inst.touchY = null;
			inst.touchIsSwipe = null;
			inst.touchSwipeDirection = null;
		}, false);

	},

	slideCarousel: function(direction) {
		this.index += direction;

		clearTimeout(this.sstimeout);
		var max = this.maxIndex();
		if( this.index < 0 ) {
			this.index = 0;
			return;
		} else if( this.index == 0 && !this.wraparound ) {
			$(this.prev).addClass(this.disabled);
		} else {
			$(this.prev).removeClass(this.disabled);
		}

		if( this.index > max ) {
			this.index = max;
			return;
		} else if( this.index == max && !this.wraparound ) {
			$(this.next).addClass(this.disabled);
		} else {
			$(this.next).removeClass(this.disabled);
		}

		this.doSlideCarousel(this.position + (direction * this.width));
		if( this.slideshow ) {
			var tmp = this;
			this.sstimeout = setTimeout( function() {
				tmp.slideCarousel(1);
			}, this.slideshowtimeout );
		}
	},


	navCarousel: function(index) {
		if( this.wraparound ) index++;
		
		clearTimeout(this.sstimeout);
		var max = this.maxIndex();
		if( index >= 0 && index <= max ) {
			this.index = index;
			this.doSlideCarousel(this.index * this.width);

			$(this.prev).add(this.next).removeClass(this.disabled);
			if( this.index == 0 && !this.wraparound )
				$(this.prev).addClass(this.disabled);
			if( this.index == max && !this.wraparound )
				$(this.next).addClass(this.disabled);
		}
		if( this.slideshow ) {
			var tmp = this;
			this.sstimeout = setTimeout( function() {
				tmp.slideCarousel(1);
			}, this.slideshowtimeout );
		}
	},


	doSlideCarousel: function(val) {
		val = -1 * val;
		var tmp = this;
		if( tmp.onbefore ) {
			tmp.onbefore( tmp, tmp.index );
		}
		$(this.slider).stop().animate(
			{ left: val + 'px' },
			750,
			'swing',
			function() {
				if( tmp.wraparound ) {
					if( tmp.index == tmp.maxIndex() ) {
						tmp.index = 1;
						tmp.doSetCarousel(tmp.index * tmp.width);
					}
					if( tmp.index == 0 ) {
						tmp.index = tmp.maxIndex() - 1;
						tmp.doSetCarousel(tmp.index * tmp.width);
					}
				}
				if( tmp.onafter ) {
					tmp.onafter( tmp, tmp.index );
				}
			});
		this.position = -1 * val;

		this.updateIndexNav();
	},

	doSetCarousel: function(val) {
		val = -1 * val;
		var tmp = this;
		$(this.slider).stop().css( { left: val + 'px' } );
		this.position = -1 * val;

		this.updateIndexNav();
	},

	updateIndexNav: function() {
		if( this.indexnav ) {
			var active = this.index;
			if( this.wraparound ) active--;
			$(this.indexnav).children().removeClass('on');
			$(this.indexnav).children().eq(active).addClass('on');
		}
	},

	maxIndex: function() {
		var pagecount = $(this.slider).children('li').length / this.inview;
		if(  $(this.slider).children('li').length % this.inview > 0 ) pagecount++;
		var max = ( pagecount ) - 1;
		return max;
	}
	

});

$.fn.dynamItCarousel = function(options) {

	/* init options */
	if(!options) options = {};

	if(!options.offset)		options.offset = 0;
   	 if(!options.inview)         options.inview = 1;
	if(!options.position)		options.position = 0;
	if(!options.index)		options.index = 0;
	if(!options.disabled)		options.disabled = 'off';

	if(!options.slideshow)		options.slideshow = false;
	if(!options.slideshowtimeout)	options.slideshowtimeout = 4000;
	if(!options.wraparound)		options.wraparound = options.slideshow;

	if(!options.onbefore)		options.onbefore = null;
	if(!options.onafter)		options.onafter = null;
	if(!options.oninit)		options.oninit = null;
	if(!options.indexnav)		options.indexnav = null;

	return this.each(function() {

		var localoptions = options;

		if(!options.prev) 		localoptions.prev = this.children('a.prev').get(0);
		if(!options.next)		localoptions.next = this.children('a.next').get(0);
		if(!options.width)		localoptions.width = $(options.slider).children('li').eq(0).width();

		var inst = new dynamItCarousel(localoptions);
		$.dynamItCarousel.init(this, inst);
	});
};

$(document).ready(function() {
	$.dynamItCarousel = new dynamItCarousel({});
});


})(jQuery);
