$(document).ready(function() {

	// Define:  header has a visible title even if what it contains is not visible (h3 a),(li span) 
	//			fold is what is hidden when the header is still visible (the content of the header)
	// for the search script, what things need to be hidden initially, and what needs to be shown in a relevant search?
	// hidden initially: div.link-body, 
	// shown with search: 

	// get the link bodies and the form hidden immediately

	var $allLinkBodies = $('#links div.link-body');
	var $formHeader = $('p#submit-link-header');
	var $form = $($formHeader).next('form');		
	var	$allCatHeadersDivs = $('#links .link-header');											
	var	$allCatHeadersH3s = $($allCatHeadersDivs).children('h3');
	var	$allCatHeaderLinks = $('a',$allCatHeadersDivs);
	var $allsubCatSpans = $('#links span');
	var $allSubCatUls = $($allsubCatSpans).next('ul');
	
	// var $allSubCatHeaders = $($allsubCatSpans).parent('li');
	var $allSubCatHeaders = $($allsubCatSpans).parent('li').hide();
	
	var $allHeaders = $($allCatHeadersDivs).add($allSubCatHeaders);
	var	$submitLink = $('div#submit-link a');
	var	$allLinks = $('div#links a').not($allCatHeaderLinks).not($submitLink);
	var	$allLinksLi = $($allLinks).parent('li');				
	
	function resetFolds() {
		$($allCatHeadersDivs).show();
		$($allLinkBodies).hide();
		$($form).hide();
		$($allSubCatUls).hide();			// in toggleSection(), ul elements are the sectionst that are  slide down
		$($allLinksLi).hide();
	}
	resetFolds();


	// _________________ link folding ________________
	//add .inline class (already in css file) so h3 elements stay on the same line as the prepended plus/minus icons
	$($allCatHeadersH3s).addClass('inline');

	// these are added before the link header text as a visual cue that they can collapse or expand link body
	var iconPlus = '+&nbsp;';	
	var iconMinus = '-&nbsp;';
	$($allCatHeadersH3s).prepend('<span class="plus">' + iconPlus + '</span>');		// add minus for default expanded state
	$($allsubCatSpans).prepend('<span class="plus">' + iconPlus + '</span>');				// add minus for default expanded state
	$($formHeader).prepend('<span class="plus">' + iconPlus + '</span>');

	// mouseover and mouseout events to highlight header (adds class .hover from css file which overlays translucent png)
	$allCatHeadersDivs.hover(function() { 
		$(this).addClass('hover'); 
	}, function() { 
		$(this).removeClass('hover'); 
	});
	$allsubCatSpans.hover(function() { 
		$(this).addClass('hover'); 
	}, function() { 
		$(this).removeClass('hover'); 
	});	
	$formHeader.hover(function() { 
		$(this).addClass('hover'); 
	}, function() { 
		$(this).removeClass('hover'); 
	});
	
	// remove bullets on all li elements that are  headers
	$($allSubCatHeaders).addClass('no-bullet');

	// I think this is right down to this point.  I don't know if I need to use findAncestorFolds() and findAncestorHeaders() yet.
	// findAncestorFolds() is the one that seems to be choking the computer
	// try to figure out removing bullets with css (but the problem is that there are too many nested li's and if I want to keep bullets on the links then I don't know how to target them without jQuery)
	// .......

	// add click events to headers to show/hide its section
	$allCatHeadersDivs.click(function() { 
		toggleSection(this, "category");
		return false;
	});
	$allsubCatSpans.click(function() { 
		toggleSection(this, "sub-category");
		return false;
	});
	$formHeader.click(function() {
		toggleSection(this, "form");
		return false;
	});


	function toggleSection(clickedHeader, clickedHeaderType) {
		var $section;
		var $spanClass = $('span', clickedHeader).attr('class');  
		
		// different headers require different DOM paths to get the the section that needs toggling
		if ( clickedHeaderType == "category" ) {				
			$section = $(clickedHeader).next('.link-body');
			if ( $spanClass == 'plus' ) {							  
				var $sectionChildren = $($section).children('ul').show();
				var $sectionChildrenLi = $($sectionChildren).children('li').show();
				$('span', clickedHeader)                              
				.removeClass("plus")				   				  
				.addClass("minus")					   				  
				.empty()							   				  
				.append(iconMinus);					   				  
				$section.slideDown();								  
			} else if ( $spanClass == 'minus' ) { 		   			  
				$('span', clickedHeader)                              
				.removeClass("minus")
				.addClass("plus")
				.empty()
				.append(iconPlus);
				$section.slideUp();
			} else {
				alert("having problems");
			};
			
		} else if ( clickedHeaderType == "sub-category" ) {
			$section = $(clickedHeader).next('ul');
			if ( $spanClass == 'plus' ) {							  
				$($section).children('li').show();		  
				$('span', clickedHeader)                              
				.removeClass("plus")				   				  
				.addClass("minus")					   				  
				.empty()							   				  
				.append(iconMinus);					   				  
				$section.slideDown();								  
			} else if ( $spanClass == 'minus' ) { 		   			  
				$('span', clickedHeader)                              
				.removeClass("minus")
				.addClass("plus")
				.empty()
				.append(iconPlus);
				$section.slideUp();
			} else {
				alert("having problems");
			};
			
		} else if ( clickedHeaderType == "form" ) {
			$section = $(clickedHeader).next('form');
			if ( $spanClass == 'plus' ) {							  
				$($section).children('li').show();
				var $sectionHeader = $($section).parent('li').show();
				$('span', clickedHeader)                              
				.removeClass("plus")				   				  
				.addClass("minus")					   				  
				.empty()							   				  
				.append(iconMinus);					   				  
				$section.slideDown();								  
			} else if ( $spanClass == 'minus' ) { 		   			  
				$('span', clickedHeader)                              
				.removeClass("minus")
				.addClass("plus")
				.empty()
				.append(iconPlus);
				$section.slideUp();
			} else {
				alert("having problems");
			};
		}

	}
	// find class of current span element so we can toggle plus/minus icon
	// if class is 'plus', then...
	// if descendent <li> links are hidden, explicitly show them
	// remove plus class
	// replace it with minus class
	// empty contents of span (remove minus sign)
	// add plus sign
	// open link body to reveal links    
	// if class is 'minus' then do all of the opposite of above
          	

	// _________________________ live search _______________________
	// this adds the search links database textbox to the page.  I add it with script instead of hardcode html because if javascript is turned off, then we don't want the search to show up because we can't search
	$('div.main-content').prepend('<div id="link-search">'
	+'<form id="submit-search" action="#">'
	+'<label for="search-box" class="main">Search Links Database</label>'
	+'<input type="text" name="search-box" id="search-box" class="text-type-med-long" />'
	+'</form>'
	+'</div>');

	// this is a custom method that extends the contains: method so as to be case insensitive
	jQuery.extend(jQuery.expr[':'], { 
		containsIgnoreCase: "(a.textContent||a.innerText||jQuery(a).text()||'').toLowerCase().indexOf((m[3]||'').toLowerCase())>=0" 
	});
	
	// there are no search results yet, so create an empty set
	var $oldSet = $('#createAnEmptyJQueryObject');
	var $oldSetLength = 0;
	var firstSearch = true;

	// search all link text for string typed into textbox
	$('#search-box').keyup(function() {
		$('div#no-matches').remove();
		var $searchText = $('#search-box').val();
		var $searchTextLength = $searchText.length;
				
		if ( $searchTextLength == 0 ) {
			resetSearch();
		} else if ( $searchTextLength > 2) {
			var $newSet = $('#links a:containsIgnoreCase('+$searchText+')'); // get the new set of links matched by the search box			
			$newSetLength = $newSet.length;
			
			if ( firstSearch ) {
				clearScreen();												// if first search, clear all non-matching links and headers from the screen
			}
			
			if ( $newSetLength == 0 ) {
				insertNoMatchMssg();
			}
			
			// initial search on the 3rd letter: $oldSet.length equals 0, so this will kick in
			//subsequent searches: kicks in when deleting letters (widens search: $newSet has more matches than $oldSet)
			if ( $newSetLength > $oldSetLength ) {
				widenSearch($newSet, $oldSet);
				
			// kicks in when adding letters (narrowing search: $oldSet has more matches than $newSet)					
			} else if ( $oldSetLength > $newSetLength  ){
				narrowSearch($newSet, $oldSet);
			}
			
			$oldSet = $newSet;
			$oldSetLength = $newSetLength;
			firstSearch = false;
		}
		return false;														// not sure if this is necessary, I don't think it hurts to have it in
	});
	
	// narrowSearch():  adding letters, closing folds ->	$oldSet > $newSet
	function narrowSearch($newLinks, $oldLinks) {
		var $diffLinks = $($oldLinks).not($newLinks);	

		// hide parent <li> of non-matching links
		$($diffLinks).parent('li').slideUp();

		// hide <ul> "folds" that don't contain any matching links                                                     
		var $newFolds = findAncestorFolds($newLinks);	      
		var $oldFolds = findAncestorFolds($oldLinks);         
		var $foldsToClose = $($oldFolds).not($newFolds);      
		$($foldsToClose).slideUp();                              

		// hide category headers that don't contain any non-matching links
		var $newHeaders = findAncestorHeaders($newLinks);	  
		var $oldHeaders = findAncestorHeaders($oldLinks);     
		var $headersToHide = $($oldHeaders).not($newHeaders); 
		$($headersToHide).slideUp();                          
		
		$($diffLinks).removeClass("highlight");
	}
	
	// widenSearch(): deleting letters, opening folds -> 	$newSet > $oldSet
	function widenSearch($newLinks, $oldLinks) {
		var $diffLinks = $($newLinks).not($oldLinks);
		$($diffLinks).addClass("highlight");
		
		// show all links that match
		var $newLi = $($newLinks).parent('li');
		var $oldLi = $($oldLinks).parent('li');	
		var $LiToOpen = $($newLi).not($oldLi);
		$($LiToOpen).show();		

		// open all <ul> "folds" if they contain a matching link
		var $newFolds = findAncestorFolds($newLinks);	
		var $oldFolds = findAncestorFolds($oldLinks);	
		var $foldsToOpen = $($newFolds).not($oldFolds);	
		$($foldsToOpen).show();		
                                                              
		// open all headers if they contain a matching link
		var $newHeaders = findAncestorHeaders($newLinks);	   
		var $oldHeaders = findAncestorHeaders($oldLinks);      
		var $headersToOpen = $($newHeaders).not($oldHeaders);  
		$($headersToOpen).slideDown();                   	
	}
	
	// problems if I toggle sections first and then do a search...
	// is this the correct behavior?
	// on search, should I trigger() all headers and sub-cat headers?
	function resetSearch() {
		resetFolds();
		firstSearch = true;
		$($allLinks).removeClass("highlight");
		$oldSet = $('#createAnEmptyJQueryObject');
		$oldSetLength = 0;
	}
	function clearScreen() {
		$($allCatHeadersDivs).hide();
	}
	
	function insertNoMatchMssg() {
		$('div#links').prepend('<div id="no-matches">'
		+'<p>Sorry, no links match that search</p>'
		+'</div>');
	}

	// for narrowSearch(), maybe don't make the call to findAncestorFolds - I don't think I need them
	function findAncestorFolds($linkSet) {
		var $subCatFolds = $($linkSet).parents('ul');
		var $catFolds = $($linkSet).parents('div.link-body');
		return $($catFolds).add($subCatFolds);		
	}

	function findAncestorHeaders($linkSet) {
		var $subCatHeaders = $($linkSet).parents('ul').siblings('span').parent('li');
		var $catHeaders = $($linkSet).parents('div.link-body').prev('div.link-header');
		var $ancestorHeaders = $($catHeaders).add($subCatHeaders);
		return $ancestorHeaders;		
	}


});
