/// <reference path="jquery-1.5.1.min.js" />
/// <reference path="SnT.Utils.js" />

(function ($) {
	$.fn.jCarouselLite = function (o) {
		o = $.extend({
			btnPrev: null,
			btnNext: null,
			btnAuto: null,
			autoSpeed: null,
			autoPlay: true,
			mouseWheel: false,
			hoverIntentDelay: null,
			speed: 200,
			fade: false,
			fadeOutTo: 0,
			fadeInTo: 0,
			fadeSpeedIn: 500,
			fadeSpeedOut: 250,
			fadeSelector: null,
			easing: null,
			vertical: false,
			circular: true,
			visible: 3,
			start: 0,
			scroll: 1,
			pager: null,
			pagerItemHtml: null,
			beforeStart: null,
			arterStart: null,
			afterEnd: null,
			lazyLoadFunction: null,
			preloader: null,
			preloadObserable: 'img.Obserable'
		}, o || {});

		return this.each(function () {

			this.Config = o;
			var me = this;
			$(me).data("carousel", this);

			var running = false, animCss = o.vertical ? "top" : "left", sizeCss = o.vertical ? "height" : "width";
			var div = $(this), ul = $("ul", div), tLi = $("li", ul), tl = tLi.size(), v = o.visible;

			if (tLi.length) {

				$(o.btnPrev).show();
				$(o.btnNext).show();
			}

			if (o.circular) {
				ul.prepend(tLi.slice(tl - v - 1 + 1).clone())
                  .append(tLi.slice(0, v).clone());
				o.start += v;
			}

			var li = $("li", ul), itemLength = li.size(), curr = o.start;
			div.css("visibility", "visible");

			li.css({ overflow: "hidden", float: o.vertical ? "none" : "left" });
			ul.css({ margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1" });
			div.css({ overflow: "hidden", position: "relative", "z-index": "2", left: "0px" });

			var liSize = o.vertical ? height(li) : width(li);
			var ulSize = liSize * itemLength;
			var divSize = liSize * v;

			ul.css(sizeCss, ulSize + "px").css(animCss, -(curr * liSize));
			div.css(sizeCss, divSize + "px");

			function fadeOutVisible(callback) {

				var args = me.GetVisibleItems();

				if (args && args.items) {

					if (o.fadeSelector) {

						args.items.find(o.fadeSelector).fadeTo(o.fadeSpeedOut, o.fadeOutTo, callback);
					}
					else {

						args.items.fadeTo(o.fadeSpeedOut, o.fadeOutTo, callback);
					}
				}
			};

			this.Previous = function () {

				var goTo = curr - o.scroll;

				if (!o.circular) {

					var diff = curr % o.scroll;
					if (diff > 0) {
						goTo = curr - diff;
					}
				}
				return go(goTo);
			};

			this.Next = function () {

				return go(curr + o.scroll);
			};

			this.GoToItem = function (itemId) {

				var index = getItemIndexByItemId(li, itemId);

				go(index);
			};

			this.intval = null;

			this.AutoPlayStop = function () {
				window.clearInterval(me.intval);
			}

			this.AutoPlayStart = function () {
				me.intval = setInterval(function () {
					go(curr + o.scroll);
				}, o.autoSpeed);
			}

			this.GetVisibleItems = function () {

				var visibleItems = vis();

				if (visibleItems) {

					return visibleItems;
				}
				return null;
			}

			if (o.btnPrev) {

				$(o.btnPrev).click(function () {

					if (o.fade) {

						fadeOutVisible(me.Previous);
					}
					else {

						me.Previous();
					}
				});
			}
			if (o.btnNext) {

				$(o.btnNext).click(function () {

					if (o.fade) {

						fadeOutVisible(me.Next);
					}
					else {

						return me.Next();
					}
				});
			}
			if (o.pager) {

				if ($(o.pager).find('ul').size() == 0) {
					var ulPager = $("<ul>");
					for (var i = 1; i < (tl / o.visible) + 1; i++) {

						ulPager.append("<li>" + (o.pagerItemHtml ? o.pagerItemHtml : i) + "</li>");
					}
					$(o.pager).append(ulPager);
				}
				$.each($(o.pager).find('li'), function (i) {

					var to = o.circular ? o.visible + (i * o.scroll) : i * o.scroll;

					$(this).data("to", to).click(function () {

						if (o.fade) {

							fadeOutVisible(function () {

								return go(to);
							});
						}
						else {

							return go(to);
						}
					});
				});
			}
			if (o.mouseWheel && div.mousewheel) {

				div.mousewheel(function (e, d) {
					return d > 0 ? go(curr - o.scroll) : go(curr + o.scroll);
				});
			}
			if (o.btnAuto) {

				$(o.btnAuto).data("isA", $(o.btnAuto).get(0).tagName == "A");
				if ($(o.btnAuto).data("isA") && $(o.btnAuto).attr("title") != "") {

					var title = $(o.btnAuto).attr("title").split("|");

					$(o.btnAuto).data("playStop", (title.length > 1 ? title : "play|stop".split("|")));
				}
				me.intval = o.autoPlay ? "" : 1;
				$(o.btnAuto).click(function (event) {

					event.preventDefault();

					$(this).removeClass("play").removeClass("stop");

					if (me.intval == "") {
						me.intval = window.setInterval(function () {
							me.Next();
						}, o.autoSpeed);
						$(this).addClass("stop");
						if ($(this).data("isA")) {

							var playStop = $(this).data("playStop");

							$(this).html(playStop[1]);

							if (playStop.length > 3)
								$(o.btnAuto).attr("title", playStop[3]);
							else if (playStop.length > 2)
								$(o.btnAuto).attr("title", playStop[2]);
							else
								$(o.btnAuto).removeAttr("title");
						}
					} else {
						window.clearInterval(me.intval);
						me.intval = "";
						$(this).addClass("play");
						if ($(this).data("isA")) {

							var playStop = $(this).data("playStop");

							$(this).html(playStop[0]);

							if (playStop.length > 2)
								$(o.btnAuto).attr("title", playStop[2]);
							else
								$(o.btnAuto).removeAttr("title");
						}
					}
				}).click();
			}
			else if (o.autoSpeed != null && o.autoPlay) {
				me.AutoPlayStart();
			}

			function vis() {
				var items = li.slice(curr).slice(0, v);
				var itemsId = new Array(items.length);

				$.each(items, function (i) {
					itemsId[i] = getId($(this));
				});

				var arg = new Object();
				arg.items = items;
				arg.itemsId = itemsId;

				return arg;
			};

			function go(to) {

				if (!running) {

					if (o.beforeStart) {
						setTimeout(function () { o.beforeStart.call(this, vis()); }, 1);						
					}

					if (o.preloader) {

						o.preloader = $(o.preloader);
						if (o.preloader.length) {

							o.preloader.show();
						}
					}

					if (o.circular) {
						if (to <= o.start - v - 1) {
							ul.css(animCss, -((itemLength - (v * 2)) * liSize) + "px");
							curr = to == o.start - v - 1 ? itemLength - (v * 2) - 1 : itemLength - (v * 2) - o.scroll;
						} else if (to >= itemLength - v + 1) {
							ul.css(animCss, -((v) * liSize) + "px");
							curr = to == itemLength - v + 1 ? v + 1 : v + o.scroll;
						} else curr = to;
					} else {

						if (to + v < 0 || to > itemLength) {

							return;
						}
						else {

							//prev 
							if (to < 0) {


							}
							else {

								//next
								var diff = itemLength - to;

								if (diff < v && diff > 0) {

									curr = to + diff - v;

								} else {

									if (to < 0 || to > itemLength - v) {
										return;
									}
									else {
										curr = to;
									}
								}
							}
						}
					}

					if (o.afterStart) {

						setTimeout(function () { o.afterStart.call(this, vis()); }, 1);
					}

					selectPager(to, o, itemLength, v, curr);

					running = true;

					ul.animate(animCss == "left" ? { left: -(curr * liSize)} : { top: -(curr * liSize) }, o.speed, o.easing, function () {

						var visibleItems = vis();

						if (o.fade) {

							if (o.fadeSelector) {

								visibleItems.items.find(o.fadeSelector).fadeTo(o.fadeSpeedIn, o.fadeInTo);
							}
							else {

								visibleItems.items.fadeTo(o.fadeSpeedIn, o.fadeInTo);
							}
						}
						if (o.afterEnd) {
							setTimeout(function () { o.afterEnd.call(this, visibleItems); }, 1);
						}

						prepareItems(curr, o, itemLength, v, li, curr);

						if (o.preloader) {

							visibleItems.items.find(o.preloadObserable).unbind("load").load(function () {

								$(o.preloader).hide();
							});
						}

						running = false;
					});

					if (!o.circular) {
						$(o.btnPrev + "," + o.btnNext).removeClass("disabled");
						$((curr - o.scroll < 0 && o.btnPrev)
                        ||
                       (curr + o.scroll > itemLength - v && o.btnNext)
                        ||
                       []
                     ).addClass("disabled");
					}
				}
				return false;
			};

			prepareItems(o.start, o, itemLength, v, li);
			selectPager(o.start, o, itemLength, v, curr);
			addHoverClass(o);

			if (o.fade) {

				var visibleItems = me.GetVisibleItems();

				if (visibleItems && visibleItems.items) {

					if (o.fadeSelector) {

						visibleItems.items.find(o.fadeSelector).css("opacity", 1);
					}
					else {

						$(visibleItems.items).css("opacity", 1);
					}
				}
			}
		});
	};
	function css(el, prop) {
		return parseInt($.css(el[0], prop)) || 0;
	};
	function width(el) {

		if (el.length) {
			var cssWidth = parseInt($(el).css("width").replace(/px/, ""));
			var width = !isNaN(cssWidth) && el[0].offsetWidth < cssWidth ? cssWidth : el[0].offsetWidth;

			return width + css(el, 'marginLeft') + css(el, 'marginRight');
		}
		else {

			return 0;
		}
	};
	function height(el) {

		if (el.length) {

			var cssHeight = parseInt($(el).css("height").replace(/px/, ""));
			var height = !isNaN(cssHeight) && el[0].offsetHeight < cssHeight ? cssHeight : el[0].offsetHeight;

			return height + css(el, 'marginTop') + css(el, 'marginBottom');
		}
		else {

			return 0;
		}
	};
	function selectPager(to, o, itemLength, v, curr) {

		if (o.pager) {
			var pageTo = to;

			if (to < v)
				pageTo = to + (itemLength - (v * 2));
			else if (to > (itemLength - (v * 2)))
				pageTo = to - (itemLength - (v * 2));

			$(o.pager).find('li').each(function () {

				var $page = $(this);
				if (o.circular) {

					$page.removeClass("selected");

					if ($page.data("to") == pageTo)
						$page.addClass("selected");
				}
				else {
					var itemTo = $page.data("to");
					var isSelected = itemTo == curr || ((curr == itemLength - v) && (itemTo > curr));

					if (isSelected) {

						$page.addClass("selected");
					} else {

						$page.removeClass("selected");
					}

				}
			});
		}
	};
	function prepareItems(curr, o, itemLength, v, li) {

		if (o.lazyLoadFunction) {

			var currPrev = getCurr(curr - o.scroll, o, itemLength, v);
			var currNext = getCurr(curr + o.scroll, o, itemLength, v);

			li.slice(currPrev + 1, currNext).each(function () {
				doCustomActions(o, $(this));
			});

			li.slice(currPrev).slice(0, v).each(function () {
				doCustomActions(o, $(this));
			});

			li.slice(currNext).slice(0, v).each(function () {
				doCustomActions(o, $(this));
			});
		}
	};
	function getCurr(to, o, itemLength, v) {
		var curr;

		if (o.circular) {
			if (to <= o.start - v - 1)
				curr = to == o.start - v - 1 ? itemLength - (v * 2) - 1 : itemLength - (v * 2) - o.scroll;
			else if (to >= itemLength - v + 1)
				curr = to == itemLength - v + 1 ? v + 1 : v + o.scroll;
			else curr = to;
		} else {
			if (to < 0 || to > itemLength - v) return; else curr = to;
		}

		return curr;
	};
	function doCustomActions(o, li) {

		var isLoaded = "isLoaded";

		if (o.lazyLoadFunction && !li.hasClass(isLoaded)) {

			var arg = new Object();

			arg.item = li;
			arg.itemId = getId(li);

			o.lazyLoadFunction.call(this, arg) ? li.removeClass(isLoaded).addClass(isLoaded) : li.removeClass(isLoaded);
		}
	};
	function getId(li) {
		var id = null;
		var idKey = "id_";

		if (li.data(idKey) == undefined) {

			var classAtr = li.attr("class");

			if (classAtr != null && classAtr != undefined && classAtr != "") {

				var classArr = classAtr.split(' ');

				if (classArr != null && classArr.length > 0) {

					$.each(classArr, function (i, c) {

						if (c.toLowerCase().slice(0, 3) == idKey) {

							id = c.slice(3);
							li.data(idKey, id);

							return false;
						}
					});
				}
			}
		}
		else
			id = li.data(idKey);

		return id;
	};
	function addHoverClass(o) {

		var elements = [o.btnPrev, o.btnNext, o.btnAuto];

		$.each(elements, function (i) {

			if (elements[i]) {
				var $element = $(elements[i]);

				if ($element.attr('class') != null && $element.attr('class') != undefined) {
					var hoverClass = $element.attr('class').split(' ').slice(-1) + 'HoverPreload';

					if (jQuery().hoverIntent && o.hoverIntentDelay) {
						var config = {
							over: function (event) { $(this).addClass(hoverClass); },
							timeout: o.hoverIntentDelay,
							out: function (event) { $(this).removeClass(hoverClass); }
						};
						$element.hoverIntent(config)
					}
					else {
						$element.hover(function () {
							$(this).addClass(hoverClass);
						}, function () {
							$(this).removeClass(hoverClass);
						});
					}
				}
			}
		});
	};
	function getItemIndexByItemId(li, itemId) {

		var index = 0;

		var selectedLi = li.filter(".Id_" + itemId);

		if (selectedLi) {

			var isLoadedLi = selectedLi.filter(".isLoaded");

			if (isLoadedLi.length) {

				index = li.index(isLoadedLi);
			}
			else {

				index = li.index(selectedLi);
			}
		}

		return index;
	};
})(jQuery);
