/*global clearInterval: false, clearTimeout: false, document: false, event: false, frames: false, history: false, Image: false, location: false, name: false, navigator: false, Option: false, parent: false, screen: false, setInterval: false, setTimeout: false, window: false, XMLHttpRequest: false, jQuery:false */
(function ($) {
	var methods, nextPicture;
	methods = {
		carouselData: {},
		savedSettings: {},
		init: function (settings) {
			var carousel, carouselId, wrapper, list, img, listCount, width, height, previousButton, nextButton, align, verticalCenter, interval, duration, callback, callbackInit;
			
			carousel = $(this);
			carouselId = carousel.attr('id');
			
			carousel.wrap('<div class="jslide" id="' + carouselId + 'Wrapper" />');
			
			wrapper = carousel.parent('div.jslide');
			list = carousel.children('li');
			img = list.children('img');
			listCount = list.size();
		
			width = (!settings.width || isNaN(parseInt(settings.width, 10)) ? 500 : parseInt(settings.width, 10));
			height = (!settings.height || isNaN(parseInt(settings.height, 10)) ? 400 : parseInt(settings.height, 10));
			previousButton = (!($(settings.previousButton)) ? null : $(settings.previousButton));
			nextButton = (!($(settings.nextButton)) ? null : $(settings.nextButton));
			align = ((!settings.align) ? 'center' : settings.align);
			verticalCenter = ((!settings.verticalCenter) && settings.verticalCenter !== false ? true : settings.verticalCenter);
			interval = (isNaN(parseInt(settings.interval, 10)) ? null : parseInt(settings.interval, 10));
			duration = (isNaN(parseInt(settings.duration, 10)) ? 600 : parseInt(settings.duration, 10));
			callback = ((!settings.callback) ? null : settings.callback);
			callbackInit = ((!settings.callbackInit) ? null : settings.callbackInit);
			
			// Save data about the carousel
			methods.carouselData[carouselId] = [0, listCount];
			methods.savedSettings.duration = duration;
			methods.savedSettings.callback = callback;
			methods.savedSettings.interval = interval;
			
			// Set style to the carousel
			wrapper.css({
				'width': width.toString() + 'px', 
				'height': height.toString() + 'px', 
				'position': 'relative', 
				'overflow': 'hidden' 
			});
			list.css({
				'float': 'left',
				'position': 'relative',
				'width': width.toString() + 'px',
				'height': height.toString() + 'px',
				'overflow': 'hidden',
				'text-align': align,
				'margin': '0',
				'padding': '0',
				'list-style-type': 'none'
			});
			carousel.css({
				'position': 'absolute', 
				'width': (width * listCount).toString() + 'px', 
				'top': '0px', 
				'left': '0px'
			});
			if (verticalCenter) {
				img.css({
					'vertical-align': 'middle'
				});
				list.css({
					'line-height': height.toString() + 'px'	
				});
			}
			
			// Set previous button event
			if (typeof previousButton === 'object') {
				previousButton.click(function () {
					$('#' + carouselId).jslide('previous');
				});
			}
			
			// Set next button event
			if (typeof nextButton === 'object') {
				nextButton.click(function () {
					$('#' + carouselId).jslide('next');
				});
			}
			
			// Set next button event
			if (interval !== null) {
				methods.interval(carousel, interval);
			}
			
			if (callbackInit !== null) {
				callbackInit.apply(carousel, methods.carouselData[carouselId]);
			}
		},
		rotate: function (carouselId, nextPicture) {
			var carousel, width, carouselData, left, duration, callback;
			
			carousel = $('#' + carouselId);
			width = carousel.children('li').width();
			carouselData = methods.carouselData[carouselId];
			left = width * nextPicture;
			duration = methods.savedSettings.duration;
			callback = methods.savedSettings.callback;
			
			carouselData[0] = nextPicture;
			
			carousel.animate({'left': '-' + left.toString() + 'px'}, duration, function () {
				callback.apply(carousel, carouselData);
			});
			
			// If interval is activated it resets it
			if(methods.savedSettings.interval !== null) {
				clearTimeout(methods.savedSettings.intervalf);
				methods.interval(carousel, methods.savedSettings.interval);
			}
			
			return nextPicture;
		},
		next: function (element) {
			var carouselId, carouselData, activePicture, counted;
			
			if (typeof element !== 'object') {
				element = $(this);
			}
			
			carouselId = $(element).attr('id');
			carouselData = methods.carouselData[carouselId];
			activePicture = carouselData[0];
			counted = carouselData[1];
			
			if (activePicture === counted - 1) {
				nextPicture = 0;
			} else {
				nextPicture = activePicture + 1;
			}
			
			methods.rotate(carouselId, nextPicture);
			return nextPicture;
		},
		previous: function (element) {
			var carouselId, carouselData, activePicture, counted;
			
			element = (typeof element !== 'object') ? $(this) : element;
			carouselId = $(element).attr('id');
			carouselData = methods.carouselData[carouselId];
			activePicture = carouselData[0];
			counted = carouselData[1];
			
			if (activePicture === 0) {
				nextPicture = counted - 1;
			} else {
				nextPicture = activePicture - 1;
			}
			
			methods.rotate(carouselId, nextPicture);
			return nextPicture;
		},
		goto: function (element, nextPicture) {
			if (typeof element !== 'object') {
				element = $(this);
			}
			
			if (nextPicture === null) {
				nextPicture = 0;
			}
			
			var carouselId = $(element).attr('id');
			methods.rotate(carouselId, nextPicture);
			
			return nextPicture;
		},
		interval: function (element, time) {
			var self, action;
			self = typeof element === 'object' ? element : this;
			action = function() {
				methods.next(self);
			};
			methods.savedSettings.intervalf = setInterval(action, time * 1000);
		}
	};
	
	$.fn.jslide = function (method) {
		if (methods[method]) {
			return methods[method].apply(this, arguments);
		} else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' +  method + ' does not exist on jQuery.jslide');
		}
	};
}(jQuery));
