/**
 * Social Media Aggregator jQuery Plugin
 * http://resource.com/
 * 
 * Copyright 2011, Resource Interactive
 * @author echong@resource.com
 * 
 * A jQuery plugin (http://jquery.com/) that aggregates data from a variety of social
 * networks into semantically sorted lists. The majority of logic lives on the server
 * to keep the client as thin as possible. Documentation of the data model can be
 * found in Markdown and HTML varieties within the docs folder of the project root.
 * 
 * If an element with id 'social-aggregator' exists on the page the script will
 * automatically populate it with the Social Media Aggregator plugin.
 * 
 * Templating provided by EJS (http://embeddedjs.com/) and can be found in the ./ejs
 * folder as 'jquery.social-aggregator.ejs.txt'.
 * 
 * The .txt extension is to workaround a mime-type issue with using the .ejs extension.
 * 
 * The scroll functionality of is provided by the jScrollPane plugin
 * (http://jscrollpane.kelvinluck.com/).
 * 
 * HTML5 Shiv (http://remysharp.com/html5-enabling-script) has been included at the
 * bottom of this document to ensure that HTML5 elements are backwards compatibile.
 */

(function($)
{
	// Define debug variables and helper functions
	window.debug = window.debug || false;
	
	/**
	 * IE6 supported debug statements
	 */
	window.trace = window.trace || function(p_log)
	{
		if (window.debug && window.console && window.console.log)
		{
			window.console.log(p_log);
		}
	}
	
	// Check whether jQuery is loaded
	if ($ == null)
	{2
		trace('jQuery was not passed to the plugin\'s context.');
		// TODO: Load jQuery as a fallback
		return;
	}
	
	// Check whether EJS is loaded
	if (EJS == null)
	{
		trace('EJS is not loaded.');
		// TODO: Load EJS as a fallback
		return;
	}
	
	// Check whether jsScrollPane is loaded
	if ($.fn.jScrollPane == null)
	{
		trace('jScrollPane is not loaded.');
		// TODO: Load jScrollPane as a fallback
		return;
	}
	
	/**
	 * Aggregates the feeds from multiple social media data sources
	 */
	var SocialAggregator = function(p_element, p_options)
	{
		trace('Initializing a Social Aggregator instance.');
		
		// Component-level variables
		var data;
		var element = $(p_element); // The HTML element that the plugin is being placed inside, wrapped with jQuery
		var options;
		
		var scrollPane;
		var scrollPaneReflowState = 'ready';
		
		// Check the environement that the plugin is running in and assign default options
		if (window.location.href.toLowerCase().search('views/debug') > -1)
		{
			options =
			{
				data_url: 'testData_2011-07-06.json',
				style_url: '../../Assets/css/jquery.social-aggregator.css',
				ejs_url: '../../Assets/scripts/ejs/jquery.social-aggregator.ejs.txt',
				ejs:
				{
					basePaths:
					{
						images: '../../Assets/images/social_aggregator'
					}
				}
			};
			
			window.debug = true;
			trace('Using debug configuration.');
		}
		else
		{
			options =
			{
				data_url: '/home/socialfeed',
				style_url: '/assets/css/jquery.social-aggregator.css',
				ejs_url: '/assets/scripts/ejs/jquery.social-aggregator.ejs.txt',
				ejs:
				{
					basePaths:
					{
						images: '/assets/images/social_aggregator'
					}
				}
			};
		}
		
		$.extend(options, p_options || {});
		
		// Load style sheets and social data
		loadStyles(options.style_url);
		loadData(options.data_url);
		
		// Check to see if a browser-specific style sheet needs to be loaded
		var css_url = options.style_url.split('.css');
		if (navigator.userAgent.search('MSIE 7') > -1)
		{
			css_url[0] += '-ie7';
			loadStyles(css_url.join('.css'));
		}
		else if (navigator.userAgent.search('MSIE 8') > -1)
		{
			css_url[0] += '-ie8';
			loadStyles(css_url.join('.css'));
		}
		
		/**
		 * Loads the data for the social aggregator
		 */
		function loadData(p_url)
		{
			trace('Loading data from: ' + p_url);
			
			$.getJSON(p_url, setData);
		}
		
		/**
		 * Initializes the social aggregator with the passed data
		 */
		function setData(p_data)
		{
			// Ensure valid data was passed
			if (p_data == null)
			{
				return;
			}
			
			trace('Data loaded succesfully.');
			trace(p_data);
			
			// Mixin the social data passed to the plugin with EJS options
			data = p_data;
			$.extend(data, options.ejs);
			
			// Initialize, load, parse, and render the EJS into the HTML element
			new EJS({ url: options.ejs_url }).update(p_element, data);
			
			// Assign click handlers
			element.delegate(".thumbnail", 'click', onContentClick);
			element.delegate(".tab", 'click', onTabClick);
			
			// Initialize the jScrollPane plugin
			scrollPane = $('#social_aggregator_body').jScrollPane().data('jsp');
			
			// Recalculate the scrollpane whenever an image finishes loading
			$('#social_aggregator_body').find('img').bind('load', reflowScrollPane);
			
			// Set the initially displayed tab
			showTab('all');
		}
		
		/**
		 * Handles the reflowing of the scroll pane when its size changes, only allows one reflow per second
		 */
		function reflowScrollPane(p_override)
		{
			// Check if the scroll pane is ready for a reflow
			if (scrollPaneReflowState == 'ready' || p_override == true)
			{
				// The scroll pane is about to be reflowed and is set back to waiting mode
				scrollPaneReflowState = 'waiting';
				
				// Reinitilizes the scroll pane plugin
				scrollPane.reinitialise();
				
				trace('reflowScrollPane() :: Reflowed scroll pane');
				
				// Check in a second if the scroll pane needs to be reflowed again
				setTimeout(function()
				{
					if (scrollPaneReflowState == 'queued')
					{
						scrollPaneReflowState = 'ready';
						reflowScrollPane();
					}
					else
					{
						scrollPaneReflowState = 'ready';
					}
				}, 1000);
			}
			else
			{
				scrollPaneReflowState = 'queued';
			}
		}
		
		/**
		 * Shows a tab's contents and sets it to active
		 */
		function showTab(p_id)
		{
			trace('showTab() :: Showing filter "' + p_id + '"');
			
			// Set the current tab to active, and all others to inactive
			var tabs = element.find('.tab');
			tabs.each(function(p_index, p_element)
			{
				if (p_element.parentNode.id == p_id)
				{
					$(p_element).addClass('selected');
				}
				else
				{
					$(p_element).removeClass('selected');
				}
			});
			
			// Shows the current content, and hides all other content
			var views = element.find('.filter');
			views.each(function(p_index, p_element)
			{
				if (p_element.id == p_id)
				{
					$(p_element).removeClass('hidden');
				}
				else
				{
					$(p_element).addClass('hidden');
				}
			});
			
			// Ensure the scroll pane conforms to the freshly displayed content's dimesnions
			reflowScrollPane(true);
		}
		
		/**
		 * Click handler for tab navigation
		 */
		function onTabClick(p_event)
		{
			// If the current tab is already active, do nothing
			if ($(this).hasClass('selected'))
			{
				return;
			}
			
			showTab(this.parentNode.id);
		}
		
		/**
		 * Click handler for loaded content
		 */
		function onContentClick(p_event)
		{
			// Set the clicked element's corresponding data
			var uid = $(this).parents('.status')[0].id;
			var content = data.data[uid];
			
			if (content == null)
			{
				trace('onContentClick() :: Content accessed by ' + uid + ' was null');
				return;
			}
			
			// Ensure that the openOverlay function exists before calling it
			if (window.openOverlay != null)
			{
				openOverlay(content);
				trace('onContentClick() :: Opening the overlay with data object ' + uid);
			}
			else
			{
				trace('onContentClick() :: No overlay available to open');
			}
		}
		
		/**
		 * Loads the stylesheets required by the aggregator
		 */
		function loadStyles(p_url)
		{
			// TODO: Support IE6 and IE7 properly
			
			// Check to see if the stylesheet has already been loaded
			var css = $('link');
			for (var i = 0; i < css.length; i++)
			{
				if (css[i].href == p_url)
				{
					trace('Style sheet already loaded from: ' + p_url);
					return;
				}
			}
			
			// Load the specified style sheet
			trace('Loading style sheet from: ' + p_url);
			
			var link = document.createElement('link');
			link.rel = 'stylesheet';
			link.media = 'screen';
			link.type = 'text/css';
			link.href = p_url;
			
			$('head').append(link);
		}
		
		return this;
	}
	
	/**
	 * jQuery plugin function
	 */
	$.fn.socialAggregator = function(p_options)
	{
		this.each(instantiatePlugin);
		
		function instantiatePlugin()
		{
			var element = $(this);
			
			// Check if the plugin already exists
			if (element.data('socialAggregator'))
			{
				return;
			}
			
			element.data('socialAggregator', new SocialAggregator(this, p_options))
		}
		
		return this;
	}
})(jQuery);

// html5shiv @rem remysharp.com/html5-enabling-script
// iepp v1.6.2 @jon_neal iecss.com/print-protector
// Dual licensed under the MIT or GPL Version 2 licenses
/*@cc_on(function(a,b){function r(a){var b=-1;while(++b<f)a.createElement(e[b])}if(!(!window.attachEvent||!b.createStyleSheet||!function(){var a=document.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}())){a.iepp=a.iepp||{};var c=a.iepp,d=c.html5elements||"abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",e=d.split("|"),f=e.length,g=new RegExp("(^|\\s)("+d+")","gi"),h=new RegExp("<(/*)("+d+")","gi"),i=/^\s*[\{\}]\s*$/,j=new RegExp("(^|[^\\n]*?\\s)("+d+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),k=b.createDocumentFragment(),l=b.documentElement,m=l.firstChild,n=b.createElement("body"),o=b.createElement("style"),p=/print|all/,q;c.getCSS=function(a,b){if(a+""===undefined)return"";var d=-1,e=a.length,f,g=[];while(++d<e){f=a[d];if(f.disabled)continue;b=f.media||b,p.test(b)&&g.push(c.getCSS(f.imports,b),f.cssText),b="all"}return g.join("")},c.parseCSS=function(a){var b=[],c;while((c=j.exec(a))!=null)b.push(((i.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(g,"$1.iepp_$2")+c[4]);return b.join("\n")},c.writeHTML=function(){var a=-1;q=q||b.body;while(++a<f){var c=b.getElementsByTagName(e[a]),d=c.length,g=-1;while(++g<d)c[g].className.indexOf("iepp_")<0&&(c[g].className+=" iepp_"+e[a])}k.appendChild(q),l.appendChild(n),n.className=q.className,n.id=q.id,n.innerHTML=q.innerHTML.replace(h,"<$1font")},c._beforePrint=function(){o.styleSheet.cssText=c.parseCSS(c.getCSS(b.styleSheets,"all")),c.writeHTML()},c.restoreHTML=function(){n.innerHTML="",l.removeChild(n),l.appendChild(q)},c._afterPrint=function(){c.restoreHTML(),o.styleSheet.cssText=""},r(b),r(k);if(c.disablePP)return;m.insertBefore(o,m.firstChild),o.media="print",o.className="iepp-printshim",a.attachEvent("onbeforeprint",c._beforePrint),a.attachEvent("onafterprint",c._afterPrint)}})(this,document);@*/

// If an element with id 'social-aggregator' exists on the page, automatically populate it with the plugin
jQuery('#social-aggregator').socialAggregator();
