/**
 * copyright (c) 2005-2007 - lx barjon <lx.barjon@gmail.com>
 * class verticalScroller
 * version : 0.7 (13-12-2007)
 * licence : GNU GPL
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************
 *
 * @author lx barjon <lx.barjon@gmail.com>
 * @access public
 * @version 0.s
 */

var verticalScroller = Class.create();
verticalScroller.prototype = {
	initialize: function( scrollerID, options ) {
		this.version = '0.7';

		if ( !document.getElementById ) return;

		// options
		Object.extend( this.options = {
			pathToImgs: 'images/',
			imgUp: 'scroll_UP.png',
			imgDown: 'scroll_DOWN.png',
			//imgUpOff: 'fleche_haut.png',
			//imgDownOff: 'fleche_bas.png',
			autoScroll: false,
			step: 1, // bigger -> faster
			speed: 3, // smaller -> faster
			stepModificator: 5, // used in incStep() and decStep()
			forceScrollHandles: false
		}, options || {} );
		this.originalStep = this.options.step;

		this.scroller = $(scrollerID);
		if ( !this.scroller ) return false;
		this.scroller.style.overflow = 'hidden';

		// insert scroll options
		new Insertion.After( this.scroller, '<div id="goUp_'+this.scroller.id+'" class="goUp">' +
		'<img id="goUpImg_'+this.scroller.id+'" src="'+this.options.pathToImgs + this.options.imgUp+'" alt="move up" /></div>' +
		'<div id="goDown_'+this.scroller.id+'" class="goDown">' +
		'<img id="goDownImg_'+this.scroller.id+'" src="'+this.options.pathToImgs + this.options.imgDown+'" alt="move down" /></div>' );
		
		if ( this.options.autoScroll) {
			this.direction = 'up';
			var blankContent = '<div style="display:block; height:'+this.scroller.offsetHeight+'px;"></div>';
			// insert blank before and after the content
			new Insertion.Top(this.scroller, blankContent );
			new Insertion.Bottom( this.scroller, blankContent );
			Event.observe( this.scroller, 'mouseover', this.stop.bind(this), false );
			Event.observe( this.scroller, 'mouseout', this.start.bind(this), false );
			Event.observe( $('goUp_'+this.scroller.id), 'click', this.goUp.bind(this), false );
			Event.observe( $('goDown_'+this.scroller.id), 'click', this.goDown.bind(this), false );
			Event.observe( window, 'load', this.start.bind(this), false );
		} else {
			//  faire des fonctions pour afficher tout un dom tri et pouvoir le remettre en état après
			if (this.scroller.parentNode.style.display == 'none') {
				this.scroller.parentNode.style.display = 'block';
				var mustHide = true;
			}
			var needScroll = ( this.scroller.scrollHeight > this.scroller.offsetHeight );
			if ( mustHide ) this.scroller.parentNode.style.display = 'none';
			// pas besoin de scroll ? -> on cache les flèches de navigation
			if ( !needScroll && !this.options.forceScrollHandles ) {
				$('goUp_'+this.scroller.id).style.display = 'none';
				$('goDown_'+this.scroller.id).style.display = 'none';
			} else {
			// sinon on accroche les events
				Event.observe( $('goDown_'+this.scroller.id), 'mouseover', this.moveUp.bind(this), false );
				Event.observe( $('goDown_'+this.scroller.id), 'mouseout', this.stop.bind(this), false );
				Event.observe( $('goDown_'+this.scroller.id), 'mouseout', this.restoreStep.bind(this), false );
				Event.observe( $('goDown_'+this.scroller.id), 'click', this.incStep.bind(this), false );
				Event.observe( $('goUp_'+this.scroller.id), 'mouseover', this.moveDown.bind(this), false );
				Event.observe( $('goUp_'+this.scroller.id), 'mouseout', this.stop.bind(this), false );
				Event.observe( $('goUp_'+this.scroller.id), 'mouseout', this.restoreStep.bind(this), false );
				Event.observe( $('goUp_'+this.scroller.id), 'click', this.incStep.bind(this), false );
			}
		}
	},

	moveUp: function() {
		if ( this.scroller.scrollTop < (this.scroller.scrollHeight - this.scroller.offsetHeight) ) {
			this.scroller.scrollTop = this.scroller.scrollTop + this.options.step;
		} else if ( this.options.autoscroll ) {
			this.scroller.scrollTop = 0;
		}
		if ( !this.options.autoscroll ) {
			this.timeout = setTimeout( this.moveUp.bind(this), this.options.speed*10 );
		}
	},
 	moveDown: function() {
		if ( this.scroller.scrollTop > 0 ) {
				this.scroller.scrollTop = this.scroller.scrollTop - this.options.step;
			} else if ( this.options.autoscroll ) {
				this.scroller.scrollTop = this.scroller.scrollHeight;
		}
		if ( !this.options.autoscroll ) {
			this.timeout = setTimeout( this.moveDown.bind(this), this.options.speed*10 );
		}
	},

	start: function() {
		this.timeout = setTimeout( this.move.bind(this), this.options.speed*10 );
	},
	stop: function() {
		if ( this.timeout ) clearTimeout(this.timeout);
	},

	move: function() {
		if ( this.direction == 'up' ) this.moveUp();
		else this.moveDown();
		this.timeout = setTimeout( this.move.bind(this), this.options.speed*10 );
	},
	goDown: function() {
		this.direction = 'down';
	},
	goUp: function() {
		this.direction = 'up';
	},

	incStep: function() {
		this.options.step += this.options.stepModificator;
	},

	decStep: function() {
		this.options.step -= this.options.stepModificator;
	},
	restoreStep: function() {
		this.options.step = this.originalStep;
	}
}

