/*jslint bitwise: true, browser: true, immed: true, newcap: true, nomen: true, onevar: true, regexp: true, undef: true, white: true, indent: 4, eqeqeq: false, plusplus: false */
/*globals jQuery, window, location */
/*jslint maxerr: 64 */

var phh = phh || {};
	
(function ($) {
	
	$(document).ready(function () {
	    phh.init();			
    }); // eo:ready	   
		   
	phh.init = function () {
		phh.jsCSS();
		phh.prepLinkRels("Opens in new window");
		phh.tabs.init({
			tab_selector_str : ".tab",
			wrapper_selector_str : ".tabbed",
			tabs_ul_classes_str : "vertical tabs brand-links",
			use_tab_text : false
		});
		phh.menu.init();
		
		phh.addHrefSlideToggle.init({selector_str : ".expander"});
    };
    
	
	phh.addHrefSlideToggle = {
	// v1.2
	/*
	requires:
		jQuery 1.3.2, 1.4.1
		href to contain #fragment id of an element which will be toggled with a slide up / down.
		.display-false {display:none;} overide in print.css
	expects:
		a.selector_str href.#id
		div#id
	
	init(options) may be passed as an {} that defines a jQuery selector string for an A link with an href 
	eg phh.addHrefSlideToggle.init({selector_str : "expand"});
	*/

		prefs : {
			selector_str : "href-toggle",
			open_str : "Read more",
			close_str : "Hide expanded article",
			hidden_class_str : "display-false"
		},
		init : function (options) {
			var 
				the, prefs,
				$links,
				hide, removeStyle
				;
			the = this;
			prefs = $.extend(the.prefs, options);

			// callbacks
			hide = function () {
				$(this)
					.addClass(prefs.hidden_class_str)
					.removeAttr("style")
					;
			};
			removeStyle = function () {
				$(this).removeAttr("style");
			};

			$links = $(prefs.selector_str);
			$links
				.each(function () {
					var
						$link,
						$display, // div to be revealed / hidden - slid up / down
						href_str,
						link_open_str,
						link_txt
						;
					$link = $(this);

					// if link has text reuse it, else use preferences
					link_txt = $link.text();
					//link_open_str = (link_txt.length > 0) ? link_txt : prefs.open_str; // copies value (not reference)
					//$link.text(link_open_str);
					if (link_txt.length === 0) {
						link_open_str = prefs.open_str;
						$link.text(link_open_str);
					} else {
						link_open_str = link_txt;
					}

					href_str = $link.attr("href");
					$display = $(href_str);
					$display.addClass(prefs.hidden_class_str);
					$(prefs.selector_str)
						.click(function () {
							if ($display.is(':visible')) {
								// hide
								$display.slideUp('slow', hide);
								$link.text(link_open_str);	
							} else {
								// show
								$display
									.slideDown('slow', removeStyle) // removeStyle not necessary
									.removeClass(prefs.hidden_class_str)
									;
								$link.text(prefs.close_str);
							}
							$link.blur();
							return false;
						});
			    }); // eo: $links.each
		} // eo: init
	}; // eo: addHrefSlideToggle
	
	
	
	phh.menu = {
		id : "menu", // #ID of UL
		mode : "mono", // mono / multi // only one submenu may be open at one time
		current_open : 0, // used if only one submenu may be open at one time
		cookie_name_str : "heinzsight",
		array : [],
		
		init : function () {// DEFINE ONE LEVEL TREE MENU FUNCTIONS //
			if (document.getElementById) {
				var 
					nav = document.getElementById(phh.menu.id),	
					ul_array = nav.getElementsByTagName('ul'), // any ul inside nav are submenus
					cookies = document.cookie,
					i, 
					i_ul_el, 
					i_li,
					i_a_first;
				
				if (cookies) {
					// cookie exists: so when looping thru submenus make each one open or closed to match phh.menu.array
					// so fill phh.menu.array from cookie			
					phh.menu.loadCookie();			
				} else {
					// cookie does not exist:
					// so make an empty array and save it in cookie
					
					phh.menu.array = new phh.menu.emptyArray(ul_array.length);
					phh.menu.saveCookie();
				}
				// loop thru all submenus
				for (i = 0; i < ul_array.length; i++) {
					i_ul_el = ul_array[i];
					i_li = i_ul_el.parentNode; // will be parent LI
					i_li.pnum = i;
					i_a_first = i_li.getElementsByTagName('a')[0];
					if (phh.menu.array[i] == 1) {
						i_a_first.className = "open";
						i_ul_el.style.display = 'block';
						phh.menu.current_open = i;
					} else {
						i_a_first.className = "closed";
						i_ul_el.style.display = 'none';
					}
					i_a_first.onclick = function () {
						phh.menu.setDisplay(this, true);
					};
					i_a_first.onmouseover = function () {
						this.className += " hover";
					};
					i_a_first.onmouseout = function () {
						this.className = this.className.replace(new RegExp(" hover\\b"), "");
					};
				}
			}
		},
		setDisplay : function (a_el, state) {
			// a_el is an <a>	
			var 
				li = a_el.parentNode, // == li
				ul = li.getElementsByTagName('ul')[0], // ul is a sibling of a_el
				isalreadyvisible = false,
				nav,
				ul_array,
				open_ul,
				open_li,
				open_a_first;
				
			if (ul.style.display == "block") { isalreadyvisible = true; }
			
			if (isalreadyvisible) {
				ul.style.display = 'none';
				a_el.className = 'closed';		
				phh.menu.array[li.pnum] = 0;
			} else {
				ul.style.display = 'block';
				a_el.className = 'open';		
				phh.menu.array[li.pnum] = 1;		
				
				// was not open before, so another LI may have been and thus other LI must be closed if in mono mode
				if (phh.menu.mode == "mono") {
				// beware that the last opened LI could be this one, which has just been opened, so test to avoid closing it
					if (phh.menu.current_open != li.pnum) {
						phh.menu.array[phh.menu.current_open] = 0;
						
						nav = document.getElementById(phh.menu.id);	
						ul_array = nav.getElementsByTagName('ul'); // any ul inside nav are submenus
						open_ul = ul_array[phh.menu.current_open];
						
						open_li = open_ul.parentNode; // will be parent LI of open UL
						open_a_first = open_li.getElementsByTagName('a')[0];
						
						open_a_first.className = "closed";
						open_ul.style.display = 'none';
					}
				}
				phh.menu.current_open = li.pnum;
			}
			phh.menu.saveCookie();
		},
		saveCookie : function () {
			var cookie_str = encodeURIComponent(phh.menu.array);
			document.cookie = phh.menu.cookie_name_str + '=' + cookie_str + "; path=/";		
		},
		loadCookie : function () {
			var 
				cookies = document.cookie,
				name_str_length,
				cookie_str,
				cookie_array_str;
				
			if (cookies) {
				name_str_length = phh.menu.cookie_name_str.length + 1; // heinz=
				cookie_str = cookies.substring(name_str_length,cookies.length);
				cookie_array_str = decodeURIComponent(cookie_str);
				phh.menu.array = cookie_array_str.split(",");
			}
		},
		emptyArray : function (length) {
			var i, empty_array;
			
			if (!length) {
				length = 0;
			}
			// length = length || 0;
			empty_array = new Array(length);
			for (i = 0; i < length; i++) {
				empty_array[i] = 0;
			}
			return empty_array;
		}
	};

	
	phh.tabs = {
		// v3.5.5 forked to 3.5.6
		/*
		version notes:
			3.5.6	wrapper_selector_str, tabs_ul_classes_str added to prefs
			3.5.5	a.html removed from config, use of 'the'
			3.5.4	.hover added to tab buttons
			3.5.3	LI.this may be ancestor rather than immediate parent
			3.5.2	documentation updated
			3.5.1	maintains location of UL
			3.5:	allows for tabs to be predefined in html
			3.0:	now with added .swoosh and multiple instances
		requires: 
			phh.jsCSS, phh.url.hash
			OSX Safari 4 needs css to be written before js in the head to avoid incorrect offsetWidth
		
		to do:
			convert '.this A' to span?
			allow overide with prefs for class names and settings
			allow span and move pdding in css
			
			allow tab to have no text
		
		assumes:
			.tabbed
				.sliding-panel-frame
					.sliding-panel-group
						.sliding-panel
							.tab
						.sliding-panel.swoosh (optional)
					
		inserts (or re-uses) controls:
			.tabbed
				ul.horizontal.tabs
					li.this a (.this defaults to :first unless set to hash id)
					li a
					li span.tab textNode > converted to > li span.tab a textNode
				div.sliding-panel-frame
				
				
		can convert:
		li
			.tab
				first node (e.g. span.inner)
					if empty will be filled with tab text
					otherwise any inner text or html is re-used unaltered
				other html (e.g. div.corner.tl)
				
		*/
		prefs : { // to be overridden, extended or remain as default
			tab_selector_str : ".tab",
			wrapper_selector_str : ".tabbed",
			tabs_ul_classes_str : "horizontal header tabs",
			use_tab_text : true
		},
		configureTabLink : function ($a, sp_control_obj, target_x) {
			$a
				.click(function () {
					var $this = $(this);
					
					// search for journal-contents within sliding panel and hide if open
					/* js journals removed
					$sliding_panel
						.parent() // .sliding-panel-group
						.find('.journals').children('.journal-contents').slideUp('fast').siblings('.journal').removeClass('open');
					*/
					phh.tabs.slidePanelGroup(sp_control_obj, target_x);
					$this
						//.parent() // LI might be grandparent rather than parent
						.parents('li:first') // will this only pick up first li found?
						.addClass('this')
						.siblings()
						.removeClass('this');
					$this.blur();
					return false; // overide mouse event
				})
				.hover(
				    function () {
					    $(this)
							.parents('li:first')
							.addClass("hover");
				    }, 
				    function () {
					    $(this)
							.parents('li:first')
							.removeClass("hover");
				    });
				
			return $a;
		},
		init : function (new_options) {
			var the, prefs;
			the = phh.tabs;
			prefs = $.extend(the.prefs, new_options);
			$(prefs.wrapper_selector_str) //.tabbed
				.each(function (tabbed_num) {
					var $tabbed_box, 
						$ul, 
						sp_control_obj, 
						sliding_panel_group, 
						$sliding_panels, 
						//ctrl_hash_obj,
						total_width, 
						tab_index_counter, 
						ul_found;
						
					total_width = 0;
					tab_index_counter = 0;
					ul_found = false;
					
					$tabbed_box = $(this);
					$sliding_panels = $tabbed_box.find('.sliding-panel-frame > .sliding-panel-group > .sliding-panel');
					sliding_panel_group = $('.sliding-panel-frame > .sliding-panel-group', $tabbed_box).get(0); // get dom element rather than jQuery object
					
					sp_control_obj = { // function scoped for each .tabbed box
						list: {}, // used to store id_objects
						
						// next properties used by: phh.tabs.slidePanelGroup
						speed: 20, 
						sliding_panel_group_el: sliding_panel_group,
						timeout: 0
					};
			
					//if ul.tabs doesn't exist create it, else re-use it
					$ul = $('ul.tabs', $tabbed_box);
					ul_found = ($ul.length !== 0);
					
					$ul = ul_found ? $ul : $('<ul class="' + prefs.tabs_ul_classes_str + '"></ul>'); // ternary conditional operater
										
					$sliding_panels	// $('.sliding-panel-frame > .sliding-panel-group > .sliding-panel')
						.each(function (i) {
							var $sliding_panel, 
								$li, 
								$a, 
								tab_txt, 
								target_x,
								id, 
								id_obj, 
								$tab,
								tab_html_str, 
								inner_html_str, 
								$inner;
							
							
							$sliding_panel = $(this);
							target_x = 0 - total_width;
							total_width = total_width + this.offsetWidth; // $sliding_panel.get(0) === this

							// if .swoosh skip to next iteration, by returning true
							// and thus do not create a tab
							if ($sliding_panel.hasClass('swoosh')) {
								return true;
							}
							
							tab_txt = $sliding_panel
								.find('.tab')
								.eq(0) // only one .tab per .sliding-panel allowed
								.text();
							tab_txt = tab_txt ? tab_txt : "tab " + (tab_index_counter + 1);
							
							
							// if tab hasClass .delete [the black spot] then remove header
							$sliding_panel
								.find('.tab')
								.each(function () {
									$(this)
										.filter('.delete')
										.remove();
								});
							
							// this block allows for custom tabs to be prewritten in html, not necessarily using A links
							// requires:
							// UL.horizontal.tabs LI A 
							// or
							// UL.horizontal.tabs LI .tab 
							//
							// check if LI:eq(i) already exists, re-use if it does
							$li = $('li', $ul).eq(tab_index_counter);
							if ($li.length === 0) { // LI doesn't exist so define it
								$li = $("<li></li>");
								$a = $('<a href="#"></a>');							
								
								if (prefs.use_tab_text) {
									$a.html(tab_txt);
								} 
								the.configureTabLink($a, sp_control_obj, target_x);
								
								$li.append($a);
								$ul.append($li);
								
								// heinz hack
								$('img', $sliding_panel).prependTo($a);
								
							} else {
								// LI exists, inside it may be an A or .tab
								$tab = $('.tab', $li);
								
								if ($tab.length === 0) { // .tab does not exist, assume there is an A to re-use
									$a = $('a', $li);
									$a.html(tab_txt); 
									the.configureTabLink($a, sp_control_obj, target_x);
									
								} else { // .tab exists
								
									
									if ($tab.is("a")) { // .tab is an A
										$tab.html(tab_txt); 
										the.configureTabLink($tab, sp_control_obj, target_x);
										
									} else { 
										// .tab is not an A (it's probably a span.tab)
										// so, prefer text in custom UL.tabs LI to text from leaf
										
										// check if .tab contains elements or just text
										if ($tab.children().length === 0) {
											// no html inside
											
											if ($tab.text().length !== 0) {
												// there is text within .tab to prefer

												tab_txt = $tab.text();  // overide tab_text
												$tab.wrapInner('<a href="#"></a>'); // wrap contents of .tab with A (there might not be any)
											
											} else {
												// there is no text within .tab to prefer

												// put A into .tab
												$tab.append('<a href="#"></a>'); // wrapInner fails if text node is empty
											}
											$a = $('a', $tab);
											$a.html(tab_txt); 
											the.configureTabLink($a, sp_control_obj, target_x);
										
										} else {			
											$inner = $tab.children(":first"); 

											// if first child is empty then insert tab_txt
											// otherwise do not change its inner text/html
											inner_html_str = $inner.html();
											if (inner_html_str.length === 0) {
												$inner.html(tab_txt);
											} 
											
											$tab.wrapInner("<a href='#'></a>");
											
											// swap SPAN for A
											tab_html_str = $tab.html();
											$tab.replaceWith(tab_html_str);

											$a = $('a', $li);
											the.configureTabLink($a, sp_control_obj, target_x);
										}
									}	
								}								
							}

							// check for id on .sliding-panel
							id = this.id;
							if (id) {
								id_obj = {
									index: tab_index_counter,
									target_x: target_x,
									$li: $li
								};
								sp_control_obj.list[id] = id_obj;
							}
							
							tab_index_counter++;
						});	// eo: sliding_panels.each
					
					// resize Panel Group
					sliding_panel_group.style.width = total_width + "px";
					
					// change to run only if no id
					$ul
						.find('li:first')
						.addClass('this');
					
					
					
					
					// add UL if it did not already exist (otherwise don't move UL)
					if (!(ul_found)) {
						//$tabbed_box.prepend($ul);	
						$('.sliding-panel-frame', $tabbed_box).before($ul);
					}
					
				});	// eo: $('.tabbed').each	
		},
		setPanelGroupX : function (sliding_panel_control, pos_x) {
			var el;
			el = sliding_panel_control.sliding_panel_group_el;
			el.style.left = pos_x + "px";
		},
		slidePanelGroup : function (sliding_panel_control, target_x) { // el gets animated
			var el, 
				x, 
				repeat, 
				adjust, 
				denominator, 
				timeout_function;
			denominator = 8;
			repeat = true;
			el = sliding_panel_control.sliding_panel_group_el;
			if (sliding_panel_control.timeout) {
				clearTimeout(sliding_panel_control.timeout);
			}
			if (!el.style.left) {
				el.style.left = "0px";
			}
			x = parseInt(el.style.left, 10);
			if (x < target_x) {
				adjust = Math.ceil((target_x - x) / denominator);
				x = x + adjust;
				if (x > target_x) {
					x = target_x;
				}
			}
			if (x > target_x) {
				adjust = Math.ceil((x - target_x) / denominator);
				x = x - adjust;
				if (x < target_x) {
					x = target_x;
				}
			}
			if (x === target_x) {
				repeat = false;
			}
			el.style.left = x + "px";
			if (repeat) {
				timeout_function = function () {
					phh.tabs.slidePanelGroup(sliding_panel_control, target_x);
				};
				sliding_panel_control.timeout = setTimeout(timeout_function, sliding_panel_control.speed);
			} else {
				if (sliding_panel_control.timeout) {
					clearTimeout(sliding_panel_control.timeout);
				}
			}
		}
	};
	
	phh.jsCSS = function () {
		// v 1.0
	    // enable javascript dependent css
	    $('body').addClass('js');
    };
	
	
	phh.prepLinkRels = function (message) {
		// v 1.0
		// looks for: rel=external
		// use instead of: target _blank 
	    message = message || "(Opens in new window)";
	    $("a[rel*='external']")
		    .click(function () {
			    window.open($(this).attr('href'));
			    return false;
		    })
		    .each(function () {
			    var title = $(this).attr("title");
			    if (!title) {
				    $(this).attr("title", message); // this.setAttribute("title", message);
			    }
		    });
    };
	






	
})(jQuery);