/**
* Swipe Box v0.5
*/

var ie = (document.all && document.getElementById);

var swipeBox = {
	
	drag:		{
		delta:	null,
		mouse:	null,
		scroll:	null,
		time:	null,
		target:	null
	},
	boxes:		{},
	id:			null,
	
	select: function(id, index, duration)
	{
		// variables
		var	box		= this.boxes[id],
			$box	= box.box,
			$pages	= box.pages,
			mid, x;
		
		// assert
		if (typeof index == 'undefined' || index === null) {
			index = box.index;
		}
		if (index < 0) {
			index = 0;
		} else if (index > box.length - 1) {
			index = box.length - 1;
		}
		
		// calculate new position and duration
		x	= box.pageOffsets[index];
		mid	= $box.width() / 2;
		x	-= mid;
		x	+= $pages[index].offsetWidth / 2;
		
		if (!duration)
		{
			var delta		= this.drag.delta,
				delta_abs	= Math.abs(delta),
				distance	= Math.abs(x - $box[0].scrollLeft);
			duration = distance / delta_abs * (this.drag.time * 0.8);
			duration = (duration > 750 ? 750 : duration);
			if (delta == 0 || distance == 0 || duration == 0) {
				return;
			}
			
			if (delta_abs > box.pageWidth && delta_abs / box.pageWidth > 1.35)
			{
				var units = delta / box.pageWidth;
				index = box.index + (delta > 0 ? Math.ceil(units) : Math.floor(units));
				if (index < 0) {
					index = 0;
				} else if (index > box.length - 1) {
					index = box.length - 1;
				}
				x	= box.pageOffsets[index];
				mid	= $box.width() / 2;
				x	-= mid;
				x	+= $pages[index].offsetWidth / 2;
			}
		}
		
		// animate
		if (index != box.index) {
			jQuery($pages[box.index]).stop(true).animate({opacity: 0.2}, duration);
		}
		jQuery($pages[index]).stop(true).animate({opacity: 1}, duration);
		$box.stop(true).animate({scrollLeft: x}, duration);
		
		// set new values
		this.boxes[id].current	= $pages[index][0];
		this.boxes[id].index	= index;
		
		// return
		return index;
	},
	mouseDown: function(e)
	{
		var	e	= (ie ? event : e),
			o	= (ie ? e.srcElement : e.target),
			$o	= jQuery(o).closest('.swipe-box');
		
		swipeBox.id				= $o.attr('id');
		swipeBox.drag.mouse		= (ie ? e.clientX : e.pageX);
		swipeBox.drag.scroll	= $o[0].scrollLeft;
		swipeBox.drag.time		= (new Date).getTime();
		swipeBox.drag.target	= $o;
	},
	mouseMove: function(e)
	{
		var	e	= (ie ? event : e),
			$o	= swipeBox.drag.target,
			id	= (!$o ? null : $o.attr('id'));
		
		if (!$o) {
			return;
		}
		o = $o[0];
		if (id != swipeBox.id) {
			if (swipeBox.drag.time !== null) {
				return;
			}
			swipeBox.id = id;
		}
		if (swipeBox.drag.time === null) {
			return;
		}
		o.scrollLeft = swipeBox.drag.scroll - ((ie ? e.clientX : e.pageX) - swipeBox.drag.mouse);
	},
	mouseUp: function(e)
	{
		if (typeof swipeBox.drag.target == 'undefined' || swipeBox.drag.time === null) {
			return;
		}
		
		var	e		= (ie ? event : e),
			$o		= swipeBox.drag.target,
			id		= $o.attr('id'),
			box		= swipeBox.boxes[id];
		
		swipeBox.drag.delta	= swipeBox.drag.mouse - (ie ? e.clientX : e.pageX);
		swipeBox.drag.time	= (new Date).getTime() - swipeBox.drag.time;
		swipeBox.select(id, box.index + (swipeBox.drag.delta > 0 ? 1 : -1));
		
		swipeBox.drag.mouse		= null;
		swipeBox.drag.scroll	= null;
		swipeBox.drag.time		= null;
		swipeBox.drag.target	= null;
	},
	updateMetrics: function(id)
	{
		for (var i in this.boxes)
		{
			if (typeof id != 'undefined' && id != i) {
				continue;
			}
			var o = document.getElementById(i), w = 0;
			this.boxes[i].pages.each(function(){
				w += this.offsetWidth - 0;
			});
			w += 100 * this.boxes[i].length;
			this.boxes[i].pageWidth = w / this.boxes[i].length;
			this.boxes[i].block.css({
				width:	w * 2,
				margin:	'0 ' + Math.floor(o.offsetWidth) + 'px'
			});
			this.boxes[i].pageOffsets = [];
			this.boxes[i].pages.each(function(){
				var x = this.offsetLeft - o.offsetLeft;
				swipeBox.boxes[i].pageOffsets.push(x);
			});
		}
	},
	
	//////////////////////////////////////////////////
	
	init: function(obj)
	{
		for (var i = 0; i < obj.length; i++)
		{
			var box = {}, id, o = obj[i];
			if (!o.id) {
				o.id = 'sb' + Math.round(Math.random() * 999999);
			}
			id = this.id = o.id;
			this.boxes[id]				= {};
			this.boxes[id].box			= jQuery('#' + id);						// ".swipe-box"
			this.boxes[id].block		= jQuery('>*', this.boxes[id].box);		// ".swipe-block"
			this.boxes[id].pages		= jQuery('>*', this.boxes[id].block);	// array of ".swipe-page"
			this.boxes[id].current		= this.boxes[id].pages[0];				// current page element
			this.boxes[id].id			= id;									// id of box object
			this.boxes[id].index		= 0;									// index of current page element from 0
			this.boxes[id].length		= this.boxes[id].pages.length;			// number of ".swipe-page" elements
			this.boxes[id].pageOffsets	= [];									// array of ".swipe-page" element positions
			this.boxes[id].pageWidth	= 0;									// average width of page elements
			
			this.updateMetrics(id);
			o.scrollLeft = 0;
			this.select(id, 0, 500);
			
			jQuery(o).mousedown(this.mouseDown);
			jQuery(window).resize(function(){
				swipeBox.updateMetrics(id);
				swipeBox.select(id, null, 300);
			});
		}
	}
};
jQuery.fn.swipeBox = function(){
	return swipeBox.init(this);
};
jQuery(function(){
	$(ie ? document.body : window).mousemove(swipeBox.mouseMove);
	$(ie ? document.body : window).mouseup(swipeBox.mouseUp);
});

