var undefined;
var ShowErrorHandler = undefined;
var OnNavigateValidate = undefined;
var OnCustomise = undefined;

//Window abstraction for IFRAMEs that act like sub-windows
var _window;						//Our abstracted (across the different dialog types) window object
var _fakewindow = new Object();		//The fake window object for non-IE dialogs
var DialogStack = new Array();		//For nesting dialogs when not in IE.
var bInDialog = false;

function ShowInfo(infoid)
{
	var info = document.getElementById(infoid);
	var pane = document.getElementById('InformationPane');
	pane.innerHTML = info.innerHTML;
}

function OnLoadPage(top)
{
	bInDialog = this.frameElement != null;
	if (bInDialog && (this.frameElement.id.indexOf('dialog_iframe')==0))
        _window = parent.parent._fakewindow;
    else
        _window = window;
	
	if (top != undefined)
	{
	    //Which one to use depends on browser and doctype, so just set both (one will be ignored, and stay at zero). 
	    //Similarly, your OnScroll/OnResize function in custommaster.asp should use Math.max(document.documentElement.scrollTop,document.body.scrollTop)
		document.body.scrollTop = top;
		document.documentElement.scrollTop = top;
    }
	InitFields();
	if (OnCustomise != undefined)
		OnCustomise();
	InitForm();
}

function OnNavigate(formid)
{
	if (!OnCheckNavigate())
		return;
	var save = document.getElementById('$Save');
	if (save != undefined)
		save.value = '';
	var next = document.getElementById('$NEXTFORMID');
	next.value = formid;
	document.forms[0].submit();
}

function OnCheckNavigate()
{
	if (OnNavigateValidate != undefined)
		return OnNavigateValidate();
	else
		return true;
}

function NewXMLHttpRequest() 
{
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) 
        return new XMLHttpRequest();
    // branch for IE/Windows ActiveX version
    else if (window.ActiveXObject) 
        return new ActiveXObject("Microsoft.XMLHTTP");
}

function ShowMenu(id, show)
{
	var menu = document.getElementById(id);
	var pop = document.getElementById('PageOfPage');
	var pagetext = pop.innerHTML;
	var pages = pagetext.split(' ');
	var total = new Number(pages[2]);
	
	if ((menu.style.display == 'none') == show)
		total += (show ? 1 : -1);	
		
	pop.innerHTML = pages[0] + ' ' + pages[1] + ' ' + total
	menu.style.display = (show?'':'none');
}

function URLEncode(plaintext) // The Javascript escape function doesn't work properly with + and space chars
{
	var safechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_.!~*'()";	// Alphanumeric + RFC2396 Mark characters
	var hex = "0123456789ABCDEF";	//for base 10 -> 16 conversion

	var encoded = "";
	for (var i = 0; i < plaintext.length; i++) 
	{
		var ch = plaintext.charAt(i);
	    if (ch == " ") 
		    encoded += "+";				// x-www-urlencoded, rather than %20
		else if (safechars.indexOf(ch) != -1) 
		    encoded += ch;
		else 
		{
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255)			    
				encoded += "+";	//Unicode Character - substitute space
			else 
			{
				encoded += "%";
				encoded += hex.charAt((charCode >> 4) & 0xF);
				encoded += hex.charAt(charCode & 0xF);
			}
		}
	}

	return encoded;
};

function SBCModalDialog(callback, url, parameter, settings, args)
{
	//Remember the parameters (regardless of which way we're doing the dialog)	
	_fakewindow.callback_args = args;
	
	if (is_IE) //Note: (window.showModalDialog) true for FF3, which has a glitch relating to returnValue that we'll need to address...
	{
		//IE
		var ret = window.showModalDialog(url,parameter,settings);
		callback(ret,args);
	}
	else
	{
		//non-IE
		if (url.indexOf('dialog.asp?title=') == 0)
		{
			var overlay, dialog, title, iframe; // Vars for the important nodes involved with displaying a dialog.
			
			//Artificial scope to protect usage of ID vars outside of if-else
			{
				var dlgId = 'dialog';
				var dlgTitleId = 'dialog_title';
				var iframeId = 'dialog_iframe';
							
				//Setup _fakewindow in the parent.
				if (bInDialog)
				{
					//This is a nested dialog situation. Push the current parent._fakewindow onto the stack
					var oldDlg = new Object();
					for (var e in parent._fakewindow)
					oldDlg[e] = parent._fakewindow[e];
					parent.DialogStack.push(oldDlg);
					//Also hide it
					parent.document.getElementById(parent._fakewindow.dlgId).style.visibility = 'hidden';
					//Now we can play around with parent._fakewindow since the new dialog will be referencing it
					parent._fakewindow.callback = callback;
					parent._fakewindow.close = parent.SBCModalDialogClose;
					parent._fakewindow.dlgId = dlgId + parent.DialogStack.length;
					parent._fakewindow.dlgTitleId = dlgTitleId + parent.DialogStack.length;
					parent._fakewindow.iframeId = iframeId + parent.DialogStack.length;
					//And make the new dialog DIV via cloning of a template DIV
					// - Grab the important nodes prior to cloning and alter their ids
					var tmp_dlg = parent.document.getElementById('template_'+dlgId);
					var tmp_dlgTitle = parent.document.getElementById('template_'+dlgTitleId);
					var tmp_iframe = parent.document.getElementById('template_'+iframeId);
					// - Change the ids before cloning
					tmp_dlg.id = parent._fakewindow.dlgId;
					tmp_dlgTitle.id = parent._fakewindow.dlgTitleId;
					tmp_iframe.id = parent._fakewindow.iframeId;
					// - Do the clone
					var newDialog = tmp_dlg.cloneNode(true);
					// - Put ids back
					tmp_dlg.id = 'template_'+dlgId;
					tmp_dlgTitle.id = 'template_'+dlgTitleId;
					tmp_iframe.id = 'template_'+iframeId;
					// - Alter display of new IFRAME to show it, since template should be set to display:none...
					newDialog.style.display = '';
					// - Add new DIV/IFRAME to the DOM
					tmp_dlg.parentNode.insertBefore(newDialog,tmp_dlg);
					//Finally, fix up local node vars to use the new nodes				
					overlay = parent.document.getElementById("overlay");
					iframe = parent.document.getElementById(parent._fakewindow.iframeId);
					dialog = parent.document.getElementById(parent._fakewindow.dlgId);
					title = parent.document.getElementById(parent._fakewindow.dlgTitleId);
				}
				else
				{
					overlay = document.getElementById("overlay");
					iframe = document.getElementById(iframeId);
					dialog  = document.getElementById(dlgId);
					title = document.getElementById(dlgTitleId);
					
					_fakewindow.callback = callback;
					_fakewindow.close = SBCModalDialogClose;
					_fakewindow.dlgId = dlgId;
					_fakewindow.dlgTitleId = dlgTitleId;
					_fakewindow.iframeId = iframeId;
				}
			}
			
			//Start loading the dialog			
			iframe.src = parameter;
			
			//Parse arguments to get information about dialog
			url = url.replace('dialog.asp?title=','');
			url = url.replace(/\+/g,' ');
			url = unescape(url);
			
			var idx,idxEnd;
			var width='350px', height='200px';
			idx = settings.indexOf('dialogWidth:');			
			if (idx >= 0)
			{
				idx += String('dialogWidth:').length;
				idxEnd = settings.indexOf(';',idx);
				width = settings.substr(idx,idxEnd-idx);
			}
			idx = settings.indexOf('dialogHeight:');			
			if (idx >= 0)
			{
				idx += String('dialogHeight:').length;
				idxEnd = settings.indexOf(';',idx);
				height = settings.substr(idx,idxEnd-idx);
			}
			
			//Now apply that information	
			dialog.style.width = width;
			dialog.style.height = height;
			iframe.style.height = (height - title.offsetHeight) + 'px';
			title.textContent = url;

			//Show the dialog			
			overlay.style.visibility = "visible";
			dialog.style.visibility = "visible";
		}
	}
}

function SBCModalDialogClose()
{
	//Hide the dialog
	if (!is_IE && !DialogStack.length)
	{
		var overlay = document.getElementById("overlay");
		overlay.style.visibility = "hidden";
		var dlg = document.getElementById("dialog");
		dlg.style.visibility = 'hidden';
		var iframe = document.getElementById('dialog_iframe');
		iframe.src = "blank.asp";
	}
	
	//Run the callback
	_fakewindow.callback(_fakewindow.returnValue,_fakewindow.callback_args);
	
	//Restore _fakewindow if in non-IE nested dialog
	if (!is_IE && DialogStack.length)
	{
		var overlay = document.getElementById("overlay");
		//Nuke current _fakewindow DIV/IFRAME
		var dlg = document.getElementById(_fakewindow.dlgId);
		overlay.removeChild(dlg);
		//Return _fakewindow to the old one, and show it
		_fakewindow = DialogStack.pop();
		document.getElementById(_fakewindow.dlgId).style.visibility = 'visible';
	}
}

function NewGridRowDialog(FormId,GridId,title,asppage,width,height,querystring)
{
	if (querystring == undefined)
		querystring = '';
	var args = new Array();
	args[0]=FormId;
	args[1]=GridId;
	SBCModalDialog(NewGridRowDialogClose,'dialog.asp?title='+URLEncode(title),asppage+'.asp?$Activity=New'+querystring,'dialogWidth:'+width+'px; dialogHeight:'+height+'px; status:no; help:no;',args);
}

function NewGridRowDialogClose(ret,args)
{
	if (ret == 'IDOK')
	{
		document.getElementById('$ACTION').value = 'Refresh';
		var param = document.getElementById('$PARAM');
		if (param != undefined)
		    param.value = 'NewRow:' + args[1] + ':' + ret;
		document.forms[0].submit();
	}
	else 
		RemoveGridRow(args[0],args[1],ret);	//they must have cancelled, remove the new grid row that was created
}

function ModifyGridRowDialog(FormId,GridId,RowNo,title,asppage,width,height,querystring)
{
	CheckpointGridRow(FormId,GridId,RowNo);
	if (querystring == undefined)
		querystring = '';		
	var args = new Array();
	args[0]=FormId;
	args[1]=GridId;
	args[2]=RowNo;
	SBCModalDialog(ModifyGridRowDialogClose,'dialog.asp?title='+URLEncode(title),asppage+'.asp?$RowNo='+RowNo+querystring,'dialogWidth:'+width+'px; dialogHeight:'+height+'px; status:no; help:no;',args);
}

function ModifyGridRowDialogClose(ret,args)
{
	if (ret == 'IDOK')
	{
		document.getElementById('$ACTION').value = 'Refresh';
		var param = document.getElementById('$PARAM');
		if (param != undefined)
		    param.value = 'ModifyRow:' + args[1] + ':' + args[2];
		document.forms[0].submit();
	}
	else
		UndoGridRow(args[0],args[1],args[2]);
}

function RemoveGridRow(FormId,GridId,RowNo)
{
	var sPostData = "Action=RemoveGridRow&FormId="+URLEncode(FormId)+"&GridId="+URLEncode(GridId)+"&RowNo="+URLEncode(""+RowNo);
	RunGridRowUtils(sPostData);
}

function CheckpointGridRow(FormId,GridId,RowNo)
{
	//Set an Undo checkpoint prior to modification
	var sPostData = "Action=Checkpoint&FormId="+URLEncode(FormId)+"&GridId="+URLEncode(GridId)+"&RowNo="+URLEncode(""+RowNo);
	RunGridRowUtils(sPostData);	
}

function UndoGridRow(FormId,GridId,RowNo)
{
	//Undo any modifications that were applied
	var sPostData = "Action=Undo&FormId="+URLEncode(FormId)+"&GridId="+URLEncode(GridId)+"&RowNo="+URLEncode(""+RowNo);
	RunGridRowUtils(sPostData);	
}

function RunGridRowUtils(sPostData)
{
	var req = NewXMLHttpRequest();	
	req.open('POST','gridrowutils.asp',false);	
	req.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	req.send(sPostData);
	if (req.status != 200)
	{
		alert(ErrorHeaderText + 'Date/Time: ' + new Date() + '\nHTTP status = ' + req.status + '\nError: ' + req.statusText + '\nURL: gridrowutils.asp');
		return 0;
	}
	if (req.responseText.substring(0,6) == "Error:")
	{
		alert(ErrorHeaderText + req.responseText);
		return 0;
	}
}