Timer = Class.create();
Timer.prototype =
{
  initialize: function(options)
	{
    var options = Object.extend(
		{
			ajaxUpdate : true,
			updateTime: 1000,
			slowTime : 5,
			fastClass: 'decrementaFast',
			slowClass: 'decrementa',
			ajaxUpdateAttr: 'ajaxUpdate',
			updateFunction: updateAll
		}, options || {});
		this.options = options;

    this.interval = '';
		this.checkStatus();
  },

	checkStatus: function()
	{
		this.fastTimer = [];
		this.slowTimer = [];
		this.slowCount = 0;
		var classe = this;
		this.slowTimerNum = 0;
		this.fastTimerNum = 0;

		// Calcolo l'orario attuale
		var date = new Date();
		var now = Math.floor(date.getTime()/1000);

		// Estraggo tutti i timer "fast"
		$$("."+this.options.fastClass).each(function(span)
		{
			// Verifico se c'è già l'end timer assegnato
			var endTime = span.readAttribute('endTime');
			// Se non c'è mi baso sul tempo che c'è scritto
			if (endTime == null)
			{
				// Il timer finirà tra "x tempo" + orario attuale
				endTime = Number(now)+Number(fromTimeFormat(span.innerHTML));
				// Me lo segno, così se devo fare 1 update non devo ricalcolarlo ( introducendo errori )
				span.writeAttribute('endTime',endTime);
			}
			// Aggiungo il timer all'array
			var timer = {};
			timer.elem = span;
			timer.endTime = endTime;
			timer.end = false;

			// Verifico se su questo timer, alla sua fine, devo fare 1 update
			var ajaxUpdate = span.readAttribute(classe.options.ajaxUpdateAttr);
			if (ajaxUpdate != null)
				timer.ajaxUpdate = true;
			else
				timer.ajaxUpdate = false;

			classe.fastTimer.push(timer);
		});

		// Estraggo tutti i timer "slow"
		$$("."+this.options.slowClass).each(function(span)
		{
			// Verifico se c'è già l'end timer assegnato
			var endTime = span.readAttribute('endTime');
			// Se non c'è mi baso sul tempo che c'è scritto
			if (endTime == null)
			{
				// Il timer finirà tra "x tempo" + orario attuale
				endTime = Number(now)+Number(fromTimeFormat(span.innerHTML));
				// Me lo segno, così se devo fare 1 update non devo ricalcolarlo ( introducendo errori )
				span.writeAttribute('endTime',endTime);
			}
			// Aggiungo il timer all'array
			var timer = {};
			timer.elem = span;
			timer.endTime = endTime;
			timer.end = false;

			// Verifico se su questo timer, alla sua fine, devo fare 1 update
			var ajaxUpdate = span.readAttribute(classe.options.ajaxUpdateAttr);
			if (ajaxUpdate != null)
				timer.ajaxUpdate = true;
			else
				timer.ajaxUpdate = false;

			classe.slowTimer.push(timer);
		});

		this.slowTimerNum = this.slowTimer.length;
		this.fastTimerNum = this.fastTimer.length;

		// Quando ho finito, do lo start
		this.start();
	},

	stop: function()
	{
		clearInterval(this.interval);
	},

	start: function()
	{
		this.interval = setInterval(this.update.bind(this),this.options.updateTime);
	},

	updateAjax: function()
	{
		this.options.updateFunction();
	},

	update: function()
	{
		var slowTime = false;
		var ajaxUpdate = false;
		var date = new Date();
		var diffTime = 0;

		// Calcolo l'orario attuale ( tanto mi serve.. non è che costi molto )
		// potenzialmente si potrebbe fare un controllo che se ho solo slow e non sono
		// nella fase slow non lo faccio.. ma probabilmente costa di più nel caso medio
		var now = Math.floor(date.getTime()/1000);

		// Verifico se è tempo di aggiornare i timer slow
		if ((this.slowCount+1) == this.options.slowTime)
			slowTime = true;

		if (this.fastTimerNum > 0)
			for (var i = 0; i < this.fastTimer.length; i++)
			{
				// Verifico che non sia finito
				if (!this.fastTimer[i].end)
				{
					// Se ho ancora da fare, aggiorno, altrimenti concludo e decremento
					// il numero di timer fast
					diffTime = this.fastTimer[i].endTime-now;
					if (diffTime >= -1)
					{
						if (diffTime > 0)
							this.fastTimer[i].elem.textContent = toTimeFormat(diffTime);
						else
							this.fastTimer[i].elem.textContent = '';
					}
					else
					{
						// Questo timer è concluso
						this.fastTimer[i].elem.textContent = '';
						this.fastTimer[i].end = true;
						this.fastTimerNum--;

						// Se alla sua fine dovevo aggiornare con ajax, procedo
						if (this.fastTimer[i].ajaxUpdate)
							ajaxUpdate = true;
					}
				}
			}

		// Se è tempo di aggiornarli ( e ho almeno qualcosa da aggiornare )
		if ((slowTime) && (this.slowTimerNum > 0))
			for (var i = 0; i < this.slowTimer.length; i++)
			{
				// Verifico che non sia finito
				if (!this.slowTimer[i].end)
				{
					// Se ho ancora da fare, aggiorno, altrimenti concludo e decremento
					// il numero di timer slow
					diffTime = this.slowTimer[i].endTime-now;
					if (diffTime > 0)
						this.slowTimer[i].elem.textContent = toTimeFormat(diffTime);
					else
					{
						this.slowTimer[i].elem.textContent = '';
						this.slowTimer[i].end = true;
						this.slowTimerNum--;

						// Se alla sua fine dovevo aggiornare con ajax, procedo
						if (this.slowTimer[i].ajaxUpdate)
							ajaxUpdate = true;
					}
				}
			}

		// Incremento il contatore ( in modulo ) che mi dirà quando è il caso di aggiornare
		// i timer slow
		this.slowCount = (this.slowCount+1)%(this.options.slowTime);

		// Se non devo più aggiornare nulla.. mi fermo
		if ((this.slowTimerNum == 0) && (this.fastTimerNum == 0))
			this.stop();

		// Verifico se devo fare 1 update ajax
		if (ajaxUpdate)
			this.updateAjax();
	}
}

