/* ========================================================

	Copyright 2003 David S. Jackson. All rights reserved.

	2/20/3 -- adding robustness, etc.
	4/11/3 -- "escape" all user input words, handling AT&T, e.g.
	5/27/3 -- not getting + or - in front of all AND, NOT terms;
				change c. line 1390
	9/04/06 -- fixed long-standing glitch in previous "fix", which was only
					putting + ahead of first two AND terms. Also tested new fix by excluding
					three terms in the NOT line.
	9/04/06 -- stripped down version to support single-site search ... which is
					hardwired c. line 

==============================================================  */
	// extra code to support using the debugger
	$now = new Date();
//	$expires = $now.toGMTString();
	$expires = new Date();
//	$expires.setHours($now.getHours() + 5);
	$expires.setMonth($now.getMonth() + 1);
	// the cookie package handles the .toGMTString() operation
//	$expires = $then.toGMTString();
//	$d = 'dummy';
	
//	var myCookie = new Cookie(name, document, expires, domain, path, isSecure);
	var myCookie = new Cookie('search', document, $expires, '', '', '');

/*
test code, verifying that cookie works
    var myInfo = "Hi there!";
	 myCookie.store(myInfo);

	var out = myCookie.get();
alert (out);
*/

// globals
//	$ga_engine = new Array('AllWeb', 'AltaVista', 'Dogpile', 'Google', 
//									'Microsoft', 'Search', 'Yahoo');
	$ga_engine = new Array( 'Google', 'Yahoo');

//	$ga_fields = new Array("f_and", "f_or", "f_not", "f_phrase");
	// moving "not" to last place, as Boolean requires special handling
	$ga_keys = new Array("and", "or", "phrase", "not");

	$ga_window_name = new Array();

//	$g_width = f_width.value;
//	$g_height = f_height.value;
	// may want to adjust these popup window sizes depending on application
	$g_width  = 650;
	$g_height = 450;


	$h_base_url              =  new Object();
	$h_base_url['Google']    = 'www.google.com';
	$h_base_url['Yahoo']     = 'search.yahoo.com';

	$h_basic_url              =  new Object( );
	$h_basic_url['Google']    = $h_base_url['Google']    + '/search';
	$h_basic_url['Yahoo']     = $h_base_url['Yahoo']     + '/search';

//=============================================================

function engine($engine, $mode)
{
// alert ('reaached top of engine');
	//=============================================================
	//	Init -- incorporating calling params from HTML page
	//=============================================================
	$g_engine = $engine;  	// AllWeb, etc.
	$g_engine_mode = $mode; // single or multi

	readUserInput();
// alert ('read user input');

	//============================================================
	// Build Full Query string
	//============================================================
/*
		the target looks like this, in terms of pieces
		$url = 'http://' + $base_url + '?' + $extra + $q;
		where "q" encodes the words (AND, OR, NOT, phrase)
		and "extra" captures the other parameters in the final URL.
*/
		var $base_url, $extra, $q;

		$base_url = $h_basic_url[$engine];

		// the buildExtra ... engine ... function is heavily 
		// data dependent with little logic,
		// so it makes sense to house data for each engine
		// in a separate function
		$code = '$extra = buildExtra' + $engine + '()';
		eval($code);
//alert ('ready to build query');

		// whereas the basics of the query are mostly the same for all engines
		$q = buildQuery($engine);

		$url = 'http://' + $base_url + '?' + $extra + '&' + $q;
//alert ('line 103; q= ' + $q + '; url= ' + $url);

	// =========== Open window for engine ======================
	openWin($url, $engine);
	return;
}	// end of engine()

//====================================================================
function assembleBoolParms()
{
alert ('top of assembleBoolParms');
	// assumption is that data is well behaved at this point;
	// no leading or trailing blanks, etc.

	// this supports Boolean search for All the Web and MSN Search

	// tactic is to do each of the four blocks separately, then join all.
	// beware JS functions trying to match a blank; had loads of trouble.
	// implemented a variant in which NOT is saved for special handling
	var $num_boxes = 4 - 1; // saving "NOT" for special handling
	var $a_pieces = new Array($num_boxes);

	var $placeholder = '&$*#@';  // arbitrary place holder
											// instead of a null string on no hits

	var $a_temp = new Array();  // be sure to clear after each use

	// collect any entries from boxes to encode in URL
	for ($i = 0; $i < $num_boxes; $i++)	{
		var $key = $ga_keys[$i];
		var $val = $gh_input[$key];
		// weed out boxes with no entry
		if ($val.length == 0)	{
			$a_pieces[$i] = $placeholder;
			continue;
		}

		switch ($i)	{
			//===========================================
			case 0:	{
				// AND terms ... a b becomes a+AND+b
			//===========================================
				$a_temp = $val.split(' ');  // okay after debug look
				if ($a_temp.length > 1)	{
					$a_pieces[$i] = $a_temp.join('+AND+');
				}
				else
					$a_pieces[$i] = $a_temp[0];
				$a_temp.length = 0;
				break;
			}
			//=============================================
			case 1:	{
				// OR terms ... a b becomes (a+OR+b)
			//=============================================
				$a_temp = $val.split(' ');
				if ($a_temp.length > 1)
					// wrap in parens
					$a_pieces[$i] = '%28'+ $a_temp.join('+OR+') + '%29';
				else
					$a_pieces[$i] = $a_temp[0];
				$a_temp.length = 0;
				break;
			}
			//=============================================
			case 2:	{
				// PHRASE terms ... a b becomes "a+b"
			//=============================================
				$a_temp = $val.split(' ');
				if ($a_temp.length > 1)
					$a_pieces[$i] = '%22'+ $a_temp.join('+') + '%22';
				else
					$a_pieces[$i] = $a_temp[0];
				$a_temp.length = 0;
				break;
			}
		}	// end of switch
	}	// end of "for" loop

	// assemble the pieces, step 1
	// but $a_pieces may well contain placeholders, so first collapse it
	var $index = 0;
	for ($i = 0; $i < $num_boxes; $i++)	{
		if ($a_pieces[$i] != $placeholder)	{
			$a_temp[$index] = $a_pieces[$i];
			$index++;
		}
	}

	// assemble, step 2
	var $q = 'q=';
	if ($a_temp.length > 1)	{
		$q = $q + $a_temp.join('+AND+');
	}
	else
		$q = $q + $a_temp[0];

	//=============================================
	// Special case of NOT
	//=============================================
	// NOT terms ... a b becomes ANDNOT+a+ANDNOT+b
	// whoa ... ANDNOT is unique to AllWeb
	if ($g_engine == 'AllWeb')
		$not_prefix = '+ANDNOT+';
	else	// Microsoft
		$not_prefix = '+AND+NOT+'; 

	$val = $gh_input['not'];
	$a_temp = $val.split(' ');
	for ($i = 0; $i < $a_temp.length; $i++)	{
		$q = $q + $not_prefix + $a_temp[$i];	
	}

	return $q;
}	// end of assembleBoolParms()

//====================================================================
function buildBasicQuery()
{
	// handles the words: AND, et al; not the extras
	// this code builds a basic query string for all engines

	// ^ is surrogate for a blank, as JS sometimes 
	// loses a blank on string concatenation via + " " or + ' '

	var $q = 'q=';
	if ($g_engine == 'Yahoo')
		$q = 'p=';

	// AND
	var $and = $gh_input['and'];
	if ($and.length > 0)	{
		$q = $q + prepend($and, '+');
	}

	// OR
	var $or = $gh_input['or'];
	if ($or.length > 0)	{
		if (($g_engine != 'Google') 
				|| (!(($or.indexOf    (" ", 1)              > 0) 
					&& ($or.lastIndexOf(" ", $or.length - 2) < $or.length)))
			)	{
//alert('index of blank:' + $or.indexOf(" "));
			$q = $q + $or + '^';
		}
		else	{	// multi-word Google 
			var $a_word = $or.split(' ');
			var $num = $a_word.length;
			var $t = '';
			for ($i = 0; $i < $num; $i++)	{
				$t = $t + $a_word[$i];
				if ($i < $num - 1)
					$t = $t + ' OR ';
			}
			$q = $q + '(' + $t + ')^';
		}	
	} // end of OR block

	// NOT
	var $not = $gh_input['not'];
	if ($not.length > 0)	{
		$q = $q + prepend($not, '-');
	}

	// PHRASE
	var $phrase = $gh_input['phrase'];
	if ($phrase.length > 0)	{
		// no embedded " is allowed
		if ($phrase.indexOf('"') >= 0)	{
			alert('No embedded " is allowed.');
			return;
		}
		// simply wrap in quotes
		$q = $q + '"' + $phrase + '"';
	}
	return $q;
}	// end of buildBasicQuery()

//====================================================================
function buildExtraGoogle()
{
	// common, although the ISO param relates to region
	var $x = 'hl=en&btnG=Google+Search';

	//==============
	// single site search
	//==============
	if ($g_single_site == 1)
		$x = $x + '&as_sitesearch=' + $g_site_url;

	return $x;
}	// end of buildExtraGoogle()

//====================================================================
function buildExtraYahoo()
{
	var $x;
	$x = 's=Search';

	//==============
	// single site search
	//==============
	if ($g_single_site == 1)
		$x = $x + '&vs=' + $g_site_url;

	return $x;
}	// end of buildExtraYahoo()

//====================================================================
function buildQuery($engine)
{
	// collect the parms and condition them

	var $q;
	if ($g_link_mode == 'basic_run')	{
		$q = buildBasicQuery();
		$q = conditionBasic($q);
	}
	else	{	// adv_run
		var $a_field;	// entry order: 
		// 	$ga_keys = new Array("and", "or", "phrase", "not");

		if ($engine == 'Google')
			$a_field  = new Array( "as_q", "as_oq", "as_epq", "as_eq");
		else if ($engine == 'Yahoo')
			$a_field  = new Array( "va", "vo", "vp", "ve");

		$q = packageAdvParms($a_field);
	}

	return $q;
}	// end of buildQuery()

//====================================================================
function clearWords()
{
	with (document.search)	{

		f_and.value = '';
		f_or.value = '';
		f_not.value = '';
		f_phrase.value = '';
	}
	return;
}	// end of clearWords()

//====================================================================
function closeWindows()
{
	if ($ga_window_name.length > 0)	{
		for (var $k = 0; $k < $ga_window_name.length; $k++)	{
			var $win_ref = open('', $ga_window_name[$k]);
			$win_ref.close();
		}
	}

	$ga_window_name.length = 0;	// reset
	return;
}	// closeWindows()

//====================================================================
function conditionAdv($text)
{
	// spun off from conditionBasic(), this being much simpler.
	// all blanks become "+" for advanced queries;
	// or URL encoded blank to post to form

	// debug: monitor input
	$a_temp = $text.split(" ");
//alert("text: " + $text + "; num of words: " + $a_temp.length);
	var $char = '+';
	if ($g_link_mode == 'adv_post')
		$char = '%20';
	var $out = $a_temp.join($char);

	return $out;
}	// end of conditionAdv()

//====================================================================
function conditionBasic($text)
{
	// prepare text to join a URL, since escape() doesn't quite cut it
//	$a_source = new Array(  ' ',   '(',   ')',   '^',   '"',   "'" , 
//									'-', '+');
	// WARNING: compressor went astray on blank followed by left paren.
	// so I'm changing the order
	$chars = '()^" ' + "'-+"; // string version of above array
	// ^ is a surrogate for a blank
	$a_ascii  = new Array('%28', '%29', '%20', '%22', '%20', '%27', 
									'%2D', '%2B' );

	// Hmmm; what about subbing for the + sign? do the engines draw 
	// a distinction on what they receive? we'll see ...

	var $out = '';
	for ($i = 0; $i < $text.length; $i++)	{
		$ch = $text.charAt($i);
		// boundary case; don't keep a trailing blank
		if (($i == $text.length -1)
			&& (($ch == ' ') || ($ch == '^')))	{
//alert('text=' + $text + '; len= ' + $text.length + '; i=' + $i +'; ch=' + $ch);
			return $out;
		}
		$done = false; // tracks whether done with a particular character
		for ($k = 0; $k < $chars.length; $k++)	{
			if ($ch == $chars.charAt($k))	{
				$out = $out + $a_ascii[$k];
				$done = true;
				break;
			} 
		}
		if (!$done)
			// character survives "as is"
			$out = $out + $ch;
	}
	return $out;
}	// end of conditionBasic()

//====================================================================
function getWinFeatures($win_num)
{
	// $win_num only applies to "duel" mode.
	// 1 is left or top window
	// 2 is right or bottom window

//   	'width=610,height=440,toolbar=yes,scrollbars=yes,location=yes,
// 	menubar=yes,resizable=yes,left=60,top=30,screenx=60,screeny=30'); 

	var $base = 'resizable=yes,scrollbars=yes,location=yes';

	// start with standard size
	var $w = $g_width;
	var $h = $g_height;

	$base = $base + ',menubar=yes,toolbar=yes';

	var $f = $base + ',width=' + $w + ',height=' + $h;

	// standard positioning on the screen
	// cascading would be better
	var $top  = 18;
	var $left = 30;

	$f = $f + ',left='    + $left + ',top='     + $top;
	$f = $f + ',screenx=' + $left + ',screeny=' + $top;
	return $f;
}	// end of getWinFeatures()

//====================================================================
function openWin($full_url, $engine)
{
	// 1. build a name for the window
		$window_name = 'SearchWin';
		$win_num = 1;

	// 2. open the window

	var $features = getWinFeatures($win_num);
   var $window_ref = open ($full_url, $window_name, $features);

	var $saved = false;
	if ($ga_window_name.length > 0)	{
		for (var $k = 0; $k < $ga_window_name.length; $k++)	{
			if ($ga_window_name[$k] == $window_ref)	{
				$saved = true;
				break;
			}
		}
	}
	if (!$saved)
		$ga_window_name[$ga_window_name.length] = $window_name;

	// 3. control what window ends up on top
		$g_win_ref1 = $window_ref;

	return;
}	// end of openWin()

//====================================================================
function packageAdvParms($a_field)
{
	var $t = '';
	for ($i = 0; $i < $a_field.length; $i++)	{
		var $key = $ga_keys[$i];
		$t = $t + '&' + $a_field[$i] + '=' + $gh_input[$key];
	}
	// drop first "&"
	$t = $t.substring(1, $t.length);

	$t = conditionAdv($t);

	return $t;
}	// end of packageAdvParms()
//====================================================================
function prepend($field, $char)
{
	// input: field ex: a b c
	// output: -a -b -c
	// ahhh; blanks are already encoded as %20
	// 5/27/3 -- could already have ^ placeholder embedded
//alert ('line 1391; field= ' + $field);

//	$a_word = $field.split(' ');
//	Sept, 2006 ... next stmts fails because only replacing first blank
//	var $temp = $field.replace('%20', ' ');
	var $temp = $field;
	while ($temp.indexOf('%20') > 0)	{
		$temp = $temp.replace('%20', ' ');
	}

	$a_word = $temp.split(' ');
	$num = $a_word.length;
//alert ('temp= ' + $temp + '; a_word= ' + $a_word + '; num= ' + $num);

	var $q = '';
	for ($i = 0; $i < $num; $i++)	{
//			$q = $q + ' ' + $char + $a_word[$i];  // fails to retain blank
		// use ^ as placeholder; must replace blank in URL anyway
		$q = $q + $char + $a_word[$i] + "^";
	}
//alert ('line 1404; q= ' + $q);
	return $q;
}	// end of prepend()

//===================================================================
function readUserInput()
{
	// since time is irrelevant in this situation, it's convenient
	// organizationally to consolidate all reading of user input
	// in this one function.

	with (document.search)	{

		// order is LH column, top to bottom, then RH col, top to bottom

		// WARNING: any array of names preceeding a call to readRadio
		// requires that the names be in the EXACT order (left to right,
		// or top to bottom) of radio buttons.

		//================================================================
		// retrieve user words, even if not needed
		//================================================================
		$gh_input = new Object();
		$gh_input['and']    = escape(f_and.value);
//alert('and input: ' + $gh_input['and']);
		$gh_input['or']     = escape(f_or.value);
		$gh_input['not']    = escape(f_not.value);
		$gh_input['phrase'] = escape(f_phrase.value);

		if (/"/.test($gh_input['phrase']))	{
			alert("You are not allowed to include a double quote in the phrase.");
			return;
		}

		$g_link_mode = 'basic_run';

		$g_single_site = 0;
		if (f_single_site.checked)	{
			$g_single_site = 1;
		}

		// robustness needed here.
		// add code to trim extra blanks ... start, inner (dbl) and last.
		// can iterate over keys in hash

		// determine region
		$ga_region = new Array('us', 'eur', 'all');
		$g_region = 'eur';

		// determine language
		$ga_language = new Array('english', 'all', 'match');
		$g_language = 'all';

		// determine freshness
		$ga_freshness = new Array('ignore', 'months');
		$g_freshness = 'ignore';

		// limit search to single site?
		// trouble trying to save true and false in cookie, so
		// using 0 (false) or 1 (true) as values of global
		$g_site_url = f_site_url.value;
		// condition re. dropping leading http prefix is present.
		// BTW, the compressor can't handle the full prefix entry w/ backslashes.
		// nor does the compressor like the extra double slash in a comment.
		if (/^http/.test($g_site_url))
			$g_site_url = $g_site_url.substring(7, $g_site_url.length);
		// drop a single trailing blank if present
		if (/ $/.test($g_site_url))
			$g_site_url = $g_site_url.substring(0, $g_site_url.length - 1);
//alert('url=' + $g_site_url);
		$g_single_site = 0;
		if (f_single_site.checked)	{
			$g_single_site = 1;
		}
	}	// end of block over document
	return;
}	// end of readUserInput()

//===================================================================



