/**********************************************************************
*	
*	version du 05/01/2009
*	
*	Classe de barre de scroll verticale
*
*	new Scroll() : nouveau fondu
*
*	parametres :
*	{
*		- idContenu : identifiant du contenu associe a la barre
*		- idBarre : identifiant de la barre de scroll
*		- idFlecheHaut : identifiant de la fleche du haut
*		- idCurseur : identifiant du curseur de la barre de scroll
*		- idFlecheBas : identifiant de la fleche du bas
*		- vitesseScrollFlechesLent : vitesse de scroll en pixels utilisee en passant la souris sur les fleches
*		- vitesseScrollFlechesRapide : vitesse de scroll en pixels utilisee en cliquant sur les fleches
*		- delaiScrollFleches : intervalle entre chaque iteration pour le scroll avec les fleches
*		- affichageBarre : definit l'affichage de la barre en fonction du contenu (Scroll.affichageBarre)
*		- affichageCurseur : definit l'affichage du curseur en fonction du contenu (Scroll.affichageBarre)
*	}
*	
**********************************************************************/

function Scroll(parametres)
{
	this.parametres = {
		idContenu: "",
		idBarre: "",
		idFlecheHaut: "",
		idCurseur: "",
		idFlecheBas: "",
		vitesseScrollFlechesLent: 0,
		vitesseScrollFlechesRapide: 15,
		delaiScrollFleches: 20,
		hauteurScrollMolette: 25,
		affichageBarre: Scroll.affichageBarre.toujoursVisible,
		affichageCurseur: Scroll.affichageBarre.visibleSiNecessaire
	};
	
	this.divScroll = null;
	this.divContenu = null;
	this.barreScroll = null;
	this.flecheHaut = null;
	this.flecheBas = null;
	
	this.vitesse = null;
	this.timerScroll = null;
	this.position = 0;
	this.positionScroll = 0;
	this.scrollActif = false;
	this.positionMouseScroll = 0;
	
	this.initialise = false;
	
	var thisObject = this;
	
	/*
	*	this.optionsDefaut()
	*	permet de tenir compte des parametres fournis tout en gardant les valeurs
	*	par defaut des parametres non fournis
	*
	*	- parametres : parametres founis
	*	
	*	note : les parametres par defaut sont this.parametres
	*/
	this.optionsDefaut = function(parametres)
	{
		if (parametres)
		{
			for (var propriete in this.parametres)
			{
				if (parametres[propriete] != undefined)
					this.parametres[propriete] = parametres[propriete];
			}
		}
	}
	this.optionsDefaut(parametres);
	
	/*
	*	this.initialiser()
	*	initialise la scrollbar
	*/
	this.initialiser = function()
	{
		this.divContenu = document.getElementById(this.parametres.idContenu);
		if (this.divContenu.parentNode.addEventListener)
			this.divContenu.parentNode.addEventListener('DOMMouseScroll', function(event) { thisObject.gererMolette(event); }, false);
		this.divContenu.parentNode.onmousewheel = function(event) { thisObject.gererMolette(event); }
		
		this.barreScroll = document.getElementById(this.parametres.idBarre);
		
		this.flecheHaut = document.getElementById(this.parametres.idFlecheHaut);
		this.flecheHaut.onmouseout = function() { thisObject.arreterScrollFleches(); }
		this.flecheHaut.onmouseup = function() { thisObject.setVitesseScrollFlecheLenteHaut(); }
		this.flecheHaut.onmousedown = function() { thisObject.setVitesseScrollFlecheRapideHaut(); }
		this.flecheHaut.onmouseover = function() { thisObject.demarrerScrollFlecheHaut(); }
		this.flecheHaut.onclick = function() { return false; }
		
		this.divScroll = document.getElementById(this.parametres.idCurseur);
		if (this.divScroll.addEventListener)
			this.divScroll.addEventListener('mousedown', function() { thisObject.setScroll(true); }, false);
		else
			this.divScroll.attachEvent('onmousedown', function() { thisObject.setScroll(true); });
		
		this.flecheBas = document.getElementById(this.parametres.idFlecheBas);
		this.flecheBas.onmouseout = function() { thisObject.arreterScrollFleches(); }
		this.flecheBas.onmouseup = function() { thisObject.setVitesseScrollFlecheLenteBas(); }
		this.flecheBas.onmousedown = function() { thisObject.setVitesseScrollFlecheRapideBas(); }
		this.flecheBas.onmouseover = function() { thisObject.demarrerScrollFlecheBas(); }
		this.flecheBas.onclick = function() { return false; }
		
		if (document.addEventListener)
			document.addEventListener('mouseup', function() { thisObject.setScroll(false); }, false);
		else
			document.attachEvent('onmouseup', function() { thisObject.setScroll(false); });
		
		if (document.addEventListener)
			document.addEventListener('mousemove', function(e) { thisObject.getMouseY(e); }, false);
		else
			document.attachEvent('onmousemove', function(e) { thisObject.getMouseY(e); });
		
		this.initialise = true;
	}
	
	/*
	*	this.adapterHauteurScroll()
	*	adapte la hauteur de la scrollbar en fonction du contenu qui y est associe
	*	cette methode devrait etre appelee a chaque fois que le contenu change
	*
	*	retourne la hauteur CSS defini si elle n'est pas a 100%, retourne offsetHeight sinon
	*/
	this.adapterHauteurScroll = function()
	{
		if (!this.initialise)
			this.initialiser();
		
		var necessaire = this.divContenu.offsetHeight > this.divContenu.parentNode.offsetHeight;
		var contenu = this.divContenu.innerHTML != "";
		
		var nouvelleHauteur;
		if (necessaire)
		{
			nouvelleHauteur = parseInt(this.divScroll.parentNode.offsetHeight * (this.divContenu.parentNode.offsetHeight / this.divContenu.offsetHeight));
			this.divScroll.style.height = nouvelleHauteur + "px";
		}
		else
		{
			this.divScroll.style.height = "100%";
			nouvelleHauteur = this.divScroll.offsetHeight;
		}
		
		this.setPosition(0);
		
		var barreVisibility = "";
		switch (this.parametres.affichageBarre)
		{
			case Scroll.affichageBarre.toujoursVisible:
				barreVisibility = "visible";
				break;
			case Scroll.affichageBarre.visibleSiContenu:
				barreVisibility = contenu ? "visible" : "hidden";
				break;
			case Scroll.affichageBarre.visibleSiNecessaire:
			default:
				barreVisibility = necessaire ? "visible" : "hidden";
		}
		this.barreScroll.style.visibility = barreVisibility;
		
		var curseurDisplay = "";
		switch (this.parametres.affichageCurseur)
		{
			case Scroll.affichageBarre.visibleSiNecessaire:
				curseurDisplay = necessaire ? "block" : "none";
				break;
			case Scroll.affichageBarre.visibleSiContenu:
				curseurDisplay = contenu ? "block" : "none";
				break;
			case Scroll.affichageBarre.toujoursVisible:
			default:
				curseurDisplay = "block";
		}
		this.divScroll.style.display = curseurDisplay;
		
		return nouvelleHauteur;
	}
	
	/*
	*	this.demarrerScrollFleches()
	*	demarre le scroll lorsqu'on utilise les fleches
	*	
	*	- vitesse : int, vitesse de scroll en pixels
	*/
	this.demarrerScrollFleches = function(vitesse)
	{
		if (!this.scrollActif && this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight > 0)
		{
			this.vitesse = vitesse;
			this.setPositionFleches();
		}
	}
	
	/*
	*	this.demarrerScrollFlecheHaut()
	*	demarre le scroll lorsqu'on utilise la fleche du haut
	*/
	this.demarrerScrollFlecheHaut = function()
	{
		this.demarrerScrollFleches(this.parametres.vitesseScrollFlechesLent);
	}
	
	/*
	*	this.demarrerScrollFlecheBas()
	*	demarre le scroll lorsqu'on utilise la fleche du bas
	*/
	this.demarrerScrollFlecheBas = function()
	{
		this.demarrerScrollFleches(-1 * this.parametres.vitesseScrollFlechesLent);
	}
	
	/*
	*	this.setVitesseScrollFlecheLenteHaut()
	*	utilise la vitesse lente de scroll vers le haut
	*/
	this.setVitesseScrollFlecheLenteHaut = function()
	{
		this.vitesse = this.parametres.vitesseScrollFlechesLent;
	}
	
	/*
	*	this.setVitesseScrollFlecheRapideHaut()
	*	utilise la vitesse rapide de scroll vers le haut
	*/
	this.setVitesseScrollFlecheRapideHaut = function()
	{
		this.vitesse = this.parametres.vitesseScrollFlechesRapide;
	}
	
	/*
	*	this.setVitesseScrollFlecheLenteBas()
	*	utilise la vitesse lente de scroll vers le bas
	*/
	this.setVitesseScrollFlecheLenteBas = function()
	{
		this.vitesse = -1 * this.parametres.vitesseScrollFlechesLent;
	}
	
	/*
	*	this.setVitesseScrollFlecheRapideBas()
	*	utilise la vitesse rapide de scroll vers le bas
	*/
	this.setVitesseScrollFlecheRapideBas = function()
	{
		this.vitesse = -1 * this.parametres.vitesseScrollFlechesRapide;
	}
	
	/*
	*	this.setPositionFleches()
	*	fonction appelee en boucle pour deplacer le contenu lorsque le scroll avec les fleches est utilise
	*/
	this.setPositionFleches = function()
	{
		if ((this.vitesse < 0 && this.position > -1 * (this.divContenu.offsetHeight - this.divContenu.parentNode.offsetHeight)) || (this.vitesse > 0 && this.position < 0))
			this.position += this.vitesse;
		
		this.setPosition();
		
		if (this.vitesse != null)
			this.timerScroll = setTimeout(function() { thisObject.setPositionFleches(); }, this.parametres.delaiScrollFleches);
	}
	
	/*
	*	this.setPosition()
	*	deplace le contenu et la scrollbar
	*
	*	- position : nouvelle position
	*/
	this.setPosition = function(position)
	{
		if (position != null)
			this.position = -position;
		
		if (this.position > 0 || this.divContenu.offsetHeight < this.divContenu.parentNode.offsetHeight)
		{
			this.position = 0;
			this.arreterScrollFleches();
		}
		else if (this.position < -1 * (this.divContenu.offsetHeight - this.divContenu.parentNode.offsetHeight))
		{
			this.position = -1 * (this.divContenu.offsetHeight - this.divContenu.parentNode.offsetHeight);
			this.arreterScrollFleches();
		}
		
		this.divContenu.style.top = this.position + "px";
		
		var differenceOffsetHeightDiv = this.divContenu.parentNode.offsetHeight - this.divContenu.offsetHeight;
		if (differenceOffsetHeightDiv != 0)
			this.positionScroll = parseInt((this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight) * this.divContenu.offsetTop / differenceOffsetHeightDiv);
		else
			this.positionScroll = 0;
		
		this.divScroll.style.top = this.positionScroll + "px";
	}
	
	/*
	*	this.arreterScrollFleches()
	*	arrete le scroll avec les fleches
	*/
	this.arreterScrollFleches = function()
	{
		if (this.timerScroll != null)
			clearTimeout(this.timerScroll);
		this.vitesse = null;
	}
	
	/*
	*	this.setScroll()
	*	active ou desactive le scroll avec la barre
	*	
	*	- actif : bool, nouvel etat
	*/
	this.setScroll = function(actif)
	{
		this.scrollActif = actif;
	}
	
	/*
	*	this.getMouseY()
	*	gestion de la position de la souris pour le scroll avec la barre
	*/
	this.getMouseY = function(e)
	{
		if (document.all)
			var mouseY = event.clientY + document.body.scrollTop;
		else
			var mouseY = e.pageY;
		if (this.scrollActif && this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight > 0)
		{
			this.positionScroll = mouseY - this.positionMouseScroll;
			if (this.positionScroll < 0)
				this.positionScroll = 0;
			if (this.positionScroll > this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight)
				this.positionScroll = this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight;
			this.divScroll.style.top = this.positionScroll+"px";
			this.position = parseInt((this.divContenu.parentNode.offsetHeight - this.divContenu.offsetHeight) * this.divScroll.offsetTop / (this.divScroll.parentNode.offsetHeight - this.divScroll.offsetHeight));
			this.divContenu.style.top = this.position+"px";
		}
		else
			this.positionMouseScroll = mouseY - this.divScroll.offsetTop;
	}
	
	/*
	*	this.gererMolette()
	*	gestion de la molette de la souris
	*/
	this.gererMolette = function(event)
	{
		if (this.divContenu.offsetHeight > this.divContenu.parentNode.offsetHeight)
		{
			var delta = 0;
			
			if (!event)
				event = window.event;
			
			if (event.wheelDelta)
				delta = event.wheelDelta / 120;
			else if (event.detail)
				delta = -event.detail / 3;
			
			if (delta)
			{
				this.position += delta * this.parametres.hauteurScrollMolette;
				this.setPosition();
			}
			
			if (event.preventDefault)
				event.preventDefault();
			event.returnValue = false;
		}
	}
}
Scroll.affichageBarre = {
	toujoursVisible: 0,
	visibleSiNecessaire: 1,
	visibleSiContenu: 2
};