netr = typeof netr === 'undefined' ? {} : netr;

netr.Carousel = function (el, options) {
	var t = this;

	this.mode = netr.Carousel.modes.LOADING;

	this.z = 501;

	this.options = $.extend({}, netr.Carousel.defaultOptions, options || {});

	this.callbacks = this.options.callbacks;

	this.activePage = this.options.startPage;
	this.elements = {};

	this.elements.wrapper = $('<div class="js-carousel cf">');

	this.elements.container = el;
	this.elements.list = el.find('ul,ol').eq(0);

	this.elements.container.after(this.elements.wrapper);
	this.elements.wrapper.append(this.elements.container);

	this.updateItems();

	this.pageCount = Math.ceil(this.itemCount / this.options.itemsPerPage);

	this.itemHeight = this.items.getHighestHeight();

	// Add navigation links
	this.elements.nav = $('<div class="nav">');
	//this.elements.navInner = $('<div class="nav-inner">');
	this.elements.previousLink = $('<a href="#" class="previous" title="' + this.options.previousLinkText + '"><span class="structural">' + this.options.previousLinkText + '</span></a>').appendTo(this.elements.navInner);

	if (this.options.showPageCounter) {
		this.elements.pageCount = $('<span class="page-count">').appendTo(this.elements.navInner);
	}

	this.elements.nextLink = $('<a href="#" class="next" title="' + this.options.nextLinkText + '"><span class="structural">' + this.options.nextLinkText + '</span></a>').appendTo(this.elements.navInner);

	this.elements.nextLink.click(function (e) {
		e.preventDefault();
		t.nextPage();
	}).mousedown(function () {
		t.elements.nextLink.addClass('next-active');
	}).mouseup(function () {
		t.elements.nextLink.removeClass('next-active');
	});
	this.elements.previousLink.click(function (e) {
		e.preventDefault();
		t.previousPage();
	}).mousedown(function () {
		t.elements.previousLink.addClass('previous-active');
	}).mouseup(function () {
		t.elements.previousLink.removeClass('previous-active');
	});

	// Create pager
	if (this.options.addPager) {
		this.pager = new netr.ui.Pager();
		for (var p = 0; p < this.pageCount; p++) {
			(function () {
				var page = p;
				t.pager.addPage(t.options.pagerFormat(t, page, t.items.eq(t.options.itemsPerPage * p)), function () {
					t.showPage(page);
				});
			})();
		}
		this.elements.nav.append(this.pager.container);
		this.pager.showPage(this.activePage);
	}

	// Insert clipping div
	this.elements.clip = $('<div class="carousel-clip cf">');
	this.elements.clip.css({
		'position': 'relative',
		'overflow': 'hidden',
		'width': this.elements.container.width(),
		'height': this.itemHeight
	});
	this.elements.container.append(this.elements.clip);
	this.elements.clip.append(this.elements.list);

	this.elements.container.append(this.elements.nav.append(this.elements.navInner));

	this.updateItems();

	// Play/pause button
	this.playPauseButton = $('<a>', {
		href: '/',
		'class': 'play',
		'html': 'Play',
		'click': function (e) {
			e.preventDefault();
			t.playPauseButton.toggleClass('paused');
			t.autoplayPaused = t.playPauseButton.hasClass('paused');
		}
	}).appendTo(this.elements.container);

	// Autoplay
	this.autoplayPaused = false;
	this.pager.container.mouseover(function () {
		t.autoplayPaused = true;
	}).mouseout(function () {
		t.autoplayPaused = false;
	});

	// Do not auto-play if there is only one image
	if (this.itemCount > 1) {
		this.autoplay();
	}
	else {
		this.playPauseButton.click();
	}

	// Calculate widths
	this.itemWidth = Math.ceil(this.elements.clip.width() / this.options.itemsPerPage);
	this.items.width(this.itemWidth);
	this.elements.list.width(this.itemWidth * this.itemCount);

	// Disable all hidden items to prevent them from getting keyboard focus
	this.disableHiddenLinks();

	this.items.eq(0).css('z-index', this.z++);

	this.mode = netr.Carousel.modes.IDLE;

	if (this.options.showPageCounter) {
		this.updatePageCountText();
	}
};
netr.Carousel.prototype = {
	callbacks: {},
	autoplay: function () {
		var t = this;
		setInterval(function () {
			var page = t.activePage == t.items.length - 1 ? 0 : t.activePage + 1;
			if (!t.autoplayPaused) {
				t.pager.showPage(page);
				t.showPage(page);
			}
		}, 4000);
	},
	doCallback: function (eventName) {
		if (this.callbacks[eventName] && typeof this.callbacks[eventName] == 'function') {
			this.callbacks[eventName].apply(this);
		}
	},
	updateItems: function () {
		this.items = this.elements.list.children('li');
		this.itemCount = this.items.size();
	},
	showPage: function (pageNum) {
		var t = this;
		this.doCallback('onBeforeShowPage');
		t.items.eq(pageNum).css({
			'opacity': 0,
			'z-index': this.z++
		}).animate({'opacity': 1}, 'slow', function () {
			t.activePage = pageNum;
		});
		this.doCallback('onAfterShowPage');
	},
	goForward: function (pages) {
		var t = this;
		var margin;
		var activePage = this.activePage;

		pages = pages || 1;

		this.enableAllLinks();
		this.elements.list.clearQueue();

		margin = -(this.itemWidth * this.options.itemsPerPage) * (activePage + pages);

		this.elements.list.animate({'marginLeft': margin}, 'slow', this.options.easing, function () {

			if (t.elements.list.queue().length === 0) {
				t.disableHiddenLinks();
			}

			if (t.options.showPageCounter) {
				t.updatePageCountText();
			}
		});
	},
	goBack: function (pages) {
		var t = this;
		var margin;
		var activePage = this.activePage;

		pages = pages || 1;

		this.enableAllLinks();
		this.elements.list.clearQueue();

		margin = -(this.itemWidth * this.options.itemsPerPage) * (activePage - pages);

		this.elements.list.animate({'marginLeft': margin}, 'slow', this.options.easing, function () {
			if (activePage === 0) {
				t.activePage = t.pageCount - 1;
				t.elements.list.css('marginLeft', -(t.itemWidth * t.options.itemsPerPage * t.pageCount));
			} else {
				t.activePage = activePage - pages;
			}

			if (t.elements.list.queue().length === 0) {
				t.disableHiddenLinks();
			}

			if (t.options.showPageCounter) {
				t.updatePageCountText();
			}
		});
	},
	nextPage: function () {
		this.doCallback('onBeforeNextPage');
		this.goForward(1);
		this.doCallback('onAfterNextPage');
	},
	previousPage: function () {
		this.doCallback('onBeforePreviousPage');
		this.goBack(1);
		this.doCallback('onAfterPreviousPage');
	},
	disableHiddenLinks: function () {
		var t = this;
		// this.items.css('visibility', 'hidden');
		// this.items.eq(this.activePage + 1).css('visibility', 'visible');
	},
	enableAllLinks: function () {
		this.items.css('visibility', 'visible');
	},
	updatePageCountText: function () {
		this.elements.pageCount.text(netr.string.format(this.options.pageCountFormat, this.activePage, this.pageCount));
	}
};
netr.Carousel.modes = {
	IDLE: 0,
	ANIMATING: 1,
	LOADING: 2
};
netr.Carousel.defaultOptions = {
	itemsPerPage: 7,
	startPage: 0,
	easing: 'easeOutCubic',
	addPager: false,
	// item parameter is first item of page
	pagerFormat: function (carousel, pageIndex, item) {
		return '<a href="#">' + pageIndex + '</a>';
	},
	showPageCounter: true,
	pageCountFormat: 'Sida {0} av {1}',
	nextLinkText: 'Nästa',
	previousLinkText: 'Föregående',
	callbacks: {}
};
