/**
 * Creates a rotating carousel on:
 *
 * <div class="carousel">
 *   <div>1</div>
 *   <div>2</div>
 * </div>
 */
PS.Carousel = {

	/**
	 * Array of controls.
	 */
	$controls: null,
	navEnabled: true,

	/**
	 * Array of items to swap between.
	 */
	$items: null,

	length: 0,
	index: 0,

	timer: null,

	configuration: {
		crossFade: false,
		updateCallback: null
	},

	/**
	 * ====================================
	 * Initialization
	 * ====================================
	 */
	initialize: function() {
	
		// Pause the carousel if you click anywhere
		var $carousel = $('.carousel').click(function(){
			PS.Carousel.pause();
		});

		// Store carousel slides in $items
		var $container = $carousel;
		this.$items = $container.children().hide();
		this.length = $container.children().length;

		// Store control elements in $controls
		var $controls = this.createControls().appendTo($carousel);
		this.$controls = $controls.children();
		
		// Add click handlers for any video elements
		this.$items.each(function(index, element){
			var $element = $(element);
			if($element.attr('data-video-src'))
			{
				$element.css('cursor', 'pointer').click(function(){
					PS.Carousel.showVideo();
				});
			}
		});

		// Start playing
		this.go(0);
		this.play();
	},

	clear: function() {
		this.$controls = null;
		this.$items = null;
		
		// Remove any old mbox content
		$('.mboxDefault').remove();
		
		this.pause();		
	},

	reset: function() {
		this.clear();
		this.initialize();
	},

	createControls: function() {

		// Add the controls.
		var $controls = $('<div>').addClass('controls');

		// OK, loop through the amount of children we have, and add a control
		// for each one of them.
		for(var i = 0; i < this.length; i++)
		{
			var $control = $('<a>');

			// Attach a click handler
			$control.data('index', i).click($.proxy(function(event){

				// Pause the carousel.
				this.pause();

				// Go to the new index.
				var newIndex = parseInt($(event.target).data('index'));
				this.update(newIndex);

			}, this));

			// Add to parent
			$control.appendTo($controls);
		}

		return $controls;
	},


	/**
	 * ====================================
	 * Controller
	 * ====================================
	 */
	update: function(newIndex) {
		if (!this.navEnabled)
			return;
		var oldIndex = this.index;
		
		if(oldIndex == newIndex)
		{
			this.$items.eq(oldIndex).show();
			this.$controls.eq(oldIndex).addClass('selected');
		}
		else
		{
			this.updateItems(this.$items.eq(oldIndex), this.$items.eq(newIndex));
			this.updateControls(this.$controls.eq(oldIndex), this.$controls.eq(newIndex));
		}

		this.hideVideo();
		this.index = newIndex;
		if (this.configuration.updateCallback)
			this.configuration.updateCallback(this.index);
	},

	updateItems: function($oldItem, $newItem) {
		this.$items.stop(true, true);

		if(this.configuration.crossFade)
		{
			$oldItem.fadeOut(800);
			$newItem.fadeIn(800);
		}
		else
		{
			$oldItem.show().fadeOut(800, function(){
				$newItem.fadeIn(800);
			});
		}
	},

	updateControls: function($oldControl, $newControl) {
	
		function animate($control, add)	{
			// Save the height before we update the control
			var oldHeight = $control.height();
			
			// Update the control
			if(add)
				$control.addClass('selected');
			else
				$control.removeClass('selected');
				
			// Get the new height after we updated the control
			var newHeight = $control.height();
			
			// Animate
			$control.height(oldHeight).animate({height: newHeight}, 200, function(){
				$(this).height('');
			});
		}
	
		this.$controls.stop(true, true);
		animate($oldControl, false);
		animate($newControl, true);
	},

	showVideo: function() {
		var $currentItem = this.$items.eq(this.index);
		
		var src = $currentItem.attr('data-video-src');
		if(src)	{
			this.pause();

			// Hide regular content
			$('.carousel').parent().children('.caption').hide();
			$currentItem.children().hide();

			// Load video player
			var $video = $('<div>').addClass('video').appendTo($currentItem.parent());
			$.ajax({
				url: src,
				type: "get",
				dataType: "html",
				success: function(data)
				{
					$video.html(data);
					PS.analytics.makeAndSendEvent($currentItem.attr('data-pro-name') + ": Video");
				}
			});
		}
	},

	hideVideo: function() {
		var $currentItem = this.$items.eq(this.index);

		if($currentItem.attr('data-video-src')) {
		
			// Remove video player
			if(typeof destroyVideo == 'function')
				destroyVideo();
			$currentItem.parent().find('.video').remove();

			// Show default content
			$('.carousel').parent().children('.caption').show();
			$currentItem.children().show();
		}
	},
	
	completeVideo: function() {
		this.hideVideo();
		this.next();
		this.play();
	},

	/**
	 * ====================================
	 * Navigation
	 * ====================================
	 */

	/**
	 * Go to a new index in the carousel, via specifying a + or - relative
	 * stepping from the current index.
	 */
	go: function(step) {
		// Wrap around so we always have a valid index.
		var absoluteIndex = (this.index + step) % this.length;
		this.update(absoluteIndex);
	},

	previous: function() {
		this.go(-1);
	},

	next: function() {
		this.go(1);
	},

	play: function() {
		if(!this.timer && this.navEnabled)
			this.timer = setInterval($.proxy(this.next, this), 7000);
	},

	pause: function() {
		if(this.timer)
			clearInterval(this.timer);
		this.timer = null;
	},

	disableNav: function() {
		if (this.navEnabled && this.$controls) {
			this.pause();
			this.navEnabled = false;
			this.$controls.parent().addClass('disabled');
		}
	},

	enableNav: function() {
		if (!this.navEnabled) {
			this.navEnabled = true;
			this.$controls.parent().removeClass('disabled');
		}
	}

}

