﻿(function($, glob) {
	glob.htmlEnc = function(text) {
		var sHTMLEnc = text + '';
		sHTMLEnc = sHTMLEnc.replace(/&/g,"&amp;");
		sHTMLEnc = sHTMLEnc.replace(/</g,"&lt;");
		sHTMLEnc = sHTMLEnc.replace(/>/g,"&gt;");
		return(sHTMLEnc);
	};

	function Sticky(el, options) {
		this.id = Sticky.id();

		this.el = $(el);

		if(this.el.size() !== 1) {
			return this;
		}

		this.shadow = this.el.clone().html('').css({
			height: this.el.height(),
			borderColor: 'transparent',
			display: 'none',
			background: 'transparent'
		}).removeAttr('id').insertBefore(this.el);

		this.settings = $.extend(true, {}, Sticky.defaults, options);

		this.originalValues = {
			position: this.el.css('position'),
			top: this.el.css('top'),
			width: this.el.css('width'),
			left: this.el.css('left'),
			marginLeft: this.el.css('margin-left')
		};

		this.contain = this.settings.contain ? $(this.settings.contain) : this.el.parent();
		this.isSticky = false;

		this.data = {
			offset: this.el.offset()
		};

		this.isActive = true;

		this.triggers();
	}

	$.extend(Sticky.prototype, {
		triggers: function(add) {
			var _this = this;

			add = arguments.length === 0 || !!add;

			this.hasTriggers = add;

			if(add) {
				Sticky.win.on('scroll.sticky_' + this.id, function() {
					_this.calculate();

					if((_this.data.scrollTop - _this.data.offset.top + _this.settings.top) > 0 && !((_this.data.scrollTop + _this.settings.top) <= _this.data.topline)) {
						if(!_this.isSticky) {
							_this.stick();
						}

						if((_this.data.scrollTop + _this.settings.top + _this.data.height) >= _this.data.bottomline) {
							// The bottom of the sticky box goes out/under the container, we should stop the sticky here
							_this.el.css('top', _this.data.bottomline - _this.data.scrollTop - _this.data.height);
						} else {
							_this.el.css('top', _this.settings.top);
						}

						_this.el.css('left', _this.data.offset.left);
					} else if(_this.isSticky) {
						_this.unstick();
					}
				});

				Sticky.win.on('resize.sticky_' + this.id, function() {
					if(_this.isSticky) {
						_this.data.offset = _this.shadow.offset();
					} else {
						_this.data.offset = _this.el.offset();
					}

					if(_this.isSticky) {
						_this.el.css('width', _this.shadow.width());
					}

					Sticky.win.trigger('scroll.sticky_' + _this.id);
				});
			} else {
				Sticky.win.off('scroll.sticky_' + this.id);
				Sticky.win.off('resize.sticky_' + this.id);
			}
		},

		calculate: function() {
			//this.data.offset = this.el.offset();
			this.data.height = this.el.outerHeight();
			this.data.scrollTop = Sticky.win.scrollTop();

			var offset = this.contain.offset();

			this.data.topline = (offset && offset.top) || 0;
			this.data.bottomline = this.data.topline + this.contain.height();
			this.data.bottomline = Math.max(this.data.bottomline, this.data.height + this.data.offset.top);

			this.shadow.css({
				height: this.el.height()
			});
		},

		stick: function() {
			this.data.offset = this.el.offset();

			this.el.css({
				position: 'fixed',
				top: this.settings.top,
				width: this.el.width(),
				left: this.data.offset.left,
				marginLeft: '0'
			});

			this.shadow.css({
				display: 'block'
			});

			this.isSticky = true;
		},

		unstick: function() {
			this.el.removeAttr('style');

			this.shadow.css({
				display: 'none'
			});

			this.isSticky = false;
		},

		setTop: function(top) {
			this.settings.top = top;

			if(this.isActive) {
				Sticky.win.trigger('resize.sticky_' + this.id);
			}
		},

		sticky: function() {
			if(!this.isActive && !this.disabled) {
				if(!this.hasTriggers) {
					this.triggers(true);
				}

				Sticky.win.trigger('resize.sticky_' + this.id);

				this.isActive = true;
			}
		},

		unsticky: function() {
			if(this.isActive) {
				if(this.isSticky) {
					this.unstick();
				}

				if(this.hasTriggers) {
					this.triggers(false);
				}

				this.isActive = false;
			}
		},

		disable: function() {
			this.unsticky();

			this.disabled = true;
		}
	});

	Sticky.defaults = {
		top: 10
	};

	Sticky.id = (function() {
		var id = 0;

		return function() {
			return ++id;
		}
	}());

	Sticky.win = $(window);

	glob.sticky = function(el, options) {
		return new Sticky(el, options);
	};


	function Carousel(el, options) {
		this.el = $(el);

		this.settings = $.extend(true, {}, Carousel.defaults, options);

		this.scroller = this.settings.scroller;
		this.scrollerWidthContainer = this.settings.scrollerWidthContainer;

		this.el.css({
			overflow: 'hidden'
		});

		this.triggers();

		this.refresh();
	}

	$.extend(Carousel.prototype, {
		triggers: function() {
			var _this = this;

			this.settings.leftButton.on('click', function(e) {
				_this.scroll(-_this.scrollWidth, e);
			});

			this.settings.rightButton.on('click', function(e) {
				_this.scroll(_this.scrollWidth, e);
			});
		},

		refresh: function() {
			//var scrollerPos = this.scroller.position();
			var scrollerLeft = parseInt(this.scroller.css('left'), 10);

			this.items = this.scroller.find(this.settings.itemSelector);
			this.scroller.width(20000);

			// var lastEl = this.items.filter(':last-child');

			// if(lastEl.size()) {
			// 	var clientRect = lastEl.get(0).getBoundingClientRect();
			// 	var pos = lastEl.position();

			// 	this.sliderWidth = Math.ceil(pos.left + clientRect.width);
			// } else {
				
			// }

			var widthRect = this.scrollerWidthContainer.get(0).getBoundingClientRect();

			if(widthRect.width) {
				this.sliderWidth = Math.ceil(widthRect.width);
			} else {
				this.sliderWidth = Math.ceil(widthRect.right - widthRect.left)+1;
			}

			var currentWidth = $(window).width();
			if(currentWidth > 768) {
				this.scroller.width(this.sliderWidth);

				this.settings.leftButton.show();
				this.settings.rightButton.hide();

				this.scrollWidth = Math.ceil(this.el.width());

				if(this.sliderWidth <= this.containerWidth) {
					this.settings.leftButton.hide();
					this.settings.rightButton.hide();
				} else {
					if(scrollerLeft < 0) {
						this.settings.leftButton.show();
					} else {
						this.settings.leftButton.hide();
					}

					if((this.containerWidth - scrollerLeft) < this.sliderWidth) {
						this.settings.rightButton.show();
					} else {
						this.settings.rightButton.hide();
					}
				}
			}
			this.containerWidth = Math.ceil(this.el.width());

			if((this.sliderWidth > this.containerWidth) && (-scrollerLeft) > (this.sliderWidth - this.containerWidth)) {
				this.scrollTo(this.sliderWidth - this.containerWidth, 0);
			}
		},

		scrollToIndexIfOutOfBounds: function(index) {
			var item = this.items.eq(index);

			if(item.size()) {
				var currentLeft = parseInt(this.scroller.css('left'), 10);
				var itemRect = item.get(0).getBoundingClientRect();
				var itemLeft = item.position().left;
				var itemWidth = item.outerWidth();
				var itemRight = itemLeft + itemWidth;

				if(itemLeft < (-currentLeft) || itemRight > (-currentLeft + this.containerWidth)) {
					var centeredLeft = (itemLeft + itemRight) / 2 - this.containerWidth / 2;

					this.scrollTo(Math.min(Math.max(centeredLeft, 0), this.sliderWidth - this.containerWidth));
				}
			}
		},

		scroll: function(relative, e) {
			if(e) {
				e.preventDefault();
			}

			var currentLeft = parseInt(this.scroller.css('left'), 10);

			var targetScroll = Math.min(Math.max(relative - currentLeft, 0), this.sliderWidth - this.containerWidth);

			this.scrollTo(targetScroll);
		},

		scrollTo: function(targetScroll, duration) {
			var _this = this;
			var scrollDuration = 450;

			if(duration || duration === 0) {
				scrollDuration = duration;
			}

			this.scroller.stop(true, false).animate({
				left: -targetScroll + 'px'
			}, {
				duration: scrollDuration,
				complete: function() {
					_this.refresh();
				}
			});
		}
	});

	Carousel.defaults = {};

	Carousel.win = $(window);

	glob.carousel = function(el, options) {
		return new Carousel(el, options);
	};
}(jQuery, this));