var ToolTip = { };

ToolTip.Base = Class.create();
ToolTip.Base.prototype =
{
  initialize: function(link, tooltip,options)
	{
    var options = Object.extend(
		{
			delta_x: 10,
			delta_y: 10,
			zindex: 1000,
			defaultClass: 'tooltip',
			centrato: false
		}, options || {});

    this.link = $(link);
		this.options = options;
		this.tooltip = tooltip;
		this.inizializzato = false;

		// Faccio il bind delle funzioni
    this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
    this.eventMouseMove = this.moveTooltip.bindAsEventListener(this);
    this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);

		// Registro i vari eventi
    this.registerEvents();

 		// Se devo eseguire un debug
		/*
		if (!$('tooltip_debug'))
		{
			var debug = new Element('div', { 'id': 'tooltip_debug' });
			$(document.body).insert(debug);
			$('tooltip_debug').setStyle(
				{ position:'fixed',
					top:'20px',
					right:'100px',
					zindex:this.options.zindex,
					backgroundcolor:'gray',
					'text-align':'left'
				});
			$('tooltip_debug').update('debug console');
		}
		*/
  },

  destroy: function()
	{
		// Tolgo gli osservatori sui vari eventi
		Event.stopObserving(this.link, "mouseover", this.eventMouseOver);
		Event.stopObserving(this.link, "mousemove", this.eventMouseMover);
		Event.stopObserving(this.link, "mouseout", this.eventMouseOut);
  },

  registerEvents: function()
	{
		// Registro i vari eventi
		Event.observe(this.link, "mouseover", this.eventMouseOver);
		Event.observe(this.link, "mousemove", this.eventMouseMove);
		Event.observe(this.link, "mouseout", this.eventMouseOut);
  },

	moveTooltip: function(evento)
	{
		// Se si sta muovendo il mouse, lo seguo
		Event.stop(evento);
		this.posiziona(evento);
	},


	primoPosizionamento: function(evento)
	{
		clearInterval(this.interval);
		this.posiziona(evento);
	},

	posiziona: function(evento)
	{
		if (!$(this.tooltip))
			return;

		// Ottengo la posizione
    var x = Event.pointerX(evento);
		var y = Event.pointerY(evento);
		// Scroll della pagina
		var scroll = document.viewport.getScrollOffsets();
		// Dimensioni del tooltip
		var dim = this.tooltip.getDimensions();

		// Dimensioni della pagina
		var winHeigh = 0;
		if (navigator.appVersion.indexOf('MSIE')>0)
			winHeigh = document.body.clientHeight;
		else
			winHeigh = window.innerHeight;

		var winWidth = 0;
		if (navigator.appVersion.indexOf('MSIE')>0)
			winWidth = document.body.clientWidth;
    else
			winWidth = window.innerWidth;


		if (this.options.centrato)
		{
			// Lo posiziono al centro
			x = winWidth/2 - dim.width/2 + scroll.left;
			y = winHeigh/2 - dim.height/2 + scroll.top;
		}
		else
		{
			// Faccio finta che non esista lo scroll, questo semplifica i calcoli e la leggibilità
			x -= scroll.left;
			y -= scroll.top;

			var newY = 0;
			var newX = 0;
			var xOk = true;
			var yOk = true;

			if ((x+dim.width+this.options.delta_x) > winWidth)
			{
				// Troppo largo, Vedo se posso ribaltarlo altrimenti lo posiziono come posso
				if ((x-dim.width-this.options.delta_x) > 0)
					newX = x-dim.width-this.options.delta_x;
				else
				{
					// Segnalo che non sono riuscito a posizionare la X, dopo vedo se posso fare qualcosa
					xOk = false;
					newX = x+this.options.delta_x;
				}
			}
			else
				newX = x+this.options.delta_x;

			if ((y+dim.height+this.options.delta_y) > winHeigh)
			{
				// Troppo alto, Vedo se posso ribaltarlo altrimenti lo posiziono come posso
				if ((y-dim.height-this.options.delta_y) > 0)
					newY = y-dim.height-this.options.delta_y;
				else
				{
					// Visto che è sfalzato sulla x, sulla Y posso permettermi di passare "sopra" al cursorse
					newY = winHeigh-dim.height;
					yOk = false;
				}
			}
			else
				newY = y+this.options.delta_y;

			// Se non sono riuscito a posizionare la X, ma la Y è ok, posso posizionare la X in modo che superi il cursorse
			// Se la Y non fosse ok, allora avrei che vado sopra al mouse, condizione da evitare
			if ((!xOk) && (yOk))
				newX -= (x+dim.width+this.options.delta_x) - winWidth;

			// Faccio ricomparire lo scroll della pagina,altrimenti posizionerei come se fossi ancora in alto
			x = newX + scroll.left;
			y = newY + scroll.top;
		}

		/*
		var testo = '';
		testo += 'Mouse '+Event.pointerX(evento)+' | '+Event.pointerY(evento);
		testo += '<br>Scroll '+scroll.left+' | '+scroll.top;
		testo += '<br>Dim '+dim.width+' | '+dim.height;
		testo += '<br>Win '+winWidth+' | '+winHeigh;
		testo += '<br>Pos '+x+' | '+y;
		testo += '<br>Display '+$(this.tooltip).style.display+' . ';
		$('tooltip_debug').update(testo);
		*/

		// Imposto la nuova posizione
		this.setStyles(x, y);
	},

  showTooltip: function(evento)
	{
		Event.stop(evento);

		if (!this.inizializzato)
		{
			this.inizializza();
			this.inizializzato = true;

			// Sposto il tooltip fuori zona
			this.setStyles(-9999,-9999);
			// Mostro il tooltip
			this.tooltip.show();

			// Lo riposiziono dopo 1 po, altrimenti getDimensions da 1 valore errato e quindi lo posiziona male
      this.interval = setInterval(this.primoPosizionamento.bind(this,evento), 50);
		}
		else
		{
			// Mostro il tooltip
			this.tooltip.show();
			// Posiziono
			this.posiziona(evento);
		}
  },

	inizializza: function()
	{
		// ottengo l'elemento dall'id
		// se manca creo 1 tooltip vuoto
		if ($(this.tooltip))
		{
			this.tooltip = $(this.tooltip);
			if (this.options.defautlClass != '')
				this.tooltip.addClassName(this.options.defaultClass);

			// Setto il posizionamento assoluto e lo z-index
			Element.setStyle(this.tooltip,
				{ position:'absolute',
					zindex:this.options.zindex
				});
		}
		else
			this.tooltip = this.creaDiv('');
	},

	creaDiv: function(testo)
	{
		// Il tooltip è un nuovo div che ho appena creato
		this.tooltip = new Element('div');
		this.tooltip.innerHTML = testo;
		// Verifico se ho un class di default da aggiungere
		if (this.options.defautlClass != '')
			this.tooltip.addClassName(this.options.defaultClass);

		// Inserisco il div nella pagina
		$(document.body).insert(this.tooltip);

		// Setto il posizionamento assoluto e lo z-index
		Element.setStyle(this.tooltip,
			{ position:'absolute',
				zIndex:this.options.zindex
	 		});
	},

  setStyles: function(x, y)
	{
    // Setto la posizione
		Element.setStyle(this.tooltip,{ top:y + "px",	left:x + "px" });
  },

  hideTooltip: function(evento)
	{
		// Nascondo ( sono uscito dall'area di attivazione )
		if ($(this.tooltip))
			$(this.tooltip).hide();
  },

	updateContent: function(text)
	{
		if ($(this.tooltip))
			$(this.tooltip).update(text);
	}
};

ToolTip.Ajax = Class.create(ToolTip.Base,
{
	initialize: function($super,link,path,options)
	{
		var options = Object.extend(
		{
			ajaxLoader : '<img src="/template/img/loader.gif">'
		}, options || {});

		this.path = path;

		$super(link,'',options);
	},

	inizializza: function(evento)
	{
		// Creo il div
		this.creaDiv(this.options.ajaxLoader);

		// Salvo in 1 variabile "locale" altrimenti la request non riesce a capire cosa aggiornare
		var tooltip = this.tooltip;
		// A questo punto richiedo una chaimata asincrona per riempire il div
		new Ajax.Request(this.path,
		{
			onSuccess: function(transport) { tooltip.innerHTML = transport.responseText; },
			asynchronous:true
		});
  }
});


ToolTip.Text = Class.create(ToolTip.Base,
{
	initialize: function($super,link,testo,options)
	{
		this.testo = testo;
		$super(link,'',options);
	},

	inizializza: function()
	{
		this.creaDiv(this.testo);
  }
});

ToolTip.Alert = Class.create(ToolTip.Base,
{
	initialize: function($super,link,testo,options)
	{
		var options = Object.extend(
		{
			defaultClass: 'alert',
			centrato: true,
			incapsula: true,
			overlay:
			{
				opacity:0.6
			}
		}, options || {});

		this.testo = testo;
		$super(link,'',options);
	},

	registerEvents: function()
	{
		// Registro i vari eventi
    Event.observe(this.link, "click", this.eventMouseOver);
  },

  destroy: function()
	{
		// Tolgo gli osservatori sui vari eventi
    Event.stopObserving(this.link, "click", this.eventMouseOver);
		Event.stopObserving(document, "click", this.eventMouseOut);
  },

  inizializza: function()
	{
		if (this.options.incapsula)
		{
			// Creo un div vuoto, poi ci inserisco il contenuto dopo con i pulsanti per chiudere etc
			this.creaDiv('');

			// Creo i 3 div head,centro,foot
			var divHead = new Element('div',{'id':'alertHead'});
			var divCent = new Element('div',{'id':'alertCent'});
			// Li inserisco all'interno del tooltip
			this.tooltip.insert(divHead);
			this.tooltip.insert(divCent);

			// Popoolo l'header
			var imgClose = new Element('img',{src:'image/delete.png',alt:'Chiudi'});
			$(divHead).insert(imgClose);

			Event.observe(imgClose, "click", this.eventMouseOut);

			// Popolo la parte centrale con il testo che mi è stato passato
			divCent.innerHTML = this.testo;
		}
		else
			this.creaDiv(this.testo);
  },

	showTooltip: function(evento)
	{
		if (evento)
			Event.stop(evento);

		if ((ToolTip.Overlay.isLoaded) && (ToolTip.Overlay.caller != this))
		{
			// Se era già aperto e non sono stato io ad aprirlo
			// Chiudo il tooltip che l'ha aperto
			ToolTip.Overlay.caller.hideTooltip();
		}

		// Mostro l'overlay
		ToolTip.Overlay.show(this,this.options.overlay);

		if (!this.inizializzato)
		{
			this.inizializza();
			this.inizializzato = true;


			// Sposto il tooltip fuori zona
			this.setStyles(-9999,-9999);
			// Mostro il tooltip
			this.tooltip.show();

			// Lo riposiziono dopo 1 po, altrimenti getDimensions da 1 valore errato e quindi lo posiziona male
      this.interval = setInterval(this.primoPosizionamento.bind(this,evento), 50);
		}
		else
		{
			// Mostro il tooltip
			this.tooltip.show();
			// Posiziono
			this.posiziona(evento);
		}

		if (this.options.overlay.opacity > 0)
		{
			// Registro l'evento che quando viene cliccato da qualche parte, allora deve far scomparire l'alert
			Event.observe(ToolTip.Overlay.overlay, "click", this.eventMouseOut);
		}
		else
		{
			// Registro l'evento che quando viene cliccato da qualche parte, allora deve far scomparire l'alert
			Event.observe(document, "click", this.eventMouseOut);
		}
  },

  hideTooltip: function(evento)
	{
		// Nascondo
		this.tooltip.hide();
		// Segno che non devo più attendere 1 click sul document
		Event.stopObserving(document, "click", this.eventMouseOut);

		ToolTip.Overlay.hide();
  }

});
ToolTip.Persistent = Class.create(ToolTip.Alert,
{
	initialize: function($super,link,testo,options)
	{
		var options = Object.extend(
		{
			defaultClass: 'tooltip',
			centrato: false,
			incapsula: true,
			overlay: {	opacity:0 }
		}, options || {});

		$super(link,testo,options);
	}
});

ToolTip.CssAlert = Class.create(ToolTip.Alert,
{
  initialize: function(testo,options)
	{
    var options = Object.extend(
		{
			zindex: 1000,
			destroyOnClose: true,
			displayOnCreate: true,
			defaultClass: 'tooltip',
			centrato: true,
			incapsula: true,
			overlay:
			{
				opacity:0.6
			}
		}, options || {});

    this.options = options;
		this.testo = testo;
		this.tooltip = null;
		this.inizializzato = false;

    this.eventMouseOut   = this.hideTooltip.bindAsEventListener(this);

		if (this.options.displayOnCreate)
			this.showTooltip();
  },

	posiziona: function()
	{
		if (!$(this.tooltip))
			return;
		// Scroll della pagina
		var scroll = document.viewport.getScrollOffsets();
		// Dimensioni del tooltip
		var dim = this.tooltip.getDimensions();

		// Dimensioni della pagina
		var winHeigh = 0;
		if (navigator.appVersion.indexOf('MSIE')>0)
			winHeigh = document.body.clientHeight;
		else
			winHeigh = window.innerHeight;

		var winWidth = 0;
		if (navigator.appVersion.indexOf('MSIE')>0)
			winWidth = document.body.clientWidth;
    else
			winWidth = window.innerWidth;


		// Lo posiziono al centro
		x = winWidth/2 - dim.width/2 + scroll.left;
		y = winHeigh/2 - dim.height/2 + scroll.top;

		// Imposto la nuova posizione
		this.setStyles(x, y);
	},
  hideTooltip: function()
	{
		// Nascondo ( sono uscito dall'area di attivazione )
		if ($(this.tooltip))
			$(this.tooltip).hide();

		// Segno che non devo più attendere 1 click sul document
		Event.stopObserving(document, "click", this.eventMouseOut);

		ToolTip.Overlay.hide();

		if (this.options.destroyOnClose)
		{
			var par = this.tooltip.parentNode;
			par.removeChild(this.tooltip);
		}
  }
});




ToolTip.Overlay =
{
	isLoaded: false,
	inizializzato: false,
	overlay:null,
	caller:null,

	inizializza: function()
	{
		this.inizializzato = true;
		// L'overlay è un nuovo div che ho appena creato
		this.overlay = new Element('div');
		// Inserisco il div nella pagina
		$(document.body).insert(this.overlay);
	},
	show: function(caller,options)
	{
		var options = Object.extend(
		{
			style:
			{
				position: 'fixed',
				top: 0,
				left: 0,
				width: '100%',
				height: '100%',
				zIndex: 998,
				'background':'#000'
			},
			opacity:0.6
		}, options || {});

		if (!this.inizializzato)
			this.inizializza();
		this.isLoaded = true;
		if (options.opacity > 0)
		{
			this.overlay.setOpacity(options.opacity);
			this.overlay.show();
			Element.setStyle(this.overlay,options.style);
		}
		this.caller = caller;
	},
	hide: function()
	{
		this.isLoaded = false;
		this.overlay.hide();
		this.caller = null;
	}

}


