
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };


if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

           
this.txtSearch = function()
	{
	// CONFIG 
	
	// this is id of the search field you want to add this script to. 
	// You can use your own id just make sure that it matches the search field in your html file.
	var id = "txtSearch";
	
	// Text you want to set as a default value of your search field.
	var defaultText = "Search the site...";	
	
	//- Array of Common Keyword to be excluded while doing autoSuggest.
	var KeywordsToExclude = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','of','off','only','on','or','in','is','it','its','but','by','could','did','do','does','got','get','go','for','are','a','all','at','as','am','an','and','also','he','hi','has','had','have','just','been','can','was','were','with','what','who','will','the','to','this','that','they','those','us','very','here','we','not'];
	
	// set to either true or false
	// when set to true it will generate search suggestions list for search field based on content of variable below
	var suggestion = true;
	
	var field = document.getElementById(id);
	field.focus();	
	
	// END CONFIG (do not edit below this line, well unless you really, really want to change something :) )

	var xmlhttp; 
	  
    // Variable list of suggestion options, separated by comma
    //var SuggestionKeywords = "above the fold, absolute link, accessibility, address bar, affordance, alt text, alt tag, anchor, animated GIF, anti-alias, applet, assumed knowledge, authoring, automagically, autoresponder, back end/front end, backup, bandwidth, banner ad, banner blindness, belt-and-suspenders, bitmap, blog, blogger, blogging, bookmark, breadcrumb, broadband, browser, cache, cached files, call to action, Cascading Style Sheets , chatroom, chrome, click-through rate, client-side/server-side, closure, compatibility mode, data compression, content management system , contextual menu, convergence, cookie, cost-per-clickthrough, cost-per-thousand, crawler, cross-browser compatibility, cybersquatter, deep-linking, default, degrade gracefully, deprecated, design pattern, directory, disjointed rollover, dither, div, div-i-tis, divitis, document type declaration, doctype, document type definition, Domain Name System, DNS server, domain name, DomaiNZ, doorway/gateway page, dots-per-inch, download, Dublin Core metadata, dynamic HTML, e-commerce, email, element, encryption, favicon.ico, File Transfer Protocol, FTP client, firewall, Fireworks, Flash, Flash Generator, flow chart, fold, above-the-fold, footer navigation, form, folksonomy, frame, frameset, front end/back end, gateway page, global navigation, granularity, Graphic Interchange Format, Graphical User Interface, hack, handle, haptics, hexadecimal colours, hits, host, hosting, hotspot, HyperText Markup Language, HyperText Transfer Protocol, HTML markup, HTML-text, hyperlink, iframes, i-mode, image map, impression, include, information architecture, information foraging, initialism, integration, interactive television, interface, internet, interstitial, intranet, Initial Public Offering, Internet Protocol, IP address, IP number, Internet Service Provider, JavaScript, Joint Photographers Expert Group, label, landing page, legacy content, link: absolute, relative, root, link farm, link rot, definition, ordered, unordered, listserv, logfiles, logfile analysis, look-and-feel, lossless compression, lossy compression, macron, mailing lists, markup, meta element, metadata, meta tag, mine-sweeping, MP3, MySQL, natural language, navigation, open source, optimise, optimisation, opt-in/opt-out, PageRank (PR), parasite economy, design pattern, perceived affordance, permission-based marketing, phishing, PHP: Hypertext Preprocessor, Portable Document Format, web portal, Pretty Good Privacy, pixel, plug-in, pop-up window, pop-under, Portable Network Graphic, prosumer, QuickTime, quirks mode, reciprocal links, referrer, referrer log, Really Simple Syndication, relative link, Realtime Transport Protocol, robot, robots file, robots.txt, rollover, disjointed rollover, root, root directory, root link, scan, scanning, schematic, SCM, SCP, search engine, search engine marketing, search engine optimisation, Section 508, Secure Sockets Certificate, semantic markup, server, sever-side/client-side, server-side include, session, session tracking, Shockwave, shopping-cart, shortcut icon, Simple Object Access Protocol, site feed, sitemap, smart tags, Synchronised Multimedia Integration Language, sniffer, spam, spim, spider, splash page, splash screen, spyware, standardista, standards-compliant/strict mode, status bar, sticky, streaming, streaming media, structured query language, stylesheet, system font, tags, tags/tagging, target, template, top-level navigation, topic path, traffic, transform gracefully, transparent GIF, trackback, typosquatter, Unicode, Unicode Transformation Format, Unified Modeling Language, Uniform Resource Identifier, Uniform Resource Locator, uploading, usability, user session, code standards, form input, vector, vector-based file, version control, viral marketing, virus, visual editor, web, Web 2.0, web accessibility, web-authoring, web browser, web font, typeface, web-log, web server logs, websafe colours, palette, web standards, WebTV, what-you-see-is-what-you-get, wireframe, Wireless Application Protocol, Wireless Markup Language, Worldwide Web, eXtensible Markup Language, XML schema"; 
    
	var classInactive = "sf_inactive";
	var classActive = "sf_active";
	var classText = "sf_text";
	var classSuggestion = "sf_suggestion";
	this.safari = ((parseInt(navigator.productSub)>=20020000)&&(navigator.vendor.indexOf("Apple Computer")!=-1));
	if(field ) //&& !safari
	{
		field.c = field.className;		
		field.className = field.c + " " + classInactive;
		field.onfocus = function()
		{
			this.className = this.c + " "  + classActive;
			//this.value = (this.value == "") ?  "" : this.value;
		};
		field.onblur = function()
		{
			this.className = (this.value != "" && this.value != defaultText) ? this.c + " " +  classText : this.c + " " +  classInactive;
			//this.value = (this.value != "" && this.value != defaultText) ?  this.value : defaultText;
			clearList();
		};
		if (suggestion)
		{
			
			var selectedIndex = 0;
						
			field.setAttribute("autocomplete", "off");
			var div = document.createElement("div"); 
			var list = document.createElement("ul");
			list.style.display = "none";
			list.style.width = "99.7%";
			
			div.className = classSuggestion;
			div.appendChild(list);  	
                                    			
			//field.parentNode.appendChild(div);
			document.getElementById("tbSearchCell").appendChild(div);

			field.onkeypress = function(e)
			{			 
			    //Get Auto Suggestion keywords from server.
				GetSuggestions();
	      
				var key = getKeyCode(e);
		
				if(key == 13)
				{ // enter
				    if (list.style.display != "none" && selectedIndex > 0)
				    {
				        selectList();
					    selectedIndex = 0;
				    }
				    
			        setFilter(0,true);
			        ConvertString();
			        getTable();
			        
					clearList();
					return false;
				};	
			};
			
				
			field.onkeyup = function(e)
			{
			
				var key = getKeyCode(e);
		
				switch(key)
				{
				case 13:
					return false;
					break;			
				case 27:  // esc
					field.value = "";
					selectedIndex = 0;
					clearList();
					break;				
				case 38: // up
					navList("up");
					break;
				case 40: // down
					navList("down");		
					break;
				default:
					startList();			
					break;
				};
			};
			
			this.startList = function()
			{
				var arr = getListItems(field.value);
				if(field.value.length > 0)
				{
					createList(arr, field.value);
				} 
				else 
				{
						clearList();
				};
				
				//- Clear previous Set Search Condition	
				SeachCondition = "";
			};
			
			this.getListItems = function(keywordPhrase)
			{
			    //- Get Array of Matching Keywords 
			    //- Each Keyword (provided in XML) are stored as "[Condition]~[ResultsFound]~[SearchHits]~[KeywordString]"
                // for e.g: X~25~56~Adult Literacy rate
				var arr = new Array();
				var TempArr = new Array();				
				var src = SuggestionKeywords;
				var src = src.replace(/, /g, "[^]");
				var arrSrc = src.split("[^]");
				var AllKeywordsFound = false;
				var SourceStrings;
				
				keywordPhrase = keywordPhrase.trim();
				
				if (keywordPhrase.trim() == "")
				{
				    return arr;
				}
				
				//- By Default search all Keywords in auto Suggestion.
				var SearchConditions = ['B', 'A', 'X'];   
				
                if (document.getElementById("chkAllWords").checked)
                {
                    SearchConditions = ['A'];
                }
                else if (document.getElementById("chkExactPhrase").checked)
                {
                    SearchConditions = ['X'];
                }
				
				arrSrc.sort();
				
				//- Process to follow:-
				//1. Get List of item that have exact Keywords matching in same order as in SearchedPhrase.
				//2. Get List of item that contains all Keywords of searchPhrase in any order.
				//3. If keywords not found in point 1 & 2, then get List of item that any of Keywords present in searchPhrase.
				
			    
			    //1. Get List of item that have exact Keywords matching.
			    for(i=0; i < arrSrc.length ;i++)
				{
				    //- Seperate out "No. of Result counts" from the actual string.
				    // Each Keyword (provided in XML) is stored as "[Condition]~[ResultsFound]~[SearchHits]~[KeywordString]"
				    SourceStrings = arrSrc[i].split("~");
				    if (SourceStrings.length == 4 && SearchConditions.indexOf(SourceStrings[0]) >= 0)
				    {
					    if(SourceStrings[3].substring(0,keywordPhrase.length).toLowerCase() == keywordPhrase.toLowerCase())
					    {
						    arr.push(arrSrc[i]);
					    }
					    //-or if keyword contained in between the phrase.
                        else if(SourceStrings[3].toLowerCase().indexOf(" " + keywordPhrase.toLowerCase()) >= 0)
                        {
	                        //- Add Item in temp Array, along with Hits Count (will be used in ranking)
	                        TempArr.push(SourceStrings[2] + " [^]" + arrSrc[i]);
                        }
					}
				};	
				
				//-Sort Items on the basis of No. of Hits
				TempArr.sort();
	            for(c=TempArr.length - 1; c >= 0; c--)
	            {
		            SourceStrings = TempArr[c].split("[^]");
	                arr.push(SourceStrings[1]);      
	            }
				
				//- Split search Phrase into keywords.
				var SplittedKeywords = keywordPhrase.split(" ");
				
				//- Clear Temp Array
				TempArr = [];
				
				//2. Search suggestion item that contains all Keywords of searchPhrase in any order.
				for(oi=0; i < arrSrc.length ;i++)
                {
                    AllKeywordsFound = false;
                    
                    //- if final Array NOT already containes this keyword.
                    if (arrSrc[i] != "" && arr.indexOf(arrSrc[i]) < 0)
                    {
                    	//- Seperate out "No. of Result counts" from the actual string.
		                // Each Keyword (provided in XML) is stored as "[Condition]~[ResultsFound]~[SearchHits]~[KeywordString]"
			            SourceStrings = arrSrc[i].split("~");
			                
			            if (SourceStrings.length >= 4 && SearchConditions.indexOf(SourceStrings[0]) >= 0)
				        {            
                            for (c=0; c < SplittedKeywords.length; c++)
			                {
			                    if (SplittedKeywords[c].length > 0)
				                {
				                    //- Exclude Common Keyword like (in, at, for, of .... etc)
				                    if (KeywordsToExclude.indexOf(SplittedKeywords[c].toLowerCase()) < 0)
				                    {
                                        //-Check if any word starts with this keyword
                                        if(SourceStrings[3].substring(0,SplittedKeywords[c].length).toLowerCase() == SplittedKeywords[c].toLowerCase())
		                                {
		                                    AllKeywordsFound = true; 					                        
		                                }
		                                //-or check if any word contains this keyword
	                                    else if(SourceStrings[3].toLowerCase().indexOf(" " + SplittedKeywords[c].toLowerCase()) >= 0)
	                                    {
		                                     AllKeywordsFound = true;
	                                    }
	                                    else
	                                    {
	                                         AllKeywordsFound = false;
	                                         break;
	                                    }
				                    }
				                }
				            }
			            }
			            
			            if (AllKeywordsFound)
			            {
			                 // Add in temp Array
				             TempArr.push(SourceStrings[2] + " [^]" + arrSrc[i]);  
			            }
                    }
                }
                
                //-Sort Items on the basis of No. of Hits
				TempArr.sort();
	            for(c=TempArr.length - 1; c >= 0; c--)
	            {
		            SourceStrings = TempArr[c].split("[^]");
	                arr.push(SourceStrings[1]);      
	            }
				
				//3. If all keywords of search phrase NOT found in suggestion, then
				//- get Items which contains any of the Input Keywords.
				if (arr.length == 0)
				{
				    //- Loop each keyword and search it in sugestions.
				    for (c=0; c < SplittedKeywords.length; c++)
				    {
					    //- Clear Temp Array
				        TempArr = [];
    				
				        if (SplittedKeywords[c].length > 0)
				        {
				            //- Exclude Common Keyword like (in, at, for, of .... etc)
				            if (KeywordsToExclude.indexOf(SplittedKeywords[c].toLowerCase()) < 0)
				            {
				                for(i=0; i < arrSrc.length ;i++)
			                    {
		                            //- if Array NOT already containes this keyword.
		                            if (arrSrc[i] != "" && arr.indexOf(arrSrc[i]) < 0)
		                            {
		                                //- Seperate out "No. of Result counts" from the actual string.
		                                // Each Keyword (provided in XML) is stored as "[Condition]~[ResultsFound]~[SearchHits]~[KeywordString]"
			                            SourceStrings = arrSrc[i].split("~");
    					                
			                            if (SourceStrings.length >= 4 && SearchConditions.indexOf(SourceStrings[0]) >= 0)
				                        {
		                                    //-Check if any word starts with this keyword
		                                    if(SourceStrings[3].substring(0,SplittedKeywords[c].length).toLowerCase() == SplittedKeywords[c].toLowerCase())
				                            {
				                               // Add in temp Array
				                                TempArr.push(SourceStrings[2] + " [^]" + arrSrc[i]);
    					                        
				                            }
				                            //-or check if any word contains this keyword
			                                else if(SourceStrings[3].toLowerCase().indexOf(" " + SplittedKeywords[c].toLowerCase()) >= 0)
			                                {
				                                // Add in temp Array
				                                TempArr.push(SourceStrings[2] + " [^]" + arrSrc[i]);
			                                }
			                            }
			                        }
			                    }
			                }
    			            
			                TempArr.sort();
			                for(k=TempArr.length - 1; k >= 0; k--)
			                {
				                SourceStrings = TempArr[k].split("[^]");
			                    arr.push(SourceStrings[1]);      
			                }
			            }
				    }
				}
					
				return arr;
			};
			
			this.createList = function(arr, keywordPhrase)
			{			
				resetList();
				var SplittedStr;
				var aContent = "";
				var HighlightedPhrase = "<span style='color:blue;'>" + keywordPhrase +"</span>";
				var KeywordRegex = new RegExp(keywordPhrase.trim(), 'gi' );
				var BulletImageHTMLString = "<img alt='' src='images/dot_arrow_option.gif' />";
				
				if(arr.length > 0)
				{
				        //Prepare List Items in following format:-
				        
				        //<li>
						// <table cellpadding="0" cellspacing="0">
		                //    <tr>
			            //        <td align="left"><a href="">Poverty</a>
			            //         </td>
			            //        <td align="right" width="20%" nowrap>216 results</td>
		                //    </tr>
	                    // </table>
	                    //</li>
	                    
					for(i=0;i<arr.length;i++)
					{	
					    SplittedStr = arr[i].split("~");		
					    
					    li = document.createElement("li");
					    
						var a = document.createElement("a");
						a.href = "javascript:void(0);";
						a.i = i+1;
						a.j = SplittedStr[0]; //- Assiging "SearchCondition in <A> attribute.
						
						
						a.innerHTML = SplittedStr[3].replace(KeywordRegex, HighlightedPhrase); //- Highlight searched keyword
						
						li.i = i+1;
						li.onmouseover = function()
						{
							navListItem(this.i);
						};

						li.onmousedown = function()
						{
							selectedIndex = this.i;
							selectList(this.i);
							
							setFilter(0,true);
			                ConvertString();
			                getTable();
			        
							return false;
						};
						  
					    li.innerHTML = "<table width='100%' cellspacing='0' cellpadding='0'><tr><td width='10px' align='right' >" + BulletImageHTMLString + "</td><td>" + getOuterHTML(a) + "</td><td width='20%' class='resultCount' style='font-Size:11;' nowrap>" + SplittedStr[1] + " results   &nbsp;</td></tr>";
						
						list.setAttribute("tabindex", "-1");
						
						list.appendChild(li);
					};
					
					//- Display label - "di Gallery - Powered by DevInfo"
					var diLabel = document.createElement("li");
					diLabel.style.backgroundColor = "#DCDCDC";  //EFEFEF
			        diLabel.style.borderStyle = "none";
			        diLabel.style.borderColor = "white";
					diLabel.innerHTML = "<table width='100%' cellspacing='1' cellpadding='0'><tr><td style='font-size:10px; font-color:#BFBFBF;'>&nbsp;&nbsp;&nbsp;di Gallery - Powered by DevInfo</td><td width='20%' style='font-size:11px; font-color:#BFBFBF; text-align:right;' nowrap>" + arr.length + " items found &nbsp;</td></tr>";
					list.appendChild(diLabel);
						
					list.style.display = "block";
				} 
				else 
				{
					clearList();
				};
			};	
			
			 function getOuterHTML(object) 
			 {
                 var element;
                 if (!object) return null;
                 element = document.createElement("div");
                 element.appendChild(object.cloneNode(true));
                 return element.innerHTML;
                };
 
			this.resetList = function()
			{
				var li = list.getElementsByTagName("li");
				var len = li.length;
				for(var i=0;i<len;i++)
				{
					list.removeChild(li[0]);
				};
			};
			
			this.navList = function(dir)
			{			
				selectedIndex += (dir == "down") ? 1 : -1;
				li = list.getElementsByTagName("li");
				if (selectedIndex < 1) selectedIndex =  li.length - 1;
				if (selectedIndex > li.length -1) selectedIndex =  1;
				navListItem(selectedIndex);
			};
			
			this.navListItem = function(index)
			{	
				selectedIndex = index;
				li = list.getElementsByTagName("li");
				for(var i=0;i<li.length;i++)
				{
					li[i].className = (i==(selectedIndex-1)) ? "selected" : "";
				};
			};
			
			this.selectList = function()
			{
			    try
			    {
			        if(selectedIndex > 0)
			        {
				        li = list.getElementsByTagName("li");	
				        var a = li[selectedIndex-1].getElementsByTagName("a")[0];
				        if (document.all) 
				        { 
                            field.value = a.innerText.trim();   // IE;
                        }
                        else if (a.textContent)
                        {
                            field.value = a.textContent.trim();    //- Other brower
                        }
                        
                        //-Set Search Condition for <A> attribute "j"
                        SeachCondition = a.getAttribute("j");
                        
                        SetSearchConditionCheckbox(SeachCondition);
				        
				        clearList();
				    }
				}
				catch (ex)
				{
				    //alert(ex);
				}
			};			
			
		};
	};
	
	this.clearList = function()
	{
		if(list)
		{
			list.style.display = "none";
			selectedIndex = 0;
		};
	};		
	this.getKeyCode = function(e)
	{
		var code;
		if (!e) var e = window.event;
		if (e.keyCode) code = e.keyCode;
		return code;
	};
	
};

// script initiates on page load. 

this.addEvent = function(obj,type,fn)
{
	if(obj.attachEvent)
	{
		obj['e'+type+fn] = fn;
		obj[type+fn] = function(){obj['e'+type+fn](window.event );}
		obj.attachEvent('on'+type, obj[type+fn]);
	} 
	else 
	{
		obj.addEventListener(type,fn,false);
	};
};

addEvent(window,"load", this.txtSearch);



   
