/***********************************************************************************
** Desc:     common.js
**
** Author:    
** Date:      04/09/2003
************************************************************************************
** Change History
************************************************************************************
** Date			Author		Description
** ----------	---------	----------------------------------------------------------
** 04/09/03		jefjohns	added new method to support multi-select.
** 04/09/03		a-justsc	added new method to support getting a domain value from a modal window
** 04/22/03		a-justsc	commented functions getValue, getSelected..., toggleViewOption
** 04/24/03		a-justsc	add function openObjectBrowser to allow for viewing extended Opty details
** 12/12/03		v-clevel	Add closeWindow function
** 01/05/04    v-clevel added maxlength checks for TEXTAREA
** 02/18/04    v-clevel modified closeWindow and confirmIfCancel to set IsDirty = false;
** 02/18/04    v-nsawan Modified to suppres the dirty check validation for the option buttons 
**                      that are autopostback = true.
** 02/28/2004  v-nsawan Modified to support the functionality to disallow the user comming to a page using 
**                      Back button. Bug:8923
** 03/18/2004  v-markdg PS:10458 Modified confirmIfDirty() to check if the Page_IsValid variable is defined
**                      before null check.
** 03/27/2004  v-sdiwak PS:10052 Modified the replace functionality in the MaxLengthPaste function
** 11/15/2004  v-rajnal PS:15824. Created an overloaded CloseWindow() method
** 11/30/2004  v-markdg PS:15877 Added openDialogWindow() method which will look at the return value
**                      of the child window and redirect to the url if it is returned.
** 08/30/2005  v-markdg PS:26526 Updated error messages per spec.
** 10/24/2005  v-markdg PS:32355 Added OptOutOfDirtyCheck functionality for controls.
**                               Modified cancel dirty check to only cancel for the current post.
***********************************************************************************/	
//This Function will be used to trap if the user clicked the back button.
function trapBackButton()
{
   var x="1";
   var isBack;
   isBack = (x != document.all.item("backButtonFlag").value);
   
   //Set the hidden flag to some value other than "1", the condition which will be used
   //to trap if the user clicked the back button.
   document.all.item("backButtonFlag").value=2;
   document.all.item("backButtonFlag").value=2;
   
   if (isBack)
   {
      //Redirect to the error page with the appropriate message Id.
      window.location.href="ErrorPage.aspx?ErrorGuid=2E87DA1D-3763-F990-E905-1F4A0352D26A";
   }
}

function Init()
{
	//Page load entry point for aspx pages.
	CheckMessages();
	//InitMSTeamService();
	SetUpDirtyCheck();

   //Check for the back button flag and its value, if its greator than 2, we don't perform any validation here(v-nsawan)
   if (document.all.item("backButtonFlag") != null && document.all.item("backButtonFlag").value <= 2)
   {
      trapBackButton()
   }
}

//Checks for any form fields titled message and shows an alert box.
function CheckMessages()
{
	
	//it's possible that more than one form will exist on the page
	//so we walk all the forms and look for a field called Message to display.
	var found;
	for(i = 0; i < document.forms.length; i++)
	{
		try  //Try catch this as not all forms will have a message field, if they dont' we don't care about it anyway.
		{
			if( (document.forms[i].message != null) && (document.forms[i].message.value != "") )
			{
				alert(document.forms[i].message.value);
				document.forms[i].message.value = "";
			}

			if( (document.forms[i].errorMessage != null) && (document.forms[i].errorMessage.value != "") )
			{
				alert(document.forms[i].errorMessage.value);
				document.forms[i].errorMessage.value = "";
				found=true;
			}

		}
		catch(exception)
		{
			//We're just going to ignore any errors that come up
		}
	}	
	if (found) history.back();
}

function ConfirmDelete()
{
	if (confirm("Are you sure")) return true; else return false;
}

function AddMeToTeam(partnerAccountID, domainUser)
{
	document.body.style.cursor = 'wait';
	var funcCall = new Object();
	funcCall.funcName = "addUserToPartnerTeam";
	funcCall.async = false;
	
	/*
		*	Make a syncronous call to the webservice
		*/
	
	//service.User.callService(function to run, parameter to pass)
	var result = service.MSTeam.callService(funcCall, domainUser, partnerAccountID);
	
	/*
	*	Check to see if there is an error
	*/
	document.body.style.cursor = 'auto';
	if(result.error)
	{
		alert("An error occured:\n\n" + result.errorDetail.string);
	}
	else
	{	
		var message = result.raw.selectSingleNode("//Message").text
		if(message.length == 0)
		{
			alert(service.successMessage);
		}
		else
		{
			alert(message);	
		}
	}
}

function InitMSTeamService()
{
	var oService; 
	//this isn't needed on most pages so we want to go ahead and set it up when the page loads if possible. But not cause an error on other pages.
	try
	{
	oService = service;
	}
	catch(e)
	{
		//just ignore it.
	}
	if(oService != null)
	{
		oService.useService(location.protocol + "//" + location.host + "/EdisonWS/Team.asmx?WSDL", "MSTeam");
	}
}

function showTable(table, imgID)
{

	var displayStyle = "none";
	if(table.rows[1].style.display == "none")
	{
		displayStyle = "";
		imgID.src = "images/collapse.gif";
	}
	else
	{
		imgID.src = "images/expand.gif";
	}
	
	//start at the 2nd row(index 1) as we don't want to hide the first row which has the collapse / expand image.
	for(i = 1; i < table.rows.length; i++)
	{
		table.rows[i].style.display = displayStyle;
	}
}


function LaunchCalendar(elm)
{
//Purpose: Launches a modal window allowing a user to pick a date from a calendar
//elm should be a html text box, this is where the date will get written back to when the calendar is closed.

	d = new Date();
	var modalOptions = "dialogHeight:290px; dialogWidth:280px; Center: Yes; Help: No; Status: No;"
	var modalArguments = "";
	var modalReturnValue = null;
	//pull any existing values in the elm.value so we can default the calendar to that date. If it's not a date the calendar will just ignore it.
	modalReturnValue = window.showModalDialog("calendarframe.aspx?ihcInd=" + d.getDate + "&DefaultDate=" + elm.value, modalArguments, modalOptions)
	if(modalReturnValue != null)
	{
		//write the selected value back to the form field.
		elm.value = modalReturnValue;
	}
		
}

function getCorrectForm()
{
	//find the first POST form. MNP quick search is a get and we don't want to use that.
	for(i = 0; i < document.forms.length; i++)
	{
		if(document.forms[i].method.toUpperCase() == "POST")
		{
			return document.forms[i];
		}
	}
	//if we are still here there was probably trouble.
	//shouldn't happen though.
	return null;
}
//run on the page_load event. Sets up the process to warn a user before leaving a page
//if they have made a change to any form element.
function SetUpDirtyCheck()
{
	//if the dirty field doesn't exist or there is no value for it, then assume we don't need to do the dirty check.
	if(document.all.item("dirty") == null || document.all.item("dirty").value == "")
	{
		return;
   }

   // Check if the state of the dirty flag was preserved on the last post
   // and set the flag to true if necessary
   if (document.all.item("dirty").value == "p")
   {
      setDirtyForm();
   }

	var oForm = getCorrectForm();
	window.attachEvent("onbeforeunload", warnForDirty);
	oForm.attachEvent("onsubmit", formSubmitCancelDirtyCheck);
	
   // Check if any controls have been excluded from the dirty check
   if (typeof(excludeFromDirtyCheckControlIds) != "undefined")
   {
      for (i = 0; i < excludeFromDirtyCheckControlIds.length; i++)
      {
         var controlToExclude = document.getElementById(excludeFromDirtyCheckControlIds[i]);

         if (controlToExclude != null)
         {
            controlToExclude.setAttribute("excludeFromDirtyCheck", "true");
         }
      }
   }

	// for each form item and add an onchange event
	// so we will know if a form has changed.
	for(i = 0; i < oForm.elements.length; i++)
	{
		//If the input control is radio button and if its autopostback, we dont want to show the dirty check message (v-nsawan)
		//TODO: Can we have this logic for dropdown that is autopostback = true, if we do then we will have to remove the
		//hack that we have put in the Smb:Dropdownlist's prerender event.
      if (oForm.item(i).type == "radio" && oForm.item(i).onclick != null && oForm.item(i).onclick.toString().indexOf("__doPostBack") != -1)
      {
         var func = new Function("formSubmitCancelDirtyCheck(); " + oForm.item(i).attributes["onclick"].value);
         oForm.item(i).onclick = func;
      }

      // Check if this control should be excluded from the dirty check.
      if (oForm.item(i).attributes["excludeFromDirtyCheck"] != null && oForm.item(i).attributes["excludeFromDirtyCheck"].value == "true") 
      {
         continue;
      }

      // Attach the set dirty event to the control
		if (oForm.item(i).onchange == null)
		{
			oForm.item(i).attachEvent("onchange", setDirtyForm)
		}
		else if (oForm.item(i).onchange.toString().indexOf("__doPostBack") == -1)
		{
			oForm.item(i).attachEvent("onchange", setDirtyForm)
		}
	}	
}

// sets the dirty field to "x" or "p" if preserving state so the user won't be 
// prompted about navigating away from the page.
function formSubmitCancelDirtyCheck(preserveDirtyState)
{
	try
	{
      if (preserveDirtyState == true && document.all.item("dirty").value == "true")
      {
         document.all.item("dirty").value = "p";
      }
      else
      {
         document.all.item("dirty").value = "x";
      }
	}
   catch(e)
   {
      document.all.item("dirty").value = "x";
   }
}

function isDirtyCheck() { 
   if (document.all['dirty'] != null) 
      return (document.all['dirty'].value == 'true'); 
   return false;
}

function confirmIfDirty(message) {
   if (typeof(Page_IsValid) != "undefined" && Page_IsValid != null) 
      Page_IsValid = true;

 	if (isDirtyCheck()) {
 		if (confirm(message))
 		{
 		   var oForm = getCorrectForm();
	      if (typeof(oForm) != "undefined")
	      {
		      oForm.dirty.value = "false";
		   } 		
 		   return true; 
 		}
 		else 
 		   return false;
 	} 
   return true;
 }


//sets the hidden text field dirty to be true so we know a value has changed on the form.
function setDirtyForm()
{
	document.all.item("dirty").value = "true";
}

//checks to see if the page has had values change on it and if the user wants to navigate away from the page
//without saving changes.
function warnForDirty()
{
	try
	{
		var oForm = getCorrectForm();
		// the dirty field is == true then let the user know their changes won't be saved.
      // The __EVENTTARGET check was added because IE fires the onbeforeunload event twice
      // in the case of link buttons. The affect is that the confirm will be displayed to 
      // the user twice. The first time the event fires the __doPostBack function 
      // has not been called yet so the __EVENTTARGET.value will be empty and the confirm 
      // message is diaplayed. The second time the event is fired the __EVENTTARGET.value 
      // will be set by the __doPostBack function so we do not set the returnValue and 
      // display the confirm again.
		if(oForm.dirty.value == "true" && (typeof(oForm.__EVENTTARGET) != "object" || oForm.__EVENTTARGET.value == ""))
		{
			event.returnValue = oForm.dirty.errorMessage;
		}
	}
	catch(e)
	{
	}
}

//walks all the input checkbox items and checks or unchecks
//all the checkboxes that have a ClientName attribute value matching
//the ClientName property.
function toggleAll(ClientName, toggleControl)
{
	var container = document.forms(1);
	var oItems = container.getElementsByTagName("input");
	var bChecked = container.chkToggle.checked;
	for(i = 0; i < oItems.length; i++)
	{
		if(oItems[i].type == "checkbox")
		{
			if(oItems[i].getAttribute("ClientName") == ClientName && oItems[i].disabled == false)
			{
				oItems[i].checked = bChecked;
			}
		}
	}
}

///Walks all the input type checkbox items in the oForm
///and any that have a ClientName attribute equal to ClientName
///parameter and are checked will be returned in an array.
function GetSelectedIDs(ClientName, oForm)
{
	//get all the input boxes.

	var oItems = oForm.getElementsByTagName("input");
	var entityIDs = new Array();
	for(i = 0; i < oItems.length; i++)
	{
		//if the item is a checkbox
		if(oItems[i].type == "checkbox")
		{
			//has to match ClientName passed in.
			if(oItems[i].getAttribute("ClientName") == ClientName && oItems[i].checked)
			{	
				//add the item to the array.
				entityIDs.push(oItems[i].value);
			}
		}
	}
	
	//return the array of entityIDs.
	return entityIDs;
}


//Walks all the input type checkbox items on the page
//and any that have a ClientName attribute value equal to ClientName
//parameter and that are checked will be sent along to be added to the partner group.
function AddIdsToGroup(ClientName, HiddenName, ErrorMessage, Limiter)
{
	//Form 0 is the MNP Form, Form 1 is the ASPX form ... we may want to possible modify this, passing into the
	//function a form name, but for now this seems to work fine for what it was designed
	var container = document.forms(1);
	var oItems = container.getElementsByTagName("input");
	
	var entityIDs = new Array();
	for(i = 0; i < oItems.length; i++)
	{
		if(oItems[i].type == "checkbox")
		{
			if(oItems[i].getAttribute("ClientName") == ClientName && oItems[i].checked)
			{
				entityIDs.push(oItems[i].value);
			}
		}
	}
	
	//If a limiting control ID has been passed in, make sure the user hasn't selected more than they are allowed
	if(Limiter != '')
	{
		var oLimitItem = document.getElementById(Limiter);
		var limitingValue = oLimitItem.value;
		if(entityIDs.length > limitingValue)
		{
			alert('You have chosen more items than you are allowed.  Please reduce your selection.');
			return false;
		}
	}
	//If no IDs are selected, return an error message and exit
	if(entityIDs.length == 0)
	{
		alert(ErrorMessage);
		return false;
	}
	else
	{

		oItems = container.getElementsByTagName("input");
		for(i = 0; i < oItems.length; i++)
		{
			if(oItems[i].type == "hidden")
			{
				if(oItems[i].name == HiddenName)
				{
					oItems[i].value = entityIDs.join("|");
				}
			}
		}
		return true;
	}
}

//  Gets the select value from a modal Dialog window to apply an event reason to an action or possibly for future extension.
//	Works by opening up DomainDialog.aspx with Query String values
//  Parameters/Usage : domainName - specifies the domain to populate the selection utility (query string value)
//					   dialogType - specifies the selection utility (currently options are 'RadioList' or 'DropDown') (query string value)
//					   hiddenName - specifies the hidden control in which to store the collection of IDs
//					   errorMessage - a pop-up message displayed if no IDs are selected
//					   popUpTitle - the <Title> of the pop-up window (query string value)
//					   limiter - the control that provides a value which may limit how many IDs the user can apply an action to
//					   returnControlName - the control to store the returned value in
// use : Opportunities.ascx (MyPendingOpportunities.aspx)
function getValue( domainName, dialogType, hiddenName, errorMessage, popUpTitle, limiter, returnControlName )
{
	if(AddIdsToGroup('chkAdd', hiddenName, errorMessage, limiter))
	{
		var oEl = event.srcElement;
		var oTxtEl = document.getElementById(returnControlName);
		var pageName = "DomainDialog.aspx?Domain="+domainName+"&DialogType="+dialogType+"&Title="+popUpTitle;
		var sFeatures="dialogHeight: 180px; dialogWidth: 285px; help: no; resizable: no; status: no; scroll: no;";
		var returnValue = window.showModalDialog(pageName, oTxtEl.value, sFeatures);
		if(returnValue == null)
		{
			return false;
		}
		else
		{
			oTxtEl.value = returnValue;
			return true;
		}
	}
	else
	{
		return false;
	}

}

//	Gets the selected item, presumably from a RadioList control
//  used : DomainDialog.aspx
function getSelectedRadioItem()
{
	var oItems = document.getElementsByTagName("input");
	
	var entityIDs = new Array();
	for(i = 0; i < oItems.length; i++)
	{
		if(oItems[i].type == "radio")
		{
			if(oItems[i].checked)
			{
				return oItems[i].value;
			}
		}
	}
}

//	Gets the selected item, presumably from a DropDown control, whose ID is specified in the parameter
//  used : DomainDialog.aspx
function getSelectedDropDownItem( controlID )
{
	var oItem = document.getElementById(controlID);
	return oItem.selectedIndex;
}

//  Switches the value in a hidden control (specified by the parameter) between
//  True and False, providing a binary switch for changing between Admin and normal
//  Contact views of data
//  used : MyOpenOpportunities.aspx, MyClosedOpportunities.aspx
function toggleViewOption( viewOptionControl )
{
	var oViewOptionControlItem = document.getElementById(viewOptionControl);
	if(oViewOptionControlItem.value == 'False')
		oViewOptionControlItem.value = 'True';
	else
		oViewOptionControlItem.value = 'False';
	return true;
}

//  Opens a modal window to browse an object, specified by the ObjectType and ObjectID
function openObjectBrowser( ObjectType, ObjectID )
{
		var pageName = "ObjectBrowser.aspx?ObjectType="+ObjectType+"&ObjectID="+ObjectID;
		var sFeatures="dialogHeight: 300px; dialogWidth: 400px; help: no; resizable: no; status: no;";
		var returnValue = window.showModalDialog(pageName, '', sFeatures);
		return returnValue;	
}

function openDialogWindow( frame, url, modalOptions )
{
	var modelArguements = new Object();
	modelArguements.UrlString = url;

	returnValue = window.showModalDialog(frame, modelArguements, modalOptions);

   if (typeof(returnValue) == 'boolean') 
   { 
      return returnValue; 
   } 
   else 
   { 
      window.navigate(returnValue); 
      return false; 
   }
}

function closeWindow(confirmMessage)
{
	if(confirm(confirmMessage))
	{
	   var oForm = getCorrectForm();
	   if (typeof(oForm) != "undefined")
	   {
		   oForm.dirty.value = "false";
		}
		closeWindow();
		return true;
	}
	else
	   return false;
}

function closeWindow()
{
	var mainwindow = window.self; 
	mainwindow.opener = window.self;
	mainwindow.close();
}

function MaxLengthPaste()
{
   var control = event.srcElement;
   if(isNaN(control.maxLength)) return;
   
   event.returnValue = false;
   var tr = control.document.selection.createRange();   
   var insertLength = control.maxLength - control.value.length + tr.text.length;
   var newData = window.clipboardData.getData("Text").substr(0,insertLength);
   newData = newData.replace(/\t/g,' ');
	tr.text = newData;
	ShowCount(control);
}

function MaxLengthDragEnter()
{   
   var control = event.srcElement;
   if(isNaN(control.maxLength)) return;
   
   var newData = event.dataTransfer.getData("Text");   
   if(newData.length + control.value.length > control.maxLength-1)
   {
      event.returnValue = false;
      event.dataTransfer.dropEffect = "none";
      event.dataTransfer.effectAllowed = "none";
   }
}

function MaxLengthKeyPress()
{
   var control = event.srcElement;
   if(isNaN(control.maxLength)) return;
   
   var tr = control.document.selection.createRange();
	// Allow user to type character if at least one character is selected
	if(tr.text.length >= 1)
	{
		event.returnValue = true;
	}	
   else if(control.value.length > control.maxLength-1)
   {
      event.returnValue = false;
   }
   ShowCount(control);
}

function MaxLengthKeyUp()
{
   var control = event.srcElement;
   ShowCount(control);
}

function ShowCount(control)
{
   var label = document.all[control.Label];
   var length = control.maxLength - control.value.length;
   
   if (length < 0)
   {
      length = 0;
   }
   
   if (typeof(label) != "undefined")
   {
      label.innerText = label.message.replace("|x|",length);
   }
}

function openDialogWindow( frame, url, modalOptions, navigate )
{
	var modelArguements = new Object();
	modelArguements.UrlString = url;

	returnValue = window.showModalDialog(frame, modelArguements, modalOptions);

   if (typeof(returnValue) == 'boolean') 
   { 
      return returnValue; 
   } 
   else if (navigate)
   { 
      window.navigate(returnValue); 
      return false; 
   }
   else
   {
      return false;
   }
}

function OpenPrintWindow( url )
{
   return openDialogWindow(url, null, "dialogHeight:600px;dialogWidth:800px;center:yes;status:no;resizable:no;help:no;", false);
}

function ValidatorFocus()
{
   var i;
    for (i = 0; i < Page_Validators.length; i++)
    {
        if (!Page_Validators[i].isvalid)
        {
            var obj = document.getElementById(Page_Validators[i].controltovalidate);

            if (obj != null) 
            {
                showErrorBubble(obj.id, true);
                break;
            }
            else
            {
                showErrorBubble(Page_Validators[i].id, true);
                break;
            }
        }
    }
}

function hideBubble()
{
   //element.className = element.className.replace(' bubbleController', '');
   var bubble = document.getElementById('errorBubble');
   if (bubble != null) {
      bubble.style.display = 'none';
   }
   var shim = document.getElementById('errorShim');
   if (shim != null) {
      shim.style.display = 'none';
   }
}

var hideTimeoutId = null;
function showErrorBubble(errorSrc)
{
   var src = document.getElementById(errorSrc);
   if (src == null) return;
   
   var shim = document.getElementById('errorShim');

   var b = document.getElementById('errorBubble');
   if (b == null) return;
   
   b.style.setExpression("left", "getElementLeft(document.getElementById('" + src.id + "'))");
   b.style.setExpression("top", "getElementTop(document.getElementById('" + src.id + "')) - (document.getElementById('errorBubble').clientHeight + 3)");

   shim.style.setExpression("left", "getElementLeft(document.getElementById('" + src.id + "'))");
   shim.style.setExpression("top", "getElementTop(document.getElementById('" + src.id + "')) - (document.getElementById('errorBubble').clientHeight + 3)");

   b.style.display = "block";
   shim.style.display = "block";
   shim.style.width = b.clientWidth;
   shim.style.height = b.clientHeight;
   
	document.recalc(true);

   if (src.className.indexOf("bubbleController") == -1) src.className += ' bubbleController';

   // Try to set focus (there doesn't seem to be a way to determine if a
   // control is visible (when a container is hidden), or can recieve focus
   try
   {
      // Set the focus on the control which failed the validation
   src.focus()
   }
   catch(e)
   {
      // If setting the focus failed, try to expand all parent ExpandColapse sections
      // (setting focus will fail if a parent container is not shown)
      expandCollapsedParents(src);
      
      src.focus();
   }

   // Scroll the window to the control to display the error message
   // This was behaving intermittantly when calling it directly, so
   // this was put in a timeout with a one millisecond delay
   var left = getElementLeft(src);
   var top = getElementTop(src) - 100
   var command = "window.scrollTo(" + left + ", " + top + ");";
   window.setTimeout(command, 1);
   //window.scrollTo(left, top);
   
   if (hideTimeoutId != null) window.clearTimeout(hideTimeoutId);
   hideTimeoutId = window.setTimeout("hideBubble();", 7000)
}

function getElementTop(src)
{
	var top = 0;
	var parent = src;
	while (parent != null)
	{
		top += parent.offsetTop;
		parent = parent.offsetParent;
	}

	return top;
}

function getElementLeft(src)
{
	var left = 0;
	var parent = src;
	while (parent != null)
	{
		left += parent.offsetLeft;
		parent = parent.offsetParent;
	}

	return left;
}

// Expand any collapsed ExpandCollapse sections which are parents
// of "element"
function expandCollapsedParents(element)
{
   var parent = element.parentElement;
   while (parent != null)
   {
      if (parent.className.match(/\bcollapsed\b/gi))
      {
         parent.previousSibling.firstChild.ExpandCollapse();
      }
         
      parent = parent.parentElement;
   }
}

function OpenNewWindow(url)
{
	window.open(url);
	bubbleEvent = false;
}

function GetIFrameEmptySource()
{
   return '';
}
