/* dispaly and search script for www.ArizonaLocalFoods.com */

// globals
var robert = 0;
var searchClass; // type of search (name/product/location)
var regionClass; // name of the region to be displayed 
var msgTimer = 0;
var theButton;
var theInput;
var matchCount = 0; //  pointer for multiple matches
var matchText = ''; //  text for multiple matches

// *************************************************************************************************************
// remove quoted paragraphs from the display
function hideTag(theTag) {
	var allHTMLTags = new Array();
	//Create Array of All HTML Tags
	var allHTMLTags=document.getElementsByTagName("blockquote");
	//Loop through all tags using a for loop
	for (i=0; i<allHTMLTags.length; i++) {
		if (theTag!=undefined) {
			allHTMLTags[i].style.display='none';
		}
		else {
			allHTMLTags[i].style.display='block';
		}
	}
	return;
}

// *************************************************************************************************************
// change the display property depending upon the region or product selected
function show() {
    var nodes = document.getElementsByTagName("div"); // get all the div elements
    var searchRegion = document.getElementById('searchRegion'); // this is the region select menu
    var searchProduct = document.getElementById('searchProduct'); // this is the product select menu
		matchCount = 0; // clear the IE multiple match flag
    for (var i = 0; i < nodes.length; i++) { // step through each div
    	cssClass = nodes[i].className; // get the class of the div
    	if (cssClass.indexOf("show-hide") == -1) { continue; } // if the class is not 'show-hide" go to the next div
        if ((cssClass.indexOf(searchRegion.options[searchRegion.selectedIndex].value) != -1 || searchRegion.selectedIndex == 0) &&
        (cssClass.indexOf(searchProduct.options[searchProduct.selectedIndex].value) != -1  || searchProduct.selectedIndex == 0))
        { // show selected or first option
           nodes[i].style.display = 'block'; // show this div
        }
        else { nodes[i].style.display = 'none'; } // hide this div
    }
		searchRegion.blur(); // remove the focus, this removes the tool tip
		searchProduct.blur(); // remove the focus, this removes the tool tip
		if (document.getElementById('search').style.display == 'block') { // return focus to the text input
		   setTimeout("document.getElementById('searchInput').focus();",100); // delay the focus change to workaround to google chrome bug
		}
		return;
} 

// *************************************************************************************************************
// Recursively find all text nodes within an element
function findTypeNodes(elem,type) {
    // Remove superfluous text nodes and merge adjacent text nodes
    elem.normalize();
    var typeNodes = [];
    // Search all children of this element to see which ones are the right type of node
    for(var nodeI = 0; nodeI < elem.childNodes.length; nodeI++) {
        if (elem.childNodes[nodeI].nodeType == type) {
					 typeNodes.push(elem.childNodes[nodeI]); // If it is a the right type of node, add it to the array
				}
        else {
            // If not a the right type of node, search it in turn
            typeNodes = typeNodes.concat(findTypeNodes(elem.childNodes[nodeI],type));
        }
    }
    return typeNodes; // return the array
}

// Recursively find all text nodes within an element having a particular class
function findClassNodes(elem,cssClass) {
    var typeNodes = [];
		var type = 3; // text type
    // Search all children of this element to see which ones are the right type of node
    for(var nodeI = 0; nodeI < elem.childNodes.length; nodeI++) {
				if (elem.childNodes[nodeI].tagName == 'DIV') { // if the element is a DIV check its display property
    			if (elem.childNodes[nodeI].style.display == 'none') { continue } // iterate if display property is 'none'
    		}
        var classes = " " + elem.childNodes[nodeI].className;
        if (classes.indexOf(cssClass) != -1) {
				typeNodes = typeNodes.concat(findTypeNodes(elem.childNodes[nodeI],type)); // If it is a the right type of node, add it to the array
        }
			else {
        	// If not the right type of node, search it in turn
        	typeNodes = typeNodes.concat(findClassNodes(elem.childNodes[nodeI],cssClass));
        }
    }
    return typeNodes; // return the array
}

// move the selection to the center of the screen
function viewSelection(range) {
		// make elements hidden while centering the selection
    document.getElementById('introduction').style.visibility = "hidden";
    document.getElementById('directory-content').style.visibility = "hidden";
    window.scrollTo(0,0); // scroll window to top, needed for IE and Firefox 2
    if (window.getSelection) { // browser other than Internet Explorer
        range.startContainer.parentNode.scrollIntoView(false); // scroll element to bottom of window
		}
		else { // browser is probably Internet Explorer
        range.select(); // element will scroll to bottom of window
		}
    window.scrollBy(0,screen.availHeight*0.4); // scroll into center of window
    document.getElementById('introduction').style.visibility = "visible";
    document.getElementById('directory-content').style.visibility = "visible";
}

// search the directory
function performSingleSearch(elem, searchElem) {
		/* This script and many more are available free online at JavaScripts.com http://javascripts.com
		Created by: Robin Winslow | http://www.robinwinslow.me.uk
		Will find and select the first instance of the value of the passed element, then when called again will move on to the next instance
		If no element passed it will try to get the value from "this" */
		
		// elem is the input object containing the search string
		// searchElem is the element to be searched
    var selectedString = ''; // Will hold the selected text to search for
    var searchString = ''; // Will hold the text to search for
    var theSelection; // Will hold the document's selection object
    // Set it to search the entire document if we haven't been given an element to search
    if (!searchElem || typeof(searchElem) == 'undefined') { searchElem = document.body; }
		// Get the search string
		if (window.getSelection) { selectedString = window.getSelection().toString()} // browser other than Internet Explorer
		else if (document.selection) { selectedString = document.selection.createRange().text;	} // Internet Explorer
    if ( selectedString && selectedString.toLowerCase() != elem.value.toLowerCase() ) {
        searchString = selectedString.split(' ')[0]; // make the search string the first four words or less of the selected text
        for (var i = 1; (i < 4 && selectedString.split(' ')[i]); i++) {
            searchString = searchString + " " + selectedString.split(' ')[i];
    	}
    	theInput.value = searchString;
    }
    else { searchString = elem.value; } // Get the string to search for from the input field
    clearTimeout(msgTimer); // clear the button text message timer
    document.getElementById('performSearch').value = 'Search'; // reset the button text
		// Start the search
    if (!searchString || !(searchString.length > 0)) { return false } // make sure the string isn't empty, or it'll crash.
    if (window.getSelection) { otherSearch(searchString, searchElem) } // browser other than Internet Explorer
    else {
       	if (document.selection) { ieSearch(searchString, searchElem) } // Internet Explorer
    	else {
    		alert("Sorry your browser doesn't support a supported selection object");
    		return false;
    	}
    }
    return true;
}


// search for browsers other than Internet Explorer	
function otherSearch(searchString, searchElem) {
            var searchString;
            var searchElem;
				var stringFound = 0; //Flag to set when string is found
            var searchMatch = new RegExp(searchString,'i');
            var textNodes = findClassNodes(searchElem,searchClass); // Get all the text nodes in the document of a particular class
            theSelection = window.getSelection(); // Get the selection
            if (theSelection.rangeCount == 1 && searchMatch.exec(theSelection.getRangeAt(0).toString())) { // If there's already a selection, and it's the string we're searching for
                var currentRange = theSelection.getRangeAt(0);
                theSelection.removeAllRanges();
                var newRange = null;
                // Move on to the next occurrence of it by iterating through text nodes...:
                for(var i = 0; i < textNodes.length; i++) {
                    // If this text node is before the currentRange, ignore it and carry on to the next one
                    if (currentRange.comparePoint(textNodes[i],0) == -1 && currentRange.startContainer != textNodes[i]) { continue; }
                    // If this text node is the same as the currentRange, find the point in the currentRange
                    else if ((currentRange.comparePoint(textNodes[i],0) == -1 && currentRange.startContainer == textNodes[i]) || (currentRange.comparePoint(textNodes[i],0) == 0)) {
                        // Create a regular expression object to do the searching
                        var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive
                        var stringToSearch = textNodes[i].textContent;
                        //while(reSearch(stringToSearch)) { // While there are occurrences of the searchString
                        while(reSearch.exec(stringToSearch)) { // While there are occurrences of the searchString
                            // Test if the index is after the currentRange's position
                            if (reSearch.lastIndex - searchString.length > currentRange.startOffset) {
                                // This is the new search position - empty the old selection and add the new selection range
                                theSelection.removeAllRanges();
                                newRange = document.createRange();
                                newRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range
                                newRange.setEnd(textNodes[i],reSearch.lastIndex); //  End node and index of the selection
                                break; // We're not interested in the other results, so break out of this while loop.
                            }
                        }
                        if (newRange) { break; } // If we found a new range, break out of this for loop, cos there's nothing more to do.
                        else { continue; } // Otherwise continue
                    } 
                    // If this text node is after the current one, search to see if it has any occurrences of the searchString
                    else if (currentRange.comparePoint(textNodes[i],0) == 1) {
                        // Create a regular expression object to do the searching
                        var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive
                        var stringToSearch = textNodes[i].textContent;
                        // If we had a find, use it
                        if (reSearch.exec(stringToSearch)) {
                            // This is the new search position - empty the old selection and add the new selection range
                            theSelection.removeAllRanges();
                            newRange = document.createRange();
                            newRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range
                            newRange.setEnd(textNodes[i],reSearch.lastIndex); //  End node and index of the selection
                            break; // We're not interested in the other results, so break out of this while loop.
                        } else { continue; }
                    }
                }
                
                if (newRange) {
                    theSelection.addRange(newRange); // Add the node to the document's current selection
                    // Make the new range visible
						viewSelection(newRange); // call function to place selection in center of screen
                    return;
                } else { otherSearch(searchString,searchElem); }
            }

            // If we don't already have a selection, just find the first instance
            else {
                // Search all text nodes
                for(var i = 0; i < textNodes.length; i++) {
                    // Create a regular expression object to do the searching
                    var reSearch = new RegExp(searchString,'gmi'); // Set it to 'g' - global (finds all instances), 'm' - multiline (searches more than one line), 'i' - case insensitive
                    var stringToSearch = textNodes[i].textContent;
                    if (reSearch.exec(stringToSearch)) { // If there are occurrences of the searchString
							stringFound = 1;
                        // This is the new search position - empty the old selection and add the new selection range
                        theSelection.removeAllRanges();
                        // Add the new selection range
                        var thisRange = document.createRange();
                        thisRange.setStart(textNodes[i],reSearch.lastIndex - searchString.length); // Start node and index of the selection range
                        thisRange.setEnd(textNodes[i],reSearch.lastIndex); //  End node and index of the selection
                        theSelection.addRange(thisRange); // Add the node to the document's current selection
							viewSelection(thisRange); // call function to place selection in center of screen
                        break; // We're done
                    }
					}
            }
				
    		if (stringFound == 0) {
            			 if (window.getSelection().toString()) { theButton.value = "top"; }
            			 else {
            			 	 theButton.value = "not found";
            				 theInput.focus();
            			 }
            			 msgTimer = setTimeout("document.getElementById('performSearch').value = 'Search';",3000);
    		}
				return;
}

// *************************************************************************************************************
// search for browser Internet Explorer			
function ieSearch(searchString, searchElem) { // Internet Explorer
    var searchString;
    var searchElem;
    var elements = document.getElementsByTagName("DIV"); // get all the elements
		var selected = (document.selection.type == "Text"); // flag set if there is a text selection
		var matchedElement; // return value from function call
		textRange = document.body.createTextRange();
		for (var elem = 0; elem < elements.length; elem++) { // loop through all the DIV elements
			if (elements[elem].style.display == 'block') { // search if displayed
			    matchedElement = getElement(elements[elem], searchString); // search the element
            if (matchedElement) {  // search text found
				   textRange.moveToElementText(matchedElement); // set the text range to the child element
				   break; // done searching
				}
			}
		}
    if (matchedElement) {
       	var numberMatches = textRange.text.match(eval('/' + searchString + '/gi')).length; // number of occurrances of search string
    	if ( matchText != searchString) { matchCount = 0; } // clear the match counter if the search text changes
        matchText = searchString; // save the search text so it can be tested for changes
        matchCount++; // increment the search counter
        for (inst = 1; inst < matchCount; inst++) { // search the text range until current instance
           	textRange.findText(searchString); // find the text
        	textRange.moveStart("character", searchString.length) ; // advance the text range
        }
        textRange.findText(searchString); // find the text
        viewSelection(textRange); // call function to place the selection in center of screen
        if (matchCount == numberMatches) { matchCount = 0; } // once all the matches have been selected, reset the counter
    }
    else {
    	if (selected) {
		   	    theButton.value = "top";
		   		document.selection.empty(); // unselect the text
		   		ieSearch(searchString, searchElem) // continue search from top
    	}
    	else { theButton.value = "not found"; }
    	msgTimer = setTimeout("document.getElementById('performSearch').value = 'Search';",3000);
		}
}

function getElement(element, searchString) { // search children of the element
			var element; // the element being searched
			var searchString; // the search string
			var matchedElement; // return from recursuve function call
			for (var child = 0; child < element.childNodes.length; child++) { // loop through all the children of the elements
				if (element.childNodes[child].nodeType != 1) { continue; } // next child if this child is not an Element
				if (element.childNodes[child].innerText && element.childNodes[child].innerText.search(eval('/' + searchString + '/i')) != -1) {
				   // text string found, now test the class
				   if (element.childNodes[child].className && element.childNodes[child].className.indexOf(searchClass) != -1) {
				   	  // the class matches, now test if the element is the one selected
				   	  if (document.selection.type == "Text") { // text is already selected
				   	  	 if (document.selection.createRange().parentElement() != element.childNodes[child]) { continue; } // not the selected element, search next child
				   		 else if (matchCount == 0 ) { document.selection.empty(); continue; } // clear the selection, search next child
					  }
				   	  return (element.childNodes[child]);
				   }
				}
				if (element.childNodes[child].childNodes) { // search child nodes of the children
				   matchedElement = getElement(element.childNodes[child], searchString);
				   if (matchedElement) { return (matchedElement); }
				}
			}
			return (false); // search string not found
}

// *************************************************************************************************************
// Multiple onload function created by: Simon Willison
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

// *************************************************************************************************************
addLoadEvent(function() {
	// enable the display for Javascript functions
	document.getElementById('search').style.display = 'block';
	document.getElementById('showHide').style.display = 'block';
	document.getElementById('displayOptions').style.display = 'block';
	 
  // create the buttons
	
  // Create the buttons
  var theHideButton = document.getElementById('hide');
  var theUnhideButton = document.getElementById('unhide');
	var theSearchInput = document.getElementById('searchInput');
	
	// Set the "Hide" onclick function
  theHideButton.onclick = function() {
    hideTag('blockquote'); // hide elements with this tag name
		if (document.getElementById('search').style.display == 'block') { theSearchInput.focus(); } // return focus to the search text input
  }
	
	// Set the  "Show" onclick function
  theUnhideButton.onclick = function() {
    hideTag(); // do not hide any elements
		if (document.getElementById('search').style.display == 'block') { theSearchInput.focus(); } // return focus to the search text input
  }
	
	// set default button to "Show"
	theUnhideButton.click();	
	
	// these buttons accept the search string and initiate the search
  theInput = document.getElementById('searchInput');
  theButton = document.getElementById('performSearch');
  var elementToSearch = document.getElementById('directory-content'); // ignore introduction, headers and footers, navigation
  var searchRegion = document.getElementById('searchRegion');
  var searchType = document.getElementById('searchType');
  var searchProduct = document.getElementById('searchProduct');
	theInput.value = '';
	theInput.onkeydown = function() { // Note that onkeypress does not work consistently with different browsers on special keys including backspace
		document.getElementById('performSearch').value = 'Search';
	};
  theButton.onclick = function() { performSingleSearch(theInput,elementToSearch); } // Set the onclick function
   
  // also perform search on enter press
  document.onkeypress = function(evt) { // window.onkeydown does not work in IE; document.onkeypress.body does not work in Firefox
    var key;
		if (!evt) { // for internet explorer
			 key = window.event.keyCode;
		}
		else { key = evt.which; }
    if (key == 13) {
			 document.getElementById('searchRegion').blur(); // remove the focus, this removes the tool tip
			 document.getElementById('searchProduct').blur(); // remove the focus, this removes the tool tip
			 document.getElementById('searchType').blur(); // remove the focus, this removes the tool tip
			 document.getElementById('performSearch').click();
		}
		else if (document.getElementById('search').style.display == 'block') { // return focus to the text input
		   setTimeout("document.getElementById('searchInput').focus();",100); // delay the focus change to workaround to google chrome bug
		}
  };
	
	// these buttons select the region to search
	searchRegion.onchange = function() { show(); }; // change the display properties
	searchRegion.options[0].selected = true; // set first option as the default
	// tool tip for region
	searchRegion.onfocus = function() { document.getElementById('toolTip-region').style.display = 'block'; }
	searchRegion.onblur = function() { document.getElementById('toolTip-region').style.display = 'none'; }
	// these buttons select the product to search
	searchProduct.onchange = function() { show(); }; // change the display properties 
	searchProduct.options[0].selected = true; // set first option as the default
	// tool tip for product
	searchProduct.onfocus = function() { document.getElementById('toolTip-product').style.display = 'block'; }
	searchProduct.onblur = function() { document.getElementById('toolTip-product').style.display = 'none'; }
	show(); // call the function to set the display style properties to default
		
	// these buttons select the type of search
	searchType.onchange = function() {
		searchClass = searchType.options[searchType.selectedIndex].value;
		if (document.getElementById('search').style.display == 'block') { // return focus to the text input
		   setTimeout("document.getElementById('searchInput').focus();",100); // delay the focus change to workaround to google chrome bug
		}
	};
	searchType.options[1].selected = true; // set first option as the default
	searchClass = searchType.options[1].value; //set the default search type
	// tool tip for search
	searchType.onfocus = function() { document.getElementById('toolTip-search').style.display = 'block'; }
	searchType.onblur = function() { document.getElementById('toolTip-search').style.display = 'none'; }
});
