/** @fileoverview Contains global routines to handle common tasks such as launching modal dialogs, keeping the session logged in, etc.*/

/** @private */
var TimeoutTimerEnabled = true;
/** @private */
var WarningUrl = "Dialogs/SessionExpirationWarning.aspx";
/** @private */
var isThisADialog = false;
/** @private */
var openWindow;
/** @private */
var theActiveWindow;
/** @private */
var IsLogout = false;
/** @private */
var theBasePage;
/** Simulates an enumeration. It's very important to keep it in sync with the 'Act.Web.xxx' enumeration @public */ 
var Mode = { AddToGroupsCompanies:0, AssociateWith:1 }; 

try
{
	var theOpener = window.opener;
}
catch(e){}

/** Launches a modal dialog, handling various housekeeping duities like turning off the timeout timer while the dialog is up.
@param {string} url url of the dialog to show
@param {string} args arguments to pass to the showModalDialog function
@param {string} features features to turn on/off for the modal dialog
@return the return value of the modal dialog's result
*/
function ActModalDialog(url,args,height,width,top,left)
{   
	if (getInternetExplorerVersion() != 7)
	{
		height =parseInt(height) +36;
		width = parseInt(width) +16;
	}
	var features = 'dialogHeight:' + height + 'px; dialogWidth:' + width + 'px; edge: Raised; center: Yes; help: Yes; resizable: No; scroll: No; status: No;';
	if (top)
	{
		features += "dialogTop:" + top + ";";
	}
	if (left)
	{
		features += "dialogLeft:" + left + ";"; 
	}

	//disable timeout
	try {DisableTimeoutTimer();}catch(e){}
	
	
	//create cookies to store the modal dialog position 
	
	// SetCookie may fail if we are already calling this from a modal dialog (i.e. opening
	// an attachment from the EmailRead dialog). Defect 77893
	try
	{   
	    SetCookie("hLeft", '', this.document);
	    SetCookie("hTop", '', this.document);
	}
	catch(e) {}
	
	var returnVal = "";
	try
	{
	    // This is to aid in unexpected timeout handling. Logoff.aspx will attempt to use dialogArguments as a test for
	    // whether the page that called it is a dialog. If dialogArguments is not null, logoff with attempt to treat it
	    // as the calling window and set its .top location to the login page. The goal is to avoid showing the login
	    // page inside a dialog when an unhandled timeout occurs while the dialog is open.
	    if (args == null || args == "")
	        args = window;
	
		returnVal = window.showModalDialog(url,args,features);
	}
	catch(e)
	{
		features = 'height=' + height + ',width=' + width + ',chrome=yes,dependent=yes,personalbar=yes,location=yes,titlebar=yes,menubar=yes,center=yes,help=yes,resizable=no,scroll=yes,status=no,';
		if(top){features += "top=" + top + ",";}
		if(left){features += "left=" + left + ",";}
		features += "modal=yes"; 
		//alert(features);
		returnVal = window.open(url,args,features);
		returnVal.focus();
	}
	
	//delete cookies to store the modal dialog position 
	DelCookie("hLeft", this.document);
	DelCookie("hTop", this.document);
		
	if (returnVal == "LOGOUT")
	{
		Logout();
	}
	
	//enable timeout
	ResetTimeoutTimer();    // ? Not sure here whether to reset or enable - most likely reset

	return returnVal;
}

/** Opens a window, disabling timeouts 
@param {string} url url of the dialog to show
@param {string} args arguments to pass to the showModalDialog function
@param {string} features features to turn on/off for the modal dialog
@return the return value of the modal dialog's result
*/
function ActWindowOpener(url,args,features)
{
	//disable timeout
	DisableTimeoutTimer();
	openWindow = window.open(url,args,features);
	return openWindow;
}

/** Starts the timeout timer for the dialog. 
	@param {boolean} IsDialog IsDialog should be set to true if the current window is a dialog
	This function is called to govern when to log the user off after too much inactivity.
@private.
*/
function StartTimeoutTimer(IsDialog){
	try
	{
	    // Do we still need this?
		CheckOnBasePage();
		if(IsDialog != null)
		{
			isThisADialog = IsDialog;
		}

		if (TimeoutTimerEnabled)
		{
			if (SessionTimeoutSetting==0)
			{
				Logout();
			}
			else
			{
				if (SessionTimeoutSetting == 2)
				{
					DisableTimeoutTimer();
					//launch window here
					//try{theOpener.parent.ShowWarningDialog();}catch(e){}
					ShowWarningDialog();
				}
				else
				{
					SessionTimeoutSetting--;
					var scriptCall = 'StartTimeoutTimer(' + IsDialog + ')';
					timerID = setTimeout(scriptCall, 60000);
					
					if(SHOWTIMEOUTMINUTES)//this is set in the web.config file
					{
						statusBar.SetStatus(SessionTimeoutSetting + " minutes", 1);
					}
				}
				if(SessionTimeoutSetting%10 == 0)
				{
					var xmlHttp = getXmlHTTP();
					var url = AppPath + "WP/XmlHttpHelper.as?task=doNothing";
					xmlHttp.open("POST",url,false);
					xmlHttp.send();
				}
			}
		}
	}
	catch(e)
	{
		//this can get here when the user has to set the password from the login page
		TimeoutTimerEnabled = false;
		//alert(e);
	}
}

/** Shows the warning dialog which informs the user that they are about to be logged off. 
@private 
*/
function ShowWarningDialog()
{	
	var returnVal = ActModalDialog(parent.AppPath + WarningUrl, this.window, STANDARDMESSAGEBOXHEIGHT, STANDARDMESSAGEBOXWIDTH);
	if (returnVal == "l")
	{
		Logout();
		return false;
	}
	else if (returnVal == "c")
	{
		ResetTimeoutTimer();
		try{ResetFocusAfterTimeoutWarning();}catch(e){};
		return false;
	}
}

/** Resets the Session Timeout Timer.  Should be called after the user interacts with the application without requiring a post back */
function ResetTimeoutTimer()
{
	SessionTimeoutSetting = StartingSessionTimeoutSetting;
	if(!TimeoutTimerEnabled)
	{
		TimeoutTimerEnabled = true;
		StartTimeoutTimer();
	}
}

/** Disables the timeout timer.  
	This keeps the server session alive and potentially slows down the web server by consuming session memory.  
	You should only call this function when showing a modal interface that doesn't use @see ActModalDialog
*/
function DisableTimeoutTimer()
{
	TimeoutTimerEnabled = false;
}

/** Enables the session timeout timer. */
function EnableTimeoutTimer()
{
	if(!TimeoutTimerEnabled)
	{
		TimeoutTimerEnabled = true;
		StartTimeoutTimer();
	}
}


/** Logs the user out of the application */
function Logout()
{
	IsLogout = true;
	if (isThisADialog || window.dialogHeight != null)       //isThisADialog is set by StartTimeoutTimer
	{
		try{OnLogOut();}    // Only applies to WP.js - WordProcessor saves a backup
		catch(e){}
		window.returnValue = "LOGOUT";
		try{
			if(theOpener.parent.location.pathname.indexOf("WP/default.aspx") != -1)
			{
				theOpener.parent.Logout();
			}
		}
		catch(e){}
		try{theOpener.top.Logout();}catch(e){}   // calls Logout on caller - only for non-modal. Modal should be handed by the window.returnValue.
		window.close();
	}
	else
	{
		TimeoutTimerEnabled = false;
		window.top.location.href = AppPath + 'logoff.aspx?timeout=true';
	}
}

/** Enables the parent timer. 
You should only call this function when showing a modal interface that doesn't use @see ActModalDialog.
@private */
function EnableParentTimer()
{
	try
	{
		theOpener.parent.EnableTimeoutTimer();
	}
	catch(e){}
}

/** Disables the parent timer.  
You should only call this function when showing a modal interface that doesn't use @see ActModalDialog.
@private */
function DisableParentTimer()
{
	try
	{
		theOpener.parent.DisableTimeoutTimer();
	}
	catch(e){}
}


/** @private 
this function checks on all parent timers and disables them if one is found.
the idea is that the top most window will maintain the timer and collapse downward when a timeout occurs
*/
function CheckOnBasePage()
{

	var theOpenerString = "window.opener";
	while(eval(theOpenerString))
	{
		theBasePage = eval(theOpenerString);
		if(theBasePage != null)
		{
			try
			{
				if(theBasePage.TimeoutTimerEnabled)
				{
					theBasePage.DisableTimeoutTimer();
					SessionTimeoutSetting = theBasePage.SessionTimeoutSetting;
				}
			}
			catch(e){}
		}
		theOpenerString += ".opener";
	}
}

/** Creates a cookie with the specified name and value on the specified document.
@param {string} sName The name for the cookie
@param {string} sValue The value for the cookie
@param {Document} oDoc The DHTML document to set the cookie on.
The cookie expires one year after it's been set.
*/
function SetCookie(sName, sValue, oDoc)
{
	//make sure this is a DHTML document object
  if (oDoc.cookie == undefined)
		oDoc = oDoc.document;

  date = new Date();
  date.setTime(date.getTime()+(365*24*60*60*1000));
  oDoc.cookie = sName + "=" + escape(sValue) + "; expires=" + date.toGMTString();
}

/**  Retrieve the value of the cookie with the specified name on the specified document.
@param {string} sName The name for the cookie
@param {Document} oDoc The DHTML document to set the cookie on.
@return the value of the cookie, or null if the cookie doesn't exist.
*/
function GetCookie(sName, oDoc)
{
	//make sure this is a DHTML document object
  if (oDoc.cookie == undefined)
		oDoc = oDoc.document;
  
  // cookies are separated by semicolons
  var aCookie = oDoc.cookie.split("; ");
  for (var i=0; i < aCookie.length; i++)
  {
	// a name/value pair (a crumb) is separated by an equal sign
	var aCrumb = aCookie[i].split("=");
	if (sName == aCrumb[0]) 
	  return unescape(aCrumb[1]);
  }

  // a cookie with the requested name does not exist
  return null;
}

/**  Delete the cookie with the specified name on the specified document.
@param {string} sName The name for the cookie
@param {Document} oDoc The DHTML document to set the cookie on.
*/
function DelCookie(sName, oDoc)
{
	//make sure this is a DHTML document object
  if (oDoc.cookie == undefined)
		oDoc = oDoc.document;
  oDoc.cookie = sName + "=; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
}


/** Show the dialog that allows the user to change the timezone for which activities are displayed
@private
*/
function ShowTimezoneSelectionDialog()
{
	try
	{
		var tzDialogURL = AppPath + "Calendars/StandaloneTimezoneSelectionForm.aspx";
		var retVal = ActModalDialog(tzDialogURL, this, 204, 439);
		if (retVal == 'TZSelect.Continue')
		{
			document.location.href = GetFullPathWithoutQstring();
		}
	}
	catch(e)
	{
	}
}

/** show the view linked fields dialog.
@private
*/
function viewLinkedFields()
{
	  var URL = AppPath + 'Companies/ViewLinkedFields.aspx';
	  var fname = ActModalDialog(URL, this, 314, 464);
}

/** hide the window's status bar */
function hidestatus()
{
	window.status = '';
	return true;
}

/** Displays exception text */
function DisplayException (msg)
{
	alert(msg);
}



/** @private */
function resizeTemplate(IsResize)
{    
	
	var theDocBody = document.body;
	//alert(theDocBody.getAttribute("flexLayout"));	
	// use the new layout if the body is marked accordingly.
	if ( typeof(theDocBody.getAttribute("flexLayout")) != "undefined" && theDocBody.getAttribute("flexLayout") )
	{
		flexLayout();
		if ( ! IsResize ) InitSplitters();
		return;
	}
	
	var minHeight = 0;
	var hasTabFrame = false;
	var iContentHeight = document.getElementById('theContent').offsetHeight;
	var iStatusbarHeight = document.getElementById('TemplateStatusBar').offsetHeight;
	var iMenuHeight = document.getElementById('theMenuTR').offsetHeight;
	var iToolbarHeight = document.getElementById('theToolbarTR').offsetHeight;
	var iStatusbarTop = document.getElementById('TemplateStatusBar').offsetTop;
	var iNavbarHeight = document.getElementById('theNavigationBar').offsetHeight;
	var iMenuAndToolbarHeight = iMenuHeight + iToolbarHeight;
	var SpaceAvailableForMainView = theDocBody.clientHeight - iMenuAndToolbarHeight - iStatusbarHeight;
	
	var	gt = null;
	try
	{
		gt = document.getElementById('gridtable');
		//maybe 'gridtable' is inside a container
		if (gt == null) gt = gtable;
	}
	catch(e)
	{}

	var filename = GetFileName();

	if(minHeight == 0)
	{
		minHeight = iMenuAndToolbarHeight + iNavbarHeight + iStatusbarHeight;
	}
	
	//try to set the tabframe height
	try
	{
		var tabFrame = document.getElementById('tabFrame');
		tabFrame.height = ((theDocBody.clientHeight - tabFrame.offsetTop) - iStatusbarHeight) - 105;
		hasTabFrame = true;
	}
	catch(e){}

	x = theDocBody.clientHeight - theDocBody.clientTop;

	if(minHeight>x) //we need to scroll
	{
		document.getElementById('ContentTable').height = minHeight-iMenuAndToolbarHeight;
		theDocBody.scroll = "auto";
		if(tabFrame != null)
		{
			if(!IsResize)
			{
				tabFrame.height	= iStatusbarTop - tabFrame.offsetTop + 24;
			}
			else
			{
				tabFrame.height = iStatusbarTop - tabFrame.offsetTop;
			}
		}
		try
		{
			gt.height = (iNavbarHeight + iStatusbarHeight) - iHeaderEtcSize;
		}
		catch(e){}
	}
	else
	{
		var z = 104; //iStatusbarHeight + iMenuAndToolbarHeight

		document.getElementById('ContentTable').height = x - (iStatusbarHeight + iMenuAndToolbarHeight);
		if (filename == "calendarview.aspx" || filename == "contactdetail.aspx" || filename == "groupdetail.aspx" || filename == "companydetail.aspx"){theDocBody.scroll = "no";}
		try
		{
			gt.height = SpaceAvailableForMainView - iHeaderEtcSize;
		}
		catch(e){}
	}
	
	if(theDocBody.scrollWidth > theDocBody.clientWidth)
	{
		theDocBody.scroll = "auto";
	}
	
	document.getElementById('MainTable').width = theDocBody.scrollWidth-1;
	// resize the content control here.
	document.getElementById('TemplateStatusBar').width = theDocBody.scrollWidth-1;
	document.getElementById('MenuTable').width = theDocBody.scrollWidth;
	try{document.getElementById('listToolbar').width = theDocBody.scrollWidth-3;}
	catch(e){}
}

/** @private
Invokes the dialog that allows users to specify a custom date range on which to filter the
activities in the list.
*/

function InvokeCustomDateRangeDialog(rangeStart, rangeEnd, dateComboObj)
{
	try
	{
		var drdURL = AppPath + 'Dialogs/SelectDateRange.aspx?sR=' + rangeStart + '&eR=' + rangeEnd; 
		var retVal = ActModalDialog(drdURL, this,224, 472);
		
		if (retVal == "" || retVal == "undefined" && retVal == null)	// Date range selection cancelled - don't leave custom date range selected
		{
			dateComboObj.selectedIndex = 0;	// pick first item in the list.
		}
		else
		{
			return retVal;
		}
	}
	catch(e)
	{
		// Let them know that IE's popup blocker stomped the date picker
		var popupMsg = GetLocalizedString("Common", "PopupBlocker.DateRange.Message", AppPath);
		alert (popupMsg);
	}
}

var RECORDHISTORYDIALOGWIDTH = "733";
var RECORDHISTORYDIALOGHEIGHT = "466";
var UPLOADFILEWIDTH = "374";
var UPLOADFILEHEIGHT = "134";
var OPPDIALOGWIDTH = "750";
var OPPDIALOGFILEHEIGHT = "585";
var VIEWGROUPSCOMPSDIALOGWIDTH = "500";
var VIEWGROUPSCOMPSDIALOGFILEHEIGHT = "434";
var VIEWGROUPSCOMPSDIALOGFILEHEIGHTWITHINTRO = "454";
var VIEWGROUPSCOMPSDIALOGFILEHEIGHTNOLIST = "400";
var LOOKUPDIALOGWIDTH = "575";
var LOOKUPDIALOGHEIGHT = "260";
var ASSOCIATEWITHDIALOGWIDTH = "673";
var ASSOCIATEWITHDIALOGHEIGHT = "400";

/** @private
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
*/
function getInternetExplorerVersion()
{
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
	var ua = navigator.userAgent;
	var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
	if (re.exec(ua) != null)
	  rv = parseFloat( RegExp.$1 );
  }
  return rv;
}
/** @private
// Returns true if browser is IE
*/
function isInternetExplorer()
{
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
	return true;
  }
  else
  {
  	return false;
  }
}

/** 
// Used to hold information about the current Group or Company and synchronize the
// state of the Record Manager Selector and the Access Control.
@constructor 
*/
function oMutableEntity() 
{ 
	//properties
	
	this.Access = -1;
	this.RecordManagerId = null;
	this.CurrentEntityID = null;
  this.RecordManagerTextboxId = null;
  this.RecordManagerImageId = null;
  this.AccessRadioButtonName = null;	
  this.SelectUsersTeamsButtonId = null;
  this.PublicTooltip = '';
  this.PrivateTooltip = '';
	this.AccessEnabled = false;
	this.CanChangeAccess = false;
	this.CanChangeRecordManager = false;
	this.CanChangeAccessPath = 'ComponentModel/canChangeAccessType.aspx';
	this.CanChangeRecordManagerPath = 'ComponentModel/canChangeRecordManager.aspx';
  
  var AccessType = { Public:0, Private:1, Limited:2 };

	//methods
	
	this.GetSelectUsersTeamsButton = function()
	{
		if (this.SelectUsersTeamsButtonId != null) return document.getElementById(this.SelectUsersTeamsButtonId);  
		return null; 
	};
	
	this.GetRecordManagerTextbox = function() 
	{  
		if (this.RecordManagerTextboxId != null) return document.getElementById(this.RecordManagerTextboxId);  
		return null; 
	}; 
	 
	this.GetRecordManagerImage = function() 
	{  
		if (this.RecordManagerImageId != null) return document.getElementById(this.RecordManagerImageId);  
		return null; 
	};
	
	this.GetAccessRadioButtons = function() 
	{  
		if (this.AccessRadioButtonName != null) return document.getElementsByName(this.AccessRadioButtonName);  
		return null; 
	};

	this.SetCurrentEntityID = function(sCurrentEntityID)
	{
	  if (this.CurrentEntityID == sCurrentEntityID)
		return;
	  else
	  {
	  //fire OnEntityChanged
	  this.OnEntityChanged();
	  }
	};
	
	this.SetRecordManagerTextboxId = function(sRecordManagerTextboxId)
	{
	  this.RecordManagerTextboxId = sRecordManagerTextboxId;
	};
	
	this.SetRecordManagerImageId = function(sRecordManagerImageId)
	{
	  this.RecordManagerImageId = sRecordManagerImageId;
	};
	
	this.SetACL_Ids = function(sAccessRadioButtonName, sSelectUsersTeamsButtonId)
	{
	  this.AccessRadioButtonName = sAccessRadioButtonName;
	  this.SelectUsersTeamsButtonId = sSelectUsersTeamsButtonId;
	};
	
	this.SetCanChangeAccess = function(bCan)
	{
	  this.CanChangeAccess = bCan;
	};
	this.GetCanChangeAccess = function()
	{
	  return this.CanChangeAccess;
	};

	this.InitAccess = function(bEnabled, iSelection, bCanChangeRecordManager, bCanChangeAccessType, sPublicTooltip, sPrivateTooltip)
	{
	this.AccessEnabled = bEnabled;
	this.Access = iSelection;
	this.CanChangeAccess = bCanChangeAccessType;
	this.PublicTooltip = sPublicTooltip;
	this.PrivateTooltip = sPrivateTooltip;
	
	//fire OnAccessTypeChanging
	this.OnAccessTypeChanging(bCanChangeRecordManager);
	
	//update RecordManagerSelector control
	this.SetRecordManagerDisplay();
	
	//update ACL control
	this.SetAccessDisplay();

	};
	
	this.SetAccess = function(iSelection)
	{
	this.Access = iSelection;
	
	//fire OnAccessTypeChanging
	this.OnAccessTypeChanging(null);

	//update RecordManagerSelector control
	this.SetRecordManagerDisplay();
	
	};
	
	this.SetAccessDisplay = function()
	{
	var oRadioBtns = this.GetAccessRadioButtons();
	var oBtn = this.GetSelectUsersTeamsButton();
	var EnablePrivate = false;
	var PrivateTooltip = '';
	var EnablePublic = false;
	var PublicTooltip = '';
	
	if (oRadioBtns == null || oBtn == null)
	  return;
	
	if (this.Access == AccessType.Private)
	{
	  EnablePrivate = this.CanChangeAccess;
	  // Clear the private tooltip on the Accessor UI.
	  PrivateTooltip = '';
	  EnablePublic = this.CanChangeAccess;

	  // Set the public tooltip based on if they can change or not. (public and limited)
	  PublicTooltip = this.CanChangeAccess ? '' : this.PublicTooltip;
	}
	else
	{
	  EnablePublic = true; //enable both limited and public radio buttons
	  // Clear the public/limited tooltip on the Accessor UI.
	  PublicTooltip = '';
	  EnablePrivate = this.CanChangeAccess;

	  PrivateTooltip = this.CanChangeAccess ? '' : this.PrivateTooltip;
	}
	
	//disable radiobuttons
	for (i=0; i<oRadioBtns.length; i++)
	{
		oRadioBtns[i].disabled = true;
		oRadioBtns[i].className = 'radioDisabled';
		oRadioBtns[i].parentElement.title = i == 1 ? PrivateTooltip : PublicTooltip;
		oRadioBtns[i].parentElement.style.color = 'GrayText';
	}
		
	//disable limited access button
	oBtn.disabled = true;

	  //set the selected radio button
	  oRadioBtns[this.Access].checked = true;
	  
	  if (EnablePublic && this.AccessEnabled)
	  {
	  // Public types are Public and Limited.
	  oRadioBtns[0].disabled = false;
	  oRadioBtns[0].className = 'radioEnabled';
	  oRadioBtns[0].parentElement.style.color = 'WindowText';
	  oRadioBtns[2].disabled = false;
	  oRadioBtns[2].className = 'radioEnabled';
	  oRadioBtns[2].parentElement.style.color = 'WindowText';
	  }
	  
	  if (EnablePrivate && this.AccessEnabled)
	  {
	  oRadioBtns[1].disabled = false;
	  oRadioBtns[1].className = 'radioEnabled';
	  oRadioBtns[1].parentElement.style.color = 'WindowText';
	  }
	
	  //should we enable the limited access button?
	  oBtn.disabled =	(this.AccessEnabled && this.Access == AccessType.Limited && EnablePublic) ? false : true;

	};
	
	this.SetRecordManagerDisplay = function()
	{
	var oImg = this.GetRecordManagerImage();
	var oTextbox = this.GetRecordManagerTextbox();
	if (this.GetCanChangeRecordManager())
	{
	  oImg.className = 'picklist';
	  oImg.style.cursor = 'hand';
	  
	  oTextbox.readOnly = false;
	  oTextbox.setAttribute('IsEditable', 'true', 1);
	  oTextbox.style.textAlign = 'left';
	  oTextbox.style.borderStyle = 'solid';
	  oTextbox.style.borderWidth = '1';
	  oTextbox.style.borderColor = '#7F9DB9';
	  oTextbox.style.backgroundColor = 'Window';
	  oTextbox.style.cursor = 'auto';
	  //color:ControlText;
	}
	else
	{
	  oImg.className = 'disabledImage';
	  oImg.style.cursor = 'text';
	  
	  oTextbox.readOnly = true;
	  oTextbox.setAttribute('IsEditable', 'false', 1);
	  oTextbox.style.textAlign = 'left';
	  oTextbox.style.borderStyle = 'solid';
	  oTextbox.style.borderWidth = '1';
	  oTextbox.style.borderColor = '#7F9DB9';
	  oTextbox.style.backgroundColor = '#F0F0F0';
	  oTextbox.style.cursor = 'text';
	}
	};
	
	this.GetAccess = function()
	{
	  return this.Access;
	};
	
	this.SetRecordManager = function(sGuid)
	{
	  this.RecordManagerId = sGuid;
	};
	
	this.GetRecordManager = function(sGuid)
	{
	  return this.RecordManagerId;
	};

	this.UpdateRecordManager = function(sGuid)
	{
	this.RecordManagerId = sGuid;

	//fire OnRecordManagerChanging
	this.OnRecordManagerChanging();

	//update ACL control
	this.SetAccessDisplay();
	};
	
	this.GetEntityNodeName = function()
	{
	if (ENTITY_NODE_NAME)
	  return ENTITY_NODE_NAME;
	else if (window.top.ENTITY_NODE_NAME)
	  return window.top.ENTITY_NODE_NAME;
	else
	  return '';
	};
	
	this.SetCanChangeRecordManager = function(bCan)
	{
	  this.CanChangeRecordManager = bCan;
	};
	this.GetCanChangeRecordManager = function()
	{
	  return this.CanChangeRecordManager;
	};
	
	//pseudo-events
	
	this.OnEntityChanged = function()
	{
	//fire OnAccessTypeChanging
	this.OnAccessTypeChanging();

	//update RecordManagerSelector
	this.SetRecordManagerDisplay();
	};
	
	this.OnRecordManagerChanging = function()
	{
	  var theURL = AppPath + this.CanChangeAccessPath;
	  theURL += '?entity='	+ this.GetEntityNodeName();
	  theURL += '&ContactID='	+ this.GetRecordManager();
	var xmlHttp = getXmlHTTP();
	xmlHttp.open("GET", theURL, false);
	xmlHttp.setRequestHeader("Content-Type", "text/HTML");
	xmlHttp.send();

	var sCan = xmlHttp.responseText;
	if (sCan.toLowerCase()  == 'true')
	  this.SetCanChangeAccess(true);
	else if (sCan.toLowerCase()  == 'false')
	  this.SetCanChangeAccess(false);
	};
	
	this.OnAccessTypeChanging = function(bCanChangeRecordManager)
	{
	  if (bCanChangeRecordManager == null)
	  {
		var theURL = AppPath + this.CanChangeRecordManagerPath;
		theURL += '?entity='	+ this.GetEntityNodeName();
		theURL += '&access='	+ this.GetAccess().toString();
		var xmlHttp = getXmlHTTP();
		xmlHttp.open("GET", theURL, false);
		xmlHttp.setRequestHeader("Content-Type", "text/HTML");
		xmlHttp.send();

	  var sCan = xmlHttp.responseText;
	  if (sCan.toLowerCase()  == 'true')
		this.SetCanChangeRecordManager(true);
	  else if (sCan.toLowerCase()  == 'false')
		this.SetCanChangeRecordManager(false);
	  }
	  else
	  {
		this.SetCanChangeRecordManager(bCanChangeRecordManager);
	  }
	};
	
}

var oMutableEntity = new oMutableEntity();

var CONTACT_DETAIL_VIEW = "CONTACT_DETAIL";
var CONTACT_LIST_VIEW = "CONTACT_LIST";
var GROUP_DETAIL_VIEW = "GROUP_DETAIL";
var GROUP_LIST_VIEW = "GROUP_LIST";
var COMPANY_DETAIL_VIEW = "COMPANY_DETAIL";
var COMPANY_LIST_VIEW = "COMPANY_LIST";
var OPPORTUNITY_VIEW = "OPPORTUNITY";
var TASK_LIST_VIEW = "TASK_LIST";
var CALENDAR_VIEW = "CALENDAR_DETAIL";
var DASHBOARD_VIEW = "DASHBOARD";

function GetCurrentView()
{
	var retVal = CONTACT_DETAIL_VIEW;
	
	var index = (document.location.href.toLowerCase()).indexOf("contactdetail.aspx");
	if(index != -1)
	{
		retVal = CONTACT_DETAIL_VIEW;
	}
	else
	{
		index = (document.location.href.toLowerCase()).indexOf("contactlistview.aspx");
		if(index != -1)
		{
			retVal = CONTACT_LIST_VIEW;
		}
		else
		{
			index = (document.location.href.toLowerCase()).indexOf("groupdetail.aspx");
			if(index != -1)
			{
				retVal = GROUP_DETAIL_VIEW;
			}
			else
			{
				index = (document.location.href.toLowerCase()).indexOf("grouplistview.aspx");
				if(index != -1)
				{
					retVal = GROUP_LIST_VIEW;
				}
				else
				{
					index = (document.location.href.toLowerCase()).indexOf("companydetail.aspx");
					if(index != -1)
					{
						retVal = COMPANY_DETAIL_VIEW;
					}
					else
					{
						index = (document.location.href.toLowerCase()).indexOf("companylistview.aspx");
						if(index != -1)
						{
							retVal = COMPANY_LIST_VIEW;
						}
						else
						{
							index = (document.location.href.toLowerCase()).indexOf("opportunitylist.aspx");
							if(index != -1)
							{
								retVal = OPPORTUNITY_VIEW;
							}
							else
							{
								index = (document.location.href.toLowerCase()).indexOf("tasklist.aspx");
								if(index != -1)
								{
									retVal = TASK_LIST_VIEW;
								}
								else
								{
									index = (document.location.href.toLowerCase()).indexOf("calendarview.aspx");
									if(index != -1)
									{
										retVal = CALENDAR_VIEW;
									}
									else
									{
										index = (document.location.href.toLowerCase()).indexOf("dashboard/default.aspx");
										if(index != -1)
										{
											retVal = DASHBOARD_VIEW;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}

	return retVal;
}
/** unencodes a string
@private */
function URLUnencode(encodedString)
{
	var output = encodedString;
	var binVal, thisString;
	var myregexp = /(%[^%]{2})/;
	while ((match = myregexp.exec(output)) != null && match.length > 1 && match[1] != '')
	{
		binVal = parseInt(match[1].substr(1),16);
		thisString = String.fromCharCode(binVal);
		output = output.replace(match[1], thisString);
	}
	return output;
}

/** Adds event listeners
elem: the element object that we want the event to be attached to.

func: The handler (or listener) function that should be invoked when the specified type of event occurs. When your function is invoked, it is passed an Event object as its only argument. This object contains details about the event (such as which mouse button was pressed) and defines methods such as stopPropagation( ).	

evtType: The name of the event type for which the handler is being registered. The event type should be a string that contains the lowercase name of the HTML handler attribute, with the leading "on" removed. Thus, if you use an onmousedown HTML attribute or onmousedown property in the Level 0 model, you'll use the string "mousedown" in the Level 2 event model.

capture: A boolean value. If true, the specified event handler captures events during the capturing phase of event propagation. If the argument is false, the event handler is a normal event handler and is triggered when the event occurs directly on the object or on a descendant of the element and subsequently bubbles up to the element.

@public */
function addEvent(elem, evtType, func, capture) {
   capture = (capture) ? capture : false;
   if (elem.addEventListener) {
      elem.addEventListener(evtType, func, capture);
   } else if (elem.attachEvent) {
      elem.attachEvent("on" + evtType, func);
   } else {
      // for IE/Mac, NN4, and older
      elem["on" + evtType] = func;
   }
}

/** Removes event listeners
elem: the element object that we want the event to be attached to.

func: The handler (or listener) function that should be invoked when the specified type of event occurs. When your function is invoked, it is passed an Event object as its only argument. This object contains details about the event (such as which mouse button was pressed) and defines methods such as stopPropagation( ).	

evtType: The name of the event type for which the handler is being registered. The event type should be a string that contains the lowercase name of the HTML handler attribute, with the leading "on" removed. Thus, if you use an onmousedown HTML attribute or onmousedown property in the Level 0 model, you'll use the string "mousedown" in the Level 2 event model.

capture: A boolean value. If true, the specified event handler captures events during the capturing phase of event propagation. If the argument is false, the event handler is a normal event handler and is triggered when the event occurs directly on the object or on a descendant of the element and subsequently bubbles up to the element.

@public */
function removeEvent(elem, evtType, func, capture) {
   capture = (capture) ? capture : false;
   if (elem.removeEventListener) {
      elem.removeEventListener(evtType, func, capture);
   } else if (elem.attachEvent) {
      elem.detachEvent("on" + evtType, func);
   } else {
      // for IE/Mac, NN4, and older
      elem["on" + evtType] = null;
   }
}

/** gets the element object from an event
@public */
function getElementFromEvent(evt) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (evt) {
       var elem = (evt.target) ? evt.target :
	  ((evt.srcElement) ? evt.srcElement : null);
       if (elem ) {
	   return elem;
       }
       else
       {
       	return null;
       }
    }
}
/*
if (!window.ActiveXObject) 
{
	window.constructor.prototype.createPopup = function()
	{	
		return Object;
	}
}
*/