/****************************************************************\
	All code copyright (c) 2006 Intuit Canada Ltd., Intuit Inc.
	Any unauthorized duplication or reuse of this code
	is a violation of applicable laws.
	Coded by Peter Harris, June 2003.
	Adapted for QB U.S. by Celia Luk and Jeff Taggart, 2006
   ============================================================
		JavaScript Toolkit for HTML Help
   ------------------------------------------------------------
   This toolkit contains routines for the following features:
	== Environment detection scripts.
		- getTopicCHM()
		- getTopicExternalPath()
		- getQuickBooksSKU()
	== User Feedback interface.
		- makeFeedbackAndHelpSupportLink( divObj )
	== Miscellaneous.
		- qbcommand( param )
		- run_qbcommand( param )
		- openURL( param )
		- QBURL( param )
		- displaytopic( param )
	== Flag for QA to indicate readiness of topics
		--feedbackButton()
	== Boiler-plate
	 - makeProAdvisorLink()
	 - makeCommunityLink()
   ------------------------------------------------------------
   _____________________ Version History ______________________
    Version 2.30 - June 23, 2006
	 - Add Feedback functions for user comments. Previously this was handled by Feedback.CHM
	 - Redefine Conditional text operators to be more "user friendly"
	 - Make functions IE7 compatible
	 - Remove "popup" functions. Popups will not be used in QB2007
	 - General cleanup to remove obsolete global variables and functions
	Version 2.20 - Feb 9, 2006
	 - Create boiler-plate for pro-advisor and community
	 - Add static expando
  	Version 2.10 - August 28, 2003
	 - Create a multi-capacitant environment where the script can link to files whether from Perforce, from CHM, or from /updates.
	Version 2.07 - July 17, 2003
	 - Reformat all links to explicitly include the CHM file, if there is one. Fixes broken expando and popup links.
	Version 2.06 - July 10, 2003
	 - Hide <H?> title and <H4>Related Topics</H4> when in an expando window.
	Version 2.05 - July 9, 2003
	 - Made SKU.js an override to ActiveX detection; added <detectsku> tag for showing detected info.
	Version 2.04 - June 12, 2003
	 - Added automatic lightning bolt to irefs linking to "http://"
	Version 2.03 - June 10, 2003
	 - Added multisectional, radio button based expando tag <a multiexpando="basename">.
	Version 2.02 - June 9, 2003
	 - Extended Strata (and Flavours) handling:
		- All codes now in arrays QUICKBOOKS_ALLSTRATA, QUICKBOOKS_STRATAWITHFLAVOUR and QUICKBOOKS_ALLFLAVOURS
		- Added (+) operator; i.e. PRO+ = PRO, PREMIER, ENTERPRISE
		- Added (-) operator; i.e. PRO- = LITE, BASIC, PRO
		- Added (:) operator; i.e. PREMIER: = PREMIER but only with no Flavour
		- Added NOT() operator; i.e. skus="NOT(ENTERPRISE,CONTRACTOR)" = anything that isn't QBES or CONTRACTOR
	 - Added automatic tooltips for expando sections. Requires <html xmlns:qb> header tag.
	Version 2.01 - June 3, 2003
	 - Added new Flavors: PROFESSIONAL, WHOLESALE, RETAIL.
	 - Added text mods "2TEXT" and "ORDINAL" for working with numbers.
	 - Added rollovers for expando graphic.
	 - Added support for multiple expando graphics (use attribute icon="", e.g. <a expando icon="green">).
	Version 2.0 - June 2003
	 - Taking what we learned in v.1, this is a complete
	   rewrite, with lots of new and wonderful stuff.
	   For information about previous versions, check
	   qbw.js from Gecko/Godzilla.

\****************************************************************/
// The following variable contains the hardcoded date of the build
// of the CHM. The reason for this that the ".lastModified" property
// doesn't work inside HTMLHelp and we need to submit this for VOC data
// from inside HTML Help (embedded browser) for the 'yes'/'no' feedback.
// We should find an automated workaround for this manual fix, to avoid
// constant updating of this value. -MTK 2-20-2003

CHM_DATE	= "6,22,2006";

// ============================================================ \\
// =====           GLOBAL ENVIRONMENT VARIABLES           ===== \\
// ============================================================ \\
// --  Any variable that is available for all functions, or  -- \\
// --  any function that's executed automatically when this  -- \\
// --  file is loaded, should be put here in this section.   -- \\
// ------------------------------------------------------------ \\



// Code added by Peter Harris 10/4/2006
//----- Define "apex" to be the topmost frame that doesn't throw a zone error -----\\
//----- Use it to replace "top" everywhere (specifically, Expando global tracking -----\\
var apex = window.self;
var tempObj = window.self;
while (tempObj) {
	apex = tempObj;
	tempObj = tempObj.parent;
	try {
		var tmp = tempObj.name;
	}
	catch (e) {
		tempObj = null;
	}
	if (apex == tempObj) {		// You've reached "top." without a zone crash. Stop looping.
		tempObj = null;
	}	
}




QUICKBOOKS_ALLSTRATA = new Array("NEUTRON", "MASNEUTRON", "LITE", "BASIC", "PRO", "PREMIER", "ENTERPRISE");
TOPIC_CHM = getTopicCHM(); // --  helpfile.chm::/
TOPIC_EXTPATH = getTopicExternalPath();	// --  C:/Program Files/QuickBooks/

// ------------------------------------------------------------ \\
// ---  DEFINE THE FILE-LINK PREFIXES FOR THIS ENVIRONMENT  --- \\
// ------------------------------------------------------------ \\

IS_EXPANDO_FRAME = ( window.name.indexOf("_expando_") > -1 );

if ( TOPIC_CHM ) {
	// ----- We are inside a CHM ----- \\
	ENVIRONMENT = "CHM";

    // v cluk - IE 7 fix to change to relative paths -- CR #QBW038847
	PATH_PREFIX_STYLESHEET = "ms-its:" + TOPIC_EXTPATH + TOPIC_CHM;  
	PATH_PREFIX_IMAGES = "ms-its:" + TOPIC_EXTPATH + TOPIC_CHM;
	PATH_PREFIX_BEHAVIORS = "../";
	PATH_PREFIX_VARIABLES = "file:///" + TOPIC_EXTPATH;
	PATH_PREFIX_HELPDEBUG = "file:///" + TOPIC_EXTPATH;
	
} else if ( (apex.Hidden) && (apex.Hidden.TOPIC_REVERSEPATH) ) 
{
	// ----- We are an update file ----- \\
	ENVIRONMENT = "UPDATE";

	var tReversePath = apex.Hidden.TOPIC_REVERSEPATH;

	PATH_PREFIX_STYLESHEET = "ms-its:" + TOPIC_EXTPATH + "admin_n.chm::/";
	PATH_PREFIX_IMAGES = "ms-its:" + TOPIC_EXTPATH + "admin_n.chm::/";
	PATH_PREFIX_BEHAVIORS = "ms-its:" + TOPIC_EXTPATH + "admin_n.chm::/";
	PATH_PREFIX_VARIABLES = tReversePath;
	PATH_PREFIX_HELPDEBUG = tReversePath;
	
} else {
	// ----- We are in development environment ----- \\
	ENVIRONMENT = "DEVELOPMENT";

	PATH_PREFIX_STYLESHEET = 	"../../_HeaderFiles/StyleSheet/";
	PATH_PREFIX_IMAGES = 		"../../_HeaderFiles/Images/";
	PATH_PREFIX_BEHAVIORS = 	"../../_HeaderFiles/JavaScript/";
	PATH_PREFIX_VARIABLES = 	"../../_HeaderFiles/JavaScript/";
	PATH_PREFIX_HELPDEBUG = 	"../../_HeaderFiles/Tools/";
}
// ------------------------------------------------------------ \\

QUICKBOOKS_VERSION	= new getQuickBooksSKU();

// -----  Define the array for variables, and then link   ----- \\
// -----  in the external file for the actual data.       ----- \\
QB_VARS = new Array();
document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_VARIABLES + "variables.js\"></script>");

// -----  Set up a link to "helpDebug.js" external file   ----- \\
document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_HELPDEBUG + "helpDebug.js\"></script>");

// ---  Define all graphics' paths (or image objects.src)   --- \\

EXPANDO_GRAPHIC = new Array();
EXPANDO_GRAPHIC["default"] = "green";
EXPANDO_GRAPHIC[0] = new Array();
EXPANDO_GRAPHIC[0]["name"] = "green";
EXPANDO_GRAPHIC[0]["open"] = new Image();	
EXPANDO_GRAPHIC[0]["open"].src = PATH_PREFIX_IMAGES + "button_expand_green_open_lo.gif";
EXPANDO_GRAPHIC[0]["close"] = new Image();	
EXPANDO_GRAPHIC[0]["close"].src = PATH_PREFIX_IMAGES + "button_expand_green_close_lo.gif";
EXPANDO_GRAPHIC[0]["openover"] = new Image();	
EXPANDO_GRAPHIC[0]["openover"].src = PATH_PREFIX_IMAGES + "button_expand_green_open_hi.gif";
EXPANDO_GRAPHIC[0]["closeover"] = new Image();	
EXPANDO_GRAPHIC[0]["closeover"].src = PATH_PREFIX_IMAGES + "button_expand_green_close_hi.gif";

ICON_PRINTER		= PATH_PREFIX_IMAGES + "icon_printer.gif";
ICON_FEEDBACK		= PATH_PREFIX_IMAGES + "icon_feedback_email.gif";
ICON_LIGHTNING		= PATH_PREFIX_IMAGES + "icon_lightningbolt.gif";
ICON_PDF			= PATH_PREFIX_IMAGES + "icon_pdf.gif";
ICON_HELP_FEEDBACK	= PATH_PREFIX_IMAGES + "icon_help_feedback.gif";
ICON_HELP_SUPPORT	= PATH_PREFIX_IMAGES + "icon_help_support.gif";

var gnScore = 0;

// ------------------------------------------------------------ \\
// ---      DISABLE THE "RIGHT-CLICK" MENU IN THE HELP      --- \\
// ------------------------------------------------------------ \\

document.onmousedown = rightclick;
// this only works because it provides an alternate window (the alert box) for the mouseup to trigger in.
// it would be better to intercept and stop the onmouseup event instead, but I can't do it yet.
function rightclick(e) {
  if (event.button == 2) {
//	alert("Right-click disabled");
//	event.returnValue = false;
//	event.cancelBubble = true;
	return false;
  }
}

// ------------------------------------------------------------ \\
// ---  INCLUDE STYLE SHEET BEHAVIORS WITH RELATIVE PATHS   --- \\
// ------------------------------------------------------------ \\

var txt = "";
txt += "<style>\n";
txt += "qb\\:tooltip { behavior: url(" + PATH_PREFIX_BEHAVIORS + "tooltip.htc); }\n";
txt += ".stripes { behavior: url(" + PATH_PREFIX_BEHAVIORS + "stripes.htc); margin-bottom: 0em; margin-top: 1em; }\n";
txt += "</style>";
document.writeln(txt);

// ------------------------------------------------------------ \\
// ----- DEFINE ALL TEXT RESOURCES HERE (FOR TRANSLATION) ----- \\
// ------------------------------------------------------------ \\

TEXT = new Array();
TEXT["feedback_ratetopic"] =		"Tell us how we can improve QuickBooks.";
TEXT["helpsupport_linktext"] =		"Can't find the help you need? Try these other resources.";
TEXT["printericontext"] =			"Print Topic";
TEXT["tooltip_expando"] =			"Expand/Collapse Text";
TEXT["tooltip_multiexpando"] =		"Display details";
TEXT["pro_advisor_text"] = 			"You could also ask your accountant for assistance. If you don't have an accountant, Intuit can help you ";
TEXT["community_text_1"] = 			"If you don't see your problem listed above, check the";
TEXT["community_text_2"] = 			"QuickBooks Community site for";

// ------------------------------------------------------------ \\
// -----   DISPLAY PRINTER ICON AND ADD ACTIVEX CONTROLS  ----- \\
// ------------------------------------------------------------ \\

var txt = "";
txt += "<object classid=clsid:596801D8-2C9D-4627-9C67-195CB81B655A id=xobj></object>";
txt += "<object classid=clsid:c1908682-7b2c-4ab0-b98e-183649a0bf84 id=aw></object>";
txt += "<object classid=clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11 id=qbHHCtrl><param name='Command' value='Minimize'></object>";

if ( !IS_EXPANDO_FRAME ) {
	txt += "<a href=\"javascript:print()\"><img src=\"" + ICON_PRINTER + "\" name=\"printicon\" align=\"right\" width=\"18\" height=\"18\" border=\"0\" alt=\"" + TEXT["printericontext"] + "\"></a>";
}
document.writeln(txt);

// ------------------------------------------------------------ \\
// -----   DATA FETCHING ROUTINES FOR GLOBAL VARIABLES    ----- \\
// ------------------------------------------------------------ \\

function getTopicCHM() {
	var loci = document.location.toString().match(/[^\/\\]*\.chm\:\:\//i);
	if (loci) {
		return loci;
	} else {
		return "";
	}
}

function getTopicExternalPath() {
	if (window.TOPIC_EXTPATH && window.QUICKPATCH_codeVersion) {
		// ----- "_updated.js" has already calculated TOPIC_EXTPATH; just use it ----- \\
		var tPath = window.TOPIC_EXTPATH;
	} else {
		// ----- figure out path on our own ----- \\
		var tPath = "";
		var loci = document.location.toString().replace(/\\/g, "/");
		switch ( loci.search(":") ) {
			case 2:		// mk:@MSITStore:
				var X = 14;
				break;
			case 6:		// ms-its:
				var X = 7;
				break;
			case 4:		// file:///
				var X = 8;
				break;
		}

		if (X==8) {	// "file:///"
			// ----- C:/Development/QuickBooks/Help/ (Y2) internalpath/ (Y3) topicfile.html (Y4) #bookmarkdata
			var Y4 = loci.indexOf("#");		Y4 = (Y4 < 0) ? loci.length : Y4;
			tPath = loci.substring(X,Y4);
			var Y3 = tPath.lastIndexOf("/")+1;
			tPath = tPath.substring(0,Y3);
			var Y2 = tPath.lastIndexOf("/",tPath.length-2)+1;
			tPath = tPath.substring(0,Y2);
		} else {
			// ----- do the calc ----- \\
			// ----- C:/ProgramFiles/IntuitProgram/ (Y1) help.chm::/ (Y2) internalpath/ (Y3) topicfile.html (Y4) #bookmarkdata
			var Y2 = loci.indexOf("::/");
			tPath = loci.substring(X,Y2);
			var Y1 = tPath.lastIndexOf("/")+1;
			tPath = tPath.substring(0,Y1);
		}
	}
	return tPath;
} // end of getTopicExternalPath

function getQuickBooksSKU() {
	var tStratum = "";
	var tFlavour = "";
	var tError = "";

	// ----- For a current list of SKUs that the product reports,   ----- \\
	// ----- check the file FlavorInstaller_common.h. Currently in  ----- \\
	// ----- **branch**/installsource/ishield6/core/script files/    ----- \\

	try {
		var objLocator = new ActiveXObject("QuickBooks.CoLocator");
		var objProfile = objLocator.Create("QBPrefs.AppParameters"); 
		var flavor = objProfile.Flavor;  // a string value; eg. "accountant"

		  if (flavor == "neutron") {
			tStratum = "NEUTRON";
			tFlavour = "";
		} else if (flavor == "masneutron") {
			tStratum = "MASNEUTRON";
			tFlavour = "";
		} else if (flavor == "atom") {
			tStratum = "ATOM";
			tFlavour = "";
		} else if (flavor == "atomlimited") {
			tStratum = "ATOMLIMITED";
			tFlavour = "";
		} else if (flavor == "lite") {
			tStratum = "LITE";
			tFlavour = "";
		} else if (flavor == "pro") {
			tStratum = "PRO";
			tFlavour = "";
		} else if (flavor == "superpro") {
			tStratum = "PREMIER";
			tFlavour = "";
		} else if (flavor == "accountant") {
			tStratum = "PREMIER";
			tFlavour = "ACCOUNTANT";
		} else if (flavor == "contractor") {
			tStratum = "PREMIER";
			tFlavour = "CONTRACTOR";
		} else if (flavor == "nonprofit") {
			tStratum = "PREMIER";
			tFlavour = "NONPROFIT";
		} else if (flavor == "healthcare") {
			tStratum = "PREMIER";
			tFlavour = "HEALTHCARE";
		} else if (flavor == "professional") {
			tStratum = "PREMIER";
			tFlavour = "PROFESSIONAL";
		} else if (flavor == "wholesale") {
			tStratum = "PREMIER";
			tFlavour = "WHOLESALE";
		} else if (flavor == "retail") {
			tStratum = "PREMIER";
			tFlavour = "RETAIL";
		} else if (flavor == "bel") {
			tStratum = "ENTERPRISE";
			tFlavour = "";
		} else if (flavor == "belacct") {
			tStratum = "ENTERPRISE";
			tFlavour = "ACCOUNTANT";
		} else if (flavor == "belcontractor") {
			tStratum = "ENTERPRISE";
			tFlavour = "CONTRACTOR";
		} else if (flavor == "belnonprofit") {
			tStratum = "ENTERPRISE";
			tFlavour = "NONPROFIT";
		} else if (flavor == "belhealthcare") {
			tStratum = "ENTERPRISE";
			tFlavour = "HEALTHCARE";
		} else if (flavor == "belprofessional") {
			tStratum = "ENTERPRISE";
			tFlavour = "PROFESSIONAL";
		} else if (flavor == "belwholesale") {
			tStratum = "ENTERPRISE";
			tFlavour = "WHOLESALE";
		} else if (flavor == "belretail") {
			tStratum = "ENTERPRISE";
			tFlavour = "RETAIL";
		} else {
			tStratum = "BASIC";
			tFlavour = "";
			tError = "Unrecognized QuickBooks.CoLocator response";
		}
	}
	catch (e) {
		tError = "Couldn't find QuickBooks.ActiveXObject";
		tStratum = "BASIC";
		tFlavour = "";
	}

	if (TOPIC_EXTPATH) {
		// ----- if there's an external path, try linking in the SKU.js override file ----- \\
		document.writeln("<script language=\"JavaScript\" src=\"" + PATH_PREFIX_VARIABLES + "SKU.js\"></script>");

	}
	this.Stratum = tStratum.toUpperCase();
	this.Flavour = tFlavour.toUpperCase();
	this.Error = tError;
} // end of getQuickBooksSKU

// ============================================================ \\
// =====           CONDITIONAL & VARIABLE TEXT            ===== \\
// ============================================================ \\

function conditionalText() {
	// ----- first off, let's find the _expando_ parent frame ----- \\
	// ----- might not be _top, but first above "_expando_"s  ----- \\
	var iTargetObj = self;
	while ( iTargetObj.name.indexOf("_expando_") >= 0 ) {
		iTargetObj = iTargetObj.parent;
	}
	var iTarget = iTargetObj.name;
	if (iTargetObj == top || iTarget == "") {
		iTarget = "_top";
	}
	if (iTargetObj == self) {
		iTarget = "";
	}

	// -----  This function scans through every HTML DOM node in the file.   ----- \\
	// -----  NB: HTML attributes are case-sensitive! 'Name' is not 'name'.  ----- \\

	var at_body = "";
	// <H4>Related Topics</H4> was changed to <p class="seealso">See Also</p>
	var at_relatedtopics = "";
	// Let's not show "See Also" links in expando topics
    var at_seealso = "";
  // Do not show "To do this task"
  var at_todotask = "";
    
	
	for (var i=0; i<document.all.length; i++) {
		nodeObj = document.all(i);
		tNode = nodeObj.nodeName.toUpperCase();

		if (tNode.substring(0,1) != "#") {
			// ----- Only check if not XML object ----- \\
			tSKUs = "";
			if ( nodeObj.attributes["skus"] ) { tSKUs = nodeObj.attributes["skus"].value; }
			if ( nodeObj.attributes["Skus"] ) { tSKUs = nodeObj.attributes["Skus"].value; }
			if ( nodeObj.attributes["SKUS"] ) { tSKUs = nodeObj.attributes["SKUS"].value; }
			if (tSKUs) {
				// ----- make this item conditional ----- \\
				if ( validateSKUs(tSKUs) ) {
					nodeObj.style.display = (tNode=="SPAN" || tNode=="A") ? "inline" : "block";
				} else {
					nodeObj.style.display = "none";
				}
			}
			// end FLAVOR conditional

			// Conditional Text For Service's e.g. QBOB 
			sService = "";
			if ( nodeObj.attributes["SERVICE"] ) { sService = nodeObj.attributes["SERVICE"].value; }
			if ( nodeObj.attributes["service"] ) { sService = nodeObj.attributes["service"].value; }
			//
			if (sService) {
				// ----- make this item conditional ----- \\
				// Can make the following if() generic as above if other services added.
				if ( QBOB_ACTIVE && ( sService == "QBOB" || sService == "qbob") ) {
					nodeObj.style.display = (tNode=="SPAN" || tNode=="A") ? "inline" : "block";
				} else {
					nodeObj.style.display = "none";
				}
			}
			// end QBOB conditional
		}

		if ( tNode == "VAR" ) {
			// ----- evaluate variable ----- \\
			setHTMLvariable( nodeObj );
		}

		if ( tNode == "A" ) {
			linkObj = nodeObj;

			if (iTarget) {
				if ( !(linkObj.target) ) {
					linkObj.target = iTarget;
				}
			}

			// ----- scan links; implement "iref"s ("Intelligent" or "Intuit" References) ----- \\
			// ----- if the target of the link is appropriate for this SKU, turn it on.   ----- \\
			var tIref = "";
			if ( linkObj.attributes["iref"] ) { tIref = linkObj.attributes["iref"].value; }
			if ( linkObj.attributes["iRef"] ) { tIref = linkObj.attributes["iRef"].value; }
			if ( linkObj.attributes["Iref"] ) { tIref = linkObj.attributes["Iref"].value; }
			if ( linkObj.attributes["IREF"] ) { tIref = linkObj.attributes["IREF"].value; }
			if (tIref) {
				var tTargetSKUs = fetchAttributeValue( linkObj, "targetSKUs" );
				if ( !tTargetSKUs ||
				     ( tTargetSKUs && validateSKUs(tTargetSKUs) )
				   ) {
					linkObj.href = tIref;
				}
			}

			// ----- it's linking to the outside world; add bolt ----- \\
			if ( linkObj.href.search( /^http:\/\//i ) >= 0 ) {
				linkObj.outerHTML = "<img src=\"" + ICON_LIGHTNING + "\" width=8 height=12>" + linkObj.outerHTML;
				// ----- we've added a new tag, so increment i to skip over the link ----- \\
				i++;
			} else {
				// ----- this is an internal link.                      ----- \\
				// ----- make the link include the CHM name explicitly  ----- \\
				// ----- this fixes broken links in expandos and popups ----- \\
				if ( TOPIC_CHM && linkObj.href
				      && ( linkObj.href.substr(0,11).toLowerCase() != "javascript:" )
				      && ( linkObj.href.indexOf("::") < 0 )
				   ) {
					linkObj.href = TOPIC_CHM + TOPIC_PATH  + linkObj.href;

				}
			}

			// ----- implement expando text links here ----- \\
			var tDivID = "";
			if ( linkObj.attributes["expando"] ) { tDivID = linkObj.attributes["expando"].value; }
			if ( linkObj.attributes["Expando"] ) { tDivID = linkObj.attributes["Expando"].value; }
			if ( linkObj.attributes["EXPANDO"] ) { tDivID = linkObj.attributes["EXPANDO"].value; }
			if ( linkObj.attributes["expando"] || linkObj.attributes["Expando"] || linkObj.attributes["EXPANDO"] ) {
				makeExpandoLink( linkObj, tDivID );
			}

			// ----- implement radio button expando text links here ----- \\
			var tDivID = "";
			if ( linkObj.attributes["multiexpando"] ) { tDivID = linkObj.attributes["multiexpando"].value; }
			if ( linkObj.attributes["MULTIEXPANDO"] ) { tDivID = linkObj.attributes["MULTIEXPANDO"].value; }
			if ( tDivID ) {
				makeMultiExpandoLink( linkObj, tDivID );
			}

		}

		if (nodeObj.id.toLowerCase() == "help_feedback_link") {
			// ----- Add the help feedback link to the bottom of the topic ----- \\
			if ( !IS_EXPANDO_FRAME ) {
				makeFeedbackAndHelpSupportLink( nodeObj , 1);
			}
		}

		if (nodeObj.id.toLowerCase() == "help_feedback_link_noresources") {
			// ----- Add the help feedback link to the bottom of the topic ----- \\
			if ( !IS_EXPANDO_FRAME ) {
				makeFeedbackAndHelpSupportLink( nodeObj, 0 );
			}
		}
		
		if (nodeObj.id.toLowerCase() == "pro_advisor_link") {
			// ----- Add the help feedback link to the bottom of the topic ----- \\
			if ( !IS_EXPANDO_FRAME ) {
				makeProAdvisorLink( nodeObj);
			}
		}
		
		if (nodeObj.id.toLowerCase() == "community_link") {
			// ----- Add the help feedback link to the bottom of the topic ----- \\
			if ( !IS_EXPANDO_FRAME ) {
				makeCommunityLink(nodeObj);
			}
		}


		// -----  Hide certain segments in the case of expando frames  ----- \\
		if (IS_EXPANDO_FRAME) {
			// ----- hide the first content tag after the body if it's an <H#> tag. ----- \\
			if ( at_body == "AT" && nodeObj.innerHTML ) {
				at_body = "PAST";
				if (tNode.substring(0,1) == "H") {
					nodeObj.style.display = "none";
				}
			}

			if ( !at_body && tNode == "BODY" ) {
				at_body = "AT";
			}

			
			// -- hide any <p class="seealso">See Also</p> blocks along with any list items -- 
			var sSeealso ="";
			if ( !at_seealso && tNode == "P" ) {
				if ( nodeObj.attributes["class"] ) { sSeealso = nodeObj.attributes["class"].value.toUpperCase(); }
				if ( sSeealso == "SEEALSO" ) { at_seealso = "AT"; }
			}
		
			if ( at_seealso == "AT" ) {
				if ( tNode == "P" ) {
					nodeObj.style.display = "none";
				}
				if ( tNode == "OL" || tNode == "UL" ) {
					nodeObj.style.display = "none";
				}
				if ( tNode != "P" && tNode != "OL" && tNode != "UL" ) {
					at_seealso = "";
				}
			}
			
			// -- QBW042126 07/25/06 cluk - hide any <span class="task">To do this task</span>
			var sTodotask ="";
			if ( !at_todotask && tNode == "SPAN" ) {
				if ( nodeObj.attributes["class"] ) { sTodotask = nodeObj.attributes["class"].value.toUpperCase(); }
          if ( sTodotask == "TASK" ) { at_todotask = "AT"; }
			}
		
			if ( at_todotask == "AT" ) {
				if ( tNode == "SPAN" ) {
					nodeObj.style.display = "none";
				}
				else {
					at_todotask = "";
				}
			}
		}



		// ------------------------------------------------------------ \\
		// ---  Include self-reporting tags for helping developers  --- \\

		if (tNode == "DETECTSKU") {
			nodeObj.outerHTML = displaySKU();
		}

		if (tNode == "LISTALLSKUS") {
			nodeObj.outerHTML = displayAllSKUs();
		}

		if (tNode == "LISTALLMODS") {
			nodeObj.outerHTML = displayAllMods();
		}

		if (tNode == "HELP") {
			nodeObj.outerHTML = displayHelp();
		}
	}

}

function setHTMLvariable ( obj ) {
	// -----  NB: HTML attributes are case-sensitive! 'Name' is not 'name'.  ----- \\

	var tOriginal = obj.innerHTML;
	var tOutput = tOriginal;
	var tOut = "";

	var tName = ""
	if ( obj.attributes["name"] ) { tName = obj.attributes["name"].value; }
	if ( obj.attributes["Name"] ) { tName = obj.attributes["Name"].value; }
	if ( obj.attributes["NAME"] ) { tName = obj.attributes["NAME"].value; }
	if (tName) {
		// ----- search for variable; does it exist? ----- \\
		tOut = QB_VARS[tName.toLowerCase()];
		if ( tOut ) {
			tOutput = tOut["word"];
		} else {
			if (window.HELP_DEBUG) {
				tOutput  = "<font color=\"red\">(" + tOriginal + ") ";
				tOutput += "<span style=\"font-family:Arial;font-size:9pt\">";
				tOutput += "<i>Error!:</i> " + tName + " <i>not found</i></span></font>";
			} else {
				// ----- leaving this "else" clause in for potential action ----- \\
				tOutput  = tOriginal;
			}
		}
	} else {
		// ----- you can apply mods to non-variables if you want ----- \\
		tOut = "OK";
		tOutput = string_trim(tOutput);
	}

	var tMods = "";
	if ( obj.attributes["mods"] ) { tMods = obj.attributes["mods"].value; }
	if ( obj.attributes["Mods"] ) { tMods = obj.attributes["Mods"].value; }
	if ( obj.attributes["MODS"] ) { tMods = obj.attributes["MODS"].value; }
	if (tOut && tMods) {
		var tMarks = tMods.split(",");
		var tAnAdd = "";
		for (var j=0; j < tMarks.length; j++) {
			switch ( string_trim(tMarks[j].toUpperCase()) ) {
			  case "A/N":
				if (tMarks[j] == "a/n") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "a" : "an";
				}
				if (tMarks[j] == "A/n") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "A" : "An";
				}
				if (tMarks[j] == "A/N") {
					tAnAdd = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "A" : "AN";
				}
			  break;
			  case "AN":
				tOutput = ("AEIOU".indexOf(tOutput.substring(0,1).toUpperCase())<0) ? "a "+tOutput : "an "+tOutput;
			  break;
			  case "CAPALL":
				tOutput = string_caps(tOutput," ");
			  break;
			  case "CAPFIRST":
				tOutput = tOutput.substring(0,1).toUpperCase() + tOutput.substring(1,tOutput.length);
			  break;
			  case "PLURAL":
				if ( tOut["plural"] ) {
					// ----- use predefined value ----- \\
					tOutput = tOut["plural"];
				} else {
					// ----- calculate it using grammar rule ----- \\
					if ( tOutput.substring(tOutput.length-1,tOutput.length).toUpperCase() ==  "S" ) {
						tOutput = tOutput + "es";
					} else {
						tOutput = tOutput + "s";
					}
				}
			  break;
			  case "POSS":
				if ( tOut["poss"] ) {
					// ----- use predefined value ----- \\
					tOutput = tOut["poss"];
				} else {
					// ----- calculate it using grammar rule ----- \\
					if ( tOutput.substring(tOutput.length-1,tOutput.length).toUpperCase() ==  "S" ) {
						tOutput = tOutput + "'";
					} else {
						tOutput = tOutput + "'s";
					}
				}
			  break;
			  case "LOWER":
				tOutput = tOutput.toLowerCase();
			  break;
			  case "UPPER":
				tOutput = tOutput.toUpperCase();
			  break;
			  case "2TEXT":
				tOutput = convertNumberToText( tOutput );
			  break;
			  case "ORDINAL":
				tOutput = convertNumberToOrdinal( tOutput );
			  break;
			}
		}
		if (tAnAdd) {
			tOutput = tAnAdd + " " + tOutput;
		}
	}

	if (obj.attributes["money"] || obj.attributes["Money"] || obj.attributes["MONEY"]) {
		// -----  display money here.  ----- \\
		// ----- US/Canada:	$1000  ----- \\
		// ----- U.K.:		£1000  ----- \\
		// ----- Québec:	1000 $ ----- \\
		tOutput = "$" + tOutput;
	}

	obj.innerHTML = tOutput;
}

function fetchAttributeValue ( obj, attName ) {
	for (var j=0; j < obj.attributes.length; j++) {
		if (obj.attributes[j].name.toUpperCase() == attName.toUpperCase()) {
			return obj.attributes[j].value;
		}
	}
}

function validateSKUs ( str ) {
	var tLists = new flattenSKUs(tSKUs);
	var tValid = false;
	if (tLists.valid) {
		if (	(tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Stratum+",") >= 0) ||
			(tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Flavour+",") >= 0) ||
			( (tLists.valid.indexOf(","+QUICKBOOKS_VERSION.Stratum+":,") >= 0 ) &&
			  (!QUICKBOOKS_VERSION.Flavour) )
		) {
			tValid = true;
		}
	}
	if (tLists.invalid) {
		if (	(tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Stratum+",") < 0) &&
			(tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Flavour+",") < 0) &&
			( (tLists.invalid.indexOf(","+QUICKBOOKS_VERSION.Stratum+":,") < 0) ||
			  (QUICKBOOKS_VERSION.Flavour) )
		) {
			tValid = true;
		}
	}
	return tValid;
}

function flattenSKUs ( source ) {
	// ----- expand expression into two flat, complete lists of SKUs  ----- \\
	// ----- and flavours, separated and bookended by commas; i.e. ----- \\
	// ----- list = ",BASIC,PRO,PREMIER,CONTRACTOR,ACCOUNTANT,".      ----- \\
	// ----- there is a ".valid" list string and an ".invalid" one.   ----- \\

	var tNots = source.match( /NOT\(([\w,]*)\)/i );
	if (tNots) {
		var tTokens = tNots[0].substring(4,tNots[0].length-1).split(",");
	} else {
		var tTokens = source.split(",");
	}

	var tList = new Array();
	for (var j=0; j < tTokens.length; j++) {
		tOut = string_trim(tTokens[j].toUpperCase());

		// ----- convert synonyms to proper code ----- \\
		var tSynOut = tOut.replace( /^(\w*)[+-:]?$/i, "$1" );
		if (tSynOut == "BEL") { tSynOut = "ENTERPRISE"; }
		if (tSynOut == "QBES") { tSynOut = "ENTERPRISE"; }
		if (tSynOut == "ACCT") { tSynOut = "ACCOUNTANT"; }
		// jtaggart 6/23/06
		// Add conversions for new QB2007 conditionals
		if (tSynOut == "PRO_ONLY") { tSynOut = "PRO"; }
		if (tSynOut == "PRO_PREMIER_ALL") { tSynOut = "PREMIER-"; }
		if (tSynOut == "PRO_PREMIER_ENTERPRISE_ALL") { tSynOut = "PRO,PREMIER,ENTERPRISE"; }
		if (tSynOut == "ENTERPRISE_ALL_ONLY") { tSynOut = "ENTERPRISE"; }
		if (tSynOut == "ENTERPRISE_VANILLA_ONLY") { tSynOut = "ENTERPRISE:"; }
		if (tSynOut == "PREMIER_VANILLA_ONLY") { tSynOut = "PREMIER:"; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL") { tSynOut = "PREMIER+"; }
		if (tSynOut == "PROFESSIONAL_SERVICES") { tSynOut = "PROFESSIONAL"; }
		if (tSynOut == "SIMPLESTART_ONLY") { tSynOut = "ATOM,ATOMLIMITED"; }
		if (tSynOut == "IM_ONLY") { tSynOut = "NEUTRON"; }
		if (tSynOut == "CCPK_ONLY") { tSynOut = "MASNEUTRON"; }
		if (tSynOut == "IM_AND_CCPK_ALL") { tSynOut = "NEUTRON,MASNEUTRON"; }
		if (tSynOut == "PRO_PREMIER_ENTERPRISE_SIMPLESTART_ALL") { tSynOut = "PRO,SUPERPRO,BEL,ATOM,ATOMLIMITED"; }
		// (NOT)s
		// These conditions may become obsolete after content cleanup, but adding for consistency
		// QBW042392 - condition ID with "NOT" are not working - cluk 7/24/2006
		// "NOT" should be filtered out and determined earlier in this function, so assign
		// tSynOut and tNots to the values after the filtering.
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_WHOLESALE") { tSynOut = "WHOLESALE"; tNots = true; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_RETAIL") { tSynOut = "RETAIL"; tNots = true; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_PROFESSIONAL_SERVICES") { tSynOut = "PROFESSIONAL"; tNots = true; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_NONPROFIT") { tSynOut = "NONPROFIT"; tNots = true; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_CONTRACTOR") { tSynOut = "CONTRACTOR"; tNots = true; }
		if (tSynOut == "PREMIER_ENTERPRISE_ALL_NOT_ACCOUNTANT") { tSynOut = "ACCOUNTANT"; tNots = true; }
		tOut = tOut.replace( /^(\w*)([+-:]?)$/, tSynOut+"$2" );
		// debug new conditionals
		//alert(tOut);
		// -----  search for +/- extensors to STRATUM; i.e. "PRO+" means PRO, PREMIER, etc. ----- \\
		// -----  pointless for top and bottom of list; no "MINIMUM-" or "MAXIMUM+"         ----- \\
		for (var k=1; k < QUICKBOOKS_ALLSTRATA.length-1; k++) {
			if ( tOut == QUICKBOOKS_ALLSTRATA[k] + "+" ) {
				// ----- "STRATUM+"; include this stratum and all above it ----- \\
				for ( var n=k; n < QUICKBOOKS_ALLSTRATA.length; n++ ) {
					var tStrat = QUICKBOOKS_ALLSTRATA[n];
					if ( (tList.toString()+",").indexOf(tStrat+",") < 0 )	{ tList.push( tStrat ); }
				}
				k = QUICKBOOKS_ALLSTRATA.length;
			}
			if ( tOut == QUICKBOOKS_ALLSTRATA[k] + "-" ) {
				// ----- "STRATUM-"; include this stratum and all below it ----- \\
				for ( var n=0; n <= k; n++ ) {
					var tStrat = QUICKBOOKS_ALLSTRATA[n];
					if ( (tList.toString()+",").indexOf(tStrat+",") < 0 )	{ tList.push( tStrat ); }
				}
				k = QUICKBOOKS_ALLSTRATA.length;
			}
		}

		// ----- if all else fails, just add the code you were passed ----- \\
		if ( (tList.toString()+",").indexOf(tOut+",") < 0 )		{ tList.push( tOut ); }
	}

	if (tNots) {
		this.valid = "";
		this.invalid = "," + tList.toString() + ",";
	} else {
		this.valid = "," + tList.toString() + ",";
		this.invalid = "";
	}
}

function addUnique ( tArray, tElement ) {
	for (var j=0; j<tArray.length; j++) {
		if (tArray[j] == tElement) {
			return tArray;
		}
	}
	tArray[tArray.length] = tElement;
	return tArray;
}

function string_caps ( str, delim ) {
	var txt = "";
	var tmp = str.split(delim);
	for (var i=0; i < tmp.length; i++) {
		if (tmp[i]) {
			txt += tmp[i].substring(0,1).toUpperCase();
			txt += tmp[i].substring(1,tmp[i].length);
			txt += delim;
		}
	}

	return txt;
}

function string_trim ( str ) {
	str = str.replace( /^\s*/ , "" );
	str = str.replace( /\s*$/ , "" );
	return str;
}

function convertNumberToText ( str ) {
	var tNum = parseInt(str);

	// ----- if it's not a number, just return the string ----- \\
	if ( isNaN(tNum) ) {
	return str;
	}

	var tOut = "";

	// ----- if it's zero, then return zero ----- \\
	if (tNum == 0) {
		tOut = "zero";
	}

	while ( tNum ) {
		var tNumStartLoop = tNum;

		if ( tNum > 999999999 ) {
			// ----- too big; just return the string ----- \\
			tOut = str;
			tNum = 0;
		}

		if ( tNum > 999999 ) {
			// ----- we're in the millions; find how many ----- \\
			var t1 = Math.floor( tNum / 1000000 );
			var t2 = convertThousandsToText(t1);
			if (tOut) { tOut += ","; }
			tOut += t2 + " million";

			tNum = tNum % 1000000;
		}

		if ( tNum > 999 ) {
			// ----- we're in the thousands; find how many ----- \\
			var t1 = Math.floor( tNum / 1000 );
			var t2 = convertThousandsToText(t1);
			if ( (tOut) && (t2) ) { tOut += ","; }
			tOut += t2 + " thousand";

			tNum = tNum % 1000;
		}

		if ( tNum < 1000 ) {
			// ----- we're under a thousand; finish ----- \\
			var t2 = convertThousandsToText(tNum);
			if ( (tOut) && (t2) ) { tOut += ","; }
			tOut += t2;

			tNum = 0;
		}

		// ----- do a final comparison to prevent infinite looping ----- \\
		if (tNumStartLoop == tNum) {
			// ----- if nothing happened to tNum then we're looping; kill ----- \\
			tNum = 0;
			tOut = str;
		}
	}

	return tOut;
}

function convertThousandsToText ( num ) {
	var tOut = "";
	if ( num > 999 ) {
		num = num % 1000;
	}

	if ( num > 99 ) {
		// ----- we're in the hundreds; find how many ----- \\
		var t1 = Math.floor( num / 100 );
		var t2 = convertDecadesToText(t1);
		tOut += t2 + " hundred";

		num = num % 100;
	}

	if ( num > 0 ) {
		// ----- we're under a hundred; finish ----- \\
		var t2 = convertDecadesToText(num);
		if (tOut) { tOut += " and "; }
		tOut += t2;
	}

	return tOut;
}

function convertDecadesToText ( num ) {
	var numbers = new Array("", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen");
	var decades = new Array("", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety");

	var tOut = "";
	if ( num > 99 ) {
		num = num % 100;
	}

	if ( num > 19 ) {
		// ----- set up the decade ----- \\
		var t1 = Math.floor( num / 10 );
		tOut += decades[t1];

		num = num % 10;
	}

	if ( num > 0 ) {
		// ----- all that remains is teens or singles ----- \\
		if (tOut) { tOut += "-"; }
		tOut += numbers[num];
	}

	return tOut;
}

function convertNumberToOrdinal ( str ) {
	var tNum = parseInt(str);

	if ( isNaN(tNum) ) {
		// ----- number is written as text ----- \\

		if ( str.substr(str.length-3) == "one" ) {
			return str.substring(0,str.length-3) + "first";
		}
		if ( str.substr(str.length-3) == "two" ) {
			return str.substring(0,str.length-3) + "second";
		}
		if ( str.substr(str.length-5) == "three" ) {
			return str.substring(0,str.length-5) + "third";
		}
		if ( str.substr(str.length-2) == "ty" ) {
			return str.substring(0,str.length-2) + "tieth";
		}

		return str + "th";

	} else {
		// ----- number is in numeric form ----- \\
		tLast = tNum % 10;

		if ( tLast == 1 ) {
			return str + "st";
		}
		if ( tLast == 2 ) {
			return str + "nd";
		}
		if ( tLast == 3 ) {
			return str + "rd";
		}

		return str + "th";
	}
}

// ------------------------------------------------------------ \\
// ============================================================ \\
// =====                EXPANDO SECTIONS                  ===== \\
// ============================================================ \\
// ------------------------------------------------------------ \\
// -----     INSERT CODE FOR EXPANDO AND MULTIEXPANDO     ----- \\

if (!(apex.GLOBAL_EXPANDO_FRAMES)) { apex.GLOBAL_EXPANDO_FRAMES = 0; }
if (!(apex.GLOBAL_EXPANDOFRAME_DATA)) { apex.GLOBAL_EXPANDOFRAME_DATA = new Array(); }
if (!(window.GLOBAL_MULTIEXPANDOS)) { GLOBAL_MULTIEXPANDOS = new Array(); }

function makeExpandoLink ( linkObj, divID ) {
	var tDivObj = findExpandoDiv( linkObj, divID );

	// -----  If there's no valid target zone for this link,       ----- \\
	// -----  then we don't activate the href, and it's just text. ----- \\
	if (tDivObj) {
		// ----- is there a specific icon= being asked for? ----- \\
		var myIcon = fetchAttributeValue( linkObj, "icon" );
		if (!myIcon) {
			myIcon = EXPANDO_GRAPHIC["default"];
		}

		// ----- get the index of the chosen expando icon ----- \\
		var iconIndex = 0;
		for (var i=0; i < EXPANDO_GRAPHIC.length; i++) {
			if ( myIcon == EXPANDO_GRAPHIC[i]["name"] ) {
				iconIndex = i;
				i = EXPANDO_GRAPHIC.length;
			}
		}

		// ----- does it default to open or closed? ----- \\
		//var tStartOpen = ( linkObj.attributes["open"] || linkObj.attributes["Open"] || linkObj.attributes["OPEN"] ) ? "YES" : "";
		
		// Static Expando - cluk
		//var tStaticExpando = ( linkObj.attributes["static"] || linkObj.attributes["Static"] || linkObj.attributes["STATIC"] ) ? "YES" : "";
    
    // cluk 6/27/06 - change expando syntax for open/static into type="open/static"
		var tExpandoType = "";
		if (linkObj.attributes["type"]) { tExpandoType = linkObj.attributes["type"].value; }
		if (linkObj.attributes["Type"]) { tExpandoType = linkObj.attributes["Type"].value; }
		if (linkObj.attributes["TYPE"]) { tExpandoType = linkObj.attributes["TYPE"].value; }
		
		var tStaticExpando = "";
    var tStartOpen = "";
	  tExpandoType = tExpandoType.toUpperCase();
		if (tExpandoType == "OPEN") 
    { 
      tStartOpen = tExpandoType;
    }
    else if (tExpandoType == "STATIC")
    {
      tStaticExpando = tExpandoType;
    }
    // Static Expando - cluk
    var tOption = tStartOpen;
    if (tStaticExpando)
    {
      tOption = tStaticExpando;
    }
    
		// ----- try to implement the DIV; it may yet be illegal ----- \\
		if ( !makeExpando_DivPrep( tDivObj, tOption ) ) {
			return;
		}
		
		if (tStaticExpando)   // Static Expando - cluk
		{
      // remove the border width of the expando
		  tDivObj.style.borderWidth = 0;
    }
    
		// ----- add open/close graphic to link ----- \\
		if ( tStartOpen ) {
			linkObj.innerHTML += "<img src=\"" + EXPANDO_GRAPHIC[iconIndex]["close"].src + "\" border=0 style=\"margin-left: 4\">";
		} else if (!tStaticExpando) {    // static expando - cluk
			linkObj.innerHTML += "<img src=\"" + EXPANDO_GRAPHIC[iconIndex]["open"].src + "\" border=0 style=\"margin-left: 4\">";
		}

		// ----- generate a unique ID if the link doesn't have one ----- \\
		if (!linkObj.id) { linkObj.id = document.uniqueID; }
		/* -----removing this bit of code for QBPP10551; we don't need the tooltip anymore and it's showing up as static text at the bottom of the Help topic.  See Teamtrack CR#QBPP10551 for a screenshot of the problem.
		if (!tStaticExpando) {
		  // ----- now generate the tooltip for this expando link    ----- \\
		  var t = "<qb:tooltip element=\"" + linkObj.id + "\" delay=\"3000\" avoidmouse=\"false\">" + TEXT["tooltip_expando"] + "</qb:tooltip>";
		  document.body.insertAdjacentHTML("beforeEnd", t);
    } -----*/
	
    
		// ----- set custom attributes in the <A> tag ----- \\
		// ----- for the DIV ID and the iconIndex     ----- \\
		linkObj.divID = divID;
		linkObj.iconIndex = iconIndex;

		if (!tStaticExpando) {
		  linkObj.href = "javascript:";
		  linkObj.onclick = expandoText;
		  linkObj.onmouseover = expandoMouseOver;
		  linkObj.onmouseout = expandoMouseOut;
		}
	}
}

function makeMultiExpandoLink ( linkObj, divID ) {
	if (!(GLOBAL_MULTIEXPANDOS[divID])) { GLOBAL_MULTIEXPANDOS[divID] = 0; }
	var tID = GLOBAL_MULTIEXPANDOS[divID] + 1;

	// ----- Div IDs for multi-expandos are made like this: "name(1)" ----- \\
	var uniqueDivID = divID+"("+tID+")";
	var tDivObj = document.all[uniqueDivID];

	// -----  If there's no valid target zone for this link,       ----- \\
	// -----  then we don't activate the href, and it's just text. ----- \\
	if (tDivObj) {
		GLOBAL_MULTIEXPANDOS[divID] = tID;

		var tStartOpen = ( linkObj.attributes["open"] || linkObj.attributes["Open"] || linkObj.attributes["OPEN"] ) ? "YES" : "";

		// ----- try to implement the DIV; it may yet be illegal ----- \\
		if ( !makeExpando_DivPrep( tDivObj, tStartOpen ) ) {
			return;
		}

		// ----- add radio button to link ----- \\
		linkObj.innerHTML = "<input type=\"radio\" name=\"" + divID + "\">" + linkObj.innerHTML;

		// ----- generate a unique ID if the link doesn't have one ----- \\
		if (!linkObj.id) { linkObj.id = document.uniqueID; }
		// ----- now generate the tooltip for this expando link    ----- \\
		var t = "<qb:tooltip element=\"" + linkObj.id + "\" delay=\"3000\" avoidmouse=\"false\">" + TEXT["tooltip_multiexpando"] + "</qb:tooltip>";
		document.body.insertAdjacentHTML("beforeEnd", t);

		// ----- set custom attributes in the <A> tag ----- \\
		// ----- for the base DIV name and # index    ----- \\
		linkObj.DivBase = divID;
		linkObj.DivIndex = tID;

		linkObj.href = "javascript:";
		linkObj.onclick = multiExpandoText;
	}
}

function makeExpando_DivPrep ( divObj, startOpen ) {
	// ----- See if this is a simple DIV or an IFRAME include file ----- \\

	tFile = "";
	if ( divObj.attributes["file"] ) { tFile = divObj.attributes["file"].value; }
	if ( divObj.attributes["File"] ) { tFile = divObj.attributes["File"].value; }
	if ( divObj.attributes["FILE"] ) { tFile = divObj.attributes["FILE"].value; }
		if (tFile) {
		// ----- There's an external file referenced by the DIV.   ----- \\
		// ----- Create and size an IFRAME for the included file.  ----- \\
		tFile = tFile.replace(/\\/g, "/");

		// ----- Convert link to explicit CHM reference.           ----- \\
//		--- Unnecessary; handled later by FixURL(). Leave out.
//		--- Keeping a copy in case problems arise in the cyclical check.
//		if ( tFile.indexOf("::") < 0 ) {
//			var tSub = TOPIC_PATH;
//			while ( tFile.substr(0,3) == "../" ) {
//				tSub = tSub.substring(0,tSub.lastIndexOf("/",tSub.length-2));
//				tFile = tFile.substring(3,tFile.length);
//			}
//			tFile = TOPIC_CHM + tSub + tFile;
//		}


		// ----- Make sure it's not a cyclical reference.          ----- \\
		// ----- walk up the "_expando_" tree and check all src.   ----- \\
		
		// 9-20-2005 mkronber:  modified this code because was not working in some cases.
		// Changed the logic to strip all compares down to the raw file name "xyz.html"
		// e.g. no leading "../" or "directory/" before the topics. This fixed the issue
		// we were seeing, also this should suffice since we have unique topic names.
		
		
		var tMe = self;
		var tLoc = "";
		var tBase = (tFile.indexOf("::/") < 0) ? tFile : tFile.substring(tFile.indexOf("::/")+3,tFile.length);
		// remove the leading "../" if present. mkronber 9-20-2005
		if ( tBase.substr(0,3) == "../" ) {
			tBase = tBase.substring(3,tBase.length);
		}
		// change "\" to "/"		
		tBase = tBase.replace(/\\/g,"/");
		// Remove directory "dir/" from file name for compare, since tBase doesn't have it.
		// mkronber 9-20-2005
		tBase = (tBase.indexOf("/") < 0) ? tBase : tBase.substring(tBase.indexOf("/")+1,tBase.length);


		var cyclical = false;
		while ( tMe.name.indexOf("_expando_") >= 0 ) {
			tLoc = unescape(tMe.location);
			tLoc = (tLoc.indexOf("::/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("::/")+3,tLoc.length);
			tLoc = tLoc.replace(/\\/g,"/");
			// remove the leading ../ if present MTK
			if ( tLoc.substr(0,3) == "../" ) {
				tLoc = tLoc.substring(3,tLoc.length);
			}
			// Remove directory from file name for compare, since tBase doesn't have it.
			// mkronber 9-20-2005
			tLoc = (tLoc.indexOf("/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("/")+1,tLoc.length);
			cyclical = cyclical || (tLoc.toLowerCase() == tBase.toLowerCase());
			tMe = tMe.parent;
		}
		// ----- also have to check against ultimate parent.       ----- \\
		tLoc = unescape(tMe.location);
		tLoc = (tLoc.indexOf("::/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("::/")+3,tLoc.length);
		tLoc = tLoc.replace(/\\/g,"/");
		// Remove directory "dir/" from file name for compare, since tBase doesn't have it.
		// mkronber 9-20-2005
		tLoc = (tLoc.indexOf("/") < 0) ? tLoc : tLoc.substring(tLoc.indexOf("/")+1,tLoc.length);
		cyclical = cyclical || (tLoc.toLowerCase() == tBase.toLowerCase());

		if ( cyclical ) {
			// ----- Cyclical reference!!!, fail and return false. ----- \\
			// If this does not properly catch a circular reference and return false, 		
			// the Javascript will enter an infinite loop!(e.g. QBW036130) mkronber 9-20-2005
			return false;
		}

		// ----- Note: a link to the <iframe> node is not the same ----- \\
		// ----- as a link to the frame object; which is to say    ----- \\
		// ----- divObj.all(0) != document.frames(tIFName).        ----- \\
		// ----- Which is why the iframe needs a name.             ----- \\

		apex.GLOBAL_EXPANDO_FRAMES++;
		var tIFName = "_expando_" + apex.GLOBAL_EXPANDO_FRAMES;
		var t = "<iframe name=\"" + tIFName + "\" frameborder=\"0\" scrolling=\"auto\"></iframe>";
		divObj.innerHTML = t;

		divObj.style.position = "absolute";
		divObj.style.top = -10000;
		divObj.style.left = -10000;
		divObj.style.display = "block";

		if ( tFile.indexOf("::") > 0 ) {
			tFile = "ms-its:" + TOPIC_EXTPATH + tFile;
		}
		document.frames(tIFName).location = tFile;

		// ----- store info we need later in global variables  ----- \\
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName] = new Array();
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName]["startOpen"] = startOpen;
		apex.GLOBAL_EXPANDOFRAME_DATA[tIFName]["outerDiv"] = divObj;

		resizeExpandoFrame( tIFName );

	} else {
		// ----- It's important to explicitly set the .style.display property, ----- \\
		// ----- so that it can be checked later by the show/hide script.      ----- \\

		if ( startOpen ) {
			// ----- Start this expando block open ----- \\
			divObj.style.display = "block";
		} else {
			divObj.style.display = "none";
		}
	}

	return true;
}

// ------------------------------------------------------------ \\
// -----       "ONCLICK" OPERATING CODE FOR EXPANDOS      ----- \\

function expandoText() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var divID = anchor.divID;
	var iconIndex = anchor.iconIndex;
	var divTag = findExpandoDiv( anchor, divID );

	if (divTag) {
		// ----- Find the open/close image in the link, if there is one  ----- \\
		// ----- it will be at the end of the <A> tag, so count backward ----- \\
		tPicObj = "";
		for (j=anchor.all.length-1; j >= 0; j-- ) {
			if (anchor.all(j).tagName == "IMG") {
				var tAnchor = unescape(anchor.all(j).src);
				if ( ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["open"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["close"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["openover"].src) )
				  || ( tAnchor == unescape(EXPANDO_GRAPHIC[iconIndex]["closeover"].src) )
				) {
					tPicObj = anchor.all(j);
					j = -1;
				}
			}
		}

		// ----- Use the .style.display property to determine open/closed status    ----- \\
		// ----- It must be set explicitly by the setup code; it defaults to blank. ----- \\
		if (divTag.style.display == "none") {
			divTag.style.display = "block";
			if (tPicObj) {
				tPicObj.src = EXPANDO_GRAPHIC[iconIndex]["close"].src;
			}
		} else if (divTag.style.display == "block") {
			divTag.style.display = "none";
			if (tPicObj) {
				tPicObj.src = EXPANDO_GRAPHIC[iconIndex]["open"].src;
			}
		}

		// ----- need to resize parent frames, if any ----- \\
		expandoText_nestedFrames( divTag );
	}
}

function multiExpandoText() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var tDivBase = anchor.DivBase;
	var tDivIndex = anchor.DivIndex;

	// ----- set the radio button to this entry ----- \\
	if ( GLOBAL_MULTIEXPANDOS[tDivBase] > 1 ) {
		document.all[tDivBase][tDivIndex-1].checked = true;
	} else {
		document.all[tDivBase].checked = true;
	}

	for (var i=1; i <= GLOBAL_MULTIEXPANDOS[tDivBase]; i++) {
		var uniqueDivID = tDivBase + "(" + i + ")";
		var tDivObj = document.all[uniqueDivID];

		if (i == tDivIndex) {
			// ----- this is the selected DIV; make visible ----- \\
			tDivObj.style.display = "block";
		} else {
			// ----- turn all others invisible ----- \\
			tDivObj.style.display = "none";
		}

		// ----- need to resize parent frames, if any ----- \\
		expandoText_nestedFrames( tDivObj );
	}
}


function expandoMouseOver() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var iconIndex = anchor.iconIndex;

	// ----- Find the open/close image in the link, if there is one  ----- \\
	// ----- it will be at the end of the <A> tag, so count backward ----- \\
	tPicObj = "";
	for (j=anchor.all.length-1; j >= 0; j-- ) {
		var imgObj = anchor.all(j);
		if (imgObj.tagName == "IMG") {
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["open"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["openover"].src;
				j = -1;
			}
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["close"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["closeover"].src;
				j = -1;
			}
		}
	}
}

function expandoMouseOut() {
	// ----- the srcElement could be a subtag of <A> (e.g. an image); ----- \\
	// ----- crawl up the DOM until you reach the actual <A> tag.     ----- \\
	var anchor = event.srcElement;
	while ( (anchor != null) && (anchor.tagName != "A") ) {
		anchor = anchor.parentElement;
	}
	if (anchor.tagName != "A") return;

	var iconIndex = anchor.iconIndex;

	// ----- Find the open/close image in the link, if there is one  ----- \\
	// ----- it will be at the end of the <A> tag, so count backward ----- \\
	tPicObj = "";
	for (j=anchor.all.length-1; j >= 0; j-- ) {
		var imgObj = anchor.all(j);
		if (imgObj.tagName == "IMG") {
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["openover"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["open"].src;
				j = -1;
			}
			if ( unescape(imgObj.src) == unescape(EXPANDO_GRAPHIC[iconIndex]["closeover"].src) ) {
				imgObj.src = EXPANDO_GRAPHIC[iconIndex]["close"].src;
				j = -1;
			}
		}
	}
}

// ------------------------------------------------------------ \\
// -----         SUPPORTING FUNCTIONS FOR EXPANDOS        ----- \\

function findExpandoDiv ( anchorObj, divID ) {
	// ----- If there's a "divID", then find that DIV ID. Otherwise,  ----- \\
	// ----- search forward in the DOM for the next valid target tag. ----- \\
	// ----- Valid:  DIV tag or LI tag with "expando" class           ----- \\
	var divTag = "";

	if (divID) {
		divTag = document.all[divID];
	} else {
		for (var j=anchorObj.sourceIndex+1; j < document.all.length; j++ ) {
			var tg = document.all(j);
			if ( (tg.tagName == "DIV" || tg.tagName == "LI") &&
			      tg.className.toLowerCase() == "expando" ) {
				divTag = tg;
				j = document.all.length;
			}
		}
	}
	return divTag;
}

function resizeExpandoFrame ( frameName ) {
	// ----- Note: passing a string (frameName), rather than a window ----- \\
	// ----- handle, allows us to set a callback with setTimeout().   ----- \\

	var iframeObj = document.frames(frameName);
	if ( (iframeObj.document != null ) &&
	     (iframeObj.document.readyState == "complete") &&
	     (iframeObj.document.body != null) )  {
		// ----- page is finished loading; polish it off ----- \\

		// ----- find top-level frame that's not an "_expando_" frame ----- \\
		var tTop = iframeObj;
		while (tTop.name.indexOf("_expando_") >= 0) {
			tTop = tTop.parent;
		}
		// ----- find the window width less the nested margins ----- \\
		var parentWidth = tTop.document.body.clientWidth;
		var tWin = iframeObj;
		while (tWin != tTop) {
			var scrollbarWidth = tWin.document.body.offsetWidth - tWin.document.body.clientWidth;
			parentWidth = parentWidth - tWin.document.body.leftMargin;
			parentWidth = parentWidth - tWin.document.body.rightMargin;
			parentWidth = parentWidth - scrollbarWidth;
			parentWidth = parentWidth - 3;
			tWin = tWin.parent;
		}
		var parentHeight = apex.document.body.clientHeight;
		var maxWidthRatio = 1.0;
		var maxWidth = parentWidth * maxWidthRatio;

		// ----- (resize once to SET the scrollHeight, once to USE the scrollHeight) ----- \\
		// ----- requires third pass because of in-line rewriting of include topics  ----- \\
		try {		
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		    iframeObj.resizeTo(maxWidth, iframeObj.document.body.scrollHeight);
		}
		catch (e) {
			// produced script error, prevent by using try/catch. taskID:182337 
		}

		// ----- since we know scroll bars are unnecessary, turn them off ----- \\
		iframeObj.document.body.scroll = 'no';

		// ----- this is the final size; now bring DIV back inline ----- \\
		apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["outerDiv"].style.position = "static";
		if ( !(apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["startOpen"]) ) {
			apex.GLOBAL_EXPANDOFRAME_DATA[frameName]["outerDiv"].style.display = "none";
		}
	} else {
		setTimeout("resizeExpandoFrame('" + frameName + "')", 100);
	}
}

function expandoText_nestedFrames ( divObj ) {
	// ----- if this is inside an included frame,     ----- \\
	// ----- keep expanding the parent frames to fit. ----- \\
	var tMe = self;
	while ( tMe.name.indexOf("_expando_") >= 0 ) {
		// -----
		tMe.resizeTo(tMe.document.body.scrollWidth, tMe.document.body.scrollHeight);
		tMe = tMe.parent;
	}
	// ----- if we're expanding, and the bottom will  ----- \\
	// ----- go past the bottom of the window, then   ----- \\
	// ----- scroll it up so it's visible.            ----- \\
	if (divObj.style.display == "block") {
		if (divObj.offsetHeight < document.body.clientHeight) {
			// ----- if the expando section is bigger than the window, don't bother ----- \\
			var tZoneBottom = divObj.offsetTop + divObj.offsetHeight;
			var tZoneY = tZoneBottom - document.body.scrollTop;
			if (tZoneY > document.body.clientHeight) {
				window.scrollTo( 0,document.body.scrollTop + (tZoneY - document.body.clientHeight) );
			}
		}
	}
}
// ============================================================ \\
// =====       END OF CONDITIONAL/EXPANDO CODE            ===== \\
// ============================================================ \\


// ============================================================ \\
// =====             "RATE THIS TOPIC" CODE               ===== \\
// ============================================================ \\

/*--------------------------------------------------------
 * function fnLoadAndRunFeedbackInfo
 *
 * Description
	Called to start loading the ACE file - ACE will read 
	it as XML.  The function fnLoadStateChange() called
	as the load status changes.  When the status is 4, the
	XML file has been loaded and is ready for reading
 *
**-------------------------------------------------------*/

function fnLoadAndRunFeedbackInfo(nScore) {
	gnScore = nScore;
	FeedbackInfo.load("qbx://ACEAccess/GetObject.xml?Type=URL&ID=FeedbackURL");
}

/*--------------------------------------------------------
 * function fnLoadStateChange
 *
 * Description
	Called for each ace xml file load status change.
	When status is 4 load is done.
 *
**-------------------------------------------------------*/

function fnLoadStateChange() {
	if (FeedbackInfo.XMLDocument.readyState == 4) {
		fnRunFB(gnScore);
	}
}

/*--------------------------------------------------------
 * function fnRunFB
 *
 * Description
	Called After the ACE file is done loading, submits
	feedback.
	
	using the form field values not the QBCommand values
	refer the the feedback EDD for details.
 *
**-------------------------------------------------------*/
function fnRunFB(nScore) {

	/////////////////////////////////////////////////
	//
	// Get Submit URL from ACE
	//
	/////////////////////////////////////////////////
	
	var currNode;
	currNode = 
		FeedbackInfo.XMLDocument.selectSingleNode("URL[@ID='FeedbackURL']/@Address");
	if (!currNode) {
		return;
	}
	document.yesno_feedback_form.action = currNode.text;

	////////////////////////////////////////////////////////////
	//
	// populate all the inputs for the form, then submit
	// start w/telling the server not to return with a 
	// UI (html), Yes votes display our own thank you
	// access point, feedback type
	//
	// refer to feedback EDD for values
	//
    // http://qube.intuit.com/library/docs/Reported%20Feedback%20Collection%20FastTrack%20EDD.doc 
	////////////////////////////////////////////////////////////
	
	var sUI = "<input type='hidden' name='ui' value='false'>";
	// for suggestion box feedback
	var sUIonly = sUI;
	sUI += "<input type='hidden' name='submit.x' value='1'>";
	var sAP = "<input type='hidden' name='access_point' value='help'>";
	var sFB = "<input type='hidden' name='feedback_type' value='help_suggestion'>";
	ui_div.innerHTML =  sUI;
	access_point_div.innerHTML = sAP;
	feedback_type_div.innerHTML = sFB;

	////////////////////////////////////////////////////////////
	//
	// get the CHM name and topic name
	//
	////////////////////////////////////////////////////////////
	
	var doc = unescape(document.URL);
	// Is this topic a patched topic (using QuickPatch)
	 var index = doc.toLowerCase().indexOf("help\\updates");
	 if (index == -1) {
		// Regular Topic
		var cut_start = doc.lastIndexOf("\\") + 1;
		var to_colon = doc.lastIndexOf("::");
		var from_colon = doc.lastIndexOf("::") + 2;
		var to_end = doc.lastIndexOf(".html");
		var chm_file = doc.substring(cut_start,to_colon).toLowerCase();
		var file_name = doc.substring(from_colon,to_end).toLowerCase();
		//alert( index + " LOCAL!! \nFILE is: " + file_name + "\nCHM is: " + chm_file );
	} else {
		// Patched Topic URL string is different, must parse differently.
		var cut_start = doc.lastIndexOf("updates") + 7;
		var to_html = doc.lastIndexOf(".html");
		var file_name = doc.substring(cut_start,to_html).replace(/\\/g, "/");
		// Get CHM name from variable declared in patched topic
		var chm_file = CHM_FILE;
		//alert( index + " PATCHED!! \nFILE is: " + file_name + "\nCHM is: " + chm_file );
	}

	var chmText		= "<input type='hidden' name='hlp_doc_chm' value='" + chm_file + "'>";
	var topicText	= "<input type='hidden' name='hlp_doc_name' value='" + file_name + "'>";
	doc_chm.innerHTML =  chmText;
	doc_name.innerHTML =  topicText;	
	
	////////////////////////////////////////////////////////////
	//
	// get the SKU/flavor/subproduct
	//
	////////////////////////////////////////////////////////////
	
	var objLocator	= new ActiveXObject("QuickBooks.CoLocator");
	var objProfile	= objLocator.Create("QBPrefs.AppParameters"); 
	var skuText		= "<input type='hidden' name='subproduct' value='" + objProfile.Flavor + "'>";
	sku.innerHTML	= skuText;

	////////////////////////////////////////////////////////////
	//
	// get Product, Version and Release
	//
	////////////////////////////////////////////////////////////
	
	var ver = objProfile.ProductVersion;  
	var rel = objProfile.Release; 
	var sProductText =	"<input type='hidden' name='product' value='quickbooks'>";
	var sVersionText =	"<input type='hidden' name='version' value='" + ver + "'>";
	var sReleaseText =	"<input type='hidden' name='release' value='" + rel + "'>";
	product_div.innerHTML =	sProductText;
	version_div.innerHTML = sVersionText;
	release_div.innerHTML = sReleaseText;

	////////////////////////////////////////////////////////////
	//
	// add rating to form... always 1, since 'yes' was clicked, 
	// also add novote/yesvote label to name
	//
	////////////////////////////////////////////////////////////
	var ratingText = "<input type='hidden' name='hlp_score' value='" + gnScore + "'>";

	ratingText += "<input type='hidden' name='hlp_name' value='";
	if (gnScore == 1) {
		ratingText +=  "yesvote'>";
	} else {
		ratingText +=  "novote'>";
	}
	rating.innerHTML = ratingText;

	////////////////////////////////////////////////////////////
	//
	// get document date, get from document object.
	//
	////////////////////////////////////////////////////////////
	
	var filedate = CHM_DATE;	
	var docdateText = "<input type='hidden' name='hlp_doc_date' value='" + filedate + "'>";
	doc_date.innerHTML = docdateText;

	////////////////////////////////////////////////////////////
	//
	// get last search
	//
	////////////////////////////////////////////////////////////
	
	var chmname;
	var awHelpSystem;
	var flavor = objProfile.Flavor;
	 if ( flavor.search(/atom/) >= 0  ) { 
		chmname = "atomcore.chm"
	 } else {
		chmname = "admin_n.chm"
	 }
	 
	awHelpSystem =  TOPIC_EXTPATH + chmname;
	 
	var sSeedQuestion = aw.GetSeedQuery (awHelpSystem);
	var lastsearchText =	
		"<input type='hidden' name='hlp_last_search' value='" + sSeedQuestion + "'>";
	last_search.innerHTML = lastsearchText;
   
	////////////////////////////////////////////////////////////
	//
	// submit the form to hidden frame, remove the buttons, and 
	// replace with the "thank you" message
	//
	////////////////////////////////////////////////////////////
	
	document.yesno_feedback_form.submit(); 
	fnHideVoteButtons();

	////////////////////////////////////////////////////////////
	//
	// If no vote then allow user to enter suggestion, along
	// with the novote we just entered
	//
	////////////////////////////////////////////////////////////
	
	// pass the feedback vars to the suggestion box form
	if (nScore == 0) {
		fnRunNoFB(sUIonly,sFB,chmText,topicText,skuText,sProductText,sVersionText,sReleaseText,docdateText,lastsearchText,currNode.text);
	}
} // end of fnRunFB()

function fnHideVoteButtons() {
	var t = "";
	t+= "<table class='feedback'><tr><td width='15'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='left' alt='Help Feedback'>"
	t+= "<td><b>Thanks for your feedback!</b></td></tr></table>";
	yes_no_feedback.innerHTML = t;
}

function minimizeHelpWindow() {
  if (qbHHCtrl) {
    qbHHCtrl.Click();
  }
}

function makeFeedbackAndHelpSupportLink( divObj, resourceslink ) {
	var t = "<br><br>";

	// depending on flag, show resources link, link to help and support center.
	// this allows certain topics to omit displaying the link (Easy Step Interview) 
	// mkronber 9-23-2005
	if ( resourceslink == 1 ){
	   t += "<table class='feedback'>";
	   t += "<tr><td width='30' align='right'><a href='javascript:run_qbcommand(\"qbw:informationandsupport\");'  onClick='minimizeHelpWindow();'><img src='" + ICON_HELP_SUPPORT + "' border='0' align='right' alt='Help Support'></a>";
	   t += "<td><a href='javascript:run_qbcommand(\"qbw:informationandsupport\");' onclick='minimizeHelpWindow();'>" + TEXT["helpsupport_linktext"] + "</a><br></table>";
	}

	t += "<IFRAME STYLE='border-width:0px; margin:0px; padding:0px; visibility:hidden; width:1px; height:1px;' name='submitTarget' ></IFRAME>";
  t +="<div id=\"yes_no_feedback\"></div>";
  t +="<div id=\"comment_feedback\"></div>";
	t += "<form name='yesno_feedback_form' method='POST' enctype='text/html' target='submitTarget'>";
	t += "<div id='ui_div'></div>";
	t += "<div id='access_point_div'></div>";
	t += "<div id='feedback_type_div'></div>";
	t += "<div id='product_div'></div>";
	t += "<div id='version_div'></div>";
	t += "<div id='release_div'></div>"
	t += "<div id='sku'></div>";
	t += "<div id='doc_name'></div>";
	t += "<div id='doc_chm'></div>"	;
	t += "<div id='doc_date'></div>";
	t += "<div id='rating'></div>";
	t += "<div id='last_search'></div>";
	t += "</form>";
	divObj.innerHTML = t;

	var s = "";
	s += "<xml 	id='FeedbackInfo' onreadystatechange='fnLoadStateChange()'></xml>";
	s += "<table class='feedback'>";
	s += "<tr><td width='30'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='right' alt='Help Feedback'>";
	s += "<td align='left' border='0'><b>Did this Help topic give you the information you needed?</b>";
	s += "</td></tr></table>";
	s += "<table class='feedback'><tr><td width='30'><td>";
	
	// get CHM name, need to treat FAQHelp_N.CHM different for yes/no buttons because the layout
	// of the dir structure in source control is different. (should fix this) MTK 10-4-1004
	var doc = unescape(document.URL);
	var cut_start = doc.lastIndexOf("\\") + 1;
	var to_colon = doc.lastIndexOf("::");
	var from_colon = doc.lastIndexOf("::") + 2;
	var to_end = doc.lastIndexOf(".html");
	var chm_file = doc.substring(cut_start,to_colon);

	if ( chm_file.toUpperCase() == "FAQHELP_N.CHM" ) {
	s += "<a href='javascript:click_yes();'><img src='/feedback_yes.gif' border='0' alt='Yes'></a>&nbsp;&nbsp;";
	s += "<a href='javascript:click_no();'><img src='/feedback_no.gif' border='0' alt='No'></a>";
	} 
	else {
	s += "<a href='javascript:click_yes();'><img src='../feedback_yes.gif' border='0' alt='Yes'></a>&nbsp;&nbsp;";
	s += "<a href='javascript:click_no();'><img src='../feedback_no.gif' border='0' alt='No'></a>";
	}
	s += "<tr><td width='30'>";
	s += "<td align='left' valign='top' border='0'><font size=-4>Requires an Internet connection.</font>";	
	s += "</td></tr></table><br><br>";
	yes_no_feedback.innerHTML = s;

} // end of makeFeedbackAndHelpSupportLink()

function click_yes (){
	fnLoadAndRunFeedbackInfo(1);
}

function click_no (){
	fnLoadAndRunFeedbackInfo(0);
} // end of click_no

// makeProAdvisorLink function - cluk (01/24/06)
function makeProAdvisorLink(divObj) {
  var text = "<br>";
  text += "<table class='feedback'><tr><td>" + TEXT["pro_advisor_text"] + " ";
  text += "<a href='admin_n.CHM::/crossell_n/task_locate_advisor.html'>find one.</a>";
  text += "</td></tr></table>";
  divObj.innerHTML = text;
} // end of makeProAdvisorLink

// makeCommunityLink function - cluk (01/24/06)
function makeCommunityLink(divObj) {
  var text = "<br>";
  text += "<table class='feedback'><tr><td>" + TEXT["community_text_1"] + " ";
  text += "<img src='" + PATH_PREFIX_IMAGES + "bolt.gif' border='0' alt='Go online' /> ";
  text += "<a href=\"javascript:QBURL('" + divObj.location + "&amp;HideURL=y')\">" + TEXT["community_text_2"] + " " + divObj.description + ".</a>";
  text += "</td></tr></table>";
  divObj.innerHTML = text;
} // end of makeCommunityLink

	/////////////////////////////////////////////////
	//
	// jtaggart 6/22/06
	// fnRunNoFB : Creates a suggestion box if "no" was clicked
	// new for QB2007 R1
	// we will no longer launch the Feedback.CHM file for user feedback
	// params are the values obtained from ACE when the user submitted the yes/no vote
	// we will record the yes/no vote and then create a new form with the suggestion box	
	//
	/////////////////////////////////////////////////

function fnRunNoFB(ui,fb_type,help_doc_chm,help_doc_name,help_subproduct,help_product,help_version,help_release,help_doc_date,help_last_search,submit_url) {

// check params
// alert(ui);
// alert(fb_type);
// alert(help_doc_chm);
// alert(help_doc_name);
// alert(help_subproduct);
// alert(help_product);
// alert(help_version);
// alert(help_release);
// alert(help_doc_date);
// alert(help_last_search);
// alert(submit_url);
	
	// create the HTML for the suggestion box form
	var t = "";
	t += "<IFRAME STYLE='border-width:0px; margin:0px; padding:0px; visibility:hidden; width:1px; height:1px;' name='submitCommentsTarget'></IFRAME>";
	t+= "<form name='comments_feedback_form' method='POST' enctype='text/html' target='submitCommentsTarget'>";
  t += ui; // ui = false since we are not using the sflopp server for the success response
	t += fb_type; // feedback_type
	t += help_version; // version
	t += help_subproduct; // subproduct
	t += help_release; // release
	t += help_product; // product
	t += help_doc_name; // hlp_doc_name
	t += help_doc_chm; // help_doc_chm
	t += help_doc_date; // hlp_doc_date
	t += help_last_search; // hlp_last_search
	t += "<input type='hidden' name='hlp_score' value='0'>"; // help_score:0=no
	t += "<input type='hidden' name='hlp_name' value='novote_followup'>"; // hlp_name	
	t += "<table class='feedback_no'><tr><td width='15'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='left' alt='Help Feedback'>";
	t += "<td><b>How can we make this information more helpful?</b></td></tr>";
	t += "<tr><td width='15'>&nbsp;</td>";
	// QBW042108 7/18/06 because of the windowing model/event handling in Payroll Setup, onKeyUp event is not able to fire in payroll setup.
	// However, PS can only fire onKeyPress event, so adding one more event to handle. But onKeyPress event is fired when the key is pressed, 
	// there is one character off when determine enable/disable Submit button for PS. But the rest of the help feedback in the product works great
	// including ESI and others.
	t += "<td><textarea rows='3' name='text_data' class='feedback_textarea' onkeyup='javascript:feedbackCommentOnKeyUp()' onkeypress='javascript:feedbackCommentOnKeyUp()'></textarea></td></tr>"; // comments_improve: this is the user comments
	t += "<tr><td width='15'>&nbsp;</td>";
	t += "<td align='right'><input type='button' name='comment_submit' value='Submit' class='feedback_button' onclick='SubmitFeedbackComment()' disabled></td></tr>";
	t += "<tr><td width='15'>&nbsp;</td><td align='left' valign='top' border='0'><font size='-4'>Requires an Internet connection.</font></td></tr>";	
	t += "</table>";
	t += "</form>";
	yes_no_feedback.innerHTML = t;
	document.comments_feedback_form.action = submit_url;
} // end of fnRunNoFB()
	
function SubmitFeedbackComment()
{
  document.forms.comments_feedback_form.submit();
  
  document.getElementById("yes_no_feedback").style.display = "none";
  
  var t = "";
  t+= "<table class='feedback'><tr><td width='15'><img src='" + ICON_HELP_FEEDBACK + "' border='0' align='left' alt='Help Feedback'>"
  t+= "<td><b>Thanks for your feedback!</b></td></tr></table>";
  document.getElementById("comment_feedback").innerHTML = t;
}

// ============================================================ \\
// =====         QA FLAG			                      ===== \\
// ============================================================ \\

function feedbackButton(version) {
	//	-1		hide feedback link  NOT USED BY QB
	//	0		shipping product
	//	1		development complete, frozen unless DRAT
	//	2		ownership probably uncertain
	//	3		draft quality, for review
	
   	//	override version passed for shipping
	version = 0;

//		if (version != 0) {
//		var user = 'jeff_taggart';
//		var site = 'intuit.com';
//		var dir = location.href.substring(0, location.href.lastIndexOf('/') + 1);
//		var url = location.href.substring(dir.length, location.href.length + 1);
//		var mailspec = user + '@' + site + '\?subject=\Help topic ' + url;

	var showFeedbackButton = "";

		if (version < 1) {
			showFeedbackButton;
			}
		else {
			showFeedbackButton += '<div>';
			showFeedbackButton += '<p><img src = "../feedback-' + version + '.gif" height="14" width="28" align="right" />';
			showFeedbackButton += '</div><br />';
			document.write(showFeedbackButton);
			}
	}
	
	function feedbackCommentOnKeyUp()
	{
	   if (comments_feedback_form.text_data.value.length > 0)
	   {
        comments_feedback_form.comment_submit.disabled = false;
     }
     else
     {
      comments_feedback_form.comment_submit.disabled = true;
     }
  }

// ============================================================ \\
// =====           ACTIVEX QUICKBOOKS COMMANDS            ===== \\
// ============================================================ \\

function qbcommand ( param ) {
	// This dummy open/close resolves UI locking issue with QB commands that in turn
	// open a dialog. e.g. qbw:check will open a dialog if no bank account exists.
	var w = window.open("","temp_window","width=4,height=1 top=10000 left=10000");
	w.close();
	var ret = xobj.RunQBCommand(param);
}

function qbcommand2 ( param ) {
	// Uses qbks2 command (encodes the URL to make sure no special characters are passed)
	// This dummy open/close resolves UI locking issue with QB commands that in turn
	// open a dialog. e.g. qbw:check will open a dialog if no bank account exists.
	var w = window.open("","temp_window","width=4,height=1 top=10000 left=10000");
	w.close();
	var ret = xobj.RunQBCommand2(param);
}

function run_qbcommand ( param )		{ var ret = xobj.RunQBCommand(param); }
function QBURL ( param )				{ var ret = xobj.OpenURL(param); }
function displaytopic ( param )			{ var ret = xobj.DisplayHTMLHelpTopic(param); }

// ============================================================ \\
// =====           JS CALLABLE LIBRARY                    ===== \\
// ============================================================ \\
// Note: Not available in Lava R1

function checkSKU() {
  window.external.Evaluate('qbSKU');
}
function checkVersion() {
  window.external.Evaluate('qbVersion');
}
function checkPackageName() {
  window.external.Evaluate('qbPackage');
}
function checkRelease() {
  window.external.Evaluate('qbRelease');
}
function checkLastSearch() {
  window.external('qbLastSearch');
}
function checkFilename() {
  window.external.Evaluate('qbFilename');
}
function ShowTopic(HAPID,hapID,strType) {
window.external('HAPID + hapID + strType');
} 
