/* Middlebury Waveform and Carousel effects */
/* by White Whale Web Services */

var settings = {
		edgeWidth : 0.25, // width of hover area on right and left edges for scrolling (portion of frame)
		maxSpeed : 15, // maximum speed (pixels per frame)
		minSpeed : 0.5, // minimum speed (pixels per frame)
		fps : 60, // frames per second
		refreshRate : 100, // how often to listen for a mouse move event
		threshold : 20 // how many pixels does the mouse have to have moved to register the change?
	},
	homepage;
	
jq14(function($) { // on DOM ready
	var header = $('#header'),
		headerWidth = 0,
		headerContent;
	if(header.length) {
		headerContent = header.html();
		headerWidth=0;
		if($.browser.msie) $('#stories').show();
		header.find('.header_photo').each(function() {
			headerWidth+=this.width+16;
		});
		if($.browser.msie) $('#stories').hide();
	}
	var waveform = $('#waveform'),
		waveformHeight = waveform.height(),
		stories = $('#stories').removeClass('nojs').empty().css('opacity',0).show(), // immediately hide the waveform and empty it
		pointer = $('<div id="bar_pointer"></div>').appendTo('body'), // the pointer
		pointerArrow = $('<div id="bar_pointer_arrow"></div>'), // and its arrow
		pointerWidth = 0, // and its width
		windowWidth, // the window width
		wordmark = $('#wordmark'); // the wordmark
	homepage = $('body').is('#homepage');
	if(ie6) pointer.add(pointerArrow).css('visibility','hidden'); // in IE6, hide the pointer arrow
	var bar_color = 0;
	if(window.waveformStories) {
		$.each(waveformStories,function(index,details) { // with each story (from JSON)
			bar_color++;
			if(bar_color==4) bar_color = 1;
			var story = $('<li id="story'+details.id+'_bar" class="'+(details.image ? '' : (details.submit ? 'submit ' : 'disabled '))+'bar"><div class="bar_contents"><div class="bar_title"><div style="width:'+details.width+'px;">'+details.title+'</div></div><div class="bar_target"><div class="bar_color bar_color'+bar_color+'" style="'+(details.color ? 'background-color:'+details.color +';' : '')+'height:'+details.height+'px;"><div class="bar_image_bw" style="margin-top:-'+(details.height/2)+'px;"></div><div class="bar_image" style="margin-top:-'+(details.height/2)+'px;">'+(details.video ? '<a href="'+details.video+'" class="open_video"></a>' : '')+'</div></div></div><div class="bar_text"><div style="width:'+details.width+'px;">'+details.text+'</div></div></div>').appendTo(stories);  // add the story bar
			story.find('.bar_contents').css('padding-'+(index%2==0 ? 'top' : 'bottom'),(Math.floor(Math.random()*6)*5));
			$.extend(details,{ // precache elements we'll need to recall
				content_height : story.find('.bar_contents').outerHeight(), // the total height of the contents
				bar_title : story.find('.bar_title'), // the headline
				bar : story.find('.bar_color'), // the bar color
				bar_image_bw : story.find('.bar_image_bw'), // the BW image div
				bar_image : story.find('.bar_image'), // the color image div
				bar_text : story.find('.bar_text') // the caption
			});
			if(ie8) { details.bar_title.css('margin-bottom',3); details.bar_text.css('margin-top',3); }
			if(!details.color) details.color = details.bar.css('background-color');
			if(details.content_height>waveformHeight) {
				var overflow = details.content_height-waveformHeight;
				details.bar.css('height',Math.max(details.height-overflow,10));
			}
			story.find('.bar_target').hover(function(e) { // onmouseenter
				if(!story.is('.open,:animated,.disabled')) {
					details.bar.stop(true).animate({padding:3,margin:-3,backgroundColor:'#fff'},200); // glow
					pointerWidth = pointer.text(details.title).show().width(); // show the pointer, set its text, and store its width
					pointerArrow.appendTo(story).show();
				}
			},function() { // onmouseleave
				if(!story.is('.open,:animated')) {
					details.bar.stop(true).animate({padding:0,margin:0,backgroundColor:details.color},200); // reset glow
				}
				pointer.add(pointerArrow).hide();
			}).bind('mousemove mouseenter',function(e) { // onmousemove
				var pointerX = e.clientX-30,
					pointerY = e.clientY-50,
					offsetTop = waveform.offset().top-$().scrollTop(),
					arrowLeft;
				if(pointerY<offsetTop-25) { pointerY = offsetTop-25; }
				if(pointerX<0) pointerX = 0;
				else if(pointerX+pointerWidth>windowWidth-12) {
					pointerX = windowWidth-12-pointerWidth;
				}
				pointer.css({left:pointerX,top:pointerY});
				pointerArrow.css({top:(pointerY-offsetTop+25)});
			}).click(function() { // onclick
				if(!story.is('.open,.submit')) {
					var open = stories.find('.open'); // find any open story
					if(open.length) open.closeStory(); 
					details.bar.animate({padding:0,margin:0,backgroundColor:details.color},200); // reset glow
					pointer.add(pointerArrow).hide(); // hide pointer and arrow
					story.openStory();
				} else if(story.is('.submit')) {
					var blackout = $('<div class="blackout"/>').css('opacity',0.7).prependTo('body'),
						overlay = $('<div class="submit_overlay"><div class="close_overlay">×</div><p class="opening">Our new website highlights the events, people, and stories that make Middlebury a unique and vibrant place.</p><p>Here’s your chance to share your story or the stories of your students, teachers, colleagues, or community. Please include your name, email address, two to three sentences that describe your story, and some keywords to help people find your story online. Don’t forget to include links to any websites that contain more information! <form method="post" action="/"><div style="float:left;"><label for="submit_name">Name:</label><input type="text" id="submit_name"/></div><div style="float:right;"><label for="submit_email">Email Address:</label><input type="text" id="submit_email"/></div><label for="submit_story">Your story:</label><textarea rows="2" columns="80" id="submit_story"></textarea><label for="submit_tags">Tags:</label><input type="text" id="submit_tags"/><input type="submit" value="Submit your story" id="submit_submit"/></form></div>').prependTo('body');
					overlay.css('top',Math.max(($('html').scrollTop()+50),90));
					blackout.add('.close_overlay').click(function() { // clicking the blackout or close button
						blackout.add(overlay).remove(); // closes the overlay
					});
				}
			});
			if(ie6) details.bar.attr('title',details.bar_title.text()); // in IE6, add a title attribute
			story.data('details',details); // store the details data for later
		});
		stories.find('.bar_title,.bar_text,.bar_glow,.bar_image_bw,.bar_image').css('opacity',0); // fade out hidden features
		stories.find('.bar_contents:odd').css('bottom',0); // make stories alternate top vs. bottom attachment
		if(header.length) stories.children().eq(Math.ceil(stories.children().length/2)-1).after('<li id="header" class="bar" style="zoom:1;width:'+headerWidth+'px;">'+headerContent+'</li>');	
		$(window).resize(function() { // on window resize
			windowWidth = $(window).width();
			if(homepage) { // if this is the homepage
				var windowHeight = $(window).height(), // get the window height
					waveformRoom = windowHeight-361, // how much room is left for the waveform? 361 is the combined height of the other elements on the homepage
					waveformHeightNew = Math.max(Math.min(waveformRoom,300),200);
				if(waveformHeightNew!=waveformHeight) { // if we need to resize the waveform
					waveform.height(waveformHeightNew); // resize it
					waveformHeight = waveformHeightNew; // store the waveform height
					$.each(waveformStories,function(index,details) { // then with each story
						if(details.content_height>waveformHeight) { // if it's taller than the waveform
							var overflow = details.content_height-waveformHeight; // calculate the overflow
							details.bar.css('height',Math.max(details.height-overflow,10)); // and shrink the bar
						} else if(details.bar) { // otherwise
							details.bar.css('height',details.height); // reset its height
						}
					});
				}
				$('body').css('padding-top',Math.max((waveformRoom-waveformHeight)/2,0)); // and center the page vertically
				nudgeFooter();
			}
		}).resize(); // and do it now
		initVideos();
		// START WIPE-IN CODE
		if(homepage&&!$.browser.msie) { // wipe in the stories from the left
			stories.children().filter(function() { // omit stories that are off the screen
					var offset = $(this).offset().left;
					return offset-30>0&&offset<windowWidth+200; // with a bit of wiggle room
				})
				.css('opacity',0) // hide the on-screen stories
				.each(function(index) { // and on a delay
					$(this).delay(index*25).fadeTo(150,1); // fade them each in
				});
		}
		// END WIPE-IN CODE
		stories.css('opacity',1);
		if($.browser.msie) stories.width((waveformStories.length*30)+headerWidth+16);
		waveform.slider();
		var permalinked = $(window.location.hash+'_bar'); // check whether a story corresponds to the hash tag
		if(permalinked.length) { // if it exists
			permalinked.openStory(); // show it
		}
	}
	var carousel = $('#carousel');
	if(carousel.length) {
		carousel.slider();
		$('#content').append('<div id="carousel_arrow"/>');
	}
});

jq14.fn.extend({
	slider : function() {
		var $ = jq14,
			self = this;
		// Set initial positions
		var self = this,
			strip = this.children(0),
			stripWidth = strip.width(),
			frameWidth = self.width(),
			offset = 0;
		self.data('stripWidth',stripWidth);
		self.data('originalWidth',stripWidth-12);
		strip.width(stripWidth);
		$(window).resize(function() { // calculate the hover areas and the strip "center" on resize
			frameWidth = self.width();
			leftEdge = settings.edgeWidth*frameWidth;
			rightEdge = frameWidth-(settings.edgeWidth*frameWidth);
		}).resize(); // and do it now
		if(!self.is('#waveform')||homepage) {
			offset = -1*((stripWidth-frameWidth)/2); // initial offset
			strip.css('left',offset);
		}
		// Attach mouseover behavior
		var destination,
			lastX=-100,
			lastTime=0;
		self.mousemove(function(e) {
			var curX = e.clientX,
				curTime = new Date().getTime(),
				modifier;
			if(Math.abs(curX-lastX)<settings.threshold||curTime-lastTime<settings.refreshRate) return; //  if the mouse has moved less than 20 or less than 100ms have elapsed, don't fire
			lastX = curX;
			lastTime = curTime;
			stripWidth = self.data('stripWidth');
			if(curX<leftEdge) {
				modifier = Math.pow((leftEdge-curX)/leftEdge,3);
				destination = 0;
			} else if(curX>rightEdge) {
				modifier = Math.pow((curX-rightEdge)/(frameWidth-rightEdge),3);
				destination = -1*(stripWidth-frameWidth);
			} else {
				destination = offset;
				modifier = 0;
			}
			if(stripWidth<frameWidth) { // if the strip is narrower than the window
				destination = -1*((stripWidth-frameWidth)/2); // move toward the center
			}
			slide(settings.maxSpeed*modifier);
		}).mouseleave(function() { // on mouse exit
			if(destination>offset) {
				destination = Math.min(offset+100,destination);
			} else {
				destination = Math.max(offset-100,destination);
			}
		});
		var animation,
			header = $('#header'),
			title = header.find('h1 img').css('position','relative'),
			headerGutter = (header.width()-40-title.width())/2;
		var slide = function(speed) {	
				clearInterval(animation);
				var direction = destination>offset ? 1 : -1;
				animation = setInterval(function() {
					$().click();
					var distance = Math.abs(destination-offset), // distance remaining
						modifier = Math.pow(distance/stripWidth,0.3), // moderator decelerates as the destination approaches
						step = Math.max(speed*modifier,settings.minSpeed);
					if(distance<=step) { // if the destination is less than the next step
						offset=destination;
						clearInterval(animation);
					} else {
						offset+=step*direction;
					}
					var percentOff = Math.abs(offset/(stripWidth-frameWidth));
					title.css('left',offset*0.3);
					strip.css('left',offset);
				},1000/settings.fps);
			};
		return this;
	},
	openStory : function() {
		var $ = jq14,
			story = this.addClass('open'), // mark the story as open
			details = story.data('details');
		if(ie6) { // in IE6
			var img = new Image();
			$(img).appendTo(details.bar_image).attr('src','/images/bars/'+details.image+'.jpg').attr('alt',details.title).width(details.width).height(details.height); // append the image
			details.bar_image.stop().css('opacity',1); // and show it
		} else { // in modern browsers
			var img = new Image();
			$(img).appendTo(details.bar_image_bw) // append the BW image
				.load(function() { // and onload
					details.bar_image_bw.fadeTo(500,0.5,function() { // fade it in
						var imgColor =  new Image();
						$(imgColor).appendTo(details.bar_image) // then append the full image
							.load(function() { // and onload
								details.bar_image.fadeTo(750,1); // fade it in
							}).attr('src','/images/bars/'+details.image+'.jpg').attr('alt',details.title).width(details.width).height(details.height);		
					});
				}).attr('src','/images/bars/'+details.image+'_bw.jpg').attr('alt',details.title).width(details.width).height(details.height);
		}
		var slider = story.parent().parent().parent(),
			stripWidth=slider.data('originalWidth')+details.width;
		if($.browser.msie) slider.children().children().width(stripWidth);
		slider.children().animate({width:stripWidth},1000,function() {
			slider.data('stripWidth',stripWidth);
		});
		story.animate({width:details.width},1100); // slide the story open
		details.bar_title.add(details.bar_text).fadeTo(1500,0.9); // fade in headline, text
		details.bar_text.find('div').animate({top:0},1000,'easeOutSine'); // drop down text
		window.location.hash = 'story'+details.id; // set the hash for permalinking
		return this; // return the original element for chaining
	},
	closeStory : function() {
		var $ = jq14,
			story = this.removeClass('open'),
			details = story.data('details');
		details.bar_image.add(details.bar_image_bw).stop(true).find('img').unbind('load'); // stop any animations and remove any upcoming load events
		details.bar_image.fadeTo(500,0,function() { // fade out the full image
			details.bar_image.empty(); // and remove it
			details.bar_image_bw.fadeTo(500,0,function() { // fade out the BW image
				details.bar_image_bw.empty(); // and remove it
			});
		}); 
		details.bar_title.add(details.bar_text).fadeTo(500,0); // fade out headline, text
		details.bar_text.find('div').animate({top:'-30px'},1000,'easeOutSine'); // fade out and slide up text
		story.animate({width:'14px'},1000); // slide the story closed
		return this; // return the original element for chaining
	}
});