/** 
@fileOverview <strong>WCMC Javscript Library</strong> The beginnings. 
This file contains a series of helper functions to accomplish common tasks within 
our WC websites. Currently, the templating section makes up for
our lack of a server-side scripting launguage to use within the web group.
This code is currently much to specific and lacks appropriate patterns and abstraction 
to a large degree. Future updates to bring this codebase out of Beta will improve this.

@author Brian Tobin
@version 0.9 Beta
@update Fri Oct 30 11:08:33 EDT 2009 

Documentation at: http://webmedia.med.cornell.edu/cmn/WC/lib/doc/WC/files.html
*/


/**
@namespace WC global namespace wrapper
*/
var WC = {};

/** 
Setup global templating 
@class Template Object 
@requires page
*/
WC.Template = {
	
	/**
	@static
	*/
	setup: function(){
		
		var page_title = $('#col_2 h1').html() ? $('#col_2 h1').html() + ' | ' : '',
			id = page.body_id ? page.body_id : '',
			section = page.section ? page.section : '',
			sub = page.sub ? page.sub : [],
			depth = sub.length;
		
		// kill the script if the page is 'home'
		// this allows designers not to worry about conflicts with their custom home page
		// updates should build on the started work arounds
		if ($('body').attr('id') === 'home')
			return;
		
		// set page title and body id
		document.title = page_title + site.the_name;
		// set page id	
		$('body').attr('id', id);			
		// add first portion of breadcrumb
		var breadcrumbs = '<li><a href="' + site.root + '">Home</a></li>';
		
		/**
		Format regular text for classes
		@inner
		@returns a lowercase string with a-z and underscores only
		@param {String} string
		*/
		function format_class(string){
			string = string.replace(/\s/g, '_').toLowerCase(); 
			string = string.replace(/\:|\(|\)'/g, '');
			return string;
		}
		
		// set section breadcrumb as plain text or links based on how deep we are in page
		if (section !== ''){
			if (depth < 1)
				breadcrumbs += '\n<li>/</li>\n<li>' + section + '</li>';
			 
			else
				breadcrumbs += '\n<li>/</li>\n<li><a href="index.html">' + section + '</a></li>';
			
		}
		
		// Add section as first body class	
		$('body').addClass(format_class(section));
					
		// loop through sub items...
		for (var i=0; i<depth; i+=1 ){
			// add those as formatted classes to body
			$('body').addClass(format_class(sub[i]));
			// add breadcrumbs
			
			// if not last item...
			var last = depth - 1;
			if (i === last)
				breadcrumbs += '\n<li>/</li>\n<li>' + sub[i] + '</li>';
			
			// make crumb a link if not last in array
			else 
				breadcrumbs += '\n<li>/</li>\n<li><a href="' + format_class(sub[i]) + '.html">' + sub[i] + '</a></li>';
			
		}
		// apend breadcrumb trail
		$('#breadcrumb ul').html(breadcrumbs);
		// highlight nav items
		this.set_nav(id, format_class(section), sub, depth);
	},
	
	/**
	@param {String} id page.body_id
	@param {String} section page.section
	@param {Array} sub page.sub
	@param {Number} depth length of sub array
	*/
	set_nav: function(id, section, sub, depth){
		
		/**
		Format nav text for matching and highlighting
		@inner
		@returns a lowercase, trimmed string
		@param {string} string
		*/
		function format_text(string){
			return string.replace(/^\s+|\s+$/g, '').toLowerCase();
		}
		
		//We need to address level 3 navs using the same matching
		// .find('ul.level_3_nav');
		
		// highlight main nav section
		$('ul.main_nav #' + section).addClass('active');
		// gather all links into array. This ecompasses both 2nd and 3rd level.
		var nav_links = $('.level_2_nav li a');
		// if there are no sub pages, depth is 0 for loop
		if (depth === ''){
			depth = 0;
		}
		// loop level 2 nav links
		for (var i=0; i<nav_links.length; i+=1){
			// loop through the page.sub array
			for (var x=0; x<depth; x+=1){
				// if formatted nav text and formatted page.sub text match, highlight it
				if (format_text(sub[x]) === format_text($(nav_links[i]).text())){
					// add the active class to the appropriate link
					$(nav_links[i]).addClass('active');
					// if find a 3rd level nav, open that sucker up
					var level_3_nav = $(nav_links[i]).parent('li').find('ul.level_3_nav');
					if (level_3_nav)
						// remove and css from javascript
						level_3_nav.css('display','inline');
				}
			}
		}
	}
};


/** 
@namespace Health Library Wrapper
*/
WC.HealthLibrary = {};

/** 
Show health library articles in modal window 
and display mapped services.
@class Modal Object
*/
WC.HealthLibrary.modal = {
	
	/**
	@param {string} article_id The article link id
	*/
	setup: function(article_id){
		// close any existing modal
		this.close();
		// init modal
		this.append_content(article_id);
		// get article content height
		var article_content_height = $('.hl_modal').height();
		// we have to give ie6 a different height than other browsers...
		if ($.browser.msie && $.browser.version === '6.0')
			$('.l').css('height', article_content_height + 46);	
		else 
			$('.l').css('height', article_content_height + 55);	
		
		// scroll the page back to the top
		$('html,body').animate({scrollTop: 0}, 800);
	},
	
	/**
	@param {string} article_id The article link id
	The scroll top element has nothing to do with append_content
	It does not belong in this function
	*/
	append_content: function(article_id){
		// select the article based on the link class
		var article_content = $('#articles div.' + article_id).html();
		// if this particular article does not exists...
		if (article_content === null){
			alert('We apologize, this article is temporarily being updated. Please check back later.');
			return;
		}
		
		var that = this;
		// currently not using any modal overlay
		this.append_overlay();
		// modal template
		// CSS should be moved from site.css to the asset possibly
		var modal = '<div class="modal_container">\n<div class="left_shadow">\n<div class="tl"></div>\n<div class="l"></div>\n</div>\n<div class="hl_modal">\n<div id="breadcrumb">\n<ul></ul>\n</div>\n';
		modal += '<div id="article_content" class="container colspan-24">' + article_content + '</div>\n';
		modal += '<div id="close">close&nbsp;&nbsp;<a href="">X</a></div>\n<div id="related_services" class="container colspan-7 last">\n</div>\n';
		modal += '</div>\n<div class="bottom_shadow">\n<div class="bl"></div>\n<div class="b"></div>\n<div class="br"></div>\n</div></div>';
	
		// get the related services
		that.populate_services(article_id,'#related_services');
		// Append our modal
		$('body').append(modal);
		// Run the template script to set the breadcrumb for us
		WC.Template.setup();			
		//position the modal
		that.position_modal();
		// if ie 6, we need to run the pngFix to the appended transparent content function before showing
		if ($.browser.msie){
			$('.left_shadow, .bottom_shadow').pngFix(); 
			$('.modal_container').show();
		}
		else 
			$('.modal_container').fadeIn(400);
	},
	
	/**
	@param {string} article_id The article link id
	@param {string} service_cont The selector for the service div container
	*/
	populate_services: function(article_id, service_cont){
		// grab the services mapping 
		$.getScript(site.service_map_location,
			function(){ 
				// find that appropriate array with given ID
				var services = service_map[article_id];
				
				// create temp array to hold html list
				var html_tmp_arr = [];
				html_tmp_arr.push('<h4>Related ENT Services</h4><ul>');
								
				// if there is no match, return null					
				if (services === undefined){
					return;
				}
				// loop through the file and return the appropriate services array, build <li> links
				for (var i=0; i<services.length; i+=1){
					var service_name = services[i];
					// turn to lowercase and replace spaces with underscores
					var service_link = services[i].toLowerCase().replace(/\s/g, '_').replace(/^\s+|\(|\)|\s+$/g, '');
					// need to abstract service dirname
					html_tmp_arr.push('<li><a href="../healthcare_services/' + service_link + '.html">' + service_name + '</a></li>');
				}
				html_tmp_arr.push('</ul>\n');
				// join array items for output - increases speed over string concatenation 
				var html_output = html_tmp_arr.join('');
				// append html to page
				$(service_cont).append(html_output);
			}
		);
	},
	position_modal: function(){
		var wrapper_offset = $('#content_wrapper').offset();
		var pos_left = wrapper_offset.left;
		$('.modal_container').css('left', pos_left - 5);
	},
	// currently not using modal overlay
	// BUG: does not show as transparent in ie7
	append_overlay: function(){
		$('body').append('<div class="overlay"></div>');
		this.size_overlay();
		$('.overlay').css('opacity', 0.7).fadeIn(100);
		$(window).resize(function(){ WC.HealthLibrary.modal.size_overlay(); });
	},
	size_overlay: function(){
		$('.overlay').css({
			width: $(window).width(),
			height: $(window).height()
		});
		if ($.browser.msie && $.browser.version === '6.0'){
			$('.overlay').css({
				height: '5000px',
				position: 'absolute'
			});
		}
	},		
	close: function(){
		$('.overlay, .modal_container').fadeOut(200, 
			function(){ 
				$(this).remove();
			}
		); 
	}
};


/** 
Filter health library links on a main library page.
@class Filter Object
*/	
WC.HealthLibrary.filter = {
	// filter item collection array
	collection: [],
	// create the collection
	create_filter_collection: function(selector){
		var group = $(selector);
		for (var i=0; i<group.length; i+=1)
			this.collection.push($(group[i]).text());
	},
	filter_articles: function(content_selector, list_selector, query){
		// get content column height for when list starts to filter
		// lock the col height so it does not shrink up and make a page jump
		var col_height = $(content_selector).height();
		$('#col_2').css('height', col_height);
		// change query to lower
		query = query.toLowerCase();
		// return null if query is backspaced to 0 length
		if (query.length === 0){
			this.show_collection(list_selector);
			return;
		}
		// run through the collection and match the query
		for (var i=0; i<this.collection.length; i+=1){
			var term = this.collection[i].toLowerCase();
			// hide those that don't match...
			if (term.match(query) === null)
				$(list_selector + ':eq(' + i + ')').css('display','none');
			// if already hidden, show the ones that do match
			else 
				$(list_selector + ':eq(' + i + ')').css('display','inline');
		}
	},
	// show any list item that is hidden
	show_collection: function(list_selector){
		$(list_selector).fadeIn(400);
		$('#col_2').removeAttr('style');
	}
};


WC.HealthLibrary.show_related_articles = function(){
	// grab the first index of the page.sub array
	var cur_service = page.sub[0] !== undefined ? page.sub[0].replace(/^\s+|\s+$/g, '') : '';
	// get jquery collection array of articles
	var articles_array = $('#articles .article');
	// initiate collection array
	var article_class_collection = [];
	// create a article class collection array from the hidden articles in the page		
	for (var i=0; i<articles_array.length; i+=1){
		var article_classes = $(articles_array[i]).attr('class');
		var classes_array = article_classes.split(' ');
		article_class_collection.push(classes_array[1]);
	}
	// get our mapping json script
	// anonymous function wrapper to pass in exeptions
	(function(){
		$.getScript(site.service_map_location,
			function(){
				// open our html temp array holder
				var html_tmp_arr = [];
				html_tmp_arr.push('<h4>Related Health Articles</h4>\n<ul>');
				// set a counter and current hidden state
				var count = 0;
				var some_hidden = false;
				// loop through the article class collection created above
				for (var i=0; i<article_class_collection.length; i+=1){
					// each specific article class
					var article_class = article_class_collection[i];
					// seach mapped service array from article_class
					var article_services = service_map[article_class];
					// if the spcific service array is found based on article_class
					if (article_services !== undefined){
						// loop through those services...
						for (var x=0; x<article_services.length; x+=1){
							var this_service = article_services[x];
							// if the service matches a service in an article array, add it to the html string
							if (this_service === cur_service){
								var article_name = article_class.replace(/_/g, ' ');
								var article_id = article_class;
								// check the exceptions list to format properly
								for (var p in services_format_exceptions){
									if (article_name == p.toLowerCase())
										article_name = services_format_exceptions[p];
								}
								// if we are on the 14th match, then our list is as high as we want it to be
								if (count >= 14){
									// time to hide the rest
									some_hidden = true;
									html_tmp_arr.push('<li class="hide"><a href="" id="' + article_id + '">' + article_name + '</a></li>');
								}
								else
									// display them as normal\n
									html_tmp_arr.push('<li><a href="" id="' + article_id + '">' + article_name + '</a></li>');
								
								count += 1;
							}
						}
					}
				}
				if (some_hidden === true)
					html_tmp_arr.push('<li><a href="" id="toggle_article_list">Show more</a></li>\n');
				
				// close our ul and div
				html_tmp_arr.push('</ul>\n');
				var html_output = html_tmp_arr.join('');
				// if there is at least one <li> in the html, append to page
				if (html_output.match('<li>'))
					$('#related_articles').append(html_output);
				
			}
		);
	// pass in the service format exceptions from one anonymous to another
	})(services_format_exceptions);
};

/** 
Cookie Object
@class Create, Read and Erase cookies<br/>
Thanks To http://www.quirksmode.org/js/cookies.html<br/>
Changed to JSON and made more readable 
*/
WC.Cookie = {
	create: function(name,value,days){
		if (days){
			var date = new Date();
			date.setTime(date.getTime() + (days*24*60*60*1000));
			var expires = '; expires=' + date.toGMTString();
		}
		else var expires = '';
		document.cookie = name + '=' + value + expires + '; path=/';
	},
	read: function(name){
		var name_equals = name + '=';
		var cookie_array = document.cookie.split(';');
		for (i in cookie_array){
			var cookie = cookie_array[i];
			if (cookie.indexOf(name_equals) === 1){
				var cookie_value = cookie.substring(cookie.length, name_equals.length + 1);
				return cookie_value;
			}
		}
		return null;
	},
	erase: function(name){
		this.create(name, '', -1);
	}
};

/** 
Debug Object
@class A simple debug bar to replace document.write and alert debugging
*/
WC.Debug = {
	init: function(where){ 
		$(where).append('<div id="error_log"></div>');
		$('#error_log').css({
			'backgroundColor': '#fff',
			'position': 'fixed',
			'bottom': '0',
			'left': '0',
			'padding': '15px 2%',
			'width': '98%',
			'color': '#ff3300',
			'z-index': '5000',
			'fontFamily': 'sans-serif',
			'fontSize': '12px'
		});
	},
	write: function(tolog){
		$('#error_log').append(tolog+', ');
	}
};

/** 
Simple get date function
@function Print out a formatted date with custom delimeter
@param {string} delimeter The type of delimeter you want to use for the date string
*/
WC.get_date = function(delimeter){
	var date = new Date();
	var month = date.getMonth();
	var day = date.getDay();
	var year = date.getFullYear();
	var date_string = month + delimeter + day + delimeter + year;
	return date_string;
}


/**
CLass Naming method:
.parent_selector
.parent_selector_dd for any drop down in the parent

@param {string} parent_selector
@param {number} speed
*/
WC.simple_drop_down = function(parent_selector, speed){
	if ($.browser.msie){
		$(parent_selector).hover(
			function(){ $(parent_selector + '_dd').css('display', 'block'); },
			function(){ $(parent_selector + '_dd').css('display', 'none'); }
		);
	}
	else {
		$(parent_selector).hover(
			function(){ $(parent_selector + '_dd').fadeIn(speed); },
			function(){ $(parent_selector + '_dd').fadeOut(speed); }
		);
	}
}

/**
@function Our usual clear input on focus
@param {string} selector ID or class for that input
@param {string} focus_color the color of the text when focused. Set blur color in css.
*/
WC.focus_clear_input = function(selector, focus_color){
	$(selector).focus(function(){
		$(this).val('').css('color', focus_color);
	});
}

/**
Used to print out all menu widths once you get them right with padding
Allows you to then use the printed widths to fix the widths of each menu item
depends on WC.Debug
*/
WC.print_menu_widths = function(){
	$(selector).each(function(i){
		WC.Debug.write( $(this).innerWidth() );
	});
}


WC.init = function(){
	WC.Template.setup();
};





