/**
 * ngCarousel - jQuery Plugin
 * Copyright (c) 2007-2009 by Danilo Kühn
 * Version: 1.1
 * Require: jQuery 1.2 or above
 * MIT licenses: http://www.opensource.org/licenses/mit-license.php
 *
 * The Plugin will create a carousel out of an <ul>-Tag and handle different sized <li>'s
 *
 * JS:
 * $('.carousel .viewport').carousel({
 *		btnPrev: '.carousel .prev',
 *		btnNext: '.carousel .next',
 *		speed: 200
 *	 });
 *
 * HTML:
 * <div class="carousel">
 *  <a class="prev"> </a>
 *  <a class="next"> </a>
 *  <div class="viewport">
 *    <ul>
 *      <li></li>
 *      <li></li>
 *    </ul>
 *  </div>
 * </div>
 */

(function($) {
	$.fn.carousel = function (o) {
		o = $.extend({btnPrev: null, btnNext: null, start: 0, position: 0, step: 0, speed: 500}, o || {});
		o.position = Math.abs(o.position) * -1;

		return this.each(function() {
			var div = $(this), ul = $("ul", div), li = $("li", ul), itemLength = li.size(), li_act = $('li.act', ul);
			var ul_width = 0;
			var viewport_width = div.outerWidth({ margin: true })

			li.css({float: "left"});
		    ul.css({margin: "0", padding: "0", left: "0px", position: "relative", "list-style-type": "none", "z-index": "1"});
		    div.css({margin: "0", padding: "0", position: "relative", "z-index": "2", overflow: 'hidden'});

			//ul_width = sum width of all li elements
		    li.each(function() {
				ul_width += $(this).outerWidth({ margin: true });
			});
			ul.width(ul_width);

			if (ul_width > viewport_width) {
				if (o.step == 0) {
					o.step = Math.round(ul_width / itemLength);
				}

				if (o.position != 0) {
					move(o.position, false);
				}

				if (o.btnPrev) {
					$(o.btnPrev).bind('click', function() {
						var to = o.position + o.step;
						if ((to > o.start) || (to + o.step > o.start)) {
							to = o.start;
							toggleBtn(this, true);
						}
						move(to, true);
						toggleBtn(o.btnNext, false);
					});
				}

				if (o.btnNext) {
					$(o.btnNext).bind('click', function() {
						var to = Math.abs(o.position) + div.width();
						if ((to + o.step > ul_width) || (to + (2*o.step) > ul_width)) {
							to = o.position - Math.abs(to - ul_width)
							toggleBtn(this, true);
						} else {
							to = o.position - o.step;
						}

						move(to, true);
						toggleBtn(o.btnPrev, false);
					});
				}

				if (li_act) {
					var li_act_width = li_act.outerWidth({ margin: true });
					var li_act_left = li_act[0].offsetLeft;

					if (li_act_left + li_act_width >= viewport_width) {
						if (li_act_left + li_act_width < ul_width) {
							move(viewport_width - li_act_left - (li_act_width * 2));
						} else {
							move(viewport_width - li_act_left - li_act_width);
						}
					}
				}

				toggleBtn(o.btnPrev, (o.position == 0));
				toggleBtn(o.btnNext, (o.position == div.width() - ul_width));
			} else {
				if (o.btnPrev) {
					$(o.btnPrev).removeClass('prev').css({float: 'left'});
				}

				if (o.btnNext) {
					$(o.btnNext).removeClass('next').css({float: 'right'});
				}

				move(Math.round((viewport_width - ul_width) / 2));
			}

			function move(to, anim) {
				anim = anim || false;
				o.position = to;
				if (anim) {
					ul.animate({left: to+"px"}, o.speed);
				} else {
					ul.css({ left: to+"px" });
				}
			}

			function toggleBtn(obj, add) {
				if (obj) {
					if (add) {
						$(obj).addClass('hide_btn');
					} else {
						$(obj).removeClass('hide_btn');
					}
				}
			}
		});
	};
})(jQuery);
