// www.webwizardry.net
// (c) 2008


// Define everything we can search for
var SearchEngines=new Array (
	{
		Category : 'Search',
		Title : 'Google (Web)',
		LongTitle : 'Google',
		Link : 'http://www.google.com/',
		Button : 'Search',
		Action : 'http://www.google.com/search',
		SearchName : 'q',
		Default : true
	},
	{
		Category : 'Search',
		Title : 'Google Images',
		Link : 'http://images.google.com/',
		Button : 'Search',
		Action : 'http://images.google.com/images',
		SearchName : 'q',
		ExtraName: 'imgsz',
		ExtraOptions: {
			'All image sizes' : '',
			'Extra Large images' : 'huge',
			'Large images' : 'xxlarge',
			'Medium images' : 'small|medium|large|xlarge',
			'Small images' : 'icon'
		}
	},
	{
		Category : 'Search',
		Title : 'Google News',
		Link : 'http://news.google.com/',
		Button : 'Search',
		Action : 'http://news.google.com/news',
		SearchName : 'q'
	},
	{
		Category : 'Search',
		Title : 'Google Maps',
		Link : 'http://maps.google.com/',
		Button : 'Search',
		Action: 'http://maps.google.com/maps',
		SearchName : 'q',
		Description : 'Enter an address, or the name of a place to search for.'
	},
	{
		Category : 'Search',
		Title : 'YouTube',
		Link : 'http://www.youtube.com/',
		Button : 'Search',
		Action : 'http://www.youtube.com/results',
		SearchName : 'search_query',
		ExtraName : 'search_type',
		ExtraOptions : {
			'Videos' : '',
			'Channels' : 'search_users'
		}
	},
	{
		Category : 'Search',
		Title : 'Reverse Phone',
		Link : 'http://www.whitepages.com/reverse-lookup',
		Button : 'Search',
		Action : 'http://www.whitepages.com/search/ReversePhone',
		SearchName : 'full_phone',
		Description : 'Enter a telephone number.'
	},
	{
		Category : 'Search',
		Title : 'Weather',
		LongTitle : 'National Weather Service',
		Link : 'http://www.weather.gov',
		Button : 'Search',
		Action : 'http://forecast.weather.gov/zipcity.php',
		SearchName : 'inputstring',
		Description : 'Enter city and state or Zip code.'
	},
	{
		Category : 'Shopping',
		Title : 'Amazon.com',
		Link : 'http://www.amazon.com/exec/obidos/redirect-home/webwizardry-20',
		Button : 'Search',
		Action : 'http://www.amazon.com/exec/obidos/external-search',
		SearchName : 'keyword',
		ExtraName : 'mode',
		ExtraOptions : {
			'All Products' : 'blended',
			'Apparel & Accessories' : 'apparel-index',
			'Automotive' : 'automotive-index',
			'Baby' : 'baby',
			'Beauty' : 'beauty-index',
			'Books' : 'books',
			'Camera & Photo' : 'photo',
			'Cell Phones & Service' : 'wireless-phones',
			'Classical Music' : 'classical',
			'Computers' : 'pc-hardware',
			'Computer & Video Games' : 'videogames',
			'DVD' : 'dvd',
			'Electronics' : 'electronics',
			'Gourmet Food' : 'gourmet-index',
			'Grocery' : 'grocery',
			'Home & Garden' : 'garden',
			'Health & Personal Care' : 'hpc-index',
			'Industrial & Scientific' : 'industrial-index',
			'Jewelry' : 'jewelry',
			'Kindle Store' : 'digital-text',
			'Kitchen & Housewares' : 'kitchen',
			'Magazine Subscriptions' : 'magazines',
			'Miscellaneous' : 'universal',
			'MP3 Downloads' : 'digital-music',
			'Music' : 'music',
			'Musical Instruments' : 'mi-index',
			'Office Products' : 'office-products',
			'Software' : 'software',
			'Sports & Outdoors' : 'sporting-index',
			'Tools & Hardware' : 'tools',
			'Toys & Games' : 'toys',
			'Unbox Video Downloads' : 'amazontv',
			'VHS' : 'vhs',
			'Watches' : 'watches'
		},
		Other : {
			'tag' : 'webwizardry-20'
		},
		Description : 'This is a referral link.'
	},
	{
		Category : 'Shopping',
		Title : 'NewEgg',
		Link : 'http://www.newegg.com/',
		Button : 'Search',
		Action : 'http://www.newegg.com/Product/ProductList.aspx',
		SearchName : 'Description',
		Other : {
			'Submit' : 'ENE'
		}
	},
	{
		Category : 'Shopping',
		Title : "eBay",
		Link : "http://www.ebay.com/",
		Button : 'Search',
		Action : 'http://search.ebay.com/search/search.dll',
		SearchName : 'satitle',
		ExtraName : 'category0',
		ExtraOptions : {
			'All Categories' : '',
			'Antiques' : '20081',
			'Art' : '550',
			'Baby' : '2984',
			'Books' : '267',
			'Business & Industrial' : '12576',
			'Cameras & Photo' : '625',
			'Cell Phones & PDAs' : '15032',
			'Clothing, Shoes & Accessories' : '11450',
			'Coins & Paper Money' : '11116',
			'Collectibles' : '1',
			'Computers & Networking' : '58058',
			'Consumer Electronics' : '293',
			'Crafts' : '14339',
			'Dolls & Bears' : '237',
			'DVDs & Movies' : '11232',
			'eBay Motors' : '6000',
			'Entertainment Memorabilia' : '45100',
			'Gift Certificates' : '31411',
			'Health & Beauty' : '26395',
			'Home & Garden' : '11700',
			'Jewelry & Watches' : '281',
			'Music' : '11233',
			'Musical Instruments' : '619',
			'Pottery & Glass' : '870',
			'Real Estate' : '10542',
			'Specialty Services' : '316',
			'Sporting Goods' : '382',
			'Sports Mem, Cards & Fan Shop' : '64482',
			'Stamps' : '260',
			'Tickets' : '1305',
			'Toys & Hobbies' : '220',
			'Travel' : '3252',
			'Video Games' : '1249',
			'Everything Else' : '99'
		}
	},
	{
		Category : 'Shopping',
		Title : 'Froogle',
		LongTitle : 'Google Product Search',
		Link : 'http://www.google.com/products',
		Button : 'Search',
		Action : 'http://www.google.com/products',
		SearchName : 'q'
	},
	{
		Category : 'Reference',
		Title : 'Merriam-Webster',
		Link : 'http://www.merriam-webster.com/',
		Button : 'Look Up',
		Action : 'http://www.merriam-webster.com/dictionary',
		SearchName : 'search_box_terms',
		ExtraName : 'book',
		ExtraOptions : {
			'Dictionary' : 'dictionary',
			'Thesaurus' : 'thesaurus',
			'Spanish-English' : 'spanish_english',
			'Medical' : 'medical'
		},
		SpecialFunction : submitMW
	},
	{
		Category : 'Reference',
		Title : 'Urban Dictionary',
		Link : 'http://www.urbandictionary.com/',
		Button : 'Look Up',
		Action : 'http://www.urbandictionary.com/define.php',
		SearchName : 'term',
		Description : 'If you need to know the definition of a slang term that\'s not in the regular dictionary, try this.'
	},
	{
		Category : 'Reference',
		Title : 'Wikipedia',
		Link : 'http://www.wikipedia.org/',
		Button : 'Look Up',
		Action: 'http://www.wikipedia.org/search-redirect.php',
		SearchName : 'search',
		ExtraName : 'language',
		ExtraOptions : {
			'Catal\u00E0' : 'ca',
			'Deutsch' : 'de',
			'English' : 'en',
			'Espa\u00F1ol' : 'es',
			'Fran\u00E7ais' : 'fr',
			'Italiano' : 'it',
			'Nederlands' : 'nl',
			'\u65E5\u672C\u8A9E' : 'ja',
			'Norsk (bokm\u00E5l)' : 'no',
			'Polski' : 'pl',
			'Portugu\u00EAs' : 'pt',
			'Rom\u00E2n\u0103' : 'ro',
			'\u0420\u0443\u0441\u0441\u043A\u0438\u0439' : 'ru',
			'Suomi' : 'fi',
			'Svenska' : 'sv',
			'T\u00FCrk\u00E7e' : 'tr',
			'\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430' : 'uk',
			'Volap\u00FCk' : 'vo',
			'\u4E2D\u6587' : 'zh'
		},
		ExtraDefault : 'en'
	},
	{
		Category : 'Reference',
		Title : 'IMDB',
		Link : 'http://www.imdb.com/',
		Button : 'Search',
		Action : 'http://www.imdb.com/find',
		SearchName: 'q',
		ExtraName: 's',
		ExtraOptions: {
			'All' : 'all',
			'Titles' : 'tt',
			'TV Episodes' : 'ep',
			'My Movies' : 'My Movies',
			'Names' : 'nm',
			'Companies' : 'co',
			'Keywords' : 'kw',
			'Characters' : 'char',
			'Quotes' : 'Quotes',
			'Bios' : 'Bios',
			'Plots' : 'Bios'
		},
		Description : 'The Internet Movie Database contains everything you need to know about who was in any movie.'
	},
	{
		Category : 'Reference',
		Title : 'Babelfish',
		Link : 'http://babelfish.yahoo.com/',
		Button : 'Translate',
		Action : 'http://babelfish.yahoo.com/translate_txt',
		Method : 'post',
		SearchName : 'trtext',
		ExtraName : 'lp',
		ExtraOptions : {
			'Chinese-simp to English' : 'zh_en',
			'Chinese-trad to English' : 'zt_en',
			'English to Chinese-simp' : 'en_zh',
			'English to Chinese-trad' : 'en_zt',
			'English to Dutch' : 'en_nl',
			'English to French' : 'en_fr',
			'English to German' : 'en_de',
			'English to Greek' : 'en_el',
			'English to Italian' : 'en_it',
			'English to Japanese' : 'en_ja',
			'English to Korean' : 'en_ko',
			'English to Portuguese' : 'en_pt',
			'English to Russian' : 'en_ru',
			'English to Spanish' : 'en_es',
			'Dutch to English' : 'nl_en',
			'Dutch to French' : 'nl_fr',
			'French to English' : 'fr_en',
			'French to German' : 'fr_de',
			'French to Greek' : 'fr_el',
			'French to Italian' : 'fr_it',
			'French to Portuguese' : 'fr_pt',
			'French to Dutch' : 'fr_nl',
			'French to Spanish' : 'fr_es',
			'German to English' : 'de_en',
			'German to French' : 'de_fr',
			'Greek to English' : 'el_en',
			'Greek to French' : 'el_fr',
			'Italian to English' : 'it_en',
			'Italian to French' : 'it_fr',
			'Japanese to English' : 'ja_en',
			'Korean to English' : 'ko_en',
			'Portuguese to English' : 'pt_en',
			'Portuguese to French' : 'pt_fr',
			'Russian to English' : 'ru_en',
			'Spanish to English' : 'es_en',
			'Spanish to French' : 'es_fr'
		},
		ExtraDefault : 'en_es',
		Other : {
			ei : 'UTF-8',
			doit : 'done',
			fr : 'bf-home',
			intl : '1'
		},
		Description : '"The practical upshot of all this is that if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language."'
	},
	{
		Category : 'Reference',
		Title : "Bible",
		Link : "http://www.biblegateway.com/",
		Button : "Look Up",
		Action : 'http://www.biblegateway.com/quicksearch/',
		SearchName : 'quicksearch',
		ExtraName : 'qs_version',
		ExtraOptions : {
			'New International Version' : '31',
			'New American Standard Bible' : '49',
			'The Message' : '65',
			'Amplified Bible' : '45',
			'New Living Translation' : '51',
			'King James Version' : '9',
			'English Standard Version' : '47',
			'Contemporary English Version' : '46',
			'New King James Version' : '50',
			'New Century Version' : '78',
			'21st Century King James Version' : '48',
			'American Standard Version' : '8',
			'Young\'s Literal Translation' : '15',
			'Darby Translation' : '16',
			'New Life Version' : '74',
			'Holman Christian Standard Bible' : '77',
			'New International Reader\'s Version' : '76',
			'Wycliffe New Testament' : '53',
			'Worldwide English (New Testament)' : '73',
			'New International Version - UK' : '64',
			'Today\'s New International Version' : '72'
		}
	},
	{
		Category : 'Tech',
		Title : 'VersionTracker',
		Link : 'http://www.versiontracker.com/',
		Button : 'Search',
		Action : 'http://www.versiontracker.com/php/qs.php',
		SearchName : 'str',
		ExtraName : 'srchArea',
		ExtraOptions : {
			'Mac OS X' : 'macosx',
			'Windows' : 'windows',
			'Palm OS' : 'palmos',
			'All Software' : 'all'
		}
	},
	{
		Category : 'Tech',
		Title : 'Freshmeat',
		Link : 'http://freshmeat.net/',
		Button : 'Search',
		Action : 'http://freshmeat.net/search/',
		SearchName : 'q',
		ExtraName : 'section',
		ExtraOptions : {
			'projects' : 'projects',
			'articles' : 'articles',
			'comments' : 'comments'
		}
	},
	{
		Category : 'Tech',
		Title : 'The Pirate Bay',
		Link : 'http://www.thepiratebay.com/',
		Button : 'Search',
		Action : 'http://www.thepiratebay.com/s/',
		SearchName : 'q',
		Other : {
			page : '0',
			orderby : '99'
		}
	},
	{
		Category : 'Tech',
		Title : 'CPAN',
		Link : 'http://search.cpan.org/',
		Button : 'Search',
		Action : 'http://search.cpan.org/search',
		SearchName : 'query',
		ExtraName : 'mode',
		ExtraOptions : {
			'All' : 'all',
			'Modules' : 'module',
			'Distributions' : 'dist',
			'Authors' : 'author'
		},
		Description : 'Search for Perl modules and documentation.'
	},
	{
		Category : 'Tech',
		Title : 'PHP.net',
		Link : 'http://www.php.net/',
		Button : 'Search',
		Action : 'http://www.php.net/search.php',
		SearchName : 'pattern',
		ExtraName : 'show',
		ExtraOptions : {
			'function list' : 'quickref',
			'whole site' : 'wholesite',
			'online documentation [en]' : 'manual',
			'bug database' : 'bugdb',
			'general mailing list' : 'maillist',
			'developer mailing list' : 'devlist',
			'documentation mailing list' : 'phpdoc'
		}
	},
	{
		Category : 'Tech',
		Title : 'W3C Validator',
		Link : 'http://validator.w3.org/',
		Button : 'Validate',
		Action : 'http://validator.w3.org/check',
		SearchName : 'url',
		Description : 'Enter the URL of a web page you want to test.'
	},
	{
		Category : 'Tech',
		Title : 'MAC Address',
		LongTitle : 'MAC Address Vendor Lookup',
		Link : 'http://www.coffer.com/mac_find/',
		Button : 'Look Up',
		Action : 'http://www.coffer.com/mac_find/',
		SearchName : 'string',
		Description : 'Enter a MAC address, or the first three bytes, or search for the manufacturer\'s name.'
	}
);
var RememberExtra={};



function getSelected() {
	// Gets the (short) title of the currently selected search engine,
	// based on the link displayed to the user (not based on the current
	// selection in the list, although that ought to match).
	// Returns null if nothing is selected.
	if(document.getElementById('SearchTitle')) {
		var linkname=document.getElementById('SearchTitle').firstChild.nodeValue;
		for (var i in SearchEngines) {
			if(SearchEngines[i].Title==linkname || SearchEngines[i].LongTitle==linkname)
					return SearchEngines[i].Title;
		}
	}
	return null;
}
function getDescription(title) {
	for (var i in SearchEngines) {
		if(SearchEngines[i].Title==title) return SearchEngines[i].Description;
	}
}
function convertToID(title) {
	return 'SearchEngine_'+title.replace(/[^\w\d\-]/g,'_');
}
function selectEngine(selection) {
	// the user has clicked something
	var oldSelected=getSelected();
	if(selection==oldSelected) {
		// no change, so don't reset
		document.getElementById('SearchBox').focus();
		return;
	}
	// remember Extra value before we change
	if(document.getElementById('Extra')) {
		RememberExtra[oldSelected]=document.getElementById('Extra').value;
	}
	// update visual status in table
	if(oldSelected) document.getElementById(convertToID(oldSelected)).className='SearchEngine';
	document.getElementById(convertToID(selection)).className='SelectedSearchEngine';
	
	// change form
	for (var i in SearchEngines) {
		if(SearchEngines[i].Title == selection) {
			var a=document.createElement('a');
			a.href=SearchEngines[i].Link;
			a.id='SearchTitle';
			if(SearchEngines[i].LongTitle != null) {
				a.appendChild(document.createTextNode(SearchEngines[i].LongTitle));
			} else {
				a.appendChild(document.createTextNode(SearchEngines[i].Title));
			}
			
			var td=document.getElementById('SearchTop');
			while(td.hasChildNodes()) td.removeChild(td.lastChild);
			td.appendChild(a);
			
			if(SearchEngines[i].ExtraName) {
				var extra=document.createElement('select');
				extra.name='Extra';
				extra.id='Extra';
				var si=0;
				var index=-1;
				for(var j in SearchEngines[i].ExtraOptions) {
					index++;
					var option=document.createElement('option');
					option.value=SearchEngines[i].ExtraOptions[j];
					option.appendChild(document.createTextNode(j));
					var extraDefault=SearchEngines[i].ExtraDefault;
					if(RememberExtra[selection]) extraDefault=RememberExtra[selection];
					if(SearchEngines[i].ExtraOptions[j] == extraDefault) si=index;
					extra.appendChild(option);
				}
				extra.selectedIndex=si;
				td.appendChild(document.createTextNode(' '));
				td.appendChild(extra);
			}
			document.getElementById('SearchButton').value=SearchEngines[i].Button;
			var p=document.getElementById('Description');
			while(p.hasChildNodes()) p.removeChild(p.lastChild);
			if(SearchEngines[i].Description) {
				p.appendChild(document.createTextNode(SearchEngines[i].Description));
			}
			document.getElementById('SearchBox').focus();
		}
	}
}
function submitSearch() {
	var selected=getSelected();
	for (var i in SearchEngines) {
		if(SearchEngines[i].Title == selected) {
			// copy all the data into the real hidden form, and submit that
			var info=new Object;
			info[SearchEngines[i].SearchName] = document.getElementById('SearchBox').value;
			if(SearchEngines[i].ExtraName) info[SearchEngines[i].ExtraName] = document.getElementById('Extra').value
			if(SearchEngines[i].Other) {
				for(var j in SearchEngines[i].Other) {
					info[j]=SearchEngines[i].Other[j];
				}
			}
			
			// special case for m-w.com
			if(SearchEngines[i].SpecialFunction) {
				SearchEngines[i].SpecialFunction(info);
				return false;
			}
			
			var form=document.getElementById('RealForm');
			form.action=SearchEngines[i].Action;
			form.method=SearchEngines[i].Method?SearchEngines[i].Method:'get';
			while(form.hasChildNodes()) form.removeChild(form.lastChild);
			for(var j in info) {
				var input=document.createElement('input');
				input.type='hidden';
				input.name=j;
				input.value=info[j];
				form.appendChild(input);
			}
			form.submit();

			return false;
		}
	}
	return false;
}
function submitMW(info) {
	var foo=encodeURIComponent(info.search_box_terms);
	switch(info.book) {
		case 'dictionary':
			window.location='http://www.merriam-webster.com/dictionary/'+foo;
			break;
		case 'thesaurus':
			window.location='http://www.merriam-webster.com/thesaurus/'+foo;
			break;
		case 'spanish_english':
			window.location='http://www.merriam-webster.com/spanish/'+foo;
			break;
		case 'medical':
			window.location='http://medical.merriam-webster.com/medical/'+foo;
			break;
	}
}
function CreateSearch() {
	// Divide search engine list into categories
	var Categories=new Array();
	var Buttons={};
	var Default=null;
	for(var i in SearchEngines) {
		if(SearchEngines[i].Private) continue; // FIXME - don't skip if it's my browser!
		var cat=SearchEngines[i].Category;
		// Add each new category to the category list
		var flag=false;
		for(var j in Categories) if(Categories[j]==cat) flag=true;
		if(flag==false) {
			Categories.push(cat);
			Buttons[cat]=new Array();
		}
		
		// Add each search engine to that category's column
		Buttons[cat].push(SearchEngines[i].Title);	
		if(SearchEngines[i].Default) Default=SearchEngines[i].Title;
	}
	
	// new improved engine selection menu
	var buttontable=document.createElement('table');
	buttontable.id='SearchEngineTable';

	// header row
	var headerrow=document.createElement('tr');
	var maxrows=0;
	for(var i in Categories) {
		var th=document.createElement('th');
		th.appendChild(document.createTextNode(Categories[i]));
		headerrow.appendChild(th);
		if(Buttons[Categories[i]].length>maxrows) maxrows=Buttons[Categories[i]].length;
	}
	var thead=document.createElement('thead');
	thead.appendChild(headerrow);
	buttontable.appendChild(thead);
	var tbody=document.createElement('tbody');
	
	for(var row=0; row<maxrows; row++) {
		var tr=document.createElement('tr');
		for(var i in Categories) {
			var td=document.createElement('td');
			if(Buttons[Categories[i]][row]) {
				var name=Buttons[Categories[i]][row];
				td.appendChild(document.createTextNode(name));
				(function(enclosed) {
					td.onclick=function() { selectEngine(enclosed); }
				}) (name);
				var desc=getDescription(name);
				if(desc) td.title=desc;
				td.className='SearchEngine';
				td.id=convertToID(name);
			}
			tr.appendChild(td);
		}
		tbody.appendChild(tr);
	}
	buttontable.appendChild(tbody);
	// end new button table

	// search box
	var input=document.createElement('input');
	input.type='text';
	input.name='SearchBox';
	input.size=40;
	input.id='SearchBox';
	
	// submit button
	var submit=document.createElement('input');
	submit.type='submit';
	submit.value='     ';
	submit.id='SearchButton';
	
	// put it all in a table
	var table=document.createElement('table');
	var tbody=document.createElement('tbody');
	var tr=document.createElement('tr');
	tr.id='FirstRow';
	var td=document.createElement('td');
	td.rowSpan=2;
	td.appendChild(buttontable); // NEW ****
	tr.appendChild(td);
	
	td=document.createElement('td');
	td.id='SearchTop';
	tr.appendChild(td);
	tbody.appendChild(tr);

	tr=document.createElement('tr');
	td=document.createElement('td');
	td.id='SearchBottom';
	td.appendChild(input);
	td.appendChild(submit);
	var p=document.createElement('p');
	p.id='Description';
	td.appendChild(p);	
	tr.appendChild(td);
	tbody.appendChild(tr);
	table.appendChild(tbody);
	
	// and put the whole table inside a form, and click the selected item
	var form=document.createElement('form');
	form.onsubmit=submitSearch;
	form.appendChild(table);
	document.getElementById('search').appendChild(form);
	selectEngine(Default);
	
	// finally, add the hidden form we'll copy stuff to later
	form=document.createElement('form');
	form.id='RealForm';
	form.style.display='none';
	document.body.appendChild(form);
}
