//------------------------------------------------------------------------------
// CLASS Slider
//------------------------------------------------------------------------------
// 
// Crea e gestisce uno slider, costituito da due layer: cursDIV (layer del cursore)
// e sliderDIV (layer della barra), definiti e personalizzati in HTML.
// Testato su IE 5.0, Mozilla 1.7 & Firefox 1.0, Opera 7
//
// Francesco Gabbrielli
// v1.1 - 21/10/06
//
//------------------------------------------------------------------------------
//
//
	function Slider(cursDIV,sliderDIV,minSize,maxSize) {

		this.reset() ;

		this.selected = 0 ;
		this.sliderDIV = sliderDIV ;
		this.cursDIV = cursDIV ;
		this.length = parseInt(sliderDIV.style.width) ;
		this.cursLength = parseInt(cursDIV.style.width) ;
		this.size = 0 ;
		this.dragging = false ;
		this.dragActive = false ;
		this.lastSelection = -1 ;

		this.minSize = minSize ;
		this.maxSize = maxSize ;

		//disabilitazione selezione sullo slider
		if(window.sidebar) {
			sliderDIV.onmousedown=this.disableSelect ;
			sliderDIV.onclick=this.reEnable ;
		} else {
			sliderDIV.onselectstart=new Function ("return false") ;
			sliderDIV.ondragstart=new Function ("return false") ;
		}

	}

	Slider.prototype.activate = function() {
		this.active = true ;
		//salva l'istanza dello slider come variabile statica (un solo slider alla volta puo' essere trascinato!!)
		var instance = this ;
		this.cursDIV.onmousedown = function() {
			if(instance.active && instance.values.length>1) {
				//per la definizione di handlers privati fuori dal costruttore
				Slider.prototype.instance = instance ;
				//inizia il trascinamento vero e proprio
				instance.dragging = true ;
				//Slider.prototype.startDrag.apply(instance,arguments) ;
				//controlla tramite il mouse move sull'intero documento che il mouse non esca dal cursore
				instance.saveDocMove = document.onmousemove ;
				//salva l'handler sul documento per ripristinarlo alla fine del trascinamento
				document.onmousemove = instance.controlDrag ;
			}
		}
		this.sliderDIV.onmousemove = this.drag ;
		this.sliderDIV.onmouseup = this.stopDrag ;
		this.cursDIV.onmouseup = this.stopDrag ;
		this.sliderDIV.onmousedown = function () {

			if(instance.active && !Slider.prototype.instance) {
				var evt = arguments.length?arguments[0]:event ;
				var d = evt.clientX-parseInt(instance.cursDIV.style.left)-parseInt(instance.sliderDIV.offsetLeft) ;
				var steps = parseInt(instance.values.length / 10) ;
				if(steps<1) steps = 1 ;
				var newSel = d>0 ? instance.selected+steps : instance.selected-steps ;
				instance.setSelection(newSel) ;
			}
			
			return false ;
		}
	}
	
	Slider.prototype.deactivate = function() {
		this.active = false ;
		this.cursDIV.onmousedown = null ;
		this.cursDIV.onmouseup = null ;
		this.sliderDIV.onmousemove = null ;
		this.sliderDIV.onmousedown = null ;
		this.sliderDIV.onmouseup = null ;
	}

	Slider.prototype.reset = function() {
	    this.values = new Array() ;
	    this.titles = new Array() ;
	    //listeners chiamati al cambio di stato
	    this.changeListeners = new Array() ;
	    this.changeListenerObjects = new Array() ;//+ flessibile di document o solo casino???
	    //listeners chiamati durante il trascinamento
	    this.dragListeners = new Array() ;
	    this.dragListenerObjects = new Array() ;
	}
	
	/** Aggiunge una coppia valore-titolo allo slider */
	Slider.prototype.addValue = function(val, title) {
	    this.insertValue(this.values.length,val,title) ;
	}

	/** Inserisce una coppia valore-titolo allo slider all'indice specificato */
	Slider.prototype.insertValue = function(index, val, title) {
	    this.values.splice(index,0,val) ;
	    this.titles.splice(index,0,title) ;
	    this.computeSize() ;
	}

	Slider.prototype.removeValue = function(index) {
	    this.values.splice(index,1) ;
	    this.titles.splice(index,1) ;
	    this.computeSize() ;
	}

	Slider.prototype.computeSize = function() {
	    this.size = parseInt(this.length/this.values.length) ;
	    if(this.size < this.minSize)
		    this.size = this.minSize ;
	    if(this.size > this.maxSize)
		    this.size = this.maxSize ;
	}

	Slider.prototype.goFirst = function() {
	    this.setSelection(0) ;
	}
	
	Slider.prototype.goLast = function() {
	    this.setSelection(this.values.length-1) ;
	}

	/** Avanza lo slider di una posizione */
	Slider.prototype.next = function() {
		if(this.selected<this.values.length-1) {
			this.setSelection(this.selected+1) ;
			return true ;
		} else
			return false ;
	}

	/** Retrocede lo slider di una posizione */
	Slider.prototype.previous = function() {
		if(this.selected>0) {
			this.setSelection(this.selected-1) ;
			return true ;
		} else
			return false ;
	}

	/** Reimposta la selezione corrente ma solo ridisegnando il cursore */
	Slider.prototype.refreshSelection = function(index) {
		if(index<0)
		    this.selected = 0 ;
		else if(index>=this.values.length)
		    this.selected = this.values.length-1 ;
		else
		    this.selected = index ;
		this.redraw() ;
	}

	/** Reimposta la selezione corrente rilanciando eventi e tutto quanto */
	Slider.prototype.setSelection = function(index) {
		this.refreshSelection(index) ;
		if(this.lastSelection!=this.selected) {
			this.fireChange() ;
			this.lastSelection = this.selected ;
		}
	}
	
	/**
	 * Imposta la posizione dello slider in base all'offset in pixel all'interno della barra
	 * in modo leggero, senza lanciare eventi
	 */
	Slider.prototype.setOffset = function(x) {
		this.refreshSelection(parseInt((this.values.length)*x/(this.length-this.cursLength))) ;
	}
	
	/** Imposta la posizione in base ai valori dello slider */
	Slider.prototype.setValue = function(p) {
		var i ;
		for(i=0;i<this.values.length;i++) {
			if(this.values[i]>=p) {
				if(this.lastSelection!=i) {
					this.lastSelection = i ;//per evitare di lanciare eventi!
					this.setSelection(i) ;//this.values[i]==p?i:i-1 ;
				}
				break ;
			}
		}
	}

	/** Restituisce il valore corrente dello slider */
	Slider.prototype.getValue = function() {
		return this.values[this.selected] ;
	}

	/** Restituisce il titolo corrente dello slider */
	Slider.prototype.getTitle = function() {
		return this.titles[this.selected] ;
	}

		/** Ridisegna lo slider: attenzione ai DOM-CSS!! */
	Slider.prototype.redraw = function() {
		this.cursDIV.style.width = this.size+"px" ;
		if(this.values.length>1) {
			this.cursDIV.title = (this.selected+1)+' di '+(this.values.length) ;
			this.cursDIV.style.left = parseInt((this.length-this.size)*this.selected*1.0/(this.values.length-1))+"px" ;
		} else {
			this.cursDIV.title = "100%" ;
			this.cursDIV.style.left = "0px" ;
		}
	}

	/** Aggiunge un listener per il cambio di stato dello slider */	
	Slider.prototype.addChangeListener = function(l,obj) {
		if(!obj)
			obj = document ;
		this.changeListeners.push(l) ;
		this.changeListenerObjects.push(obj) ;
	}

	Slider.prototype.removeChangeListener = function(l) {
	    var i ;
	    for(i=0;i<this.changeListeners.length;i++) {
		if(this.changeListeners[i]==l) {
		    this.changeListeners.remove(i) ;
		    this.changeListenerObjects.remove(i) ;
		    break ;
		}
	    }
	}
	
	Slider.prototype.removeChangeListeners = function() {
		this.changeListeners = new Array() ;
		this.changeListenerObjects = new Array() ;
	}
	
	/** Aggiunge un listener per il trascinamento dello slider */	
	Slider.prototype.addDragListener = function(l,obj) {
		this.dragListeners.push(l) ;
		this.dragListenerObjects.push(obj) ;
	}
	
	Slider.prototype.removeDragListeners = function() {
		this.dragListeners = new Array() ;
		this.dragListenerObjects = new Array() ;
	}

	Slider.prototype.fireChange = function() {
		var i ;
		if(this.active)
			for(i=0;i<this.changeListeners.length;i++) {
				this.changeListeners[i].call(this.changeListenerObjects[i],this.getValue()) ;
                        }
	}
	
	Slider.prototype.fireDrag = function() {
		var i ;
		if(this.active)
			for(i=0;i<this.dragListeners.length;i++)
				this.dragListeners[i].call(this.dragListenerObjects[i],this.getValue()) ;
	}
	

// Handlers per il drag
//------------------------------------------------------------------------------
//
	//Slider.prototype.startDrag = function() {
		//Slider.prototype.instance.lastSelection = Slider.prototype.instance.getValue() ;
		//Slider.prototype.instance.dragging = true ;
	//}
	
	Slider.prototype.drag = function() {
		var x ;
		var inst = Slider.prototype.instance ;
		var evt = arguments.length?arguments[0]:event ;
		
		if(inst && inst.dragging && inst.active) {
			inst.dragActive=true ;
			x = evt.clientX-parseInt(inst.sliderDIV.offsetLeft)-inst.cursLength/2 ;
			if(x<0) x=0 ;
			if(x>inst.length-1-inst.cursLength) x=inst.length-1-inst.cursLength ;
			var old = inst.selected ;
			inst.setOffset(x) ;
			if(old!=inst.selected)
				inst.fireDrag() ;
		}
	}
	
	Slider.prototype.stopDrag = function() {
		var inst = Slider.prototype.instance ;
		if(inst && inst.dragging && inst.active) {
			inst.dragging = false ;
			if(inst.lastSelection!=inst.selected)
				inst.fireChange() ;
			document.onmousemove = inst.saveDocMove ;
			Slider.prototype.instance = null ;
		}
	}
	
	/** Gufo sulle spalle del drag(): appena quello non viene chiamato interrompe il trascinamento */
	Slider.prototype.controlDrag = function() {
		var inst = Slider.prototype.instance ;
		if(inst) {
			if(!inst.dragActive)
				inst.stopDrag() ;
			inst.dragActive=false ;
		}
	}
//
//------------------------------------------------------------------------------

	Slider.prototype.disableSelect = function() {return false;}
	Slider.prototype.reEnable = function() {return true;}
	
//
//
//------------------------------------------------------------------------------
// FINE CLASS Slider
//-----------------------------------------------------------------------------

