/*--------------------------------------
  ShowcaseSlider
----------------------------------------
  <!> Requirements
  ImageZoomer requires frameworks
  Prototype.js and script.aculo.us.
----------------------------------------
                            8 Aug 2010
                     (C) Kazuhisa Togo
--------------------------------------*/


var ShowcaseSlider = Class.create({
	// Set default values
	defaults: {
		delay: 4,
		duration: 1
	},

	//------------------------------
	// Constructor
	//------------------------------

	initialize: function( selector, options ){
		// Initialize variables
		this.nodes = {};
		this.options = options || {}; 
		this.currentSelection = 0;
		this.autoplay_enabled = Object.isUndefined( this.options.autoPlay ) ? true : !! this.options.autoPlay;
		this.autostop_enabled = Object.isUndefined( this.options.autoStop ) ? true : !! this.options.autoStop;
		this.delay    = ( this.options.delay    || this.defaults.delay    );
		this.duration = ( this.options.duration || this.defaults.duration );

		// Get nodes
		if( Object.isString( selector )){
			this.nodes.items = $$( selector );
		} else {
			this.nodes.items = [];
			$A( selector ).each( function( val, key ){
				this.nodes.items[key] = val;
			}.bind(this));
		}

		// Show/hide nodes
		this.nodes.items.each( function( e, i ){
			if( i > 0 ) e.hide();
			else e.show();
		});

		// Bind self object
		[ 'select', 'forward', 'reverse', 'play', 'stop', 'observe' ].each( function( key ){
			this[key] = this[key].bind(this);
		}.bind(this));

		// Enable autoplay
		if( this.autoplay_enabled ) this.play();

		// Start observing trigger event
		if( this.options.trigger ){
			for( var key in this.options.trigger ) this.observe( this.options.trigger[key], key );
		}

		// Execute onInitialized callback
		if( this.options.onInitialized ) try{( this.options.onInitialized.bind( this ))();} catch(e){alert(e);}
	},


	//------------------------------
	// Select item
	//------------------------------

	select: function( selection ){
		// Calculate selection number
		if( isNaN( selection ) && ! Object.isString( selection )) selection = undefined;
		if( selection !== 0 && ( selection == '+' || selection == undefined || selection == '' )) selection = this.currentSelection + 1;
		else if( selection == '-' ) selection = this.currentSelection - 1;
		if( selection && ! isNaN( selection )){
			if( selection < 0 ) selection = this.nodes.items.length - 1;
			if( selection > this.nodes.items.length - 1 ) selection = 0;
		}

		if( this.currentSelection != selection ){
			// Select
			// If effect callback is set, it will use that.
			(( this.options.effect || function( next, current ){
				if( current.fadeEffect && current.fadeEffect.cancel ) current.fadeEffect.cancel();
				if( next.fadeEffect    && next.fadeEffect.cancel    ) next.fadeEffect.cancel();
				current.fadeEffect = new Effect.Fade( current, { duration: this.duration });
				next.fadeEffect    = new Effect.Appear(  next, { duration: this.duration });
			}).bind(this))( this.nodes.items[selection], this.nodes.items[this.currentSelection]);

			// Execute onSelected callback
			if( this.options.onSelected ) try{
				( this.options.onSelected.bind(this))( selection, this.currentSelection );
			} catch(e){alert(e);};

			this.currentSelection = selection;
		}

		// Disable autoplay
		if( this.autostop_enabled ){
			this.stop();
		} else if( this.autoplay_enabled ){
			this.play();
		}
	},

	// Forward
	forward: function(e){
		this.select('+');
		try{ if( e ||( e = window.event || event )) Event.stop(e); } catch(err){}
	},

	// Backward
	reverse: function(e){
		this.select('-');
		try{ if( e ||( e = window.event || event )) Event.stop(e); } catch(err){}
	},


	//------------------------------
	// Timer
	//------------------------------

	// Recursive timer
	autoplay: function(){
		// Forward
		this.forward();
		// Recursive call
		this.play();
	},

	// Enable autoplay
	play: function(e){
		this.stop(e);
		this.autoplay_enabled = true;
		this.autoplay_timer = setTimeout( this.autoplay.bind(this),  this.delay * 1000 );
	},

	// Disable autoplay
	stop: function(e){
		this.autoplay_enabled = false;
		if( this.autoplay_timer ) clearTimeout( this.autoplay_timer );
		try{ if( e ||( e = window.event || event )) Event.stop(e); } catch(err){}
	},


	//------------------------------
	// Observe trigger event
	//------------------------------

	// Begin trigger event observing
	observe: function( elm, evt ){
		if([ 'forward', 'reverse', 'play', 'stop' ].indexOf( evt ) < 0 && isNaN( evt )) return;
		if( ! ( elm = $( elm ))) return;
		if( isNaN( evt )){
			Event.observe( elm, 'click',    this[evt]);
			Event.observe( elm, 'keypress', this[evt]);
		} else {
			Event.observe( elm, 'click',    function(e){ this.select(evt); if( e ||( e = event )) Event.stop(e); }.bind(this));
			Event.observe( elm, 'keypress', function(e){ this.select(evt); if( e ||( e = event )) Event.stop(e); }.bind(this));
		}
	}
});
