/* TIControlledRotator: the Tierra Interactive Rotator, with controls
   Rotates through a selection of items and allows visitor to control the playback
   
   All options are identical to TIRotator, with the following additions to the options object:
       - controls (object):
           - hide (bool): whether to hide the controls when no mouse activity (defaults to false)
           - opacity (0-1): opacity of the controls
           - swap_play_pause (bool): whether to swap the play and pause button depending on state
           - link_to_items (bool): if true, clicking an item will jump to that frame (defaults to true)
           - buttons (object):
               - play (string/element): ID string or element that represents the play button
               - pause (string/element): same as above; leave null if using swap_play_pause
               - next (string/element): same as above
               - prev (string/element): same as above
*/

var TIControlledRotator = new Class ({
	//Extends TIRotator to include controls
	Extends: TIRotator,
	Binds: ['play', 'pause', 'next', 'prev'],
	options: {
		controls: {
			// By default the controls are always showing. If hide is set to true, controls will show only when mouse enter the animation.
			hide: false,
			opacity: 1,
			swap_play_pause: true, // if true, will swap "play" and "pause" classes on play button
			link_to_items: true, // if true, will allow user to click an item to jump to it
			use_fade: true, // if true, uses a fade animation when using next/prev or jumping to a frame
			play_on_jump: false, // if true, will continue rotation when jumping to a specific frame
			buttons: { // all buttons accept string (ID selector) or element
				play: 'play',
				pause: null, // Null since by default we'll be swapping the play button
				next: 'next',
				prev: 'prev'
			}
		}
	},
	controls: [],
	btn: {
		play: 'play'
	},
	
	initialize: function(items, parentEl, options) {
		// TIControlledRotator functions differently than TIRotator
		// items should be an array of <a> elements whose href's are URLs, or a string that's a selector for such <a> elements
		if ($type(items) == 'string') {
			items = $$(items);
		}
		item_hrefs = new Array();
		items.each(function(el) {
			item_hrefs.push(el.get('href'));
		});
		this.controls = items;
		
		// Pass everything along to TIRotator's initialize function
		this.parent(item_hrefs, parentEl, options);
		// Initialize the button elements
		this.btn = new Hash(this.options.controls.buttons);
		this.btn.each(function(value, key) {
			if ($type(value) == 'string') {
				this.btn[key] = $(value);
			}
		}, this);
		this.init_buttons();
	},
	
	init_buttons: function() {
		// Set up the play/pause/next/prev buttons
		if (this.options.controls.swap_play_pause) {
			this.btn.play.addEvent('click', function(e) {
				if ($chk(e)) e.stop();
				if (this.playing) {
					this.pause();
				} else {
					this.play();
				}
			}.bind(this));
		} else {
			this.btn.play.addEvent('click', this.play);
			if ($type(this.btn.pause) == 'element')
				this.btn.pause.addEvent('click', this.pause);
			// Activate the play button if we're auto-playing
			if (this.options.autoplay) {
				this.btn.play.addClass('active');
			}
		}
		if ($type(this.btn.next) == 'element')
			this.btn.next.addEvent('click', this.next);
		if ($type(this.btn.prev) == 'element')
			this.btn.prev.addEvent('click', this.prev);
		
		// Set up the item links
		if (this.options.controls.link_to_items) {
			this.controls.each(function(el, index) {
				var rotator = this;
				el.addEvent('click', function(e) {
					if ($chk(e)) e.stop();
					rotator.display(index);
				});
			}, this);
		} else {
			this.controls.each(function(el) {
				el.addEvent('click', this.dead_link);
				el.setStyle('cursor', 'default');
			}, this);
		}
		this.controls[0].addClass('active');
	},
	
	swap_items: function(prev, next, duration) {
		// Pass responsibility on to TIRotator's swap_items method
		this.parent(prev, next, duration);
		this.highlight_current();
	},
	
	pause: function(e) {
		if ($chk(e)) e.stop();
		if (this.playing) {
			this.rotateTimer = $clear(this.rotateTimer);
			this.playing = false;
			if (this.options.controls.swap_play_pause) {
				this.btn.play.removeClass('pause');
				this.btn.play.addClass('play');
			} else {
				this.btn.pause.addClass('active');
				this.btn.play.removeClass('active');
			}
		}
	},
	
	play: function(e) {
		if ($chk(e)) e.stop();
		if (!this.playing) {
			this.playing = true;
			this.rotate();
			if (this.options.controls.swap_play_pause) {
				this.btn.play.removeClass('play');
				this.btn.play.addClass('pause');
			} else {
				this.btn.play.addClass('active');
				this.btn.pause.removeClass('active');
			}
		}
	},
	
	display: function(position) {
		// If we're displaying an explicit frame, we want to reset the timer or pause completely
		// If we're paused already, no need
		if (!this.options.controls.play_on_jump)
			this.pause();
		else if (this.playing)
			this.rotateTimer = $clear(this.rotateTimer);
		
		// Swap with the previous item
		var prev;
		if ($type(this.items[this.pos]) == 'element') {
			prev = this.items[this.pos];
		} else {
			prev = $('item-' + this.pos);
		}
		
		this.pos = position;
		var duration = (this.options.controls.use_fade ? null : 0);
		
		// Display it immediately (no fade) if it exists, otherwise load and display
		if ($type(this.items[this.pos]) == 'element') {
			this.swap_items(prev, this.items[this.pos], duration);
		} else if ($('item-' + this.pos)) {
			this.swap_items(prev, $('item-' + this.pos), duration);
		} else {
			this.load(this.options.controls.use_fade, prev);
			this.highlight_current();
		}
	},
	
	next: function(e) {
		if ($chk(e)) e.stop();
		
		var next = this.pos + 1;
		if (next == this.items.length) {
			next = 0;
		}
		this.display(next);
	},
	
	prev: function(e) {
		if ($chk(e)) e.stop();
		
		var prev = this.pos - 1;
		if (prev < 0) {
			prev = this.items.length - 1;
		}
		this.display(prev);
	},
	
	dead_link: function(e) {
		if ($chk(e)) e.stop();
	},
	
	highlight_current: function() {
		this.controls.removeClass('active');
		this.controls[this.pos].addClass('active');
	}
});
