
var slideId = 0;

(function ($) {
	jQuery.fn.jGridSlide = function (opts) {
		// Variables
		var defaultOpts = {
			// Affichage
			'width': 'auto',
			'height': 'auto',
			'cols': 'auto',
			'rows': 'auto',
			'overflow' : 'hidden',
			// Comportement du slide
			'type': 'scroll',
			'auto': false,
			'pauseOnHover': true,
			'speed': 500,
			'delay': 2500,
			// Interactions manuelles
			'prev': '',
			'next': '',
			'list': '',
			'tick': function (index, element) {
				return $('<a/>').text(index + 1);
			}
		};
		// Traitement
		return this.each(function () {
			// Variables
			var container = $(this);
			var parent = container.parent();
			var elements = container.children();
			var overflow = parent.css('overflow');
			var options = $.extend({}, defaultOpts, opts);
			if (elements.size() < 2) return;
			// Traitement des options auto
			if (options.width === 'auto') {
				options.width = 0;
				elements.each(function() {
					options.width = Math.max(options.width, container.width());
				});
			}
			if (options.height === 'auto') {
				options.height = 0;
				elements.each(function() {
					options.height = Math.max(options.height, container.height());
				});
			}
			if (options.cols === 'auto' && options.rows === 'auto') options.cols = elements.size();
			if (options.rows === 'auto') options.rows = Math.ceil(elements.size() / options.cols);
			if (options.cols === 'auto') options.cols = Math.ceil(elements.size() / options.rows);
			// Dimensions en pourcentages
			if (typeof(options.width) === 'string' && options.width.slice(-1) === '%') {
				parent.css('overflow', 'hidden');
				options.width = parseFloat(options.width) * parent.width() / 100;
				parent.css('overflow', overflow);
			}
			if (typeof(options.height) === 'string' && options.height.slice(-1) === '%') {
				parent.css('overflow', 'hidden');
				options.height = parseFloat(options.height) * parent.height() / 100;
				parent.css('overflow', overflow);
			}
			// Cas de boutons precedent/suivant et des listing qui sont des fonctions
			if (typeof(options.next) === 'function') options.next = options.next(this);
			if (typeof(options.prev) === 'function') options.prev = options.prev(this);
			if (typeof(options.list) === 'function') options.list = options.list(this);
			// Creation du wrapper global
			var wrapper = $('<div/>').css({
				'position': 'relative',
				'display': 'block',
				'width': options.width,
				'height': options.height,
				'margin': 0,
				'padding': 0,
				'overflow': 'hidden',
				'border': '0px none',
				'outline': '0px none'
			}).data('slideId', slideId++);
			// Creation de la grille
			var grid = $('<div/>').css({
				'position': 'absolute',
				'top': 0,
				'left': 0,
				'display': 'block',
				'width': options.width * options.cols,
				'height': options.height * options.rows,
				'margin': 0,
				'padding': 0,
				'overflow': 'hidden',
				'border': '0px none',
				'outline': '0px none'
			}).appendTo(wrapper);
			// On wrap chaque element et on l'ajoute a la grille
			elements.each(function (index, element) {
				var x = index % options.cols;
				var y = Math.round((index - x) / options.cols);
				$('<div/>').css({
					'position': 'absolute',
					'top': options.height * y,
					'left': options.width * x,
					'width': options.width,
					'height': options.height,
					'margin': 0,
					'padding': 0,
					'overflow': options.overflow
				}).append(element).appendTo(grid).data('jGridY', options.height * y).data('jGridX', options.width * x).data('jGridIndex', index);
			});
			elements = grid.children();
			// Suivant et precedent
			$(options.next).bind('click', function (e) {
				e.stopPropagation();
				wrapper.trigger('pause').trigger('next').trigger('start');
			});
			$(options.prev).bind('click', function (e) {
				e.stopPropagation();
				wrapper.trigger('pause').trigger('prev').trigger('start');
			});
			// La liste des boutons
			var list = $(options.list);
			if (list.size()) {
				// Ajout des boutons
				elements.each(function (index, element) {
					var node = options.tick;
					if (typeof (node) === 'function') node = node(index, element);
					$(node).data('jGridIndex', index).appendTo(list);
				});
				// Changement de variable
				list = list.children();
				// Ajout des clicks
				list.bind('click', function (e) {
					e.stopPropagation();
					var index = $(this).data('jGridIndex');
					wrapper.trigger('pause').trigger('goto', index).trigger('start');
				}).bind('activate', function (e) {
					e.stopPropagation();
					list.removeClass('current');
					$(this).addClass('current');
				});
			}
			// On prepare le wrapper
			wrapper.appendTo(container).data('jGridIndex', 0).data('jGridTimer', 0);
			// Gestion des evenement
			wrapper
			// Aller a un element precis
			.bind('goto', function (e, index) {
				e.stopPropagation();
				// Recuperation de l'index
				if (typeof (index) === 'undefined') index = wrapper.data('jGridIndex');
				index = index % elements.size();
				wrapper.data('jGridIndex', index);
				// Recuperation des coordonnées
				var element = elements.eq(index);
				var x = element.data('jGridX');
				var y = element.data('jGridY');
				// Animation
				if (options.type === 'fade') {
					grid.stop(true)
					.animate({'opacity': 0}, options.speed / 2)
					.animate({'top': -y, 'left': -x}, 0)
					.animate({'opacity' : 1}, options.speed / 2);
				}
				else {
					grid.stop(true)
					.animate({'top': -y, 'left': -x}, options.speed);
				}
				// Mise a jour de la liste des boutons
				list.eq(index).trigger('activate');
			})
			// Elements suivant et precedents
			.bind('next', function (e) {
				e.stopPropagation();
				var index = wrapper.data('jGridIndex');
				wrapper.trigger('goto', index + 1);
			})
			.bind('prev', function (e) {
				e.stopPropagation();
				var index = wrapper.data('jGridIndex');
				wrapper.trigger('goto', index - 1);
			})
			// Scroll auto
			.bind('start', function (e) {
				e.stopPropagation();
				// Verifications
				if (!options.auto) return;
				if (wrapper.data('jGridTimer') !== 0) return;
				// Sinon, on le lance
				wrapper.data('jGridTimer', setInterval(function () {
					wrapper.trigger('next');
				}, options.delay + options.speed));
			})
			.bind('pause', function (e) {
				e.stopPropagation();
				// Verifications
				if (!options.auto) return;
				if (wrapper.data('jGridTimer') === 0) return;
				// Sinon, on l'arrete
				clearInterval(wrapper.data('jGridTimer'));
				wrapper.data('jGridTimer', 0);
			})
			.bind('mouseenter', function (e) {
				e.stopPropagation();
				if (options.pauseOnHover) wrapper.trigger('pause');
			})
			.bind('mouseleave', function (e) {
				e.stopPropagation();
				if (options.auto) wrapper.trigger('start');
			});
			// Initialisation
			wrapper.trigger('goto', 0).trigger('start');
		});
	};
})(jQuery);

