//register setUpQuickSearch so it runs when the DOM is done
domrequiredfunctions.push("setUp()");

//this is an offset specifically for IE6 and for the left hand nav. it determines the vertical spacing of the fly-outs
ie6offset = 0;



/*==========================================================================================================
 *	page set up
 *==========================================================================================================
 *
 *  setUp():
 *  --------------------------------
 *  this function gets registered above and runs the functions required
 *  to initiate this page
 *
 *
 *  setUpQuickSearch():
 *  --------------------------------
 *  this function sets up the quick search predictive search bar.
 *  it also set up the data object qsobjects which is used to display the
 *  results of the search
 *
 *
 *  deleteExampleText(event):
 *  --------------------------------
 *  this removes the example text from the search box when the user clicks
 *  in side to activate the search
 *
 *
 *  setUpTabs():
 *  --------------------------------
 *  this sets up the tabs that are located on the right side of the search box.
 *  it sets up the data object switchtabobjs and assigns event handlers .
 *
 *
 *
*/
var qsobjects,
    switchtabobj;

function setUp() { 
	setUpQuickSearch();
	setUpTabs();
	setUpDropDowns();
}

function setUpQuickSearch() {

	var searchbar = new PredictiveSearchBar();
	var downarrow = document.createElement('img');
		downarrow.src = baseimagepath+"/homepage/quicksearch_return_toggle_arrow_down.gif";
	
	searchbar.insertSearchBar($("searchnav"));
	searchbar.searchbox = $("searchbox");
	searchbar.searchoptions = $("results");
	searchbar.searchbox.observe('keyup', searchbar.searchBoxEvent.bindAsEventListener(searchbar) );
	searchbar.searchbox.observe('focus', function (e) {deleteExampleText(e);});
	var tmp = $('qsreturns');
	qsobjects = {open:true, qsreturns:tmp, results:$('results'), decoration:tmp.down('.decoration'), arrowparent:$('results').next('a'), arrowup:tmp.down('img'), arrowdown:downarrow, copy:$('resultslabel') };
		
	tmp.down('a.open').observe('click',quickSearchPannel);
	closeQSpannel();
	
}

function deleteExampleText(event) {
	var element = event.element();
	element.clear();
	Event.stopObserving(element, 'focus', function (e) {deleteExampleText(e);});
}

function setUpTabs() {
	
	var pdflink = $('pdflink');
	var demolinks = $('demolinks');
	
	var pdfimgoff = document.createElement('img');
		pdfimgoff.src = baseimagepath+"/homepage/sup_content_tabs_guide_off.gif";
	var demoimgon = document.createElement('img');
		demoimgon.src = baseimagepath+"/homepage/sup_content_tabs_demo_active.gif";
		
	//pdflink.down('a').observe('click',switchTabs);
	//demolinks.down('a').observe('click',switchTabs);
	
	switchtabobjs = {demo:$('demos'), pdf:$('guides'), pdfimgparent:$('pdflink').down(), pdfimgon:pdflink.down('img'), pdfimgoff:pdfimgoff, demoimgparent:$('demolinks').down(), demoimgon:demoimgon, demoimgoff:demolinks.down('img')};
	
	switchtabobjs.demo.setStyle({display:'none'});
	
	
	
}

/*==========================================================================================================
 *	QUICK SEARCH RESULTS
 *==========================================================================================================
 *
 *  the following function control the search result display area
 *  this whole section could benefit from some refactoring and renaming
 *
 *
 *  quickSearchPannel(event)
 *  --------------------------------
 *  this determines whether to close the results panel or updated it with new
 *  results from the searchbar.searchBoxEvent() function
 *
 *
 *  openQSpannel()
 *  --------------------------------
 *  this displays the results panel, sets a flag for the display being true
 *  and changes the UI arrow from a down pointing arrow to an up pointing arrow
 *
 *
 *  updateQSpanel()
 *  --------------------------------
 *  this sets the display styles and positions for the search returns
 *  there are numerous adjustments made for IE versions
 *
 *
 *  closeQSpannel()
 *  --------------------------------
 *  this closes the search returns panel
 *  it does a lot of css changes like updateQSpanel() does but in reverse as it
 *  were.
 *
 *
 *
*/



function quickSearchPannel(event) {
	
	if (qsobjects.open) {
		closeQSpannel();
	} else {
		updateQSpanel();
	}

}

function openQSpannel() {
	
	if (!qsobjects.open) {
		qsobjects.open = true;
		qsobjects.results.setStyle({display:'block'});
		qsobjects.arrowparent.replaceChild(qsobjects.arrowup, qsobjects.arrowdown );
	}
	
}

function updateQSpanel() {
	
	var displayoffset = 	15,
		returnheightadj = 	10,
		copy_top = 			5,
		dec_top =			11,
		minheight =			145,
		qtop = Number(qsobjects.qsreturns.getStyle("top").replace(/px/ig,"")),
		rheight;
		
	
	
	if (!qsobjects.open) { openQSpannel(); }
	
	try { 
		rheight = $('soptions').getHeight();
	} catch (e) {
		rheight = 20;
	}
		
	if(isIE6) {
		returnheightadj = 5;
		qtop = 0;
		copy_top = 1;
		dec_top = 5;
				
	} else if (isIE7) {
	
		returnheightadj += 0;
	
	} 
	
	if (rheight < minheight) {
		rheight = minheight;
		if(isIE6) { displayoffset=20;copy_top=5;}
	}
	
	qsobjects.qsreturns.setStyle({top:qtop+'px',paddingBottom:returnheightadj+'px',height:rheight+returnheightadj+'px'});
	qsobjects.copy.setStyle({top:rheight+copy_top+'px'});
	qsobjects.decoration.setStyle({
		top:dec_top+'px',
		height:rheight+displayoffset+returnheightadj+'px',
		background:'transparent url('+baseimagepath+'/homepage/quicksearch_return_toggle_background_open.gif) no-repeat bottom'
	});
	
}

function closeQSpannel() {
	if (qsobjects.open) {
		qsobjects.open = false;
		qsobjects.results.setStyle({display:'none'});
		
		qsobjects.copy.setStyle({top:'0px'});
		
		if(isIE6) {
			qsobjects.qsreturns.setStyle({top:'-5px',height:'20px'});
			
			qsobjects.decoration.setStyle({
				top:'-5px',
				height:'20px',
				background:'url('+baseimagepath+'/homepage/quicksearch_return_toggle_background.gif) no-repeat top'
			});
		} else {
		
			qsobjects.qsreturns.setStyle({top:'0px',height:'20px'});
			
			qsobjects.decoration.setStyle({
				top:'0px',
				height:'20px',
				background:'url('+baseimagepath+'/homepage/quicksearch_return_toggle_background.gif) no-repeat top'
			});
		}
		
		var tmp = qsobjects.arrowparent.replaceChild(qsobjects.arrowdown, qsobjects.arrowup );
		
	}
}

/*==========================================================================================================
 *	TABS
 *==========================================================================================================
 *
 * this is the function that handles the tab click events
 *  it switch the images around and show or hide the specific content panel:
 *  PDF or DEMO
*/


function switchTabs(event) {
	
	var element = event.element;
	
	var urlprefix = /^http:\/\/localhost:8080/i;
	
	var pdfsrcs = {active:baseimagepath+'/homepage/sup_content_tabs_guide_active.gif',off:'/media/images/homepage/sup_content_tabs_guide_off.gif'};
	var demosrcs = {active:baseimagepath+'/homepage/sup_content_tabs_demo_active.gif',off:'/media/images/homepage/sup_content_tabs_demo_off.gif'};
	
	//var reg = /active/ig
	
	if (switchtabobjs.pdfimgon.src == $('pdflink').down('img').src) {// Step by Step guides active
		
		//pdf/guides active
		
		switchtabobjs.pdfimgparent.replaceChild(switchtabobjs.pdfimgoff, switchtabobjs.pdfimgon);
		switchtabobjs.demoimgparent.replaceChild(switchtabobjs.demoimgon, switchtabobjs.demoimgoff);

		switchtabobjs.demo.setStyle({display:'block'});
		switchtabobjs.pdf.setStyle({display:'none'});
		
	} else {
		
		//demos active
		
		switchtabobjs.pdfimgparent.replaceChild(switchtabobjs.pdfimgon, switchtabobjs.pdfimgoff);
		switchtabobjs.demoimgparent.replaceChild(switchtabobjs.demoimgoff, switchtabobjs.demoimgon);
		
		switchtabobjs.demo.setStyle({display:'none'});
		switchtabobjs.pdf.setStyle({display:'block'});
	}

}

/*==========================================================================================================
 *	DROP DOWNS
 *==========================================================================================================
 *
 *  setUpDropDowns():
 *  -------------------------
 *  this set up the drop down selectors for th two tabs on the right of the search bar
 *  the second drop down initiates first as it gets passed into the first drop down
 *  as an object to be updated
 *
 *  "guidebutton" and "demobutton" are the "go" buttons you hit once your selection is made.
 *
 *  DropDown:
 *  -------------------------
 *  this is a Class that creates and controls the drop downs. It is created using
 *  prototype Class.create function
 *
 *
 *
 *
*/



function setUpDropDowns() {


	/*
	 	if statement added b/c safari fires this function a 2nd time creating the 2nd set of the same dropdowns.  
	 	checks to see if elements already exist - if not we create them
	*/
	
	if($('guideplatformselect')){
		//alert('already exists');
	}else{
		var guidetwo = new DropDown("guidebutton", "guidetaskselect", "none", "pdf", "guidetask", "--Select a Task--", true);
		var guideone = new DropDown(guidetwo, "guideplatformselect", "", "home", "guideplatform", "--Select a Platform--", false);
			
		var demotwo = new DropDown("demobutton", "demotaskselect", "none", "demo", "demotask", "--Choose a task--",false);
		var demoone = new DropDown(demotwo, "demoplatformselect", "", "home", "demoplatform", "--Choose a channel--", false);


	}
		

	
		Event.observe(guideone.id, 'change', guideone.changed.bindAsEventListener(guideone));
		Event.observe(guidetwo.id, 'change', guidetwo.changed.bindAsEventListener(guidetwo));
	
		Event.observe(demoone.id, 'change', demoone.changed.bindAsEventListener(demoone));
		Event.observe(demotwo.id, 'change', guidetwo.changed.bindAsEventListener(demotwo));
}

var DropDown = Class.create({

	initialize: function(target, id, listid, uri, attachtarget, caption, newwindow) { // <- string/obj, string, string, string, string/obj
	
	/*
		[target] in this case is an <a> tag as we want to change the href attribute
		or target is the next drop down obj
		
		[id] the id to give to the "select" element
		
		[listid] the id of the main left hand navigation menu. 
		This is matched against the "title" property.
		if the sting is empty the top lvel is returned.
		if the string has "none" no list is returned.
		
		[uri] is the uri you want back. In this case options 
		are [home,demo,video,pdf] where "home" is the content page, 
		demo and video are deep links into "home" and pdf is a pdf
		
		[attachtarget] where in the page to attach the list
		
		[caption] is the copy for first element in the list that describes the list content type and give direction
		
		[newwindow] to open the link in a new window or not
		
		this oject also assumes the existence of a variable called nav that 
		is created in nav_data.js this var is a data set that represents the 
		left hand navigation of the site and includes links to PDFs, demos 
		and videos as well as content pages. It also used for the 
		"predictive search" filter
	
	*/
		
		this.dropobj;
		this.target = $(target);
		this.attachtarget = $(attachtarget);
		this.id = id;
		this.listid = listid;
		this.returnuri = uri;
		this.caption = caption;
		this.create();
		this.newwindow = newwindow
		
	},

	create: function() {
	
		this.dropobj = document.createElement("select");
		this.dropobj.id = this.id;
		this.populate();
		this.attachtarget.appendChild(this.dropobj);
	},
	
	populate: function() {
		var list = this.generateList();
		this.appendList(list);
		
	},
	
	appendList:function(list) {
		
		var op = document.createElement("option");
			op.value = "";
			op.innerHTML = this.caption;
			
		this.dropobj.appendChild(op);
		
		for (var i=0, l; l=list[i]; i++) {
		
			var op = document.createElement("option");
				op.value = l.uri+":::"+l.title;
				op.innerHTML = l.title;
				
			this.dropobj.appendChild(op);
			
		}
		
	},
	
	repopulate:function() {
		this.clearList();
		this.populate();
	},
	
	generateList:function() {
		var list = [];
		
		if (this.listid.length > 0) {
			if (this.listid != "none") {
				//find appropriate list
				for (var i=0,n; n=nav[i]; i++) {
					if (this.listid == n.title) {
						//mine list
						for (var i=0,l; l=n.catagories[i]; i++) {//assumes that nav has "catagories" in it's stucture
							list.push({title:l.title,uri:eval("l.uris."+this.returnuri)});
						}
					
						break;
					}
				}
			}
		} else {
			for (var i=0,n; n=nav[i]; i++) {
				list.push({title:n.title,uri:n.uris.home});
			}
		}
		
		return list;
		
	},
	
	clearList:function() {
		
		if (this.dropobj.childElements().length > 0) {
			while (this.dropobj.childElements().length > 0) {
				this.dropobj.childElements()[0].remove();
				
			} 
		}
		
	},
	
	changed:function(event) {
		var element = event.element(),
			entry = $F(element).split(":::");
		
		if (this.target instanceof DropDown) { // checking to see if this.target a drop down
			if (entry.length > 0 && entry[0].length > 0) {
				this.target.listid = entry[1];
				this.target.repopulate();
			}
		} else if (this.target.tagName.toLowerCase() == "a") {// check to see if this.target is an anchor <a> tag
			this.target.writeAttribute("href", entry[0]);
			if (this.newwindow) {
				this.target.writeAttribute("target", "infocenter");
			}
		
		}
		
	}
	
});

/*==========================================================================================================
 *	Predictive Search Bar
 *==========================================================================================================
 *
 *  this Class creates the predictive search bar. It has been tuned for speed
 *  so you will see most decision trees are in the form of switch/case
 *  structures.
 *
 *  regular expressions are used to do the heavy lifting of the search
 *  there are also (outside of this comment) two undocumented features:
 *  AND and OR.
 *
 *  the event handlers for this object are actually created outside the object's
 *  initialization in setUpQuickSearch()
 *
 *  searchNavArray does the actual searching
 *  scrubDuplicates does the list clean up
 *
 *  everything else is display or key press oriented
 *
 *
 *
*/



var PredictiveSearchBar = Class.create({

	initialize: function() {
		
		this.searchbox = null;
		this.searchoptions = null;
		this.maxreturns = 10;
		
		/* searchBoxEvent */
		this.results = [];
		
		/* previousSelection && nextSelection */
		this.selectedindex = -1;
		
		/* changeTargetURI */
		this.searchTargetURI = "";
				
	},

	searchBoxEvent: function(event) {
		
		var element = event.element(),
			str = $F(element),
			keyhit = Number(event.keyCode),
			validkey = this.validateKeyPress(keyhit);
		
		switch (validkey){ //search nav list
			case true:
				switch (this.searchbox) {
					case element:
						switch (str.length > 0 ){
							case true:
								this.results = this.searchNavArray(str);
								
								switch (this.results.length > 0) {
									case true:
										this.outputResults();										
										updateQSpanel(); // <-sloppy reference to function
										break;
									
									case false:
										this.searchoptions.innerHTML = "<span id=\"failed\">Nothing Found</span>";
										//closeQSpannel()
								}
								break;
							
						}
						
				}
				
				
		}
		
	},
		
	outputResults: function() {
		
		var maxlength = 5,
			output = "",
			localist = this.results.splice(0,maxlength);
			
		output += "<ul id=\"soptions\">";
		for (var i=0, l; l=localist[i]; i++) {
			var r = l[0],
				p = l[1];
			
			output += "<li class='title'";
			if (i==0) {
				output += "id=\"first\"";
			}
			if (p.length > 0) {
				output += "><a href=\""+r.uris.home+"\"  class=\"searchreturnlink\" title=\""+l[1]+" - "+r.title+"\">"+l[1]+" - "+r.title+"</a>";
			} else {
				output += "><a href=\""+r.uris.home+"\" class=\"searchreturnlink\" title=\""+r.title+"\">"+r.title+"</a>";
			}
			output += "<ul>";
			if (r.uris.demo.length >0) {
				output += "<li class='contenttypedemo' id=\"first\">";
				output += "<a href=\""+r.uris.demo+"\">Interactive Demo</a>";
				output += "</li>";
			}
			
			if (r.uris.video.length >0) {
				output += "<li class='contenttypevideo' ";
				if (r.uris.demo.length <1) { output += "id=\"first\"" }; 
				output += ">";
				output += "<a href=\""+r.uris.video+"\">video</a>";
				output += "</li>";
			}
			
			if (r.uris.pdf.length >0) {
				output += "<li class='contenttypepdf' ";
				if (r.uris.demo.length <1 && r.uris.video.length <1) { output += "id=\"first\"" }; 
				output += ">";
				output += "<a href=\""+r.uris.pdf+"\">pdf</a>";
				output += "</li>";
			}
			
			output += "</ul>";
			output += "</li>";
			
						
		}
		output += "</ul>";
		
		this.searchoptions.innerHTML = output;
		
	}, 
		
	changeTargetURI: function() {
		this.searchTargetURI = this.results[this.selectedindex].uri;
		this.highlightSelection(this.selectedindex);

	},
	
	validateKeyPress: function(k) {
		var valid = false;
		switch (k < 48){// update on everything that's not a control key etc.
			case false:
				valid = true;
				break;
			case true: // these are the exception keys to update on
				switch (k) {
					case 13: //return
						valid = true;
						break;
					case 32: //space
						valid = true;
						break;
					case 8: //backspace
						valid = true;
						break;
					case 46: //delete
						valid = true;
						break;
					case 38: //up arrow
						valid = true;
						break;
					case 40: //down arrow
						valid = true;
						break;
				}
		}
		return valid;
	},
		
	searchNavArray: function(s) {
		var reg_or = /\bor\b/ig,
			reg_and = /\band\b/ig,
			reg_extraspace = /\s+/g,
			reg_trailingspace = /(\w)\s+$/,
			reg_leadingspace = /^\s+/,
			reg_hangingor = /\s*\|\s*$/,
			reg_set = [],
			tmparr = [];
		
		s = s.replace(reg_or, "|");//or 
		reg_set = s.split(reg_and);//and
		
		switch (reg_set.length) {
			case 0:
				reg_set.push(s);
				break;
		}
		
		for (var i=0, l=reg_set.length; i<l;i++) {
			reg_set[i] = reg_set[i].replace(reg_hangingor, "");
			reg_set[i] = reg_set[i].replace(reg_extraspace," ");
			reg_set[i] = reg_set[i].replace(reg_trailingspace, "$1");
			reg_set[i] = reg_set[i].replace(reg_leadingspace, "");
			reg_set[i] = eval("/"+reg_set[i]+"/ig"); //create reg exp
		}
		
		var searchthrough = function(larray, parent) {
			var validcells = ['title','description','keywords','catagories'];
			larray.each(function(n,i){
				validcells.each(function(param){
					switch (n[param] instanceof Array) {
						case true:
							searchthrough(n[param], n.title);
							break;
							
						case false:
							reg_set.each(function(r){
								switch (r.test(n[param])) {
									case true:
										tmparr.push([i, n, parent]);
								}
								
							})
							
							break;
					}
				})
			}) 
		}
		
		searchthrough(nav,"");
		
		return this.scrubDuplicates(tmparr);
		
	},
	
	insertSearchBar: function(targetobj) {
		var output = "";
		output += "<input type=\"text\" id=\"searchbox\" autocomplete=\"off\" value=\"Example: &quot;pay a bill&quot;\" />";
		targetobj.innerHTML = output
		
	},
	
	scrubDuplicates: function(a) {
		var returnarray = [],
			cleanedarray = [],
			counter = 0;
		
		for (var i=0, element; element=a[i]; i++) {
			var isnewitem = true;
			switch (i) {// put the first element in a into cleanedarray
				case 0:
					cleanedarray[counter++] = element;
			}
			
			for (var j=0, c_element; c_element=cleanedarray[j];j++) {
				switch (c_element[0] == element[0]) { // the [0] item is an identifier for the nav list item <- faster than a string search
					case true:
						isnewitem = false;
				}
			}
			
			switch (isnewitem) {
				case true:
					cleanedarray[counter++] = element;
			}
		}
		
		for (var i=0, r; r=cleanedarray[i];i++){
			returnarray.push([r[1],r[2]]); //removing the duplicates key
		}
		
		return returnarray;
	}
			
})







