﻿// Coverflow style navigation.
// Requires: Mootools 1.2.1

// Visual styles
var darkness = 0.25;      // opacity of inactive images

// Layout dimensions
var width = 577;   // width of each frame: 576 + 1px left border
var frames = 7;    // total number of frames
var pad = 142;     // equal to #flow-content left setting

// Used internally
var position = 1;  // current position (frame number)
var flow;          // the #flow-content element
var slider;        // slider control
var handle;        // #flow-slider-handle element
var handleWidth;
var sliderWidth;
var sliding = false; // keep track of when the slider is being used
var handling = false; // keep track of when the slider handle is clicked
var links = new Array(frames); // used to hold href links

// This function runs once the document is fully loaded, before it gets rendered in the browser
window.addEvent('domready', function()
{
	flow = $('flow-content'); // so we don't have to look it up every time
	
	// Create slider
    sliderWidth = $('flow-slider').getStyle('width').toInt();
    slider = new Slider('flow-slider', 'flow-slider-handle', {
    	steps: sliderWidth,
    	onChange: function(step) {
    		slideflow(step / sliderWidth);
    	},
    	onComplete: function(step) {
    		centerflow(step / sliderWidth);
    	}
    });
    handle = $('flow-slider-handle');
    handleWidth = handle.getStyle('width').toInt();
    handle.addEvent('mousedown', function() { handling = true; });
    handle.setStyle('left', getHandlePosition());

	// Set up initial state of coverflow images
    $$('.flow-image').setOpacity(darkness);
    $('flow-frame' + position).getElement('.flow-image').setOpacity(1);
    
    // extract any links that may be wrapping coverflow images
    $$('.flow-image').each(function(image, index) {
    	var anchor = image.getParent('a');
    	if (anchor != null)
    	{
    		links[index] = anchor.getProperty('href');
    		anchor.removeProperty('href');
    	}
    	else links[index] = '';
    });

    // Set up initial state of coverflow text
    $$('.cover-text').slide('hide');
    $('cover-text' + position).slide('show');
    
    // Create slider events
    $('flow-left').addEvent('click', function() { flowleft(); });
    $('flow-right').addEvent('click', function() { flowright(); });
    
    // Add click event for next image
    var img = $('flow-frame' + (position + 1)).getElement('.flow-image');
    img.addEvent('click', function() { flowright(); });
    img.setStyle('cursor', 'pointer');
});

// Calculate handle position, adjust 3px for IE6
function getHandlePosition()
{
	var p = (position - 1) * ((sliderWidth - handleWidth) / (frames - 1));
	
	// This evaluates to true for IE < 7
	if (Browser.Engine.trident && Browser.Engine.version < 5)
		p -= 3; // fix 3px bug on IE6
	
	return p;
}

// onChange event for slider handle
function slideflow(location)
{
	// only perform this function if the handle has been clicked
	if (handling)
	{
		// set coverflow panel position
		flow.setStyle('left', pad - ((frames - 1) * width + 1) * location);
		
		// check to see if this is the first call to onchange
		if (!sliding)
		{
			// hide current text panel
			$('cover-text' + position).slide('out');		
			sliding = true;
		}
		var curr = 'flow-frame' + position;
		
		// set opacity on coverflow panels
		var pos = (location * (frames - 1) + 1); // decimal between 1 and [number of frames]
		position = pos.round(); // int between 1 and [number of frames]
	
		if (position > pos) // fading out of prev panel
		{
			var prev = 'flow-frame' + (position - 1);
			$(curr).getElement('.flow-image').setOpacity((pos - position + 1) * (1 - darkness) + darkness);
			$(prev).getElement('.flow-image').setOpacity((position - pos) * (1 - darkness) + darkness);
		}
		else // fading into next panel
		{
			var next = 'flow-frame' + (position + 1);
			$(next).getElement('.flow-image').setOpacity((pos - position ) * (1 - darkness) + darkness);
			$(curr).getElement('.flow-image').setOpacity((position + 1 - pos) * (1 - darkness) + darkness);
		}
	}
}

// onComplete event for slider
function centerflow(location)
{
	if (handling) // slider handle was used
	{
		// use normal tween duration for this animation
		flow.set('tween', {duration: 'normal'});
		handle.set('tween', {duration: 'normal'});
		$$('.flow-image').set('tween', {duration: 'normal'});
		
		flow.tween('left', [flow.getStyle('left').toInt(), pad - (position - 1) * width]);
		handle.tween('left', [handle.getStyle('left').toInt(), getHandlePosition()]);
		
		var pos = (location * (frames - 1) + 1); // decimal between 1 and [number of frames]
		var next = 'flow-frame' + position;
		var curr;
		
		if (pos < position) curr = 'flow-frame' + (position - 1);
		else                curr = 'flow-frame' + (position + 1);
	
		fadeframes(curr, next);
		imageclicks();
		
		// show text and reset sliding flag
		$('cover-text' + position).slide('in');
		sliding = false;
		handling = false;
	}
	else // slider background was clicked
	{
		// use long tween duration for this animation
		flow.set('tween', {duration: 'long'});
		handle.set('tween', {duration: 'long'});
		$$('.flow-image').set('tween', {duration: 'long'});
		
		// fade out current image
		$('flow-frame' + position).getElement('.flow-image').fade(darkness);
		
		// get new position
		var pos = (location * (frames - 1) + 1); // decimal between 1 and [number of frames]
		position = pos.round(); // int between 1 and [number of frames]

		// fade in new image
		$('flow-frame' + position).getElement('.flow-image').fade('in');
		
		// scroll to new image
		flow.tween('left', [flow.getStyle('left').toInt(), pad - (position - 1) * width]);
		
		foldtext();
		imageclicks();
		
		// need the delay because the slider handle is not positioned until after oncomplete finishes
		var moveslider = function()
		{
			handle.tween('left', [handle.getStyle('left').toInt(), getHandlePosition()]);
		};
		moveslider.delay(10);
	}
}

// set click events on inactive images
function imageclicks()
{
	// remove old click events
	$$('.flow-image').removeEvents('click');
	$$('.flow-image').setStyle('cursor', 'default');
	
	if (position > 1)
	{
		var prev = $('flow-frame' + (position - 1)).getElement('.flow-image');
		var anchor = prev.getParent('a');
		if (anchor != null) anchor.removeProperty('href');
		prev.addEvent('click', function() { flowleft(); });
		prev.setStyle('cursor', 'pointer');
	}
	if (position < frames)
	{
		var next = $('flow-frame' + (position + 1)).getElement('.flow-image');
		var anchor = next.getParent('a');
		if (anchor != null) anchor.removeProperty('href');
		next.addEvent('click', function() { flowright(); });
		next.setStyle('cursor', 'pointer');
	}
	
	// If the current frame has a link defined, add it back in.
	if (links[position - 1] != '')
	{
		var addlink = function() {
			var current = $('flow-frame' + position);
			var anchor = current.getElement('a');
			if (anchor != null)
			{
				anchor.setProperty('href', links[position - 1]);
			}
			current.getElement('.flow-image').setStyle('cursor', 'pointer');
		};
		addlink.delay(500);
	}
}

// Scroll one frame to the left
function flowleft()
{
	if (position > 1)
	{
		var curr = 'flow-frame' + position--;
		var next = 'flow-frame' + position;
		animate(curr, next);
		imageclicks();
	}
}

// Scroll one frame to the right
function flowright()
{	
	if (position < frames)
	{		
		var curr = 'flow-frame' + position++;
		var next = 'flow-frame' + position;	
		animate(curr, next);
		imageclicks();
	}
}

function slideto(frame)
{
	// use long tween duration for this animation
	flow.set('tween', {duration: 'long'});
	handle.set('tween', {duration: 'long'});
	$$('.flow-image').set('tween', {duration: 'long'});
		
	// fade out current image
	$('flow-frame' + position).getElement('.flow-image').fade(darkness);
		
	// get new position
	position = frame;

	// fade in new image
	$('flow-frame' + position).getElement('.flow-image').fade('in');
		
	// scroll to new image
	flow.tween('left', [flow.getStyle('left').toInt(), pad - (position - 1) * width]);
		
	foldtext();
	imageclicks();
		
	handle.tween('left', [handle.getStyle('left').toInt(), getHandlePosition()]);
}

function animate(current, next)
{
	// set tween duration to long for this animation
	flow.set('tween', {duration: 'long'});
	handle.set('tween', {duration: 'long'});
	$$('.flow-image').set('tween', {duration: 'long'});
	
	// scroll coverflow frame and slider handle to next position
	flow.tween('left', [flow.getStyle('left').toInt(), pad - (position - 1) * width]);
	handle.tween('left', [handle.getStyle('left').toInt(), getHandlePosition()]);
	
	fadeframes(current, next);
	foldtext();
}

// Fade the coverflow screen in/out for the current/next frame
function fadeframes(current, next)
{
	$(current).getElement('.flow-image').fade(darkness);
	$(next).getElement('.flow-image').fade('in');
}

// Fold the coverflow text divs in/out
function foldtext()
{
	$$('.cover-text').slide('out'); // hide all divs to avoid bugs when funcion is called rapidly in succession
	
	var slide = function()
	{
		$('cover-text' + position).slide('in');
	};
	slide.delay(500);
}