/* Library of Javascript Functions

/* 
====================================================================================================================
	 backButton()  		Dummy function created to avoid an error when something calls backButton()
====================================================================================================================
*/
function backButton() 
{
  window.history.back() ;
	return ;
}

/* 
====================================================================================================================
	 blankBar() 		Display a blank end bar
====================================================================================================================
*/
function blankBar( c_message ) 
{

	if ( c_message === undefined ) 
	{
	
		if ( history.length > 1 ) { c_message='<a href="javascript: history.back()">Back</a><br>' ; }
		else { c_message="<br>"; }
	}
	
	with ( document )
	{
		write('<span class="t12" style="background-color:#cccc99; border: solid 1px; display:block; text-align:center">');
		write('<br>');
		write( c_message );
		write('<br>');
		write('</span>');
	}
	
	return( "" ); // Return a blank string to document.write()
	
} // end blankBar()

/* 
====================================================================================================================
	continueBar() 	
	 		Description	Formats and Displays the  "Continue to" bar at the bottom of the page.
	 		Arguments		c_Link	string		The URL of the document to open
									c_Title	string		The title of the document
			Returns			A blank string to document.write()
====================================================================================================================
*/
function continueBar( c_link, c_title, l_nosocial ) 
{
	
	if( l_nosocial == null || l_nosocial === undefined ) { l_nosocial = false ; }

	// Show social networking links unless l_nosocial is passed as "true"
	if ( l_nosocial == false ) { 	showSocialNetworkLinks() ; }

	// If the required arguments are not passed, display a blank bar rather than a continue bar.
	if( c_link  == null || c_link  === undefined ) { document.write( blankBar()); return(""); }
	if( c_title == null || c_title === undefined ) { document.write( blankBar()); return("" );}
	
	with ( document )
	{
	
		var c_line = "Continue to <a href=" + c_link + ">" + c_title + "</a>";

		// Start main div
		write('<div id="noprint">');
		write('<center>');		
		// "For More Good Reading" notice //
		write('<span class="t14" >For more good reading, check out the StarCraft Custom Builders\' complete "<a href="articleslist.htm">articles index</a>.');		
		write('<span class="t14" style="background-color:#cccc99; border:solid 1px; display:block; width:100%">');
		write('<br>');
		write(c_line);
		write('<br><br>');
		write('</span>');		
		// Report broken links
		write( '<span class="t12">Are any links on this page broken? Please <a href="contactus">report broken links</a>.</span>' ) ;
		write('</center>') ;
		// End main div
		write('</div>');
	}
	
	return('');

} // end continueBar() 

// ====================================================================================================================
//  Set of functions related to mouse drag
// --------------------------------------------------------------------------------------------------------------------
//  dragMove()				repositions the object whenever the document.mousemove event occurs.
//	dragStart()				Initialize a Drag.  Sets document events to allow a drag operations
//  dragStop()				End a drag.  Resets document event back to their default values.
//
//	A drag is initialized by the onMouseDown event of any container object.  Its position must be absolute or relative.
//  and it must be to the front of all other objects.  Thiese functions do not check that the object is in front, so 
//  either it must already be in front, or the calling routine must place it on top of all other objects in the
//  document.
//
//  The drag is ended by the onMouseUp event of the dragged object.
//  
//  This code modified from an article by Mike Hall at BrainJar.com. http://www.brainjar.com/dhtml/drag/default2.asp
//  -------------------------------------------------------------------------------------------------------------------

// do the dragging (called repeatedly by onMouseMove)

// --------------------------------------------------------------------------------------------------------------------
// Mouse drag the object.  Called repeatedly by mousemove, so this must be FAST.
// --------------------------------------------------------------------------------------------------------------------
//

function dragMove(e)
{

	// Firefox does not like the global var goEvent, so capture the event passed as an arg, or the
	// window.event or the Nav 5 window.Event or, as a last resoort, the globar var and assign it
	// to goEvent.
	//
	//         arg   IE       Nav5     global var
	goEvent = (e || event || Event || goEvent);

	var x, y;

	// Get cursor position with respect to the page.
	if (isIE())
	{
		x = goEvent.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
		y = goEvent.clientY + document.documentElement.scrollTop + document.body.scrollTop;
	}
	else
	{
		with(goEvent)
		{
			x = clientX + window.scrollX;
			y = clientY + window.scrollY;
		}
	}
	// Move drag element by the same amount the cursor has moved.
	with(goDragObj)
	{
		dragNode.style.left = (x + dragStartLeft - cursorStartX) + "px";
		dragNode.style.top = (y + dragStartTop - cursorStartY) + "px";
	}

	// Stop the event flow and cancel any default action for it.
	if (isIE())
	{
		with(goEvent)
		{
			cancelBubble = true;
			returnvalue = false;
		}
	}
	else
	{
		goEvent.preventDefault();
	}

	return ("");

}
// end dragMove()

// --------------------------------------------------------------------------------------------------------------------
// Start a mouse drag.
// --------------------------------------------------------------------------------------------------------------------
//

function dragStart( oEvent, oDragObj )
{
 
 	// Start Validation
	//
	
	// See if the browser is supported
	if ( !isIE() && !isGecko() )
	{
		// Browser not supported
		window.status = "This browser is not supported. Cannot proceed."; 
		return ("");
	}
		
	// If an targett object was passed, set this object to tgoDragObj.  If goDragObj was not passed (null) or is
	// not an object, and the browser is IE, assign window.event.srcElement to goDragObj.  This is available 
	// only in IE.
	//
	// The drag object must be a container objects <div> <table> etc, positioned absolute, fixed or relative, with
	// a z-index high enough that it is on top of all other objects it is likely to pass over.  The z-object level is
	// not checked in this function.
	//
	 
 	if ( oDragObj == null || typeof( oDragObj ) != "object" ) 
	{ 
		if ( isIE() )
		{
			oDragObj = window.event.srcElement ;
		}
	}
	
 	if ( oDragObj == null || typeof( oDragObj ) != "object" ) 
	{
		window.status = "No drag object reference passed. Cannot proceed."; 
		return( "" );
	} 
	
	
	if ( oEvent == null || typeof( oEvent ) != "object" )
	{
		if ( isIE() )
		{
			oEvent = window.event ;
		}
	}
	
	if ( oEvent == null || typeof( oEvent ) != "object" )
	{
		window.status = "No drag event reference passed. Cannot proceed."; 
		return( "" );
	}

	// End Validation
	
	// Start processing
	//
	//var el
 	var x = 0 ;
	var y = 0 ;

	// Assign the drag object argument to the global object.
	//
	// Assign the passed dragObject to the global variable.  Why .dragMode, I don't know, but it works.
	goDragObj.dragNode = oDragObj ;
	
	// Assign the passed event to the global event object.
	goEvent = oEvent ;
	
	 // Get cursor position with respect to the page.
  if ( isIE() ) 
	{
		x = goEvent.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
    y = goEvent.clientY + document.documentElement.scrollTop  + document.body.scrollTop;

  }
  else
	{
		x = goEvent.clientX + window.scrollX;
    y = goEvent.clientY + window.scrollY;
  }
	
  // Save starting positions of cursor and element.
	//
	// For no obvious reason with ( goDragObj ){} does not work here
  goDragObj.cursorStartX = x;
  goDragObj.cursorStartY = y;
  goDragObj.dragStartLeft  = parseInt( goDragObj.dragNode.style.left );
  goDragObj.dragStartTop   = parseInt( goDragObj.dragNode.style.top  );

	// Fall-back assignment in case parseInt() has a problem above
  if ( isNaN(goDragObj.dragStartLeft)) goDragObj.dragStartLeft = 0;
  if ( isNaN(goDragObj.dragStartTop )) goDragObj.dragStartTop  = 0;

	// Add our handler for the mousemove and mouseup events.  Prevent further bubbling or default action.
	addHandler( document, "mousemove", dragMove, true ) ;
	addHandler( document, "mouseup",   dragStop, true ) ;
	
 	return ( "" )
	 ;
} // end dragStart() --------------------------------------------------------------------------------------------------


// --------------------------------------------------------------------------------------------------------------------
// Stop a mouse drag..  Undo any changes to document elements made during the drag operation.
// --------------------------------------------------------------------------------------------------------------------
//
function dragStop()
{
  // Stop capturing mousemove and mouseup events, restore default behavior.
	removeHandler ( document, "mousemove", dragMove, true )
	removeHandler ( document, "mouseout",  dragStop, true )	

	return( "" )
	
} // end dragStop()----------------------------------------------------------------------------------------------------

//
//  End of mouse drag functions
// ====================================================================================================================


// ====================================================================================================================
//
// 	Event Handler Functions.  addHandler(), removeHandler()
//
// addHandler and removeHandler.  Cross-browser event handling for IE5+,  NS6 and Mozilla
//
// addHandler (
//		elmObj			Object					The element object to which the handler is to be added
//		evnType			String					The type of event to handle. Must be passed without the "on", "mouseover" not
//																"onmouseover"
//		evnHandler	Object/Function	The event handler to add.  This can be an object or an inline function.  An inline
//																function cannot be removed except by setting it to null.  								
//		useCapture	Boolean					If true, useCapture indicates that the user wishes to initiate capture. 
//																After initiating capture, all events of the specified type will be dispatched to 
//																the registered listener before being dispatched to any EventTargets beneath it in 
//																the DOM tree. Events which are bubbling upward through the tree will not trigger a
//																listener designated to use capture. Note that this parameter is not optional in all
//																browser versions. If not specified, useCapture is false.
//	)
//
//		return			true if a handler was added, false if it was not.
// --------------------------------------------------------------------------------------------------------------------
function addHandler( elmObj, evnType, evnHandler, useCapture)
{
	var r
	
	// If the element object owns an addEventListener() method (W#C DOM: Moxilla, Netscape, Firefox, IE v9 & after )
 	if (elmObj.addEventListener)
	{
   	elmObj.addEventListener(evnType, evnHandler, useCapture);
   	return true;
 	}
	// If the element object owns an attachEvent() method (MS DOM: IE before v9)
	else if (elmObj.attachEvent)
	{
    r = elmObj.attachEvent("on"+evnType, evnHandler);
    return r;
  }
	// If nothing else works, try brute force.
	else 
	{
		var sEvnType = "on" + evnType ;
		elmObj.sEvnType = evnHandler ;
		return true   ;
  }
	
}	// end addHandler()--------------------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------------------------------------
// removeHandler (
//		elmObj			Object					The element object from which the handler is to be removed
//		evnType			String					The name of the event from which the handler is to be removed.
//		evnHandler	Object/Function	The event handler to remove.
//		useCapture	Boolean					removeEventListener() only.  Specifies whether the handler being removed was
//																registered as a capturing handler or not. If a handler was registered twice, 
//																one with capture and one without, each must be removed separately. Removal of a
//																capturing listener does not affect a non-capturing version of the same listener, 
//																and vice versa.
//
//		return			true if the handler was removed, false if it was not.  Not reliable until WC3 permits checking
//								for the presence of a handler.  At present there is no way to do this.
// --------------------------------------------------------------------------------------------------------------------

function removeHandler(elmObj, evnType, evnHandler, useCapture)
{
	var r
	
	// If the element object owns an removeEventListener() method (W#C DOM: Moxilla, Netscape, Firefox, IE v9 & after )
  if (elmObj.removeEventListener)
	{
    elmObj.removeEventListener(evnType, evnHandler, useCapture);
    return true;
	}	
	// If the element object owns an detachEvent() method (MS DOM: IE before v9)
  else if (elmObj.detachEvent)
	{
    var r = elmObj.detachEvent("on"+evnType, evnHandler);
    return r;
	}
	// If nothing else works, try brute force.
	else 
	{
		var sEvnType = "on" + evnType ;
		elmObj.sEvnType = null ;
		return true ;
  }
	
} // end removeHandler() ----------------------------------------------------------------------------------------------


// --------------------------------------------------------------------------------------------------------------------
// Format and Display the standard "End" bar
// --------------------------------------------------------------------------------------------------------------------
//
function endBar() {

	var c_line = "End";
	
	with ( document )
	{
		write('<div id="noprint">');
		
		// Add whitespace as a seperator
		write('<br><br>');
		
		// Copyright Notice //
		write('<span class="t10" style="display:block; text-align:center">Copyright &copy;');
		write(getThisYear());
		write(' StarCraft Custom Builders, Design/Build Remodelers, Lincoln, Nebraska.  All rights under copyright reserved.');
		write('</span>');
	
	// End Bar //
		write('<div class="t12" style="background-color:#cccc99; border: solid 1px; display:block; text-align:center; width:100%">');
		write('<br>');
		write( "<b>End</b>" );
		write('<br><br>');
		write('</div>'); // End t12 class
	
	// "For More Good Reading" notice //
		write('<span id="noprint" class="t14" style="display:block; text-align:center">For more good reading, check out the StarCraft Custom Builders\' complete "<a href="articleslist.htm">articles index</a>.');

		write('</div>'); // noprint
	}
	
	// Return a blank string //
	return("");
	
} // end endbar() -----------------------------------------------------------------------------------------------------


// --------------------------------------------------------------------------------------------------------------------
// Returns the width of the document body in pixels.  DEPRECATED: This is the same as getViewportWidth()
// --------------------------------------------------------------------------------------------------------------------
//
function getBodyWidth() 
{

	// If IE strict, width is returend in documentElement.clientwidth, if "quirk, in body.client widty and if not IE
	// (Mozilla, Firefox, Navigator ) it is contained in window.innererwidth.  This function returns the first of
	// these values that is valid.
	
	//	     all but Explorer     Explorer 6+ strict                      All other Explourer versions
	return ( window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth );

} // end getBodyWidth()

// --------------------------------------------------------------------------------------------------------------------
// Returns the current date in text format as January 1, 2011
// --------------------------------------------------------------------------------------------------------------------
//
function getCalendarDate() 
{
	var amonths = new Array(13);
		amonths[0]	= "January";
		amonths[1]	= "February";
		amonths[2]	= "March";
		amonths[3]	= "April";
		amonths[4]	= "May";
		amonths[5]	= "June";
		amonths[6]	= "July";
		amonths[7]	= "August";
		amonths[8]	= "September";
		amonths[9]	= "October";
		amonths[10]	= "November";
		amonths[11]	= "December";
	var xtoday	=	new Date();
	var nmonth  = xtoday.getMonth();
	var cmonth	= amonths[nmonth];
	var cday		= xtoday.getDate() - 1;
	var cyear		= xtoday.getFullYear();
	var cdate		= cmonth + " " + cday +', ' + cyear;
	return cdate;

} // end getCalendarDate()

// --------------------------------------------------------------------------------------------------------------------
//	Returns an array containing a reference to all objects on a document with the specified class
 
//	Argimemts
//		searchClass		String	Class name,
//		node					Object	An object with a getElementsByTagName method. 
//		tagName				String (optional) the tag name (for selecting only <tag> elements with specific class). 

//	Returns					An array containing all the elements found of the specified class
		
//	Description			If the tabName is specified, the function gets all alement with that tag name into an array 
//									using getElementsByTag(). If a tagName is not specified, then it searches for any tag name 
//									(i.e. all elements).
//
// Not finished, do not use
function getElementsByClass( searchClass, node, tag ) 
{

	var classElements = new Array();

	if ( node == null )

		node = document;

	if ( tag == null )

		tag = '*';
	try{
		var els = node.getElementsByTagName(tag);
	} 
	catch (err) { 
		alert( node ) ; 
	} 
	var elsLen = els.length;

	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");

	for (i = 0, j = 0; i < elsLen; i++) 
	{

		if ( pattern.test(els[i].className) ) 
		{

			classElements[j] = els[i];

			j++;

		}

	}

	return classElements;

}	// end getElementsByClass() -----------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------------------------------------
//	getStringPixelMetrics()		
//		Arguments		cStr						The string to be tested
//								cContainerID		The ID of the container used in testing.  Must already exist and be fully formatted.
//		Returns			The pixel width and pixel height of a string in an array:
//								a[ 0 ] = width in pixels
//								a[ 1 ] = height in pixels
// --------------------------------------------------------------------------------------------------------------------
//
function getStringPixelMetrics( cStr, cContainerID )
{
	// Use this var to return the results
	var aDims = new Array(2) ;
	
	// The id value of a container object (div, table, etc. ) must be passed as an argument.  If not, exist with
	// a status bar message
	if ( !cContainerID ) { window.status = "getStringPixelDimensions: Container ID not passed as an argument."; return(""); }

	var oContainer = document.getElementById ( cContainerID ) ;
	if ( !oContainer ) { window.status = "getStringPixelMetrics: Container failed to create."; return ( null ); }


	with ( oContainer )
	{
		// Add the string to the container
		innerHTML  = cStr ;
		
		// Return the width and height of the string in pixels in the array aDims[]
		aDims[ 0 ] = clientWidth;
		aDims[ 1 ] = clientHeight;
	}

	return ( aDims )

} //end getStringPixelMetrics( cStr )


//
//---------------------------------------------------------------------------------------------------------------------
//  getStyle()	Returns the setting of a object.style property
//
//		Arguments:		oElmObj			a referece to an object on the document
//									cStyleProp	the name of the style property to get the setting of
//
//		Returns:			the style setting or null if none is found.
//---------------------------------------------------------------------------------------------------------------------
//
function getStyle( oElmObj, cStyleProp )
{

	if ( oElmObj == null ) { return (null) ; }

	var y = null ;
	
	// CurrentStyle is used by IE
	if ( oElmObj.currentStyle )
	{
		var y = oElmObj.currentStyle[ cStyleProp ];
	}
	
	// getComputedStyle() works in Mozilla and Opera
	else if ( window.getComputedStyle )
	{
		var y = document.defaultView.getComputedStyle(oElmObj,null).getPropertyValue( cStyleProp );
	}
	
	return y;

} // end getStyle()


// --------------------------------------------------------------------------------------------------------------------
//	getThisYear()  Returns the current year as a string, i.e. "2011"
// --------------------------------------------------------------------------------------------------------------------
//
function getThisYear() 
{
	var xtoday	=	new Date();
	var cyear		= xtoday.getFullYear();
	return cyear;
	
} //end getThisYear()


// --------------------------------------------------------------------------------------------------------------------
// Function returns the brower's viewport height in pixels
// --------------------------------------------------------------------------------------------------------------------
//
function getViewportHeight()
{

	// If IE strict, height is returend in documentElement.clientheight, if "quirk, in body.clientheight and if not IE
	// (Mozilla, Firefox, Navigator ) it is contained in window.innererheight.  This function returns the first of
	// these values that is valid.
	return ( window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight );
	
} // end getViewportHeight()



// --------------------------------------------------------------------------------------------------------------------
// Function returns the brower's viewport width in pixels
// --------------------------------------------------------------------------------------------------------------------
//
function getViewportWidth()
{

	// If IE strict, width is returend in documentElement.clientwidth, if "quirk, in body.client width and if not IE
	// (Mozilla, Firefox, Navigator ) it is contained in window.innererwidth.  This function returns the first of
	// these values that is valid.
	return ( window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth || 0 );
	
} //end getViewportWidth()

// --------------------------------------------------------------------------------------------------------------------
// Returns the vertical offset from the top of the document to the top of the viewport
// --------------------------------------------------------------------------------------------------------------------
//
function getVerticalOffset()
{
	//       All but Explorer      Explorer 6+ strict                    All other explorer
	return ( window.pageYOffset || document.documentElement.scrolltop || document.body.scrollTop ) ;

} // end getVerticalOffset()


// --------------------------------------------------------------------------------------------------------------------
// Displays a Google Ad Panel below the Top Panel
// --------------------------------------------------------------------------------------------------------------------
//
function googleAdPanel( nwidth, nheight, cAdSlot ) 
{
	
	if ( !googleAds ) { return (""); }
	
	// Test width argument //
	if ( nwidth === undefined ) { google_ad_width   = "360"; } 
	else { google_ad_width = nwidth ; }
	
	// Test height argument //
	if ( nheight === undefined ) { google_ad_height = "280"; }
	else { google_ad_height = nheight ; }
	
	// Test Ad Slot argument -- Ad Slot codes determine which shape ad is being used //
	if ( cAdSlot == undefined ) { google_ad_slot="0518129271"; }
	else { google_ad_slot = cAdSlot ; }
	
	// Display Google Add Panel //
	// Define publisher ID -- We are the publisher
	google_ad_client = "pub-1557579244563846";

	document.write(' <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>');
	
	return ('');
	
} // end googleAdPanel(nwidth,nheight)

// --------------------------------------------------------------------------------------------------------------------
// Displays a message box to replace the native alert()
// --------------------------------------------------------------------------------------------------------------------
// 
function msgBox( cTitle, cMsg )
{

	window.status = "msgBox Entered" ;
	
	// Remove the existing msgBox
	//
	// Only one msgBox can be displayed at one time.  If one already exists, just remove it.
	var oMsgBox = document.getElementById( "msgBox" );
	if ( oMsgBox ) { document.body.removeChild( oMsgBox ); }

	// Create the msgBox object.
	//
	// Create the box as a divider object.  It has not yet been placed on the dorument.
	var oMsgBox = document.createElement( "div" ) ;
	//
  // If the object did not create, exit with message to the status bar.
	if ( !oMsgBox ) { window.status = "MsgBox: Message box did not Create" ; return ( null ) ; }
	
	// We want the msgBox to center on the screen.
	//
	// Set search box height and width
	var nBoxW	= 350 ;
	var nBoxH	=  90 ;
	// Not so tall for IE which automatically adds padding
	if ( isIE() ) { nBoxH = 85; }
	
	// Calculate the box top and left to place the message box in the center of the view port.
	//
	// The top of the box is calculated as an offset from the very top of the document 
	var nTop		= Math.round( ( getViewportHeight() - nBoxH ) /2  ) + getVerticalOffset();
	// Reduce the view port width by 17 to account for scrollbars.  No offset from the
	// left of the document is needed unless the user has enlarged the window over two
	// of more monitors.  If he has done that, too bad.
	var nLeft		= Math.round( ( getViewportWidth()  - nBoxW - 17  ) /2 ) ;
	
	// Set the attributes for the msgBox.
	with ( 	oMsgBox ) 
	{
		setAttribute("class", "t14" );
		//if ( isIE() ) { class = "t14" ; } 
		setAttribute("id", "msgBox" );
		style.backgroundColor = "#6d6360" ; 
		style.border 			= "1px solid white " ;
		style.color				= "white" ;
		style.fontFamily 	= "Arial, Helvetica, sans-serif"
		style.height			= nBoxH + "px" 
		style.left				= nLeft + "px" ;
		style.position 		= "absolute" ;
		style.textAlign		= "left" ;
		style.top					= nTop + "px";
		style.width				= nBoxW + "px" ;
		style.visibility  = "visible" ;
		style.zIndex			= 10000 ;
	}
	
	window.status = "Message box created" ;
	
	// Add the msgBox to the document.body.
	document.body.appendChild( oMsgBox );
	
	// Test for msgBox actually added to the document
	var oMsgBoxTest = document.getElementById( "msgBox" );
	if ( oMsgBoxTest ) { window.status = "Message box appended" ; }
	// End of msgBox ===============================================
	
	// Add the msgTitlebar
	// Create the title bar as a divider object.  It has not yet been placed on the document.
	var oMsgTitleBar = document.createElement( "div" ) ;
	//
  // If the object did not create, exit with message to the status bar.
	if ( !oMsgTitleBar ) { return ( "MsgBox: Title bar did not Create" ) ; }

	// Set the attributes for the titleBar.  Most will be inherited from oMsgBox
	with ( 	oMsgTitleBar ) 
	{
		setAttribute("id", "titleBar" );
		
		style.borderBottom = "1px solid white " ;
		style.fontWeight	= "bolder" ;
		style.height			= "2.2em" ; 
		style.left				= "0px" ;
		style.position 		= "relative" ;
		style.textAlign		= "center" ;
		style.top					= "0px" ;
		style.width				= "auto" ;
		style.verticalAlign = "middle" ;
		style.visibility  = "visible" ;
		
		innerHTML = cTitle ;
	}
	
	window.status = "Title bar created" ;
	
	// Add the titleBar to the MsgBox.
	oMsgBox.appendChild( oMsgTitleBar );

	// Test for titleBar actually added to the document
	var oMsgTitleBarTest = document.getElementById( "titleBar" );
	if ( oMsgTitleBarTest ) { window.status = "Title bar appended" ; }
	// End of titleBar ==============================

	// Add the msgCloseBtn to titleBar
	//
	// Create msgCloseBtn as a divider object.  It has not yet been placed on the document.
	var oMsgCloseBtn = document.createElement( "div" ) ;
	//
  // If the object did not create, exit with message to the status bar.
	if ( !oMsgCloseBtn ) { return ( "MsgBox: Close Button did not Create" ) ; }
	
	// Set the attributes for the msgCloseBtn.  Most will be inherited from oMsgBox or oTitleBar
	with ( 	oMsgCloseBtn ) 
	{
		setAttribute("id", "msgCloseBtn" );
		
		style.cursor			= "pointer" ;
		style.fontFamily 	= "arial, helvetica, sans-serif"
		style.fontSize		= "1.5em" ;
		style.fontWeight	= "bold" ;
		style.height			= "2.2em" ; 
		style.left				= "5px" ;
		style.lineHeight	= "2em" ;
		style.position 		= "absolute" ;
		style.textAlign		= "left" ;
		style.top					= "-10px" ;
		style.width				= "1em" ;
		style.verticalAlign = "middle" ;
		style.visibility  = "visible" ;
		
		innerHTML 		= "X" ;
		
	} // endwith ( oMsgCloseBtn )
	
	window.status = "TClose button created" ;
		
	// Add the msgCloseBtn to the titleBar.
	oMsgTitleBar.appendChild( oMsgCloseBtn );
	//
	// Test for msgCloseBtn actually added to the titleBar
	var oMsgCloseBtnTest = document.getElementById( "msgCloseBtn" );
	if ( oMsgCloseBtnTest ) 
	{ 
		window.status = "Close button appended" ;
		
		// Add events to the button.  Events cannot be added until the element is added to the document
		var mouseoverStr = 'function movr { ( document.getElementById( "msgCloseBtn") ).style.color = "yellow" } '
		addHandler( oMsgCloseBtnTest, "mouseover", function movr() { ( document.getElementById( "msgCloseBtn") ).style.color = "yellow" } , true );
		var mouseoutStr	 = 'function mout { ( document.getElementById( "msgCloseBtn") ).style.color = "white" } '
		addHandler( oMsgCloseBtnTest, "mouseout",  function mout() { ( document.getElementById( "msgCloseBtn") ).style.color = "white" }, true );
		var clickStr     = 'function mclk { ( document.removeChild( document.getElementById( "msgBox"))) }'
		addHandler( oMsgCloseBtnTest, "click", function mclk() { document.body.removeChild( document.getElementById( "msgBox")) }, true ); 
	}
	// End of msgCloseBtn ============================

	// Add the msgBody element to msgBox
	// Create the message body as a divider object.  It has not yet been placed on the document.
	var oMsgBody = document.createElement( "div" ) ;
	//
  // If the object did not create, exit with message to the status bar.
	if ( !oMsgBody ) { window.status = "MsgBox: Message body did not Create" ; return ( null ) ; }

	// Set the attributes for the MsgBody.  Most will be inherited from oMsgBox
	with ( 	oMsgBody ) 
	{
		setAttribute("id", "msgBody" );
		
		style.height			= "auto" ; 
		style.left				= "0px" ;
		style.margin			= "10px" ;
		style.textAlign		= "left" ;
		style.width				= "auto" ;
		style.visibility  = "visible" ;
		
		innerHTML = cMsg ;
	}

	window.status = "Message Body created" ;

		// Add the msgBody to the msgBox.
	oMsgBox.appendChild( oMsgBody );
	
	//
	// Test for msgBody actually added to the msgBox
	var oMsgBodyTest = document.getElementById( "msgBody" );
	if ( oMsgBodyTest ) { window.status = "Message body appended" ; }
	// End of msgBody =========================================

	//
	// Return a blank string
	return ( "" );
	
} // end msgBox()	

//
// --------------------------------------------------------------------------------------------------------------------
// function hideSearchItemOverlay()
//
//		Arguments			None
//		Description		Hides the searhOvl div by setting visibility to "hidden"
//    Called by			onmouseout of each search term column.
//
// function showSearchItemOverlay( oDiv, lShow )
//
// 		Arguments
//				oDiv			Object reference to the search term item division that triggered this display, i.e.
//						  		onmouseover="showSearchItemOverlay( this, true )"
//				lShow			If true, display the overlay, if false, hide it.
//		
//		Description: 	Displays an overlay div on top of search term column items that allows the entire search term to be
//									viewed.  The  actual overlay div is created in showSearchTermListColumns() and is initially hidden.
//									It is displayed when  triggered by the onmouseover event of any search term, and hidden on the
//									onmouseout event.
// --------------------------------------------------------------------------------------------------------------------
//
function hideSearchItemOverlay()
{
	// If the overlay div cannot be found, just exit.
	var oSearchOvl = document.getElementById( "searchOvl" ) ;
	if ( !oSearchOvl ) { return false ; }
			
	with ( oSearchOvl )
	{
		innerHTML        = "" ;
		style.display = "none" ;
	}
	
	return
		
} // end hideSearchItemOverlay()

function showSearchItemOverlay( oSrchItem )
{
	
	// If the overlay div cannot be found, just exist.
	var oSearchOvl = document.getElementById( "searchOvl" ) ;
	if ( !oSearchOvl ) { return false ; }
	
	// If a reference to the search bar item div was not passed, there is nothing to do.  Just exit.
	if ( oSrchItem == null ) { return false; }

	// Copy the string inside the search item.  This will be transferred to oSearchOvl
	var cStr = oSrchItem.innerHTML;
		
	var nTop	= oSrchItem.offsetTop  + oSrchItem.parentNode.offsetTop  ;
	var nLeft	= oSrchItem.offsetLeft + oSrchItem.parentNode.offsetLeft ;
	
	with ( oSearchOvl )
	{
		//parentNode.style.overflow = "visible" ;
		style.display			= "inline" ;
		style.left				= nLeft + "px";
		style.top					= nTop + "px" ;
		//style.visibility  = "visible" ;
		style.width				= "200px" ;
		innerHTML					= cStr ;
	}
	
	// Add the event handler that displays the searchbox
	addHandler( oSearchOvl, "click", showSearchBox, true )
	
	return true ;

} // end  showSearchItemOverlay()--------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------------------------------------
// showSearchBox()	Displays a floating popup search box.  Triggered as an event of searchOvl.
//		Arguments:		e		The event that triggered the function (in Mozilla and later versions of IE)
//		Returns				true if the box is displayed, otherwise false.
// --------------------------------------------------------------------------------------------------------------------
//
function showSearchBox( e )
{
	// See if the div "searchBox" exists.  If so, get a reference to the div object.
	var oSearchBox = document.getElementById( "searchBox" ) ;
	
	if ( !oSearchBox ) { 	return ( false ); }
	
	// See if the search text object is in the document.  If so, get a reference.
	// searchText is a text input control on oSearchBox.
	var oSearchText = document.getElementById( "searchText" ) ;

	// Search text object does not exist, exit with false
	if ( !oSearchText )  { return ( false ); }
	
	// Get the text to be searched on from the innerHTML of the searchOvl.  A reference to the searchOvL object is
	// contained in e.target.
	var cSearchText = ""
	// If this is IE, there may be no argument e, so get the event from window.event for IE or Event for Nav5
	e = ( e || event || Event );
	// For Mozilla
	if ( e.target ) { cSearchText = cSearchText = e.target.innerHTML; }
	// For IE
	else if (e.srcElement) { cSearchText = e.srcElement.innerHTML ; }
	
	// Set search box height and width
	var nBoxW	= 350 ;
	var nBoxH	=  90 ;
	// Not so tall for IE which automatically adds padding
	if ( isIE() ) { nBoxH = 85; }
	
	// Calculate the box top and left to pace the search box in the center of the view port.
	//
	// The top of the box is calculated as an offset from the very top of the document 
	var nTop	= Math.round( ( getViewportHeight() - nBoxH ) /2  ) + getVerticalOffset();
	// Reduce the viewport width by 17 to account for scrollbars.  No offset from the
	// left of the document is needed unless the user has enlarged the window over two
	// of more monitors.  If he has done that, too bad.
	var nLeft	= Math.round( ( getViewportWidth()  - nBoxW - 17  ) /2 ) ;
	
	// The searchBox <div> was innstantiated as invisible.  Position it on the screen and make it visible.
	with ( oSearchBox )
	{
		if ( style.display != "inline" )
		{
			style.display			= "inline" ;
			style.top					= nTop + "px" ;
			style.left				= nLeft + "px" ;
			style.height			= "auto" ;
			style.visibility	= "visible" ;
			style.width				= nBoxW + "px" ;
		}
		
	} // endwith ( oDiv )
	
	// Insert the search text as the value of the search text box
	oSearchText.value = cSearchText;
	
	return( true );
	
} // end showSearchBox( nBoxH, nBoxW )

//---------------------------------------------------------------------------------------------------------------------
//showSocialNetworkLinks()	Display a row of social networking widgets that link to social networking sites
//		Arguments							None
//---------------------------------------------------------------------------------------------------------------------
//
function showSocialNetworkLinks()
{
	with (document )
	{
		write('<div align="center">');
		write('<img src="images/sharethisarticle.png" alt="Share this article with friends..." style="position:absolute; margin-left:-40px; margin-top:-40px; z-index:-10;">');

		// e-Mail
		write('<a rel="nofollow" target="_blank" href="mailto:?subject=Take a look at <i>The Deck Handbook: Composite and Plastic Decks</i>" title="Send an e-mail about this article.">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat 0px 0px; display:inline-block; width: 32px; height: 32px;" /></span></a>');
		
		// Twitter
		write('<a rel="nofollow"  target="_blank"  href="http://twitter.com/home?status=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20%20-%20http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F" title="Twitter">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -32px 0px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Facebook
		write('<a rel="nofollow"  target="_blank" href="http://www.facebook.com/share.php?u=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;t=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20" title="Facebook">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -64px 0px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//delicio
		write('<a rel="nofollow"  target="_blank" href="http://delicious.com/post?url=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20&amp;notes=%20%20%20%0D%0A%0D%0AInterested%20in%20sharing%20your%20B2B%20content%20on%20Facebook%2C%20Twitter%2C%20LinkedIn%20or%20delicious%3F%20Do%20multi-option%20social%20media%20sharing%20tools%20such%20as%20ShareThis%20seem%20like%20overkill%3F%0D%0A%0D%0AThat%20was%20our%20conclusion%20after%20researching%20the%20social%20media%20sites%20on%20which%20r" title="del.icio.us">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -96px 0px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Linkedin
		write('<a rel="nofollow"  target="_blank" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20&amp;source=B2B+Online+Marketing+-+Business.com+&amp;summary=%20%20%20%0D%0A%0D%0AInterested%20in%20sharing%20your%20B2B%20content%20on%20Facebook%2C%20Twitter%2C%20LinkedIn%20or%20delicious%3F%20Do%20multi-option%20social%20media%20sharing%20tools%20such%20as%20ShareThis%20seem%20like%20overkill%3F%0D%0A%0D%0AThat%20was%20our%20conclusion%20after%20researching%20the%20social%20media%20sites%20on%20which%20r" title="LinkedIn">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat 0px -32px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//stumbledupon 
		write('<a rel="nofollow"  target="_blank" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20" title="StumbleUpon">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -32px -32px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Digg
		write('<a rel="nofollow"  target="_blank" href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20&amp;bodytext=%20%20%20%0D%0A%0D%0AInterested%20in%20sharing%20your%20B2B%20content%20on%20Facebook%2C%20Twitter%2C%20LinkedIn%20or%20delicious%3F%20Do%20multi-option%20social%20media%20sharing%20tools%20such%20as%20ShareThis%20seem%20like%20overkill%3F%0D%0A%0D%0AThat%20was%20our%20conclusion%20after%20researching%20the%20social%20media%20sites%20on%20which%20r" title="Digg">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -64px -32px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Reddit
		write('<a rel="nofollow"  target="_blank" href="http://reddit.com/submit?url=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20" title="Reddit">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -96px -32px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Yahoo Buzz
		write('<a rel="nofollow"  target="_blank" href="http://buzz.yahoo.com/submit/?submitUrl=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;submitHeadline=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20&amp;submitSummary=%20%20%20%0D%0A%0D%0AInterested%20in%20sharing%20your%20B2B%20content%20on%20Facebook%2C%20Twitter%2C%20LinkedIn%20or%20delicious%3F%20Do%20multi-option%20social%20media%20sharing%20tools%20such%20as%20ShareThis%20seem%20like%20overkill%3F%0D%0A%0D%0AThat%20was%20our%20conclusion%20after%20researching%20the%20social%20media%20sites%20on%20which%20r&amp;submitCategory=science&amp;submitAssetType=text" title="Yahoo! Buzz">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat 0px -64px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		//Technorati
		write('<a rel="nofollow"  target="_blank" href="http://technorati.com/faves?add=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F" title="Technorati">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -32px -64px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		// Sphinn
		write('<a rel="nofollow"  target="_blank" href="http://sphinn.com/index.php?c=post&amp;m=submit&amp;link=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F" title="Sphinn">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -64px -64px; display:inline-block; width: 32px; height: 32px;" /></span></a>');

		// Google Bookmark
		write('<a rel="nofollow"  target="_blank" href="http://www.google.com/bookmarks/mark?op=edit&amp;bkmk=http%3A%2F%2Fblogs.business.com%2Fb2b-online-marketing%2F2009%2Fcreate-share-buttons%2F&amp;title=Code%20to%20Create%20Custom%20Share%20Buttons%20for%20Facebook%2C%20Twitter%2C%20LinkedIn%20%26%20Delicious%20&amp;annotation=%20%20%20%0D%0A%0D%0AInterested%20in%20sharing%20your%20B2B%20content%20on%20Facebook%2C%20Twitter%2C%20LinkedIn%20or%20delicious%3F%20Do%20multi-option%20social%20media%20sharing%20tools%20such%20as%20ShareThis%20seem%20like%20overkill%3F%0D%0A%0D%0AThat%20was%20our%20conclusion%20after%20researching%20the%20social%20media%20sites%20on%20which%20r" title="Google Bookmarks">');
		write('<span style="background:url(\'images/socialwidgets.png\') no-repeat -96px -64px; display:inline-block; width: 32px; height: 32px;" /></span></a>');
		write('</div>');
	
	}
	
} // End of showSocialNetworkLinks()

// --------------------------------------------------------------------------------------------------------------------
// showRating()  	Display the a reader rating for this article.  
//		Arguments:	nPct			The % of readers who rated the article helpful or very helpful
// --------------------------------------------------------------------------------------------------------------------
//
function showRating( nPct )
{
	// Test for variables passed
	if ( nPct === undefined ) { return("") ; }
	
	// Display the rating
	with ( document )
	{
				
		write( '<div id="noprint" align="center" style="background-color:#6B4129; color:#ffcc99; font-weight:bold; margin-right:-5px; margin-left:-5px;">');
		/* Facebook Link.  showFacebook is in default.js
		write( '<div align="right" style="background:ivory; align:right; margin-right:-10px; width:200px">' );
		write( showFacebook() );
		write( '</div>' ) ;
		// End Facebook*/
		write( '<span class="t14"><br>' + nPct + '% of readers rating this article found it "helpful" or "very helpful."<br> Please send us your rating and comments below. Thank you.<br><br></span>') ;
		write( '</div>') ;
		write('<div id="noprint" align="center" class="t12">For more good reading, check our complete <a href="articleslist.htm">Articles Index</a>.</div>');
	}
	return ("") ;
} // End function showRating

// --------------------------------------------------------------------------------------------------------------------
// Formats and displays text describing the services provided by StarCraft
// --------------------------------------------------------------------------------------------------------------------
//
function whoWeAre()
{
	with ( document )
	{
		// Add blank lines for mozilla browsers
		if ( isGecko() ) { write( "<br><br>" ) ; }
		
		// Outside div
		write(' <div id = "whoweareOutside" > ');
	
		write( '<center>' );
		write('<div class="h4du" style="line-height: 2em; text-align:center; vertical-align:middle">About StarCraft Custom Builders </div>');
		write(' <br> ');
		write('<span class="t20"><span class="greentext" style="padding:15px"><b>Preserving the Past, Building the Future, Since 1996.</b></span></span>' );
		write( '</center>' );
		write(' <br> ');

		// Inside div
		write( '<div class="t14" style="text-align:left" >');

		write( 'StarCraft Custom Builders is a design/build remodeling company located in Lincoln, Nebraska, serving Lincoln, Omaha, Bellevue, Papillion, Seward, Beatrice, Wahoo, and Fremont, Nebraska.  We specialize in heritage homes &mdash;  generally, homes built before 1970 &mdash; including Victorian, Arts & Crafts, Bungalow, Craftsman, Prairie and post-war modern retro houses.  We emphasize remodeling to conform to the architectural period of the home. Over the years we have become the experts at building heritage bathrooms and kitchens, with all the modern conveniences, into the small spaces typical of older homes. ') ;
		write(' <br><br> '); 
		write( 'We also design and build <a href="deck.handbook.htm">decks and porches</a>, <a href = "garage.htm">garages and outbuildings</a>, and <a href = "addition1.htm">home additions</a>.  Our interior <a href = "designbuilder.htm">design/build</a> team can help you with the interior remodeling of any room in your home, including walls, <a href = "porcelain.or.ceramic.htm">ceramic and porcelain tile</a>, <a href = "nebraska.woods.htm">hardwood</a> flooring, painting and finishing, or renovation of any kind.  Need to remove a load-bearing wall to enlarge a room?  We can do that.  We can also work with you to update the outside of your home whether it needs siding, roofing, <a href = "windows.htm">windows</a>, doors, gutters or all of the above. Our designers are very skilled at matching exterior renovations to the <a href = "Architectural.Styles.htm">historic period</a> of your old home.');                                                     
		write(' <br><br> ');
		write('Our <a href="design.process.htm">Design Service</a> features the very latest architectural CAD software that allows us to plan your project and show you in full-color, photo-realistic images what it will look like when it is finished.  You can view it from any angle, get a detailed look at any feature, and examine it from every imaginable perspective to make sure you love it before we build it.');
		write(' <br><br> ');
		write('Our <a href="construction.process.htm">Construction Management Service</a> relieves you of the worries of supervising and managing a complex remodeling project and places the responsibility and the risk where it ought to be &mdash; in the hands of trained and experienced professionals.' );
		write(' <br><br> ');
		write(' We stand behind our workmanship with a written three-year limited <a href="warranties.htm"> warranty</a>, the longest in our business, and three times longer than our competition.  If any of our work is defective in any way we will remedy the problem quickly, and at no cost to you.' ) ;
  	write(' <br><br> ');
		write('For any remodeling or renovation need, big or small, StarCraft Custom Builders if the first choice of seasoned professionals in south-east Nebraska.  Find out why, and what we can do for you.  <a href="contactus.htm">Contact us</a> at your convenience.' );

		// Inside div close
		write( '</div>');

		// Outside div close
		write('</<div>');
		
	} // endwith( document )		

	return("");
	
} // end ( whoWeAre )

//--------------------------------------------------------------------------------
//Debugging tools
//--------------------------------------------------------------------------------

//--------------------------------------------------------------------------------
// Displays the properties of the object passed as an argument.  Used for debugging
//--------------------------------------------------------------------------------
function dumpProps( oObj, n ) 
{
	
	var noRecurs = false ;
	var cIndent = "" ;
	
	if ( n == null || n <= 0 ) { noRecurs = true }
	else
	{
		for ( i=0; i=n; i++ )
		{
		cIndent = cIndent + ( "&nbsp;" ) ;
		}
	}
	
	var msg = ""
	
  // Go through all the properties of the passed-in object 
  for (var i in oObj) 
	{
    // if a parent (2nd parameter) was passed in, then use that to 
    // build the message. Message includes i (the object's property name) 
    // then the object's property value on a new line 
    var msg = msg + i + ": " + oObj[i] + "\n";
						
    // If this property (i) is an object, then recursively process the object 
    if (typeof oObj[i] == "object" && noRecurs == false ) 
		{
				 n = n + 2;
         dumpProps( oObj[i], n ); 
				 n = Math.max( 2, n-2 ) ;
		}
			
	} // endfor (var i in oObj)
	 
	// Display the message. If the user clicks "OK", then continue. If they 
	// click "CANCEL" then quit this level of recursion 
  if (!confirm(msg)) { return; }

	return "" 
	 
}  // end dumpProps(oObj, oParentNode) 

