var scrollShow = new Class( {
	
	options: {
		className: 'scrollShow_holder',
		autoHeight: false,
		position: 'L',
		startElement: 0,
		
		swHolder: null,
		swClassName: 'scrollShow_switchButton',
		swEffectTransition: Fx.Transitions.Circ.easeOut,
		swEffectDuration: 1000,
		swGenerate: false,
		
		scHolder: null,
		scClassName: 'scrollShow_scrollButton',
		scEffectTransition: Fx.Transitions.Circ.easeInOut,
		scEffectDuration: 1000,
		scLabelLeft: 'prev',
		scLabelRight: 'next',
		scGenerate: true,
		scOnLeftOver: null,
		scOnLeftOut: null,
		scOnLeftClick: null,
		scOnRightOver: null,
		scOnRightOut: null,
		scOnRightClick: null,
		
		circle: true
	},
	
	initialize: function ( obj, options ) {
		this.setOptions( options );
		this.holder = $(obj);
		
		this.holder.setStyles( { 'overflow': 'hidden', 'position': 'relative' } );
		this.holder.setStyle( 'visibility', 'hidden' );
		
		this.holderWidth = this.holder.getSize().size.x;
		this.holderHeight = this.holder.getSize().size.y;
		this.maxHeight = 0;
		this.maxWidth = 0;
		this.barWidth = 0;
		this.elements = new Array();
		
		this.scrollInProgress = false;
		this.actPos = 0;
		
		this.bar = new Element( 'div' ).setStyles( { 'position': 'absolute', 'top': '0px' } );
		this.innerBar = new Element( 'div' ).setStyles( { 'position': 'relative' } ).injectInside( this.bar );
		
		var elements = this.holder.getChildren();
		elements.each( function ( obj, i ) {
			var size = obj.getSize();
			obj.setStyles( { 'position': 'absolute', 'top': '0px', 'left': this.actPos + 'px' } ),
			this.maxHeight = Math.max( this.maxHeight, size.size.y );
			this.maxWidth = Math.max( this.maxWidth, size.size.x );
			this.barWidth += size.size.x;
			obj.injectInside( this.innerBar );
			this.elements.push( {
				object: obj,
				position: this.actPos
			} );
			this.actPos += size.size.x;
		}, this );
		
		this.bar.setStyle( 'width', this.barWidth + 'px' );
		this.innerBar.setStyle( 'width', this.barWidth + 'px' );
		
		if( this.options.autoHeight ) {
			this.holder.setStyle( 'height', this.maxHeight );
			this.bar.setStyle( 'height', this.maxHeight );
		}
		
		this.bar.injectInside( this.holder );
		
		//this.scrollEffect = new Fx.Scroll( this.holder, {
		this.scrollEffect = new Fx.Style( this.bar, 'left', {
			transition: this.options.scEffectTransition,
			duration: this.options.scEffectDuration,
			onStart: function () { this.scrollInProgress = true; }.bind( this ),
			onComplete: function () { this.scrollInProgress = false; }.bind( this ),
			wait: true
		} );
		
		this.switchEffect = new Fx.Style( this.bar, 'left', {
			transition: this.options.swEffectTransition,
			duration: this.options.swEffectDuration,
			onStart: function () { this.scrollInProgress = true; }.bind( this ),
			onComplete: function () { this.scrollInProgress = false; }.bind( this ),
			wait: true
		} );
		
		this.prv_scrollButtons();
		this.prv_switchButtons();
		
		this.set( this.options.startElement );
		this.holder.setStyle( 'visibility', 'visible' );
	},
	
	set: function( number ) {
		if( number >= this.elements.length || number < 0 )
			return false;
		//this.holder.scrollTo( -1*this.elements[number].position, 0 );
		this.bar.setStyle( 'left', -1*this.elements[number].position + 'px' );
		this.actNumber = number;
		
		this.disableScButtons();
		this.disableSwButtons();
	},
	
	goTo: function( number, effect ) {
		if( number >= this.elements.length || number < 0 || this.scrollInProgress )
			return false;
		effect.start( -1*this.elements[number].position );
		this.actNumber = number;
		
		this.disableScButtons();
		this.disableSwButtons();
	},
	
	prv_switchButtons: function ( elNum ) {
		this.switchButtons = new Array();
		
		if( this.options.swHolder == null && this.options.swGenerate == false)
			return false;
		
		if( !this.options.swGenerate )
			this.switchButtons = $ES('.' + this.options.swClassName, this.options.swHolder );
		else {
			this.switchButtons = new Array();
			for( i=0; i<this.elements.length; i++ )
				this.switchButtons.push( new Element( 'div' ).addClass( this.options.swClassName ).setHTML( i+1 ).injectInside( this.options.swHolder ) );
		}
		
		for( i=0; i<this.switchButtons.length; i++ ) {
			this.switchButtons[i].addEvent( 'mouseover', this.swOnOver.bind( this, i ) );
			this.switchButtons[i].addEvent( 'mouseout', this.swOnOut.bind( this, i ) );
			this.switchButtons[i].addEvent( 'click', this.swOnClick.bind( this, i ) );
		}
	},
	
	prv_scrollButtons: function () {
		if( this.options.scHolder == null && this.options.scGenerate == false)
			return false;
		
		this.scrollButtons = {};
		if( !this.options.scGenerate ) {
			this.scLeftButton = $E( '.' + this.options.scClassName + '_left', this.options.scHolder );
			this.scRightButton = $E( '.' + this.options.scClassName + '_right', this.options.scHolder );
		}
		else {
			this.scLeftButton = new Element( 'div' ).addClass( this.options.scClassName + '_left' ).setStyles( { 'visibility': 'hidden', 'float': 'left' } ).setHTML(this.options.scLabelLeft!=null?this.options.scLabelLeft:'').injectInside( document.body );
			this.scRightButton = new Element( 'div' ).addClass( this.options.scClassName + '_right' ).setStyles( { 'visibility': 'hidden', 'float': 'left' } ).setHTML(this.options.scLabelRight!=null?this.options.scLabelRight:'').injectInside( document.body );
			var dims = this.scLeftButton.getSize();
			var loc = this.holder.getCoordinates();
			
			//alert( Json.toString( dims ) + "\n\n" + Json.toString( loc ) );
			
			this.scLeftButton.setStyles( {
				position: 'absolute',
				top: loc.top + ( this.holderHeight - dims.size.y ) / 2 + 'px',
				left: loc.left + 'px'
			} );
			var dims = this.scRightButton.getSize();
			this.scRightButton.setStyles( {
				position: 'absolute',
				top: loc.top + ( this.holderHeight - dims.size.y ) / 2 + 'px',
				left: loc.left + this.holderWidth - dims.size.x + 'px'
			} );
		}
		if( this.scLeftButton ) {
			this.scLeftButton.addEvent( 'mouseover', this.scOnLeftOver.bind( this, this.scLeftButton ) );
			this.scLeftButton.addEvent( 'mouseout', this.scOnLeftOut.bind( this, this.scLeftButton ) );
			this.scLeftButton.addEvent( 'click', this.scOnLeftClick.bind( this, this.scLeftButton ) );
			this.scLeftButton.setStyle( 'visibility', 'visible' );
		}
		if( this.scRightButton ) {
			this.scRightButton.addEvent( 'mouseover', this.scOnRightOver.bind( this, this.scRightButton ) );
			this.scRightButton.addEvent( 'mouseout', this.scOnRightOut.bind( this, this.scRightButton ) );
			this.scRightButton.addEvent( 'click', this.scOnRightClick.bind( this, this.scRightButton ) );
			this.scRightButton.setStyle( 'visibility', 'visible' );
		}
		
	},
	
	disableScButtons: function () {
		if( this.scRightButton ) {
			if( this.actNumber == this.elements.length - 1 && !this.options.circle ) {
				this.scRightButton.isBttDisabled = true;
				this.scRightButton.addClass( this.options.scClassName + '_right_disabled' );
			}
			else {
				this.scRightButton.isBttDisabled = false;
				this.scRightButton.removeClass( this.options.scClassName + '_right_disabled' );
			}
		}
		if( this.scLeftButton ) {
			if( this.actNumber == 0 && !this.options.circle ) {
				this.scLeftButton.isBttDisabled = true;
				this.scLeftButton.addClass( this.options.scClassName + '_left_disabled' );
			}
			else {
				this.scLeftButton.isBttDisabled = false;
				this.scLeftButton.removeClass( this.options.scClassName + '_left_disabled' );
			}
		}
	},
	
	disableSwButtons: function () {
		for( i=0; i<this.switchButtons.length; i++ ) {
			if( i == this.actNumber )
				this.switchButtons[i].addClass( this.options.swClassName + '_actual' );
			else
				this.switchButtons[i].removeClass( this.options.swClassName + '_actual' );
		}
	},
	
	scOnLeftOver: function () {
		if( $type(this.options.scOnLeftOver) == 'function' )
			this.options.scOnLeftOver();
		this.scLeftButton.addClass( this.options.scClassName + '_left_hover' );
	},
	
	scOnLeftOut: function () {
		if( $type(this.options.scOnLeftOut) == 'function' )
			this.options.scOnLeftOut();
		this.scLeftButton.removeClass( this.options.scClassName + '_left_hover' );
	},
	
	scOnLeftClick: function () {
		if( this.scrollInProgress || this.scLeftButton.isBttDisabled )
			return false;
		
		if( this.actNumber == 0 )
			number = this.elements.length - 1;
		else
			number = this.actNumber - 1;
		
		if( $type(this.options.scOnLeftClick) == 'function' )
			this.options.scOnLeftClick.attempt( number, this );
		
		this.goTo( number, this.scrollEffect );
	},
	
	scOnRightOver: function () {
		if( $type(this.options.scOnRightOver) == 'function' )
			this.options.scOnRightOver();
		this.scRightButton.addClass( this.options.scClassName + '_right_hover' );
	},
	
	scOnRightOut: function () {
		if( $type(this.options.scOnRightOut) == 'function' )
			this.options.scOnRightOut();
		this.scRightButton.removeClass( this.options.scClassName + '_right_hover' );
	},
	
	scOnRightClick: function () {
		if( this.scrollInProgress || this.scRightButton.isBttDisabled )
			return false;
		
		if( this.actNumber == this.elements.length - 1 )
			number = 0;
		else
			number = this.actNumber + 1;
		
		if( $type(this.options.scOnRightClick) == 'function' )
			this.options.scOnRightClick.attempt( number, this );
		
		this.goTo( number, this.scrollEffect );
	},
	
	swOnOver: function ( btt ) {
		if( $type(this.options.swOnOver) == 'function' )
			this.options.swOnOver();
		this.switchButtons[btt].addClass( this.options.swClassName + '_hover' );
	},
	
	swOnOut: function ( btt ) {
		if( $type(this.options.swOnOut) == 'function' )
			this.options.swOnOut();
		this.switchButtons[btt].removeClass( this.options.swClassName + '_hover' );
	},
	
	swOnClick: function ( btt ) {
		if( this.scrollInProgress || this.actNumber == btt )
			return false;
		
		if( $type(this.options.swOnClick) == 'function' )
			this.options.swOnClick.attempt( number, this );
		
		this.goTo( btt, this.switchEffect );
	}
	
} );

scrollShow.implement(new Options);
