
/* Codes below depends on jQuery */	
(function ($) {

	window.getWidth = function (obj) {
		var width = parseInt(obj.css('width')) || 0,
			padding_right = parseInt(obj.css('padding-right')) || 0,
			padding_left = parseInt(obj.css('padding-left')) || 0,
			border_right = parseInt(obj.css('border-right-width')) || 0,
			border_left = parseInt(obj.css('border-left-width')) || 0,
			margin_right = parseInt(obj.css('margin-right')) || 0,
			margin_left = parseInt(obj.css('margin-left')) || 0,
			total = width + padding_right + padding_left + margin_right + margin_left,
			outer_width = obj.outerWidth(true);
		return (total < outer_width) ? outer_width : total;
	};
	window.getHeight = function (obj) {
		var height = parseInt(obj.css('height')) || 0,
			padding_top = parseInt(obj.css('padding-top')) || 0,
			padding_bottom = parseInt(obj.css('padding-bottom')) || 0,
			border_top = parseInt(obj.css('border-top-width')) || 0,
			border_bottom = parseInt(obj.css('border-bottom-width')) || 0,
			margin_top = parseInt(obj.css('margin-top')) || 0,
			margin_bottom = parseInt(obj.css('margin-bottom')) || 0,
			total = height + padding_top + padding_bottom + margin_top + margin_bottom,
			outer_height = obj.outerHeight(true);
		return (total < outer_height) ? outer_height : total;
	};

	/* Carousel */
	$.fn.carousel = function (options) {
		var settings = $.extend({
				viewable: 1,
				viewport: 'div.viewport',
				list: 'ul.item-list',
				items: '> li.item',
				prevButton: 'a.prev',
				nextButton: 'a.next',
				selectedItem: 'on',
				index:0,
				speed: 500,
				autoSlide: false,
				direction: 1,
				mode: 'horizontal',	// 'horizontal' || 'vertical'
				delay: 2000
			}, options);
		return this.each(function () {
			if (this.initialized) {
				if (this.destroy) {
					this.destroy();
				}
			}
			var self = this,
				$self = $(self),
				viewport = $self.find(settings.viewport),
				list = viewport.find(settings.list),
				items = list.find(settings.items),
				pos,
				item_anchors,
				viewable,
				dir;
			if (!items.length) {
				return;
			}
			pos = ((settings.mode === 'horizontal') ? getWidth($(items[0])) : getHeight($(items[0]))) * settings.viewable;
			item_anchors = items.find('a');
			viewable = items.slice(settings.index, settings.index + settings.viewable);
			if (settings.mode === 'horizontal') {
				dir = (settings.direction > 0) ? 'left' : 'right';
			} else if (settings.mode === 'vertical') {
				dir = (settings.direction > 0) ? 'top' : 'bottom';
			}
			self.prevButton = $self.find(settings.prevButton);
			self.nextButton = $self.find(settings.nextButton);
			self.prev = function () {
				if (self.status === 'moving') {
					return;
				}
				list = viewport.find(settings.list);
				items = list.find(settings.items);
				viewable = items.slice(settings.index, settings.index + settings.viewable).addClass('viewable');
				var anim = {},
					prev_items = items.slice(items.length - settings.viewable),
					check = prev_items.filter('.viewable'),
					clones;
				if (check.length) {
					clones = check.clone();
					list.append(clones);
				}
				anim[dir] = 0;
				list.prepend(prev_items).css(dir, -pos);
				self.status = 'moving';
				list.animate(anim, settings.speed, function () {
					viewable.removeClass('viewable');
					if (clones && clones.length) {
						clones.remove();
					}
					self.status = 'stopped';
				});
			};
			self.next = function () {
				if (self.status === 'moving') {
					return;
				}
				var anim = {},
					next_items = items.slice(settings.viewable),
					diff = settings.viewable - next_items.length,
					clones;
				list = viewport.find(settings.list);
				items = list.find(settings.items);
				viewable = items.slice(settings.index, settings.index + settings.viewable).addClass('viewable');
				if (diff > 0) {
					clones = items.slice(0, diff).clone().addClass('dummy');
					list.append(clones);
				}
				anim[dir] = -pos;
				self.status = 'moving';
				list.animate(anim, settings.speed, function () {
					if (clones && clones.length) {
						clones.remove();
					}
					list.css(dir, 0).append(viewable);
					viewable.removeClass('viewable');
					self.status = 'stopped';
				});
			};
			self.autoSlide = function () {
				self.timer = window.setInterval(function () {
					if (settings.direction > 0) {
						self.next();
					} else {
						self.prev();
					}
				}, settings.delay);
			};
			self.stop = function () {
				window.clearInterval(self.timer);
				return null;
			};
			self.prevButton.bind('click.carousel', function (e) {
				e.preventDefault();
				if (items.length > settings.viewable) {
					self.prev();
				}
			});
			self.nextButton.bind('click.carousel', function (e) {
				e.preventDefault();
				if (items.length > settings.viewable) {
					self.next();
				}
			});
			if (settings.autoSlide) {
				self.autoSlide();
				$self
					.bind('mouseenter.carousel', function () {
						self.stop();
					})
					.bind('mouseleave.carousel', function () {
						self.autoSlide();
					});
			}
			self.destroy = function () {
				self.prevButton.unbind('click.carousel');
				self.nextButton.unbind('click.carousel');
				if (settings.autoSlide) {
					$self.unbind('.carousel');
				}
			};
			self.initialized = true;
		});
	};

// On DOM ready
}(jQuery));




