/**
 * jquery.scrollable 0.13. Put your HTML scroll.
 * 
 * http://flowplayer.org/tools/scrollable.html
 *
 * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
 *
 * Released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 * >> Basically you can do anything you want but leave this header as is <<
 *
 * Since  : 0.10 - 03/01/2008
 * Version: 0.13 - Wed Nov 05 2008 12:04:04 GMT-0000 (GMT+00:00)
 */
(function ($) {

	// constructor
	function Scrollable(el, config) {

		// current instance
		var self = this;

		if (!Scrollable.current) {
			Scrollable.current = this;
		}

		var opts = {
			size: 5,
			vertical: false,
			activeClass: 'active',
			speed: 300,
			onSeek: null,
			clickable: true,

			inactiveClassNext: 'inactive_next',
			inactiveClassPrev: 'inactive_prev',

			// jquery selectors
			items: '.items',
			prev: '.prev',
			next: '.next',
			navi: '.navi',
			naviItem: 'span',
			loop: false
		};

		this.opts = $.extend(opts, config);
		this.opts.horizontal = !opts.vertical;

		// root / itemRoot
		this.root = $(el);
		var root = this.root;
		var itemRoot = $(opts.items, root);
		if (!itemRoot.length) {
			itemRoot = root;
		}

		// wrap itemRoot.children() inside container
		itemRoot.css({
			position: 'relative',
			overflow: 'hidden',
			visibility: 'visible'
		});
		itemRoot.children().wrapAll('<div class="__scrollable" style="position:absolute"/>');

		this.wrap = itemRoot.find(":first");
		this.wrap.css(opts.horizontal ? "width" : "height", "200000em").after('<br clear="all" />');
		this.items = this.wrap.children(':visible');
		this.index = 0;

		// set dimensions based on offsets of the two first elements
		if (opts.horizontal) {
			/*
		  try {
			  itemRoot.width(opts.size * (this.items.eq(1).offset().left - this.items.eq(0).offset().left) -2);
		  } catch (e) {
		  
		  }	
	  */
		} else {
			itemRoot.height(opts.size * (this.items.eq(1).offset().top - this.items.eq(0).offset().top) - 2);
		}

		// mousewheel
		if ($.isFunction($.fn.mousewheel)) {
			root.bind("mousewheel.scrollable", function (e, delta) {
				self.move(-delta, 50);
				return false;
			});
		}

		// item.click()
		if (opts.clickable) {
			this.items.each(function (index, arg) {
				$(this).bind("click.scrollable", function () {
					self.click(index);
				});
			});
		}

		self.getStatus();

		this.activeIndex = 0;

		// prev
		$(opts.prev, root).click(function () {
			self.prev();
		});
		$('#prev').click(function (event) {
			if (window.hbv && hbv.Gallery && hbv.Gallery.atEnd()) {
				self.end();
			} else {
				self.prev();
			}
			return false;
		});

		// next
		$(opts.next, root).click(function () {
			self.next();
		});

		$('#next').click(function (event) {
			if (window.hbv && hbv.Gallery && hbv.Gallery.atBegin()) {
				self.begin();
			} else {
				self.next();
			}
			return false;
		});

		// navi 			
		$(opts.navi, root).each(function () {
			var navi = $(this);

			var status = self.getStatus();

			// generate new entries
			if (navi.is(":empty")) {
				for (var i = 0; i < status.pages; i++) {

					var item = $("<" + opts.naviItem + "/>").attr("page", i).click(function (e) {
						var el = $(this);
						el.parent().children().removeClass(opts.activeClass);
						el.addClass(opts.activeClass);
						self.setPage(el.attr("page"));
						e.preventDefault();
					});

					if (i === 0) {
						item.addClass(opts.activeClass);
					}
					navi.append(item);
				}

				// assign onClick events to existing entries
			} else {

				// find a entries first -> syntaxically correct
				var els = navi.find("a");

				if (!els.length) {
					els = navi.children();
				}

				els.each(function (i) {
					var item = $(this);
					item.attr("page", i);
					if (i === 0) {
						item.addClass(opts.activeClass);
					}

					item.click(function () {
						navi.find("." + opts.activeClass).removeClass(opts.activeClass);
						item.addClass(opts.activeClass);
						self.setPage(item.attr("page"));
					});

				});
			}

		});
	}

	// methods
	$.extend(Scrollable.prototype, {

		getVersion: function () {
			return '@VERSION';
		},

		click: function (index) {

			var item = this.items.eq(index),
			klass = this.opts.activeClass;

			//Bilderkarussel in der Bildergalerie 
			if (document.getElementById('bauer_lecker_bildergalerie_bildansicht') && window.hbv && hbv.Gallery) {
				hbv.Gallery.setCurrent(index);
			}

			if (!item.hasClass(klass) && (index >= 0 || index < this.items.size())) {
				this.items.removeClass(klass);
				item.addClass(klass);
				var delta = Math.floor(this.opts.size / 2);
				var to = index - delta;

				if (to !== this.activeIndex) {
					this.seekTo(to);
				}
			}
		},

		//UPDATE 28.05.2009
		setElements: function () {
			var len_old = this.items.length;
			this.items = this.wrap.children(':visible');
			if (len_old != this.items.length) {
				this.begin();
				var r = this.root;
				$(r).find('.prev').addClass(this.opts.inactiveClassPrev);
				return false;
			} else {
				return true;
			}
		},
		//UPDATE 28.05.2009
		getStatus: function () {
			var len = this.items.size();
			//UPDATE 03.04.2009
			var anz = this.items.length;
			var maxsize = this.opts.size;

			//Workaround f�r doppelte __scrollable
			if ($('#carousel_items').children('.__scrollable').children().length == 1) {
				if ($('#carousel_items').children('.__scrollable').children('.__scrollable').length > 0) {
					anz = $('#carousel_items').children('.__scrollable').children('.__scrollable').children().length;
				}
			}

			var r = this.root;

			if (anz <= maxsize) {
				$(r).find('.next').addClass(this.opts.inactiveClassNext);
			}
			//Workaround f�r doppelte __scrollable
			//UPDATE 03.04.2009
			return {
				size: this.opts.size,
				total: len,
				index: this.index,
				pages: Math.ceil(len / this.opts.size),
				page: Math.ceil(this.index / this.opts.size)
			};
		},

		// all other seeking functions depend on this generic seeking function		
		seekTo: function (index, time) {

			// UPDATED 20.02.2009
			if (index < 0) {
				index = 0;
			}
			//Fixed Bug, Zeigt nun alle Elemente bis zum Ende an 
			if (this.items.length / 2 != 0) {
				index = Math.floor(index);
			}

			var max = Math.min(index, this.items.length - this.opts.size);

			if (index <= max) {
				var item = this.items.eq(index);
				this.index = index;

				if (this.opts.horizontal) {
					var left = this.wrap.offset().left - item.offset().left;
					this.wrap.animate({
						left: left
					},
					time || this.opts.speed);

				} else {
					var top = this.wrap.offset().top - item.offset().top;
					this.wrap.animate({
						top: top
					},
					time || this.opts.speed);
				}

				Scrollable.current = this;
			}

			//UPDATE 03.04.2009 
			var anz = this.items.length;
			var maxsize = this.opts.size;
			var r = this.root;

			if (index >= (anz - maxsize) || (max <= 0)) {
				//Rechts am Ende angelangt, Pfeil-Klasse �ndern 
				$(r).find('.next').addClass(this.opts.inactiveClassNext);
			}
			if (anz != maxsize) {
				if ((index + maxsize) > maxsize) {
					if (anz > 0 && (anz > maxsize)) {
						$(r).find('.prev').removeClass(this.opts.inactiveClassPrev);
					}
				} else {
					$(r).find('.prev').addClass(this.opts.inactiveClassPrev);
					if (anz > 0 && (anz > maxsize)) {
						$(r).find('.next').removeClass(this.opts.inactiveClassNext);
					}
				}
			}
			//UPDATE 03.04.2009
			// UPDATED 20.02.2009
			// custom onSeek callback
			if ($.isFunction(this.opts.onSeek)) {
				this.opts.onSeek.call(this);
			}

			// navi status update
			var navi = $(this.opts.navi, this.root);

			if (navi.length) {
				var klass = this.opts.activeClass;
				var page = Math.ceil(index / this.opts.size);
				page = Math.min(page, navi.children().length - 1);
				navi.children().removeClass(klass).eq(page).addClass(klass);
			}

			this.activeIndex = index;
			return true;
		},

		move: function (offset, time) {
			var to = this.index + offset;
			if (this.opts.loop && to > (this.items.length - this.opts.size)) {
				to = 0;
			}
			this.seekTo(to, time);
		},

		next: function (time) {
			this.move(1, time);
		},

		prev: function (time) {
			if (this.setElements()) {
				this.move(-1, time);
			}
		},

		movePage: function (offset, time) {
			this.move(this.opts.size * offset, time);
		},

		setPage: function (page, time) {
			var size = this.opts.size;
			var index = size * page;
			var lastPage = index + size >= this.items.size();
			if (lastPage) {
				index = this.items.size() - this.opts.size;
			}
			this.seekTo(index, time);
		},

		prevPage: function (time) {
			this.setPage(this.getStatus().page - 1, time);
		},

		nextPage: function (time) {
			this.setPage(this.getStatus().page + 1, time);
		},

		begin: function (time) {
			this.seekTo(0, time);
		},

		end: function (time) {
			this.seekTo(this.items.size() - this.opts.size, time);
		}

	});

	// keyboard; 
	// disabled due to arrow key probs in FF (lennart)
	if (0) $(window).bind("keypress.scrollable", function (evt) {

		var el = Scrollable.current;
		if (!el) {
			return;
		}

		if (el.opts.horizontal && (evt.keyCode == 37 || evt.keyCode == 39)) {
			el.move(evt.keyCode == 37 ? -1 : 1);
			return evt.preventDefault();
		}

		if (!el.opts.horizontal && (evt.keyCode == 38 || evt.keyCode == 40)) {
			el.move(evt.keyCode == 38 ? -1 : 1);
			return evt.preventDefault();
		}

		return true;

	});

	// jQuery plugin implementation
	jQuery.prototype.scrollable = function (opts, arg0, arg1) {
		// return API associated with this instance
		if (!opts || typeof opts == 'number') {
			var index = opts || 0;
			var el = $.data(this.get()[index], "scrollable");
			if (el) {
				return el;
			}
		}

		this.each(function () {

			// @deprecated way of accessing API
			if (typeof opts == "string") {
				var el = $.data(this, "scrollable");
				el[opts].apply(el, [arg0, arg1]);

				// create new Scrollable instance
			} else {
				var instance = new Scrollable(this, opts);
				$.data(this, "scrollable", instance);
			}
		});

		return this;
	};

})(jQuery);
