/**
* Perpetual Homepage Features
* @fileoverview Provide method to display former home page themees and features,
* along with the ability to send a url for that theme
* ©copyright 2010, Weill Cornell Medical College
* @author Brian Tobin
* @version 0.9.3.2
* @update Wed Jun 23 16:30:11 EDT 2010
*
* bugs:
* [1] When refreshing a page that has a assoc featured article, page reverts to most current
*     because client side cache does not sync up fast enough 
* [2] rss_cache does not load as fast as first obj is needed
*
*/


WC.UI.Perpetual = function(){
	
	var theme 				= homepage_features,
		themes_length 		= homepage_features.length,
		perpetuating 		= false,
		peeking				= false,
		active_thumb 		= false,
		active_detail 		= false,
		rss_cache 			= {},
		rss_cache_loaded 	= false,
		scrolling			= false,
		load_attempts 		= 0,
		trigger				= '#perpetuate',
		theme_container		= '#theme_container',
		theme_carriage		= '#theme_carriage',
		theme_slides		= '#theme_slides',
		theme_thumb			= '.theme_slide',
		theme_detail		= '.theme_detail',
		scroll_arrow		= '.scroll_arrow',
		hidden_class		= 'hidden_slide',
		theme_thumb_width 	= 47, // width=35 + border=2 + margin=10
		grown_thumb_width	= 62,
		detail_width 		= 260,
		scroll_speed		= 800,
		window_width		= function(){ return $(window).width(); },
		is_first			= function(node){ return node.index() === 0; },
		is_last				= function(node){ return node.index() === (themes_length - 1); };
		
	
	/** 
	* Access parts of the current URL 
	* @private
	*/
	var read_url = {
		url: function(){
			return window.location.href;
		},
		no_id: function(){
			return read_url.url().match(/\/$|\.html$/) !== null;
		},
		base: function(){
			return read_url.no_id() ? read_url.url() : read_url.url().replace(/#id\=[0-9]{1,3}$/, '');
		},
		ext: function(){
			return read_url.no_id() ? null : read_url.url().match(/#id\=([0-9]{1,3})$/)[0];
		},
		id: function(){
			return read_url.no_id() ? null : read_url.url().match(/#id\=([0-9]{1,3})$/)[1];
		}
	};
	
	
	/** 
	* Update the URL with the proper ID 
	* @private
	*/
	function set_url(id){
		var ext = '#id=' + id,
			full = read_url.base() + ext;
		window.location.href = full;
	}
	
	
	/** 
	* Add all thumbnails to holder 
	* @private
	*/
	function populate_thumbs(){
		for (var i=0; i<themes_length; i+=1){
			// append in reverse since slides float left
			$(theme_slides).prepend(thumb_tpl(i));
		}
	}
	
	
	/* 
	* Query themes dicionary Select - Where style 
	*
	* @private
	* @param prop
	* @param match
	*/
	function query_where(prop, match){
		var obj_index;
		for (var i=0; i<themes_length; i+=1){
			if (match == theme[i][prop]){
				obj_index = i;
			}
		}
		return obj_index;
	}
	
	
	/** 
	* Get Feature article feed and return it as JSON
	* Read in JSON and store it in cache by index
	* @private
	*/
	function preload_feature_data(){
		// use goggle rss -> json converter
		var url = 'http://weill.cornell.edu/news/releases/affiliate/feature.rss',
			gurl = 'http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&callback=?&q=' + url + '&num=' + themes_length,
			max;
		
		// jquery get json from google conversion	
		$.getJSON(gurl, function(data){
			// select the feed
			var feed = data.responseData.feed;
			// pull out all fields from each item
			for (var i=0; i<feed.entries.length; i+=1){
				
				// reference them
				var title = feed.entries[i]['title'],
					blurb = feed.entries[i]['content'],
					link = feed.entries[i]['link'];
				
				// change length of blurb based on length of title
				if (title.length < 30){
					blurb = blurb.substring(0, 375);
					max = 375;
				}
				else if (title.length < 50){
					blurb = blurb.substring(0, 275);
					max = 275;
				}
				else {
					blurb = blurb.substring(0, 200);
					max = 200;
				}
				
				// if the blurb is smaller than max - 10, then we can fit the whole thing
				// no elipsis needed
				if (blurb.length < max - 10){
					blurb = blurb + ' ';
				}
				// further truncate to last space between words - no fragments
				else {
					blurb = blurb.substring(0, blurb.lastIndexOf(' ')) + '... ';
				}

				// if link
				if (typeof link !== "undefined"){
					// match link for client side cache	and grab index of match
					var match_obj = query_where("link", link);
					// cache attributes for feature articles
					if (typeof match_obj !== "undefined"){
						rss_cache[match_obj] = {
							"title": title,
							"link": link,
							"blurb": blurb
						};
					}
				}
			}
			rss_cache_loaded = true;
		});
	}
	
	
	/** 
	* Show the Past Feature thumbnails 
	* @private
	*/
	function perpetuate(e){
		perpetuating = true;
		// fade out link
		$(this).fadeOut(300);
		// set carriage slides and arrows
		set_carriage();
		// animate the height of the grey bar
		$('.grey_border_top').animate({ height: '57px' }, 1000);
		// show the themes
		$(theme_container).show(1200, function(){
			$(theme_container + ' a.close').fadeIn(500)
		});
		$(window).bind('resize', window_resize);
		e.preventDefault();
	}
	
	
	/** 
	* Hide the Past Features thumbs 
	* @private
	*/
	function unperpetuate(e){
		perpetuating = false;
		unpeek();
		$(theme_container + ' a.close').fadeOut(300);
		$(theme_container).hide(1000, function(){
			$(trigger).fadeIn(400);
			reset_scroll();
		});
		$('.grey_border_top').animate({ height: '20px' }, 1200);
		$(window).unbind('resize', window_resize);
		e.preventDefault();
	}
	
	
	/**
	* Window resize function
	* @private
	*/
	function window_resize(){
		unpeek();
		set_carriage();
		// TODO: reset on window resize is very buggy and slow
		set_hidden_slides();
	}
	

	/** 
	* Handle thumbnail rollover
	* @private
	*/
	function peek(){
		// don't do anything if still scrolling
		if (scrolling) return;
		// if already active, end
		else if ($(this).hasClass('active')) return;
		
		// grab detail html
		var slide_info = gather_slide_info(),
			is_hidden = $(this).hasClass(hidden_class),
			self = this;
		
		// unpeek any active and peeked
		unpeek();
		
		// if slides are hidden, check scroll function
		if (is_hidden){
			animate_scroll('-=');
		}
				
		// ensure scrolling is complete before peeking commences
		if (!scrolling){		
			show_detail(self, slide_info);
		} 
		// if still is strolling, give it some extra time
		else {
			unpeek();
			setTimeout(function(){
				show_detail(self, slide_info);
			}, scroll_speed);
		}
	}
	
	
	/** 
	* Show detail
	* @private
	*/
	function show_detail(self, slide_info){
		
		var detail_html = $('.detail_html', self).html();
		
		$(self)
			.stop()
			.animate({ 'height': '45px', 'width': '60px' }, 500,
				function(){
					// get left position after animation wraps up
					// or else detail will not line up
					var left = $(self).offset().left;
				
					// switch direction of detail if getting close to right side of container	
					if ((left - ((window_width() - slide_info.current_carriage_width) / 2) + detail_width) >= slide_info.current_carriage_width){
						left = left - (detail_width - grown_thumb_width);
					}
				
					// append thumb detail, position and fade in, set hover and click events
					$('body').append( theme_detail_tpl(detail_html) );
					$(theme_detail)
						.css({ 'left': left })
						.fadeIn(300)
						.hover(
							function(){
								// set active on rollover
								active_detail = true;
							},
							function(){
								unpeek();
								active_detail = false;
							}
						)
						.find('a.detail_close')
						.bind('click', unpeek);
				})
			.addClass('active');
			peeking = true;
	}
	
	
	/** 
	* Hide thumbnail detail on rollover 
	* @private
	*/
	function unpeek(){
		// fade out theme detail if showing
		$(theme_detail).fadeOut(300, function(){ $(this).remove() });
		$(theme_thumb + '.active')
			.stop()
			.animate({ 'height': '35px', 'width': '35px' }, 500)
			.removeClass('active');
		peeking = false;
	}
	

	/** 
	* All Powerful Smart Function
	* @private
	*/
	function gather_slide_info(){
		
		var current_carriage_width 		= window_width() - 93,
			rollover_growth_buffer 		= 25,
			total_slides_visible 		= Math.floor(current_carriage_width / theme_thumb_width),
			total_slides_showable		= Math.floor((current_carriage_width - rollover_growth_buffer) / theme_thumb_width),
			total_slides 				= themes_length,
			leftover				 	= current_carriage_width % theme_thumb_width,
			total_slides_width			= (total_slides * theme_thumb_width) + rollover_growth_buffer + 50, // extra for multiple animations
			current_scroll_position 	= get_scroll_position(),
			total_slides_hidden_left	= Math.abs(current_scroll_position / theme_thumb_width),
			actual_slides_hidden		= $(theme_thumb).slice(total_slides_showable + total_slides_hidden_left, total_slides),
			total_slides_hidden 		= actual_slides_hidden.length;
												
		return {
			current_carriage_width : current_carriage_width,
			rollover_growth_buffer : rollover_growth_buffer,
			total_slides_visible : total_slides_visible,
			total_slides : total_slides,
			leftover : leftover,
			total_slides_showable : total_slides_showable,
			total_slides_width : total_slides_width,
			current_scroll_position	: current_scroll_position,
			total_slides_hidden_left : total_slides_hidden_left,
			actual_slides_hidden : actual_slides_hidden,
			total_slides_hidden	: total_slides_hidden
		};
	}
	
	
	/** 
	* Adjust width of themes carriage 
	* Show scroll arrows if carriage is not
	* wide enough to display all slides
	* @private
	*/
	function set_carriage(callback){
		
		var slide_info = gather_slide_info(),
			arrows_displaying = $('.scroll_arrow').css('display');
			
		// adjust the sizes	
		$(theme_container).css('width', window_width() + 'px');
		$(theme_carriage).css('width', slide_info.current_carriage_width + 'px');
		$(theme_slides).css('width', slide_info.total_slides_width + 'px');
		
		// handle arrow showing
		if (slide_info.total_slides_hidden > 0){
			// if arrows are not already shown, show them
			if (arrows_displaying == 'none'){
				$(scroll_arrow).fadeIn(500);
			}
		}
		else {
			// hide the arrows if showing
			if (arrows_displaying == 'block'){
				$(scroll_arrow).fadeOut(500);
			}
		}
		set_hidden_slides();
	}
	
	
	/** 
	* Reset theme slides position left to 0
	* @private
	*/
	function reset_scroll(){
		$(theme_slides).animate({ 'left': '0px' }, 500, function(){
			set_carriage();
		});
	}
	
	
	/** 
	* Get current scroll position
	* @private
	*/
	function get_scroll_position(){
		return parseFloat($(theme_slides).css('left').replace(/px/, ''));
	}


	/** 
	* Scroll slides
	* accepts from either arrow clicks or slide peeking 
	* called in the init() window resize function
	* @private
	*/
	function scroll(){
		
		var slide_info 	= gather_slide_info(),
			direction 	= $(this).attr('class').split(' ')[1].split('_')[0],
			reached_end = (slide_info.total_slides_hidden_left + slide_info.total_slides_showable == slide_info.total_slides);
			
		// hide detail if showing
		if (peeking) unpeek();
				
		if (direction == 'left'){
			// if slide is at start point
			if (slide_info.current_scroll_position == 0) return;
			animate_scroll('+=');
		}
		else if (direction == 'right'){
			// if hasn't reached end, scroll
			if (reached_end) return;
			animate_scroll('-=');
		}		
	}
	
	
	/** 
	* Add hidden class to hidden slides
	* @private
	*/
	function set_hidden_slides(slide_info){
		
		var slide_info = slide_info || gather_slide_info(),
			slides_hidden = slide_info.actual_slides_hidden;

		// clear hidden classes
		$(theme_thumb).removeClass('hidden_slide');
		
		// if hidden slides, add hidden classes
		if (slides_hidden.length > 0){
			slides_hidden.each(function(i){
				$(this).addClass('hidden_slide');
			});
		}
	}
	
	
	/** 
	* Move slides container appropriate direction
	* @param operator {string} either '+=' or '-='
	* @param speed {number} if you want a specific speed rather than default scroll speed
	*/
	function animate_scroll(operator, speed){
		scrolling = true;
		// animate the slides container
		$(theme_slides).animate({ 'left': operator + theme_thumb_width }, speed || scroll_speed, function(){
			scrolling = false;
			// update hidden slides
			// not passing slide info because we need updated positioning
			set_hidden_slides(); 
		});
	}
	

	/** 
	* Feature Article Template 
	* @private
	*/
	function feature_tpl(dictionary, index){
		return '<div><div><a href="' + dictionary[index]['link'] + '">' + 
				dictionary[index]['title'] + '</a>' +
				'<br/>' + dictionary[index]['blurb'] +
				'&nbsp;<a href="' + dictionary[index]['link'] + 
				'" class="read_more"><span>Read More</span></a></div></div>';
	}
	
	
	/** 
	* Thumbnail rollover and detail html template 
	* @private
	*/
	function thumb_tpl(index){
		return '<div class="theme_slide" id="' + theme[index]['id'] +
				'" style="background: url(' + theme[index]['thumb'] + ') -20px -10px no-repeat;">' +
				'<div class="detail_html">' +
				'<h5>' + theme[index]['date'] + '</h5>' +
				'<h4>' + theme[index]['title'] + '</h4>' +
				'<p>' + theme[index]['blurb'] + ' <a href="' + 
				theme[index]['link'] + '">Read More</a></p>' +
				'<a class="detail_close">x</a>' + 
				'</div></div>';
	}
	
	
	/** 
	* Theme detail 
	* @private
	*/
	function theme_detail_tpl(detail_html){
		return '<div class="theme_detail">' + detail_html + '</div>';
	}
	
	
	/** 
	* Caption Template 
	* @private
	*/
	function blurb_tpl(index){
		return '<div class="caption ' + theme[index]['class'] + '">' +
				'<span>' + theme[index]['blurb'] + '</span>' +
				'<br/><a href="' + theme[index]['link'] + 
				'" class="read_more"><span>Read The Story</span></a>' +
				'</div>';
	}
	

	/** 
	* Load a Feature 
	* @private
	*/
	function load_theme(e, id){
		var e = e || window.event,
			id = (e && e.type === 'click') ? parseFloat($(this).attr('id')) : parseFloat(id),
			cur_shade = $('body').attr('class').split(' ')[1],
			index = query_where("id", id);
																
		// if current shade, remove that class from body	
		if (typeof cur_shade !== 'undefined'){
			$('body').removeClass(cur_shade);
		}
		// reset nav color and spotlight catpion
		$('ul.section_nav_home li a').removeAttr('style');
		$('.spotlight div.caption').remove();
		
		// add all theme parts [ logoimage, bgimage, featuredphoto, shade, blurb ]
		$('body')
			.css('background-image', 'url(' + theme[index]['bgimage'] + ')')
			.addClass(theme[index]['shade']);
		$('#logo a').css('background-image', 'url(' + theme[index]['logoimage'] + ')');
		$('.spotlight')
			.css('background-image', 'url(' + theme[index]['featureimage'] + ')')
			.append(blurb_tpl(index));

		// color the nav if there is a color for change
		if (theme[index]['navcolor'] !== null){
			$('ul.section_nav_home li a').css('color', theme[index]['navcolor']);
		}
		
		// set url
		set_url(id);
		// load feature article
		load_feature_article(id, index);
	}
	
	
	/** 
	* Load the feature article 
	*
	* @private
	* @param id
	* @param index
	*/
	function load_feature_article(id, index){
		// make sure rss_cache is loaded
		// try 7 times, then load the default
		if (!rss_cache_loaded && load_attempts < 7){
			setTimeout(function(){
				load_feature_article(id, index);
			}, 100);
			load_attempts++;
			return;
		}
		else {
			// if index is found in the cache of feature article objects
			// replace current feature article with stored
			if (typeof rss_cache[index] !== "undefined"){
				$('.featured').html(feature_tpl(rss_cache, index));
			}
			// else default to blurb text in homepage_feature dict
			else {
				$('.featured').html(feature_tpl(theme, index));
			}
		}
	}

	
	return {
		
		/** 
		* Init setup and events
		* @function
		*/
		init: function(){
			// do what it says
			preload_feature_data();
			populate_thumbs();
			
			// bind opener link
			$(trigger).bind('click', perpetuate);
						
			// thumb click event and hover
			$(theme_thumb)
				.bind('click', load_theme)
				.mouseover(peek);
			
			// bind close
			$(theme_container + ' a.close').bind('click', unperpetuate);			
			
			// scroll arrow click event
			$('.scroll_arrow').bind('click', scroll);
			
			// TODO: if widget interferes with other function on home page
			//$('ul.kitchen_drawer li a').click(unperpetuate);
			
			// either init most recent theme, or if there is 
			// an id in the url, show that theme
			if (read_url.no_id()){
				load_theme(false, themes_length);
			}
			// if there is id in url
			else {
				load_theme(false, read_url.id());
			}
		}
	};
}();






