//=======================================================================================================
// Globals.js
//
// Defines the Globals class that holds various global variables we'll need and declares an object called
// "Globals" that is of the Globals data type.  It also defines various functions that I find useful.
//
// Chris Bartley
// HealthStream
// cpb@healthstream.com
// February 18, 1999
//
// Prerequisites: none
//=======================================================================================================

// create the global variables object that rules the current document
var Globals = new Globals();

//=======================================================================================================
// Globals()
//
// Initializes the Globals object.  To create an instance of a Globals object, use code similar to this:
//
//    <script src="Globals.js" type="text/javascript" language="JavaScript"></script>
//
// The above code declares an object (of type "Globals") called Globals that you may then use in later code.
// For example:
//
//    <script type="text/javascript" language="JavaScript">
//    <!--
//    // will show the current debugging state in an alert box
//    alert(Globals.IsDebuggingOn());
//    //-->
//    </script>
//
// Note that you do NOT need to declare the "Globals" object--it is done for you simply by including the Globals.js file.
//
// Public Properties
//
//    [none, to prevent accidental tampering with Global values]
//
// Public Methods
//
//    Method                   Returned Data Type     Description
//    ------                   ------------------     -----------
//    IsDebuggingOn()          boolean                returns true if debugging is on, false if not
//    SwitchDebugState()       boolean                switches the current debugging state to the opposite state, returns new debugging state (true if debugging on, false if it's off)
//    TurnDebugOn()                                   turns on debugging and opens the debugging window
//    TurnDebugOff()                                  turns off debugging and closes the debugging window
//    IsNS()                   boolean                returns a boolean indiciating whether the user's browser is a Netscape browser
//    IsIE()                   boolean                returns a boolean indiciating whether the user's browser is a Microsoft browser
//    IsMac()                  boolean                returns a boolean indiciating whether user's machine is running MacOS
//    IsWin()                  boolean                returns a boolean indiciating whether user's machine is running Windows
//    BrowserVersion()         string                 returns a string indicating the full version number of the user's brower
//    BrowserVersionMajor()    string                 returns a string indicating the major version number of the user's brower (everything to the left of the decimal)
//    BrowserVersionMinor()    string                 returns a string indicating the minor version number of the user's brower (everything to the right of the decimal)
//    Platform()               string                 returns a string indicating the platform the user is on
//    Coll()                   string                 returns a string used to make cross-browser code easier to write
//    StyleObj()               string                 returns a string used to make cross-browser code easier to write
//    ContentAreaWidth([win])  integer                returns an integer indicating the width of the content area of the calling code or of the given content area win (i.e. browser window or frame)
//    ContentAreaHeight([win]) integer                returns an integer indicating the height of the content area of the calling code or of the given content area win (i.e. browser window or frame)
//    Globals_HandleResize()                          helps fix Netscape's stupid onResize bug.  It puts positioned elements back in place by reloading the page.
//
//=======================================================================================================
// Functions
//
//    CPBParseInt(numStr)      string                 Essentially the same as Math.ParseInt, but it returns 0 instead of NaN if given a null value
//    ViewSource()                                    Displays the source of the current page
//
//=======================================================================================================
function Globals()
	{
	var pos;																	// used in determining the browser's minor version number

	// ------------------ Public Properties ----------------------------------------
	//
	// There are NO public properties for this class.  All access must be via the public methods.  This is to prevent accidental tampering with Global values.
	
	// ------------------ Private Properties ---------------------------------------
	this.b_debug = false;												// whether debugging is on
	this.b_IsNS = false;													// whether this is a Netscape browser
	this.b_IsIE = false;													// whether this is a Microsoft browser
	this.b_IsMac = false;												// whether user's machine is running MacOS
	this.b_IsWin = false;												// whether user's machine is running Windows
	this.b_IsOther = false;												// whether user's machine is running MacOS or Windows
	this.s_BrowserVersion = "0";										// full version number of the user's brower
	this.s_BrowserVersionMajor = "0";								// major version number of the user's brower (everything to the left of the decimal)
	this.s_BrowserVersionMinor = "0";								// minor version number of the user's brower (everything to the right of the decimal)
	this.s_Platform = "";												// the platform the user is on
	this.s_Coll = "";														// used in making cross-browser code easier to write
	this.s_StyleObj = "";												// used in making cross-browser code easier to write
	this.o_DebuggingWindow = null;									// handle to the debugging window
	this.i_WindowWidth = null;									      // used by Globals_HandleResize to fix the Netscape resize bug
	this.i_WindowHeight = null;									   // used by Globals_HandleResize to fix the Netscape resize bug
	
	// ------------------ Public Methods -------------------------------------------
	this.IsDebuggingOn = Globals_IsDebuggingOn;					// returns current debugging state
	this.SwitchDebugState = Globals_SwitchDebugState;			// switches the current debugging state to the opposite state
	this.TurnDebugOn = Globals_TurnDebugOn;						// turns on debugging and opens the debugging window
	this.TurnDebugOff = Globals_TurnDebugOff;						// turns off debugging and closes the debugging window	
	this.IsNS = Globals_IsNS;											// returns a boolean indiciating whether the user's browser is a Netscape browser
	this.IsIE = Globals_IsIE;											// returns a boolean indiciating whether the user's browser is a Microsoft browser
	this.IsMac = Globals_IsMac;										// returns a boolean indiciating whether the user's machine is running MacOS
	this.IsWin = Globals_IsWin;										// returns a boolean indiciating whether the user's machine is running Windows
	this.BrowserVersion = Globals_BrowserVersion;				// returns a string indicating the full version number of the user's brower
	this.BrowserVersionMajor = Globals_BrowserVersionMajor;	// returns a string indicating the major version number of the user's brower (everything to the left of the decimal)
	this.BrowserVersionMinor = Globals_BrowserVersionMinor;	// returns a string indicating the minor version number of the user's brower (everything to the right of the decimal)
	this.Platform = Globals_Platform;								// returns a string indicating the platform the user is on
	this.Coll = Globals_Coll;											// returns a string used to make cross-browser code easier to write
	this.StyleObj = Globals_StyleObj;								// returns a string used to make cross-browser code easier to write
	this.ContentAreaWidth = Globals_ContentAreaWidth;			// returns an integer indicating the width of the content area of the calling code or of the given content area (i.e. browser window or frame)
	this.ContentAreaHeight = Globals_ContentAreaHeight;		// returns an integer indicating the height of the content area of the calling code or of the given content area (i.e. browser window or frame)
	this.HandleResize = Globals_HandleResize;		            // helps fix Netscape's stupid onResize bug.  It puts positioned elements back in place by reloading the page.

	// ------------------ Object Initialization ------------------------------------
	// Detect the browser, and then set browser-detection globals appropriately.
	if (navigator.appName)
		{
		this.b_IsNS = (navigator.appName == "Netscape");									// set to true if this is a Netscape browser
		this.b_IsIE = (navigator.appName == "Microsoft Internet Explorer");			// set to true if this is a Microsoft browser
		}

	// set the version numbers
	if (navigator.appVersion)
		{
		this.s_BrowserVersion =  parseFloat(navigator.appVersion).toString(10);		// get the full browser version
		this.s_BrowserVersionMajor = parseInt(navigator.appVersion).toString(10);	// extract the major browser version
		pos = this.s_BrowserVersion.indexOf(".");
		if (pos != -1)
			{
			this.s_BrowserVersionMinor = this.s_BrowserVersion.substring(pos+1);		// extract the minor browser version
			}
		}

	// set the platform
	if (navigator.platform)
		{
		this.b_IsMac = (navigator.platform.indexOf("Mac") != -1);						// set to true if the user's machine is running MacOS
		this.b_IsWin = (navigator.platform.indexOf("Win") != -1);						// set to true if the user's machine is running Windows

		if (this.b_IsMac)
			this.s_Platform = 'Mac';
		else if (this.b_IsWin)
			this.s_Platform = 'Win';
		else
			this.s_Platform = '???';
		}
		
	// define these differently for IE4 and higher to make cross-browser code easier to write
	if ((this.s_BrowserVersion >= 4) && (this.b_IsIE))
		{
		this.s_Coll = "all.";
		this.s_StyleObj = ".style";
		}
	
	// If Netscape, get the content area width and height for Globals_HandleResize().  IE doesn't need it.
	if (this.b_IsNS)
		{
		this.i_WindowWidth = window.innerWidth;
		this.i_WindowHeight = window.innerHeight;
		}
	}
//=======================================================================================================
// Globals_IsDebuggingOn()
//
// Returns true if debugging is on, false if not
//
// Inputs:  none
// Outputs: boolean that is true if debugging is on, false if it is off
//-------------------------------------------------------------------------------------------------------
function Globals_IsDebuggingOn()
	{
	return this.b_debug;
	}
//=======================================================================================================
// Globals_SwitchDebugState()
//
// Switches the current debugging state to the other state.  If debugging is on, this method will turn
// it off.  If debugging is off, this method will turn it on.
//
// Inputs:  none
// Outputs: boolean representing the new debugging state (true if debugging is on, false if it is off)
//-------------------------------------------------------------------------------------------------------
function Globals_SwitchDebugState()
	{
	if (this.b_debug)
		{
		this.TurnDebugOff();
		}
	else
		{
		this.TurnDebugOn();
		}
	return Globals_IsDebuggingOn(); 
	}
//=======================================================================================================
// Globals_TurnDebugOn()
//
// Turns on debugging, and opens the debugging window.
//
// Inputs:  none
// Outputs: none
//-------------------------------------------------------------------------------------------------------
function Globals_TurnDebugOn()
	{
	this.b_debug = true;
	this.o_DebuggingWindow = window.open("Debugger.html","debugWindow","toolbar=yes,width=550,height=450,toolbar=no,directories=no,status=yes,scrollbars=yes,resizable=yes,menubar=yes");
	}
//=======================================================================================================
// Globals_TurnDebugOff()
//
// Turns off debugging, and closes the debugging window.
//
// Inputs:  none
// Outputs: none
//-------------------------------------------------------------------------------------------------------
function Globals_TurnDebugOff()
	{
	this.b_debug = false;
	if (this.o_DebuggingWindow)
		{
		this.o_DebuggingWindow.close();
		this.o_DebuggingWindow = null;
		}
	}
//=======================================================================================================
// Globals_IsNS()
//
// Returns a boolean indiciating whether the user's browser is a Netscape browser.
//
// Inputs:  none
// Outputs: Boolean (true if the user's browser is a Netscape browser, false if not)
//-------------------------------------------------------------------------------------------------------
function Globals_IsNS()
	{
	return this.b_IsNS;
	}
//=======================================================================================================
// Globals_IsIE()
//
// Returns a boolean indiciating whether the user's browser is a Microsoft browser.
//
// Inputs:  none
// Outputs: Boolean (true if the user's browser is a Microsoft browser, false if not)
//-------------------------------------------------------------------------------------------------------
function Globals_IsIE()
	{
	return this.b_IsIE;
	}
//=======================================================================================================
// Globals_IsMac()
//
// Returns a boolean indiciating whether the user's machine is running MacOS
//
// Inputs:  none
// Outputs: Boolean (true if the user's machine is running MacOS, false if not)
//-------------------------------------------------------------------------------------------------------
function Globals_IsMac()
	{
	return this.b_IsMac;
	}
//=======================================================================================================
// Globals_IsWin()
//
// Returns a boolean indiciating whether the user's machine is running Windows
//
// Inputs:  none
// Outputs: Boolean (true if the user's machine is running Windows, false if not)
//-------------------------------------------------------------------------------------------------------
function Globals_IsWin()
	{
	return this.b_IsWin;
	}
//=======================================================================================================
// Globals_BrowserVersion()
//
// Returns a string indicating the full version number of the user's brower
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_BrowserVersion()
	{
	return this.s_BrowserVersion;
	}
//=======================================================================================================
// Globals_BrowserVersionMajor()
//
// Returns a string indicating the major version number of the user's brower (everything to the left of
// the decimal)
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_BrowserVersionMajor()
	{
	return this.s_BrowserVersionMajor;
	}
//=======================================================================================================
// Globals_BrowserVersionMinor()
//
// Returns a string indicating the minor version number of the user's brower (everything to the right of
// the decimal)
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_BrowserVersionMinor()
	{
	return this.s_BrowserVersionMinor;
	}
//=======================================================================================================
// Globals_Platform()
//
// Returns a string indicating the platform the user is on
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_Platform()
	{
	return this.s_Platform;
	}
//=======================================================================================================
// Globals_Coll()
//
// Returns a string used to make cross-browser code easier to write
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_Coll()
	{
	return this.s_Coll;
	}
//=======================================================================================================
// Globals_StyleObj()
//
// Returns a string used to make cross-browser code easier to write
//
// Inputs:  none
// Outputs: String
//-------------------------------------------------------------------------------------------------------
function Globals_StyleObj()
	{
	return this.s_StyleObj;
	}
//=======================================================================================================
// Globals_ContentAreaWidth([win])
//
// Returns an integer indicating the width of the content area of the calling code or of the given
// content area win (i.e. browser window or frame).  Thus, if you call it with no arguments (or an undefined or
// null-valued argument) it returns the width of the content area in which the calling code is located.  You
// can get the width of some other browser window or frame by passing this function a reference to it.
//
// Inputs:  none
// Outputs: integer
//-------------------------------------------------------------------------------------------------------
function Globals_ContentAreaWidth(win)
	{
	win = (win) ? win : window;
	if (this.b_IsNS)
		{
		return win.innerWidth;
		}
	else
		{
		return win.document.body.clientWidth;
		//return win.document.body.offsetWidth;
		}
	}
//=======================================================================================================
// Globals_ContentAreaHeight([win])
//
// Returns an integer indicating the height of the content area of the calling code or of the given
// content area win (i.e. browser window or frame).  Thus, if you call it with no arguments (or an undefined or
// null-valued argument) it returns the height of the content area in which the calling code is located.  You
// can get the height of some other browser window or frame by passing this function a reference to it.
//
// Inputs:  none
// Outputs: integer
//-------------------------------------------------------------------------------------------------------
function Globals_ContentAreaHeight(win)
	{
	win = (win) ? win : window;
	if (this.b_IsNS)
		{
		return win.innerHeight;
		}
	else
		{
		return win.document.body.clientHeight;
		//return win.document.body.offsetHeight;
		}
	}
//=======================================================================================================
// Globals_HandleResize()
//
// Helps fix Netscape's stupid onResize bug.  It puts positioned elements back in place by reloading the page.
//
// This function is meant to be set as a page's onResize event handler (by setting the onResize attribute
// in the body tag, etc).
//
// Inputs:  none
// Outputs: none
//-------------------------------------------------------------------------------------------------------
function Globals_HandleResize()
	{
	if (this.b_IsNS)
		{
		// I had to use window.innerWidth and window.innerHeight here since Globals_ContentAreaWidth() and Globals_ContentAreaHeight() caused errors.
		// It seems that this.b_IsNS is defined in this function, but once Globals_ContentAreaWidth() or Globals_ContentAreaHeight() is called it is no longer defined.
		if ((this.i_WindowWidth != window.innerWidth) || (this.i_WindowHeight != window.innerHeight))
			history.go(0);
		}
	}
//=======================================================================================================
// CPBParseInt(numStr[,radix])
//
// A better version of Math.ParseInt...well, at least I think so.  The real version returns NaN if given a
// null value--i think that's annoying and should return 0 instead, so i wrote this.  Otherwise, this
// version is identical.
//
// Signature:  CPBParseInt(string[,integer|string]) --> integer
//
// Input:      numStr: a string to be converted to an integer
//             radix:  base of number contained in numStr (optional)
// Output:     the integer in numStr, or 0 if conversion was not possible.
//-------------------------------------------------------------------------------------------------------
function CPBParseInt(numStr)
	{
	var theNum = 0;
	var theRadix = 10;
	
	if (CPBParseInt.arguments.length > 1)
		{
		theRadix = CPBParseInt(CPBParseInt.arguments[1]);		// make sure the radix is an integer
		}

	theNum = parseInt(numStr, theRadix);							// try to convert numStr to a integer
	return (isNaN(theNum) ? 0: theNum);								// return 0 if it's NaN, otherwise just return the integer
	}
//=======================================================================================================
// ViewSource()
//
// Displays the source of the current page.
//
// Signature:  ViewSource()
//
// Inputs:  none
// Outputs: none
//-------------------------------------------------------------------------------------------------------
function ViewSource()
	{
	if (Globals.IsIE() && Globals.IsMac())
		alert('Sorry, this feature is not supported in the Macintosh version of Internet Explorer.'+"\n\n"+'Please view the source code by choosing "source" from the "View" menu.');
	else
		document.location.href = 'view-source:' + document.location.href;
	}
//=======================================================================================================
