var Carousel = function(container_id, params) {
	this.container = $(container_id);
	this.authorsImages = [];
	this.mediasImages = {};
	Object.copyParams(this, params);

	this.media = !(this.items !== null && typeof this.items == "object" && 'splice' in this.items && 'join' in this.items);

	if (this.media) {
		this.prevArr = $('media_larr');
		this.nextArr = $('media_rarr');
		// Carousel for media
		Event.add(this.prevArr, 'mousedown', this.moveMediasHandler.bindAsEventListener(this, 0));
		Event.add(this.nextArr, 'mousedown', this.moveMediasHandler.bindAsEventListener(this, 1));
		this.mediaType = 'all'; // default 'all'

		this.currentIndex = {
			'all': 0,
			'photo': 0,
			'video': 0,
			'caricature': 0,
			'infographics': 0
		};

		this.selected = {
			'all': 0,
			'photo': 0,
			'video': 0,
			'caricature': 0,
			'infographics': 0
		};

		this.typeLinks = {
			'photo':		[ 'все фотоленты',		'/photolents/'	],
			'video':		[ 'все видео',			'/video/'		],
			'caricature':	[ 'все карикатуры',		'/caricature/'	],
			'infographics':	[ 'вся инфографика',	'/infografika/'	]
		}

		Event.add($$(this.container, 'UL')[0], 'mouseover', this.selectMedia.bind(this));
		this.preloadMedias();
	} else {
		this.currentIndex = 0;
		// Carousel for authors
		Event.add($('author_larr'), 'mousedown', this.moveAuthorsHandler.bindAsEventListener(this, 0));
		Event.add($('author_rarr'), 'mousedown', this.moveAuthorsHandler.bindAsEventListener(this, 1));
		this.preloadAuthors();
	}

	return this;
};

Carousel.prototype = {
	preloadAuthors: function () {
		for (var i = 0, l = this.items.length; i < l; i++) {
			var img = this.items[i];
			var image = new Image();
			image.src = this.imagesPath + '/' + img.src;
			this.authorsImages.push(image);
		}
	},

	preloadMedias: function () {
		var listImages = this.items[this.mediaType];
		var listItems = $$(this.container, 'LI');

		if (!this.mediasImages[this.mediaType]) {
			for (var mediaType in this.items) {
				this.mediasImages[mediaType] = {'images': []};
				for (var i = 0, l = listItems.length * (mediaType == this.mediaType ? 2 : 1); i < l; i++) {
					var srcImg = this.items[mediaType].items[i];
					if (!srcImg) {break;}
					var image = new Image();
					image.src = this.imagesPath + '/' + srcImg.src;
					this.mediasImages[mediaType].images.push(image);
				}
				this.mediasImages[mediaType].lastIndex = this.mediasImages[mediaType].images.length -1;
			}
		} else {
			for (i = this.currentIndex[this.mediaType] + listItems.length - 1, l = this.mediasImages[this.mediaType].lastIndex + listItems.length; i < l; i++) {
				srcImg = listImages.items[i];
				if (!srcImg) {break;}
				image = new Image();
				image.src = this.imagesPath + '/' + srcImg.src;
				this.mediasImages[this.mediaType].images.push(image);
			}
			this.mediasImages[this.mediaType].lastIndex = this.currentIndex[this.mediaType] + (listItems.length*2) - 1;
		}
	},

	selectMedia: function (event) {
		var e = Event.elementEqual(event, 'IMG');
		if (!e) { return false; }
		el = e.parentNode.parentNode;

		var index;
		var listItems = $$(this.container, 'LI');

		for (var i = 0, l = listItems.length; i < l ; i++) {
			var element = listItems[i];
			element.className = '';
			if (element == el) {
				index = i + this.currentIndex[this.mediaType];
				this.selected[this.mediaType] = i;
			}
		}

		el.className = 'active';

		this.fillCaption(index, el);
	},

	switchMediaType: function (className) {
		this.mediaType = className;
		var listItems = $$(this.container, 'LI');
		for (var i = 0, l = listItems.length; i < l ; i++) {
			var element = listItems[i];
			element.className = '';
			element.innerHTML = (i + this.currentIndex[this.mediaType] < this.items[this.mediaType].items.length) ? this.getNextElementMedias(i + this.currentIndex[this.mediaType]) : '<a></a>';
		}
		if (this.selected[this.mediaType] < listItems.length && this.selected[this.mediaType] >= 0) {
			listItems[this.selected[this.mediaType]].className = 'active';
		}

		this.fillCaption(this.selected[this.mediaType] + this.currentIndex[this.mediaType], listItems[this.selected[this.mediaType]]);

		this.preloadMedias();

		var link = $('media_type_title');
		if (this.mediaType != 'all') {
			link.innerHTML = this.typeLinks[this.mediaType][0];
			link.href = this.typeLinks[this.mediaType][1];
		} else {
			link.innerHTML = '';
		}

		Object.Class.replace(this.prevArr, 'hidden', '', (this.getNextIndexMedias(0, listItems.length) < 0));
		Object.Class.replace(this.nextArr, 'hidden', '', (this.getNextIndexMedias(1, listItems.length) == this.items[this.mediaType].items.length || this.items[this.mediaType].items.length <= listItems.length));
	},

	fillCaption: function (index, el) {
		var item = this.items[this.mediaType].items[index];

		if (item.label) {
			var a = el.firstChild.firstChild;
			a.href = item.label_url;
			a.innerHTML = item.label;
			Object.Class.add(el, 'labeled');
		}
		$('media_header').innerHTML = '<a href="' + item.url + '">' + item.title + '</a>';
		$('media_text').innerHTML = '<a href="' + item.url + '">' + item.text  + '</a>';
	},

	moveAuthorsHandler: function (event, dir) {
		this.course = dir;
		this.moveAuthorsStart(dir);

		Event.add(document.body, 'mouseup', this.moveStop.bind(this));
		Event.cancelEvent(event);
	},

	moveMediasHandler: function (event, dir) {
		this.course = dir;
		this.moveMediasStart(dir);

		Event.add(document.body, 'mouseup', this.moveStop.bind(this));
		Event.cancelEvent(event);
	},

	moveAuthorsStart: function (dir) {
		if (this.timeout) { return; }
		if (this.course >= 0){
			this.moveAuthors(dir);
			this.timeout = window.setTimeout(function(){
				this.timeout = null;
				this.moveAuthorsStart(dir);
	        }.bind(this), 500);
		}
	},

	moveMediasStart: function (dir) {
		if (this.timeout) { return; }
		if (this.course >= 0) {
			this.moveMedias(dir);
			this.timeout = window.setTimeout(function(){
				this.timeout = null;
				this.moveMediasStart(dir);
	        }.bind(this), 500);
		}
	},

	moveStop: function () {
		this.course = -1;
		Event.remove(document.body, 'mouseup', this.moveStop.bind(this));
	},

	moveAuthors: function (dir) {
		var listItems = $$(this.container, 'LI');

		var a = [];
		var tmp, current, nextIndex;

		// collecting array of original values
		for (var i = 0, l = listItems.length; i < l; i++) {
			var element = listItems[i];
			a[i] = element.innerHTML;
		}

		nextIndex = this.getNextIndexAuthors(dir, listItems.length);

		if (!dir) { // Prev
			for (i = a.length - 2; i >= 0; i--) {
				tmp = a[i + 1];
				a[i + 1] = a[i];
				if (i > 0) {
					a[i] = tmp;
				} else {
					a[i] = this.getNextElementAuthors(nextIndex);
					this.currentIndex--;
				}
			}
		} else { // Next
			for (i = 1, l = a.length; i < l; i++) {
				tmp = a[i - 1];
				a[i - 1] = a[i];
				if (i < a.length - 1) {
					a[i] = tmp;
				} else {
					a[i] = this.getNextElementAuthors(nextIndex);
					this.currentIndex++;
				}
			}
		}

		// Rendering resulting array into table
		for (i = 0, l = a.length; i < l; i++) {
			var html = a[i];
			listItems[i].innerHTML = html;
		}
	},

	moveMedias: function (dir) {
		var listItems = $$(this.container, 'LI');

		var a = [];
		var tmp, current, nextIndex;

		nextIndex = this.getNextIndexMedias(dir, listItems.length);
		// preload next images
		if (nextIndex == this.mediasImages[this.mediaType].lastIndex - 1) {
			this.preloadMedias();
		}

		// stop Moving carousel
		if ((nextIndex == this.items[this.mediaType].items.length) || (nextIndex < 0)) {
			this.moveStop();
			return;
		}

		// collecting array of original values
		for (var i = 0, l = listItems.length; i < l; i++) {
			var element = listItems[i];
			a[i] = element.innerHTML;
		}

		if (!dir) { // Prev
			for (i = a.length - 2; i >= 0; i--) {
				tmp = a[i + 1];
				a[i + 1] = a[i];
				if (i > 0) {
					a[i] = tmp;
				} else {
					a[i] = this.getNextElementMedias(nextIndex);
					this.currentIndex[this.mediaType]--;
					this.selected[this.mediaType]++;

				}
			}
		} else { // Next
			for (i = 1, l = a.length; i < l; i++) {
				tmp = a[i - 1];
				a[i - 1] = a[i];
				if (i < a.length - 1) {
					a[i] = tmp;
				} else {
					a[i] = this.getNextElementMedias(nextIndex);
					this.currentIndex[this.mediaType]++;
					this.selected[this.mediaType]--;
				}
			}
		}

		// Rendering resulting array into table
		for (i = 0, l = a.length; i < l; i++) {
			var html = a[i];
			listItems[i].innerHTML = html;
			listItems[i].className = (i == this.selected[this.mediaType]) ? 'active' + (this.items[this.mediaType].items[i].label ? ' labeled' : '') : '';
		}

		Object.Class.replace(this.prevArr, 'hidden', '', (nextIndex - 1 < 0));
		Object.Class.replace(this.nextArr, 'hidden', '', (nextIndex + 1 == this.items[this.mediaType].items.length));
	},

	getNextIndexAuthors: function (dir, listSize) {
		var offset = this.currentIndex + (dir ? listSize : -1);
		return (offset % this.items.length + this.items.length) % this.items.length;
	},

	getNextIndexMedias: function (dir, listSize) {
		var offset = this.currentIndex[this.mediaType] + (dir ? listSize : -1);
		return offset;
	},

	getNextElementAuthors: function (index) {
		var el = [];
		el[0] = '<a href="';
		el[1] = this.nextUrl(index);
		el[2] = '"><img src="';
		el[3] = this.nextSrc(index);
		el[4] = '" width="50" height="50" alt="" /><span>';
		el[5] = this.nextTitle(index);
		el[6] = '</span></a>';
		return el.join('');
	},

	getNextElementMedias: function (index) {
		var el = [];
		el[0] = '<span>';
		el[1] = this.nextLabel(index);
		el[2] = '</span><a href="';
		el[3] = this.nextUrl(index);
		el[4] = '"><img src="';
		el[5] = this.nextSrc(index);
		el[6] = '" width="120" height="83" alt="';
		el[7] = this.nextAlt(index).replace(/(\")/g, '&quot;');
		el[8] = '" title="';
		el[9] = this.nextAlt(index).replace(/(\")/g, '&quot;');
		el[10] = '" /></a>';
		return el.join('');
	},

	nextLabel: function (i) {
		var label = this.items[this.mediaType].items[i].label;
		return label ? '<a href="' + this.items[this.mediaType].items[i].label_url + '">' + this.items[this.mediaType].items[i].label + '</a>' : '';
	},
	nextUrl: function (i) {
		return this.media ? this.items[this.mediaType].items[i].url : this.items[i].url;
	},

	nextSrc: function (i) {
		return this.imagesPath + '/' + (this.media ? this.items[this.mediaType].items[i].src : this.items[i].src);
	},

	nextTitle: function (i) {
		return (this.media ? this.items[this.mediaType].items[i].title : this.items[i].title);
	},

	nextAlt: function (i) {
		return (this.media ? this.items[this.mediaType].items[i].alt : '');
	}
};

