// Secondary Window Handling JavaScript Function
// File:    winSecondary.js
// Author:  Eric Baars
// WEBCAT:  2.2
// Version: 1.5
// History:
//     6 Jun 2000  Initial creation
//     7 Jun 2000  If openSecondary called with URL, need to use it.
//    13 Jun 2000  V1.1: New secondary window types...ETB
//    20 Jun 2000  Secondary Create windows cascade, new function...ETB
//    21 Jun 2000  Close secondary when done with it...ETB
//    29 Jun 2000  Secondary Expansion window, new function...ETB
//    30 Jun 2000  Allow detail display (wsec2features) to have menubar...DP
//    12 Jul 2000  V1.2: Add type to window name...ETB
//    19 Jul 2000  Framed control windows...ETB
//    24 Jul 2000  Reposition/resize detail window (1.1 bug)...ETB
//    26 Jul 2000  V1.3: Secondary Expansion window cascades...ETB
//    12 Sep 2000  Framed control adds optional and/or radio buttons...ETB
//    26 Sep 2000  New showHelp API...ETB
//    15 Jan 2001  N6 compatability issues...ETB
//     4 Apr 2001  WEBCAT2.2: New caller stack...ETB
//    14 May 2001  Add "log"ics type...ETB
//	  18 Jan 2002  Added addChildWindow( ) call and function closeWindow( )...CJF
//	  15 Feb 2002  Changed size of edit window...CJF
//	  15 Apr 2002  Modified showHelp API to include reference to anchor on help page...CJF
//    02 Nov 2006  Added functions for highlighting text and embedding Adobe
//                 Acrobat open parameter...SRK
//    21 Dec 2006  Added error checking to addAdobeSearchParameter...SRK
//    19 Jul 2007  Added help focusing for non ie...Derek Lam
//    27 Jul 2007  Added help focusing for expert search...Derek Lam
//    04 Apr 2008  Added focusing the opener window when back button is clicked
//    20 May 2008  Fixed highlighting bug for escape sequences...Derek Lam
//    28 Jul 2010  Label for radio...Derek Lam
//    09 Aug 2010  ghelp...Derek Lam
//    19 Aug 2010  Added clear and invert to multi entry delete...Derek Lam
//    20 Aug 2010  Added try catch to button action to force close even if opener gone...Derek Lam
//    20 Aug 2010  Added escape close event...Derek Lam
//    23 Aug 2010  Highlighting now supports quotes, asterisk, and stop words...Derek Lam

// API:
// closeSecondaryWindow()
// openSecondaryProcessWindow(fKind,sURI)
// openSecondaryFrames(aParam,sFnBody,sHTMLContent)
// showHelp(aParam,sHelpText)


// Global Variables
//-----------------------------------------------------------------------------
// Secondary Window Global Variables
var whndGlobalSecondary = null;

// Processes
//-----------------------------------------------------------------------------
// Main Utility: Open secondary window
function openSecondaryProcessWindow(kind, processURI) {
//if (!window.confirm('openProcess('+kind+','+processURI+')')) return;
	var temp = top.name.split('_');
	if (kind == temp[0]) {
		var ctr = parseInt(temp[1],10) + 1;
	} else {
		var ctr = 1;
	}
	var wName = kind + '_' + ctr;
	var wFeatures = getFeatures(kind,ctr);
	closeSecondaryWindow();
	whndGlobalSecondary = window.open(processURI,wName,wFeatures);
	addChildWindow( whndGlobalSecondary ) ;
	whndGlobalSecondary.focus();
	return whndGlobalSecondary;
}

// Utility: Calculate dynamic cascading window features
function getFeatures(type,level) {
	var bLeftJustify = false;
	var bTopJustify = false;
	var fWide = 0.75;
	var fTall = 0.75;
	if (type == 'bro') {                            // browse
		bLeftJustify = true;
		fWide = 0.95;
		fTall = 0.80;
	} else if (type == 'pro') {                     // process (becomes "browse" after first level)
		bLeftJustify = true;
		if (level > 1) {
			fWide = 0.95;
			fTall = 0.80;
		}
	} else if (type == 'exp') {                     // expansion
	} else if (type == 'cre') {                     // create
	} else if (type == 'hel' || type == 'edi' || type == 'log') {    // help or edit or logic handling
		fWide = 0.60; // Modified from 0.5, 0.5.
		fTall = 0.60;
	} else if (type == 'det') {                     // detail
		bTopJustify = true;
		fWide = 0.90;
		fTall = 0.75;
	}
	var cornerLeft = (bLeftJustify) ? 0 : 1 - fWide - 0.02;
	var cornerTop = (bTopJustify) ? 0 : 0.05 + 0.05 * level;
	var screenTall = ((0.9 - cornerTop) < fTall) ? (0.9 - cornerTop) : fTall;
//alert("fW="+fWide+"\nfT="+fTall+"\ncl="+cornerLeft+"\nct="+cornerTop+"\nst="+screenTall);
	var features = "width=" + fWide * screen.availWidth;
	features += ",height=" + screenTall * screen.availHeight;
	features += ",screen.X=" + cornerLeft * screen.availWidth;
	features += ",screen.Y=" + cornerTop * screen.availHeight;
	features += ",left=" + cornerLeft * screen.availWidth; // same as screen.X
	features += ",top=" + cornerTop * screen.availHeight; // same as screen.Y
	features += ",titlebar=yes,hotkeys=no,scrollbars=yes,menubar=yes,resizable=yes,dependent=yes";
	return features;
}

// Main Utility: Close secondary window
function closeSecondaryWindow() {
	if (whndGlobalSecondary) {
		if (!whndGlobalSecondary.closed) whndGlobalSecondary.close();
		whndGlobalSecondary = null;
	}
}

// Utility: Write the secondary control and data panes
// Required to accommodate timing issues in Netscape6
// Global variables required to pass data via setTimeout()
var winHandle = "";
var frameControl = "";
var frameContent = "";
var focusElement = -1;

// Utility: actual function
function writeSecondaryFrames() {
	// write control frame - buttons
	winHandle.SecControlFrame.document.open();
	winHandle.SecControlFrame.document.writeln(frameControl);
	winHandle.SecControlFrame.document.close();

	// write data or edit controls
	winHandle.SecDataFrame.document.open();

	buildAnchorsForExpertSearch();

	winHandle.SecDataFrame.document.writeln(frameContent);
	winHandle.SecDataFrame.document.close();
	if (focusElement > -1) {
		winHandle.SecDataFrame.document.DataForm.elements[focusElement].focus();
	}
}

// Main Utility: Open secondary window with frame set controls
// Parameters
//  param[0] = title of framed secondary control window
//  param[1] = label for "OK" button: performs action of functionBody
//  param[2] = label for "Close" button: closes window w/ no other effect
//  param[3] = "and/or" indicator for which radio is checked by default
//  param[4] = "AND"ing string
//  param[5] = "OR"ing string
//  param[6] = Clear
//  param[7] = Invert
//	functionBody = string containing JavaScript code to execute when "OK" button selected
//	contentFrame = HTML string of controls to manipulate before selecting OK/Close
function openSecondaryFrames(param,functionBody,contentFrame,windowSetting,focus) {
	// frame set HTML
	var fsContent = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" ';
	fsContent += '"http://www.w3.org/TR/html4/frameset.dtd">\n';
	fsContent += '<HTML>\n<HEAD>\n<TITLE>' + param[0] + '<\/TITLE>\n';
        fsContent += '<script type="text/javascript">';
        fsContent += 'function closeWindow(inB) { top.close() } ;</script>' ;
	fsContent += '<\/HEAD><FRAMESET ROWS="15%, 85%">\n';
	fsContent += '<FRAME NAME="SecControlFrame" SRC="" FRAMEBORDER=1 SCROLLING="no"> <\/FRAME>\n';
	fsContent += '<FRAME NAME="SecDataFrame" SRC="" FRAMEBORDER=0> <\/FRAME>\n';
	fsContent += '<\/FRAMESET>\n<\/HTML>\n';

        var keypress = 'onkeypress="top.doKeypress(event);" onkeydown="top.doKeypress(event);"';

	// control frame HTML
	var cfContent = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\n';
	cfContent += '<HTML>\n<HEAD>\n<TITLE><\/TITLE>';
	cfContent += '<script type="text/javascript">';
        cfContent += 'function doKeypress(event) {';
        cfContent += 'if (event.keyCode == 27 || event.which == 27)';
        cfContent += 'top.close();';
        cfContent += '}';
	cfContent += 'function buttonAction() {';
	cfContent += functionBody;
	cfContent += '}</script>';
	cfContent += '<\/HEAD>\n';
	cfContent += '<BODY onkeypress="doKeypress(event);" onkeydown="doKeypress(event);" STYLE="background-color:#ffffff;">\n';
	cfContent += '<FORM NAME="ControlForm" STYLE="text-align:center;">';
	cfContent += '<INPUT TABINDEX=1 TYPE="button" VALUE="' + param[1] + '" onClick="try{buttonAction();}catch(err){top.close();}">';
	cfContent += '&#160;&#160;&#160;';
	cfContent += '<INPUT TABINDEX=4 TYPE="button" VALUE="' + param[2] + '" onClick="top.close();top.opener.focus();">';
	if (param.length == 6) {
		cfContent += '&#160;&#160;&#160;&#160;&#160;';
		if (param.length[3] == 'and') {
			cfContent += '<label for="rbAnd">' + param[4] + '</label><INPUT NAME="select_method" TYPE="radio" VALUE="and" id="rbAnd" CHECKED>';
			cfContent += '<label for="rbOr">' + param[5] + '</label><INPUT NAME="select_method" TYPE="radio" VALUE="or" id="rbOr">';
		} else {
			cfContent += '<label for="rbAnd">' + param[4] + '</label><INPUT NAME="select_method" TYPE="radio" VALUE="and" id="rbAnd">';
			cfContent += '<label for="rbOr">' + param[5] + '</label><INPUT NAME="select_method" TYPE="radio" VALUE="or" id="rbOr" CHECKED>';
		}
	} else if (param.length == 8) {
                cfContent += '&#160;&#160;&#160;';
                cfContent += '<input type="button" value="' + param[6] + '" onclick="top.SecDataFrame.doClear();" />';
                cfContent += '&#160;&#160;&#160;';
                cfContent += '<input type="button" value="' + param[7] + '" onclick="top.SecDataFrame.doInvert();" />';
        }
	cfContent += '<\/FORM>\n';
	cfContent += '<\/BODY><\/HTML>\n';


	// write top-level frameset
	if( windowSetting ) {
		winHandle = windowSetting.openNewWindow( 'edi', "" ) ;
		windowSetting.writeFrame( "SecControlFrame","","SecDataFrame","",1,"",winHandle ) ;
	} else {
		winHandle = openSecondaryProcessWindow('edi',"");
	//alert("after window create");
		winHandle.document.open();
		winHandle.document.writeln(fsContent);
		winHandle.document.close();
	}
	frameControl = cfContent;
	frameContent = contentFrame;
	if ( focus ) {
		focusElement = focus;
	} else {
		focusElement = 0 ;
	}
	setTimeout('writeSecondaryFrames()', 20);

        return winHandle;
}

// Show Help
//-----------------------------------------------------------------------------
// Main Utility: Show help window (Help button onClick Handler)
function showHelp(parameters, message) {
	var title = "Help";
	var closetxt = "Close";
	var csspath = "";
	if (message == "") message = "No help available";
	if (parameters.length >= 3) {
		title = parameters[0];
		closetxt = parameters[1];
		csspath = parameters[2];
	}

	// setup window contents
	var fsContent = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" ';
	fsContent += '"http://www.w3.org/TR/html4/frameset.dtd">\n';
	fsContent += '<HTML>\n<HEAD>\n<TITLE>' + title + '<\/TITLE>\n';
        fsContent += '<SCRIPT language="JavaScript">function closeWindow( inB ) { top.close( ) } ;</SCRIPT>' ;
	fsContent += '<\/HEAD><FRAMESET ROWS="12%, 88%">\n';
	fsContent += '<FRAME NAME="SecControlFrame" SRC="" FRAMEBORDER=0 SCROLLING="no"> <\/FRAME>\n';
	fsContent += '<FRAME NAME="SecDataFrame" SRC="" FRAMEBORDER=1 SCROLLING="yes"> <\/FRAME>\n';
	fsContent += '<\/FRAMESET>\n<\/HTML>\n';

	var cfContent = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ';
	cfContent += '<HTML>\n<HEAD>\n<TITLE><\/TITLE><\/HEAD>\n';
	cfContent += '<BODY STYLE="background-color:#ffffff;">\n';
	cfContent += '<FORM STYLE="text-align:center;">';
	cfContent += '<INPUT TYPE="button" VALUE="'+ closetxt + '" onClick="top.close();top.opener.focus();">';
	cfContent += '<\/FORM>\n';
	cfContent += '<\/BODY><\/HTML>\n';

	var dfContentTop = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ';
	dfContentTop += '<HTML>\n<HEAD>\n<TITLE><\/TITLE>\n';
	dfContentTop += '<LINK HREF="' + csspath + 'eloquent.css" REL="Stylesheet" TYPE="text/css">\n';
	dfContentTop += '<LINK HREF="' + csspath + 'help.css" REL="Stylesheet" TYPE="text/css">\n';

        //based on http://www.quirksmode.org/js/findpos.html
        dfContentTop += '<script type="text/javascript">';
        dfContentTop += 'function gotoAnchor() {';
        dfContentTop += 'name = unescape(top.opener.top.lv_prompt2);' ;
        dfContentTop += 'var obj;' ;
        dfContentTop += 'var a = document.anchors;'  ;
        dfContentTop += 'for (var i = 0; i < a.length; i++) { if (a[i].name == name) { obj = a[i]; break; } } ' ;
        dfContentTop += 'if (!obj) return;' ;
        dfContentTop += 'var curtop = obj.offsetTop;' ;
        dfContentTop += 'while (obj = obj.offsetParent) { curtop += obj.offsetTop; } ' ;
        dfContentTop += 'scroll(0, curtop);' ;
        dfContentTop += '}</script>' ;

	dfContentTop += '<\/HEAD>\n';

	dfContentTop += '<BODY ' ;
	dfContentTop += '>\n';
	var dfContentBot = '<\/BODY><\/HTML>\n';

	// write top-level frameset
	winHandle = openSecondaryProcessWindow('hel',''); // use global variable
	addChildWindow( winHandle ) ;
        winHandle.document.open();
	winHandle.document.writeln(fsContent);
	winHandle.document.close();

	frameControl = cfContent;
	frameContent = dfContentTop;
        message = unescape(message);
        if (top.typeID && top.typeID == "Entry") {
          message = ghelpEntry(message);
        }
        message = ghelpProcess(message);
	frameContent += message
	frameContent += dfContentBot;
	focusElement = -1;
        writeSecondaryFrames();
        if (top.lv_prompt && top.lv_prompt != "") {
          // sometimes lv_prompt gets timed out before 100, so use lv_prompt2
          top.lv_prompt2 = top.lv_prompt;
          setTimeout("winHandle.SecDataFrame.gotoAnchor();", 100);
        }
}

function highlight(docHandle, text)
{
	var before="<span color='#FF0000' class='highlighted'>";
	var after="</span>";
	rng = docHandle.body.createTextRange();
	for (i=0; rng.findText(text)!=false; i++)
	{
		try
		{
			rng.pasteHTML(before + rng.text + after);
		}
		catch (ex)
		{
			window.alert
				(
					"Unable to highlight text!" + 
					"\n\n" + 
					ex.message + 
					"\n\n" + 
					ex.description
				);
		}
		finally
		{
			rng.collapse(false);
		}
	}
	rng.collapse(true);
}

/*
 * This is the function that actually highlights a text string by
 * adding HTML tags before and after all occurrences of the search
 * term. You can pass your own tags if you'd like, or if the
 * highlightStartTag or highlightEndTag parameters are omitted or
 * are empty strings then the default <font> tags will be used.
 * Source:
 * http://www.nsftools.com/misc/SearchAndHighlight.htm
 */
function doHighlight(bodyText, searchTerm, highlightStartTag, highlightEndTag) 
{
  if (bodyText.length   == 0) return bodyText;
  if (searchTerm.length == 0) return bodyText;

  // the highlightStartTag and highlightEndTag parameters are optional
  if ((!highlightStartTag) || (!highlightEndTag)) {
    highlightStartTag = "<span class='highlighted'>";
    highlightEndTag = "</span>";
  }
  
  // find all occurences of the search term in the given text,
  // and add some "highlight" tags to them (we're not using a
  // regular expression search, because we want to filter out
  // matches that occur within HTML tags and script blocks, so
  // we have to do a little extra validation)
  var newText = "";
  var i = -1;
  var lcSearchTerm = searchTerm.toLowerCase();
  var lcBodyText = bodyText.toLowerCase();
    
  while (bodyText.length > 0) {
    i = lcBodyText.indexOf(lcSearchTerm, i+1);
    if (i < 0) {
      newText += bodyText;
      bodyText = "";
    } else {
      // skip anything inside an HTML tag
      if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) {
        // skip anything inside a <script> block or inside an escape sequence or inside the buildNoticationBody() function that is used for shopping cart
        if (lcBodyText.lastIndexOf("/script>", i) >= lcBodyText.lastIndexOf("<script", i) &&
            lcBodyText.lastIndexOf(";", i) >= lcBodyText.lastIndexOf("&", i) &&
            lcBodyText.lastIndexOf(");", i) >= lcBodyText.lastIndexOf("buildnotificationbody", i)) {
          newText += bodyText.substring(0, i) + highlightStartTag + bodyText.substr(i, searchTerm.length) + highlightEndTag;
          bodyText = bodyText.substr(i + searchTerm.length);
          lcBodyText = bodyText.toLowerCase();
          i = -1;
        }
      }
    }
  }
  
  return newText;
}

/**
 * This is sort of a wrapper function to the doHighlight function.
 * It takes the searchText that you pass, optionally splits it into
 * separate words, and transforms the text on the current web page.
 * Only the "searchText" parameter is required; all other parameters
 * are optional and can be omitted.
 *
 * Source:
 * http://www.nsftools.com/misc/SearchAndHighlight.htm
 */
function highlightSearchTerms(searchText, treatAsPhrase, warnOnFailure, highlightStartTag, highlightEndTag)
{
  if (!searchText) return;

  searchText = removeUnwantedCharacters(searchText);

  if (searchText.length == 0 || searchText == "\"\"") return;

  // if the treatAsPhrase parameter is true, then we should search for 
  // the entire phrase that was entered; otherwise, we will split the
  // search string so that each word is searched for and highlighted
  // individually
  if (treatAsPhrase) {
    searchArray = [searchText];
  } else {
    searchArray = getSearchArray(searchText);
  }

  if (!document.body || typeof(document.body.innerHTML) == "undefined") {
    if (warnOnFailure) {
      alert("Sorry, for some reason the text of this page is unavailable. Searching will not work.");
    }
    return false;
  }
  
  var bodyText = document.body.innerHTML;
  for (var i = 0; i < searchArray.length; i++) {
    if (!isStop(searchArray[i])) {
      bodyText = doHighlight(bodyText, searchArray[i], highlightStartTag, highlightEndTag);
    }
  }
  
  document.body.innerHTML = bodyText;
  return true;
}

function getSearchArray(searchText) {
  var searchArray;
  if (isQuote(searchText)) {
    searchText = searchText.substring(1, searchText.length - 1);
    searchArray = [searchText];
  } else {
    searchArray = searchText.split(" ");
  }
  return searchArray;
}

function removeUnwantedCharacters(searchText) {
  var result = new Array();
  for (var i = 0; i < searchText.length; i++) {
    var c = searchText.charAt(i);
    if (!isNaN(c) ||
        c >= "a" && c <= "z" ||
        c >= "A" && c <= "Z" ||
        c == "\"" ||
        c == " ")
    result.push(c);
  }
  return result.join("");
}

function isStop(searchText) {
  var width = document.getElementById("hlWidth");
  if (width) {
    width = parseInt(width.value);
    if (isNaN(width)) {
      width = 1;
    }
  } else {
    width = 2;
  }
  if (searchText.length <= width) {
    return true;
  }
  var stopWords = document.getElementById("hlStopWords");
  if (stopWords) {
    stopWords = stopWords.split(",");
  } else {
    stopWords = ["the", "and"];
  }
  for (var i = 0; i < stopWords.length; i++) {
    if (stopWords[i].toLowerCase() == searchText.toLowerCase()) {
      return true;
    }
  }
  return false;
}

function isQuote(searchText) {
  return searchText.length >= 3 &&
         searchText.charAt(0) == "\"" &&
         searchText.charAt(searchText.length - 1) == "\"";
}

function addAdobeSearchParameter(url) {
  if (!window.Cookie) {
    return url;
  }
  var searchTerm = Cookie.read("searchTerm");
  if (searchTerm == null) {
    return url;
  }
  searchTerm = removeUnwantedCharacters(searchTerm);
  var searchArray = getSearchArray(searchTerm);
  searchTerm = "";
  for (var i = 0; i < searchArray.length; i++) {
    if (!isStop(searchArray[i])) {
      searchTerm += " " + searchArray[i];
    }
  }
  if (searchTerm.length == 0) {
    return url;
  }
  searchTerm = searchTerm.substring(1);
  var after = "#search=&quot;" + searchTerm + "&quot;";
  return url + after;
}
