/* 
	Compteur for jQuery v1.5
	Written by Mimeau Mathieu February 2011.
*/


(function($) { 

var PROP_NAME = 'compteur';
var MIN_SPEED = 600;
var MAX_SPEED = 50;

function Compteur() {
	this._defaults = {
		element: null,
		entier: 2,
		decimal: 1,
		speed: MAX_SPEED,
		
		masq: null,
		seperator: '',
		animate: 'fast'
		
	};
};

$.extend(Compteur.prototype, {
	init: false,
	run: false,
	
	markerClassName: 'hasCompteur',

	setDefaults: function(options) {
		extendRemove(this._defaults, options || {});
	},
	
	_attach: function(target, options) {
		target = $(target);
		if (target.hasClass(this.markerClassName)) {
			return;
		}
		options._total = options.entier + options.decimal;
		var allOptions = $.extend({_position: target.css('position')},
			this._defaults, options || {});
		$.data(target[0], PROP_NAME, allOptions);
		target.addClass(this.markerClassName);
		
		if(this.init == false) {
			this.init = true;
			$.compteur._create(target[0]);
		}
	},

	_currentCompteur: function(target, pos) {
		var options = $.data(target, PROP_NAME);
		return ($(target).hasClass(this.markerClassName) ?
			$('> div:eq('+parseInt(parseInt(options._total)-parseInt(pos))+')', target).imagecube('current').innerHTML : null);
	},
	
	_nextCompteur: function(target, pos, value) {
		var options = $.data(target, PROP_NAME);
		Compteur = this;
		
		this.run = true;
		
		return ($(target).hasClass(this.markerClassName) ?
			$('> div:eq('+parseInt(parseInt(options._total)-parseInt(pos))+')', target).imagecube('rotate', value, function() {
				options._current_value = options._cache_value;
				if(options._final_value == options._current_value) options.event = false;
				Compteur._changeCompteur(target, options);
				
				Compteur.run = false;
				if(options.event === true)
				{
					if(options.animate == 'slow')
					{
						var current_val = Compteur._parseToString(target, options._current_value);
						var final_val = Compteur._parseToString(target, options._final_value);
						final_val = parseInt(final_val.substr(parseInt(parseInt(options._total)-parseInt(pos)),1));
						current_val = parseInt(current_val.substr(parseInt(parseInt(options._total)-parseInt(pos)),1));
						
						if(final_val != current_val) Compteur._run(target, pos);
					}
					else if(options.animate == 'fast' && pos == 1)
					{
						Compteur._run(target, pos);
					}
					else if (options.animate == 'disable')
						Compteur._run(target, pos);
				}
				else
				{
					options.speed = MAX_SPEED;
					$('.compteur > div').imagecube('change', 'speed', options.speed);
				}
			}): null);
	},

	_stopCompteur: function(target, timerOnly) {
		var options = $.data(target, PROP_NAME);
		if (options._timer) {
			clearTimeout(options._timer);
			options._timer = null;
		}
		if (!timerOnly) {
			options.repeat = false;
		}
		$.data(target, PROP_NAME, options);
	},

	_changeCompteur: function(target, options, value) {
		if (typeof options == 'string') {
			var opts = {};
			opts[options] = value;
			options = opts;
		}
		options._total = options.entier + options.decimal;
		var curOptions = $.data(target, PROP_NAME);
		extendRemove(curOptions || {}, options || {});
		$.data(target, PROP_NAME, curOptions);
		//this._prepareRotation(target);
	},

	_destroyCompteur: function(target) {
		target = $(target);
		if (!target.hasClass(this.markerClassName)) {
			return;
		}
	},
	
	_initCompteur: function(target, value)
	{
		if(value = this._parseToDecimal(target, value))
		{
			var options = $.data(target, PROP_NAME);
			var target = $(target);
			
			if(value >= 0)
			{
				options._final_value = parseInt(value, 10);

				if(options._final_value > options._cache_value)
				{
					options._signe = 1;
					var direction = 'up';
					var selection = 'forward';
				}
				else
				{
					options._signe = -1;
					var direction = 'down';
					var selection = 'backward';
				}
				$('> div', target).imagecube('change', 'selection', selection);
				$('> div', target).imagecube('change', 'direction', direction);
				
				var animate = options.animate;
				options.animate = 'disable';
				options.event = true;
				this._changeCompteur(target[0], options);
				this._run(target[0], 1);
				this._changeCompteur(target[0], 'animate', animate);
			} else alert('Négatif');
		}
		else alert('Veuillez entrer un nombre valide. Merci.');
	},
	
	_addCompteur: function(target, value)
	{
		if(value = this._parseToDecimal(target, value))
		{
			var options = $.data(target, PROP_NAME);
			var target = $(target);
			
			if(options._final_value + parseInt(value, 10) >= 0)
			{
				options._final_value += parseInt(value, 10);

				if(options._final_value > options._cache_value)
				{
					options._signe = 1;
					var direction = 'up';
					var selection = 'forward';
				}
				else
				{
					options._signe = -1;
					var direction = 'down';
					var selection = 'backward';
				}
				$('> div', target).imagecube('change', 'selection', selection);
				$('> div', target).imagecube('change', 'direction', direction);
				
				options.event = true;
				
				this._changeCompteur(target[0], options);
				this._run(target[0], 1);
				
			} else alert('Négatif');
		}
		else alert('Veuillez entrer un nombre valide. Merci.');
	},
  
	_create: function(target)
	{
		var options = $.data(target, PROP_NAME);
		var target = $(target);
		target.html("");
		for(var i=(options.entier+options.decimal); i>0; i--)
		{
			var div = document.createElement('div');
			if(options.element != null) div.setAttribute('class', options.element+' elt'+i);
			div.setAttribute('style', 'float:left; text-align:center;');
			if(i == options.decimal && options.seperator != null)
				$(div).addClass(options.seperator);
			for(var j=0; j<10; j++)
			{
				var child_div = document.createElement('div');
				child_div.innerHTML = j;
				$(div).append(child_div);
			}
			target.append(div);
		}
		
		options._init = false;
		options._event = false;
		options._current_value = 0;
		options._final_value = 0;
		options.val = 0;
		this._changeCompteur(target[0], options);
		
		$('> div', target).imagecube({direction: 'up', pause: 0, full3D: false, shading: false, repeat: false, speed: 50});
	},
  
	_run: function(target, pos)
	{
		var options = $.data(target, PROP_NAME);
		var target = $(target);
		if(options.event === false || this.run === true ) return false;
		
		if(options.animate == 'disable')
		{
			var current_val = this._parseToString(target[0], options._current_value);
			var final_val = this._parseToString(target[0], options._final_value);
			for(var i=0; i<options._total; i++)
			{
				var final_value = parseInt(final_val.substr(options._total-i-1,1));
				var current_value = parseInt(current_val.substr(options._total-i-1,1));
				if(final_value != current_value)
				{
					this._nextCompteur(target[0], i+1, final_value);
				}
			}
			options._cache_value = options._final_value;
		}
		else if(options.animate == 'slow')
		{
			var value = "";
			var current_val = this._parseToString(target[0], options._current_value);
			var final_val = this._parseToString(target[0], options._final_value);
			
			for(var i=0; i<options._total; i++)
			{
				var final_value = parseInt(final_val.substr(options._total-i-1,1));
				var current_value = parseInt(current_val.substr(options._total-i-1,1));
				
				if(final_value != current_value)
				{
					current_value += parseInt(options._signe);
					if(current_value > 9) current_value = 0;
					else if(current_value < 0) current_value = 9;
					
					this._nextCompteur(target[0], i+1, "");
				}
				value = String(current_value) + value;
			}
			value = parseInt(value, 10);
			options._cache_value = value;
			
		}
		else if(options.animate == 'fast')
		{
			current = options._current_value;
			
			if(options._signe > 0) current += options._signe;
			
			if(current%Math.pow(10,pos) == 0)
			{
				if(options.event === true && (options.animate == 'disable' ||options.animate == 'slow' ||options.animate == 'fast') && options.val <10) this._run(target[0], pos+1, 1);
			}
			
			this._modify_speed(target[0]);
			
			options._cache_value = options._current_value + options._signe;
			
			this._nextCompteur(target[0], pos, "");
		}
		this._changeCompteur(target[0], options);
	},
	
	_modify_speed: function(target)
	{
		var options = $.data(target, PROP_NAME);
		if((options._signe == 1 && options._current_value+10 > options._final_value) || (signe == -1 && options._current_value-10 < options._final_value))
		{
			options.speed = options.speed + options.speed/4;
		}
		else options.speed = MAX_SPEED;
		
		if(MIN_SPEED < options.speed) options.speed = MIN_SPEED;
		
		$('.compteur > div').imagecube('change', 'speed', options.speed);
	},

	_parseNumber: function(target, number)
	{
		var options = $.data(target, PROP_NAME);
		
		number = parseFloat(number);
		
		if(isNaN(number)) return false;
		
		number = number.toFixed(options.decimal);
        number = String(number).replace(".", "");

		var reg=new RegExp('^\-',"g");
		signe = reg.exec(String(number));
        number = String(number).replace(signe, "");
		
		if(String(number).length > (options.entier+options.decimal)) return false;
		
		while(String(number).length < (options.entier+options.decimal)) number = 0+number;

		if(signe != null) number = signe+number;
		return number;
	},
	_parseToDecimal: function(target, number)
	{
		var options = $.data(target, PROP_NAME);
		
		number = this._parseNumber(target, number);
		
		if(number === false) return false;
		return number;
	},

	_parseToNumber: function(target, number)
	{
		var options = $.data(target, PROP_NAME);
		
		number = this._parseNumber(target, number);
		
		var exp= '/(.{'+options.decimal+'}$)/';
		value = String(number).replace(eval(exp), "." + "$1");

		if(number === false) return false;
		return value;
	},
	
	_parseToString: function(target, value)
	{
		var options = $.data(target, PROP_NAME);
		
		var value = String(value);
		while(String(value).length < (options.entier+options.decimal)) value = 0+value;
		
		return value;
	}

});

function extendRemove(target, props) {
	$.extend(target, props);
	for (var name in props) {
		if (props[name] == null) {
			target[name] = null;
		}
	}
	return target;
}

$.fn.compteur = function(options) {
	var otherArgs = Array.prototype.slice.call(arguments, 1);
	if (options == 'current' || options == 'next') {
		return $.compteur['_' + options + 'Compteur'].
			apply($.compteur, [this[0]].concat(otherArgs));
	}
	return this.each(function() {
		if (typeof options == 'string') {
			$.compteur['_' + options + 'Compteur'].
				apply($.compteur, [this].concat(otherArgs));
		}
		else {
			$.compteur._attach(this, options);
		}
	});
};

$.compteur = new Compteur();
})(jQuery);

