// ==========================
//
// Internet Search Gadget
// Jack Chapple, jack@jcxp.net
// 2006 :)
//
// ==========================

// ==========================
// Initialize variables/objects and determine default scope
// ==========================

var wmiLocator;
var scopesKeyPath = 'Software\\Microsoft\\Internet Explorer\\SearchScopes';
var wshObj        = new ActiveXObject( 'Wscript.Shell' );
var defaultScope = '';

var searchDisplayName = '';
var searchURL         = '';

System.Gadget.settingsUI        = "Settings.html";
System.Gadget.onSettingsClosing = settingsChangeHandler;

// ==========================
// Initial Function
// ==========================

function doInit()
{
	System.Gadget.onSettingsClosed = doInit;

	try
	{
		defaultScope = wshObj.RegRead( 'HKCU\\' + scopesKeyPath + '\\DefaultScope' );
	}
	catch(e){}

	var defaultScopesArray = returnSettingsScopes();
	var multipleScopes = System.Gadget.Settings.read( 'multipleScopes' );

	var searchBox = document.getElementById( 'searchBox' );

	if ( multipleScopes )
	{
		searchURL = "";
		searchDisplayName = "Search...";
	}
	else
	{
		// ==========================
		// Loop through scopes to find default
		// ==========================

		var searchScopes = returnSearchScopes();

		for ( var i in searchScopes )
		{
			var thisScopeID = searchScopes[i]['id'];

			if ( searchScopes[i]['IsDefault'] && !defaultScopesArray )
			{
				// ==========================
				// No User Preference, use IE Default Scope
				// ==========================

				searchDisplayName = searchScopes[i]['DisplayName'];
				searchURL = searchScopes[i]['URL'];

				break;
			}
			else if ( defaultScopesArray )
			{
				// ==========================
				// User has defined a default scope for the Gadget, use it
				// ==========================

				if ( thisScopeID == defaultScopesArray )
				{
					searchDisplayName = searchScopes[i]['DisplayName'];
					searchURL = searchScopes[i]['URL'];

					break;
				}
			}
		}
	}

	searchBox.className = 'boxUnfocus';
	searchBox.value = searchDisplayName;
}

// ==========================
// Teh ZOMGPHARP! O.O
// ==========================

function doSearch()
{
	var searchBox = document.getElementById( 'searchBox' );

	var defaultScopesArray = returnSettingsScopes();
	var searchScopes = returnSearchScopes();
	var multipleScopes = System.Gadget.Settings.read( 'multipleScopes' );


	if ( !multipleScopes )
	{
		var sQueryURL = parseSearchURL( searchURL, searchBox.value );

		System.Shell.execute( sQueryURL );
	}
	else
	{
		for ( var i in searchScopes )
		{
			for ( var i2 in defaultScopesArray )
			{
				if ( defaultScopesArray[i2] == searchScopes[i]['id'] )
				{
					sQueryURL = parseSearchURL( searchScopes[i]['URL'], searchBox.value );

					System.Shell.execute( sQueryURL );
				}
			}
		}
	}

	if ( System.Gadget.Settings.read( 'clearBoxOnSearch' ) == true )
	{
		searchBox.className = 'boxUnfocus';
		searchBox.value = searchDisplayName;
	}

	searchBox.blur();

	return false;
}

// ==========================
// Parse Raw Search URL into finalized URL
// ==========================

function parseSearchURL( inputURL, searchKeywords )
{
	var sQueryURL = inputURL;

	var sQuery = searchKeywords.replace( /\s/g, '+' );
	sQuery = escape( sQuery );

	sQueryURL = sQueryURL.replace( /{searchTerms}/g, sQuery );
	sQueryURL = sQueryURL.replace( /{inputEncoding}/g, 'UTF-8' );
	sQueryURL = sQueryURL.replace( /{outputEncoding}/g, 'UTF-8' );
	sQueryURL = sQueryURL.replace( /{startPage}/g, '1' );
	sQueryURL = sQueryURL.replace( /{startIndex\??}/g, '0' );
	sQueryURL = sQueryURL.replace( /{language}/g, 'en-us' );

	return sQueryURL;
}

// ==========================
// Search Box Receives Focus
// ==========================

function boxFocus( obj )
{
	if ( obj.value != searchDisplayName )
	{
		obj.select();

		return;
	}

	obj.value = '';
	obj.className = 'boxFocus';
}

// ==========================
// Search Box Looses Focus
// ==========================

function boxBlur( obj )
{
	if ( obj.value ) return;

	obj.className = 'boxUnfocus';
	obj.value = searchDisplayName;
}

// ==========================
// Returns an Array of user-defined scope(s) (or false if no user preference)
// ==========================

function returnSettingsScopes()
{
	var defaultSetting = System.Gadget.Settings.read( 'defaultScopes' );

	if ( !defaultSetting ) return false;

	var scopesArray = Array();

	scopesArray = defaultSetting.split( ',' );

	return scopesArray;
}

// ==========================
// Settings Page onLoad
// ==========================

function settingsOnLoad()
{
	try
	{
		defaultScope = wshObj.RegRead( 'HKCU\\' + scopesKeyPath + '\\DefaultScope' );
	}
	catch(e){}

	var defaultScopesArray = returnSettingsScopes();

	var providersList = document.getElementById( 'providersList' );
	var searchProviders = returnSearchScopes();

	// ==========================
	// Populate List Box with Search Providers
	// ==========================

	for ( var i in searchProviders )
	{
		var thisDispName = searchProviders[i]['DisplayName'];
		var thisID       = searchProviders[i]['id'];
		var thisDefault  = searchProviders[i]['IsDefault'];

		if ( thisDefault ) thisDispName += " (IE Default)";

		providersList.options[i] = new Option( thisDispName, thisID );

		if ( defaultScopesArray )
		{
			for ( var i2 in defaultScopesArray )
			{
				if ( defaultScopesArray[i2] == thisID )
				{
					providersList.options[i].selected = true;
				}
			}
		}
		else
		{
			if ( thisDefault )
			{
				providersList.options[i].selected = true;
			}
		}
	}

	var providerCount = returnSelectedProviderCount();

	if ( providerCount > 1 ) document.getElementById( 'defaultIELabel' ).disabled = true;

	var clearBoxOnSearch = System.Gadget.Settings.read( 'clearBoxOnSearch' );

	if ( clearBoxOnSearch ) document.getElementById( 'clearBoxOnSearch' ).checked = true;
}

// ==========================
// Save Settings
// ==========================

function settingsChangeHandler()
{
	var multipleScopes = false;
	var defaultScopeString = '';
	var defaultScopesArray = Array();
	var providersList = document.getElementById( 'providersList' );

	if ( returnSelectedProviderCount() > 1 ) multipleScopes = true;

	var i2 = 0;

	for ( var i = 0; i < providersList.length; i++ )
	{
		if ( !multipleScopes )
		{
			if ( providersList[i].selected )
			{
				defaultScopeString = providersList[i].value;

				break;
			}
		}
		else
		{
			if ( providersList[i].selected )
			{
				defaultScopesArray[i2] = providersList[i].value;

				i2++;
			}
		}	
	}

	if ( multipleScopes ) defaultScopeString = defaultScopesArray.join( ',' );

	System.Gadget.Settings.write( 'defaultScopes', defaultScopeString );
	System.Gadget.Settings.write( 'multipleScopes', multipleScopes );
	System.Gadget.Settings.write( 'clearBoxOnSearch', document.getElementById( 'clearBoxOnSearch' ).checked );

	if ( document.getElementById( 'setDefaultIE' ).checked )
	{
		wshObj.RegWrite( 'HKCU\\Software\\Microsoft\\Internet Explorer\\SearchScopes\\DefaultScope', defaultScopeString );
	}
}

// ==========================
// Returns number of selected providers
// ==========================

function returnSelectedProviderCount()
{
	var selectedCount = 0;
	var providersList = document.getElementById( 'providersList' );

	for ( var i = 0; i < providersList.options.length; i++ )
	{
		if ( providersList.options[i].selected ) selectedCount++;
	}

	return selectedCount;
}

// ==========================
// Make sure that we can't have multiple provider choices
// and the IE Default Provider checkbox both selected
// ==========================

function providerListChange()
{
	var selectedCount = returnSelectedProviderCount();
	var setDefaultIEBox = document.getElementById( 'setDefaultIE' );
	var defaultIELabel = document.getElementById( 'defaultIELabel' );

	if ( selectedCount > 1 && setDefaultIEBox.checked )
	{
		wshObj.popup( 'You cannot set multiple default Internet Explorer Search Engines!', 0, 'Whoops!', 64 );
		setDefaultIEBox.checked = false;
		defaultIELabel.disabled = true;
	}
	else if ( selectedCount > 1 && !setDefaultIEBox.checked )
	{
		defaultIELabel.disabled = true;
	}
	else if ( selectedCount <= 1 )
	{
		defaultIELabel.disabled = false;
	}
}

// ==========================
// Returns an array on a given registry key
// ==========================

function fetchRegArray( sKeyPath )
{
	if ( !wmiLocator )
		var wmiLocator = new ActiveXObject( 'WbemScripting.SWbemLocator' );

	var wmiServer     = wmiLocator.ConnectServer( null, 'root\\default' );
	var wmiRegistry   = wmiServer.Get( 'StdRegProv' );
	var enumKeyMethod = wmiRegistry.Methods_.Item( 'EnumKey' );

	var inParams         = enumKeyMethod.inParameters.SpawnInstance_();
	inParams.hDefKey     = 0x80000001; // HKCU
	inParams.sSubKeyName = sKeyPath;

	var outParams = wmiRegistry.ExecMethod_( enumKeyMethod.Name, inParams );
	var subKeys = outParams.sNames.toArray();

	return subKeys;
}

// ==========================
// Returns an array of all search scopes
// ==========================

function returnSearchScopes()
{
	var searchScopes = fetchRegArray( scopesKeyPath );
	var defaultExists = false;

	for ( var i in searchScopes )
	{
		// ==========================
		// Populate each array entry with useful information
		// ==========================

		var thisScopeID = searchScopes[i];

		searchScopes[i] = Array();

		searchScopes[i]['id']          = thisScopeID;
		searchScopes[i]['DisplayName'] = wshObj.RegRead( 'HKCU\\' + scopesKeyPath + '\\' + thisScopeID + '\\DisplayName' );
		searchScopes[i]['URL']         = wshObj.RegRead( 'HKCU\\' + scopesKeyPath + '\\' + thisScopeID + '\\URL' );
		searchScopes[i]['IsDefault']   = ( defaultScope == thisScopeID ) ? true : false;

		if ( searchScopes[i]['IsDefault'] ) defaultExists = true;

		// ==========================
		// If the Display Name is a resource reference, assume (Default) value
		// ==========================

		if ( searchScopes[i]['DisplayName'].indexOf( '@ieframe.dll' ) > -1 )
			searchScopes[i]['DisplayName'] = wshObj.RegRead( 'HKCU\\' + scopesKeyPath + '\\' + thisScopeID + '\\' );
	}

	if ( !defaultExists ) searchScopes[0]['IsDefault'] = true;

	return searchScopes;
}
