// Set BusinessFunction hidden field
function waMasterPage_SetBusinessFunction(BusinessFunctionCode)
{
	var ctl = $('BusinessFunction');
	if (ctl != null) ctl.value = BusinessFunctionCode;
}
// Navigating the ASPNet mangled client id hierarchy
function waMasterPage_GetAncestorClientID(control, childId, ancestorId)
{
	var childClientId = (control.id != undefined) ? control.id : (control.get_id != undefined) ? control.get_id() : (control.get_element != undefined) ? control.get_element().id : '';
	var ret = null;
	var client = new String(childClientId);
	var child = new String(childId);
	var ancestor = new String(ancestorId);
	if ((client.length > 0) && (ancestor.length > 0) && (child.length > 0))
	{
		if (ancestor.length + child.length < client.length)
		{
			client = client.substr(0, client.length - child.length);
			var index = client.lastIndexOf(ancestor);
			if (index >= 0)
			{
				ret = client.substr(0, index + ancestor.length);
			}
		}
	}
	return ret;
}
// Get client ID of a sibling in the server control hierarchy
// Parameters:
//   control is a DHTML object or a Telerik client object
//   siblingId is the server control ID whose client ID is being requested
// NOTE: assume that the server side id is that part of the client id after the last underscore character
function waMasterPage_GetSiblingClientID(control, siblingId)
{
	var clientId = (control.id != undefined) ? control.id : (control.get_id != undefined) ? control.get_id() : (control.get_element != undefined) ? control.get_element().id : '';
	return waMasterPage_GetSiblingClientIDFromClientID(clientId, siblingId);
}
function waMasterPage_GetSiblingClientIDFromClientID(clientId, siblingId) {
    var ret = null;
    var client = new String(clientId);
    var index = client.lastIndexOf("_");
    if ((index >= 0) && (client.length > index + 1)) {
        var me = client.substring(index + 1);
        var sibling = new String(siblingId);
        if ((client.length > 0) && (sibling.length > 0) && (me.length > 0)) {
            if (me.length < client.length) {
                client = client.substr(0, client.length - me.length);
                ret = client + sibling;
            }
        }
    }
    return ret;
}
// Get client ID of the naming container of a server control
// Parameters:
//   control is a DHTML object or a Telerik client object
// NOTE: assume that the server side id is that part of the client id after the last underscore character
function waMasterPage_GetNamingContainerClientID(control) {
    var clientId = (control.id != undefined) ? control.id : (control.get_id != undefined) ? control.get_id() : (control.get_element != undefined) ? control.get_element().id : '';
    var ret = null;
    var client = new String(clientId);
    var index = client.lastIndexOf("_");
    if ((index >= 0) && (client.length > index)) {
        var me = client.substring(index);
        if ((client.length > 0) && (me.length > 0)) {
            if (me.length < client.length) {
                ret = client.substr(0, client.length - me.length);
            }
        }
    }
    return ret;
}

function waMasterPage_GetChildElementByTagNameServerID(ctrl, tagName, serverID) {
    var ctrls = ctrl.getElementsByTagName(tagName);
    for (var index = 0; index < ctrls.length; index++) {
        var id = ctrls[index].id;
        if ( (id.length >= serverID.length) && (id.substr(id.length-serverID.length, serverID.length) == serverID) ) return ctrls[index];
    }

    return null; 
}

//
// Get RadWindow object that the javascript code is currently running in
// This code was copied from a telerik example  (EditorInWindow.aspx RadEditor example)
//
function waMasterPage_GetThisRadWindow() {
    var oWindow = null;
    if (window.radWindow) oWindow = window.radWindow;
    else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
    return oWindow;
}
				    
// waCurrencyInfo
var _waCurrencyInfo = new Array();
function waCurrencyInfoInit() {
    _waCurrencyInfo = new Array();
}
function waCurrencyInfo$(CurrencyCode) {
    for (var i = 0; i < _waCurrencyInfo.length; i++) {
        var id = _waCurrencyInfo[i].CurrencyCode;
        if (id == new String(CurrencyCode).substring(0, id.length)) return _waCurrencyInfo[i];
    }
    return null;
}
// Contains ISO4217 currency code, current exchange rate and properties of RadNumericTextBox's client NumberFormat (CultureInfo.NumberFormat DotNet property)
function waCurrencyInfo(CurrencyCode, Rate, AllowRounding, DecimalDigits, DecimalSeparator, GroupSeparator, GroupSizes, NegativePattern, NegativeSign, PositivePattern) {
    this.CurrencyCode = CurrencyCode;
    this.Rate = Rate;
    this.AllowRounding = AllowRounding;
    this.DecimalDigits = DecimalDigits;
    this.DecimalSeparator = DecimalSeparator;
    this.GroupSeparator = GroupSeparator;
    this.GroupSizes = GroupSizes;
    this.NegativePattern = NegativePattern;
    this.NegativeSign = NegativeSign;
    this.PositivePattern = PositivePattern;
    if (waCurrencyInfo$(CurrencyCode) == null) _waCurrencyInfo.push(this);
    this.SetNumberFormat = function(numberFormat) {
        numberFormat.AllowRounding = this.AllowRounding;
        numberFormat.DecimalDigits = this.DecimalDigits;
        numberFormat.DecimalSeparator = this.DecimalSeparator;
        numberFormat.GroupSeparator = this.GroupSeparator;
        numberFormat.GroupSizes = this.GroupSizes;
        numberFormat.NegativePattern = this.NegativePattern;
        numberFormat.NegativeSign = this.NegativeSign;
        numberFormat.PositivePattern = this.PositivePattern;
    }
}
// Cross-Browser support
// For browser-dependent code
var waCrossBrowser_isIE_ = null;
function waCrossBrowser_isIE()
{
	if (waCrossBrowser_isIE_ == null) waCrossBrowser_isIE_ = (navigator.appName.search(/internet explorer/i) >= 0);
	return waCrossBrowser_isIE_;
}
function waCrossBrowser_SetTextContent(ctl, text)
{
	if (ctl != null)
	{
		if (waCrossBrowser_isIE())
			ctl.innerText = (text == null) ? "" : text;
		else
		    ctl.textContent = (text == null) ? "" : text;
	}
}
function waCrossBrowser_GetTextContent(ctl)
{
	if (ctl != null)
	{
		if (waCrossBrowser_isIE())
			return ctl.innerText;
		else
			return ctl.textContent;
	}
	else
		return null;
}
function waCrossBrowser_FirstChildElement(parent) {
    var node = null;
    if ((parent != null) && (parent.nodeType == 1)) {
        node = parent.firstChild;   // With firefox this may be a text node, with IE it is always an element
        while ( (node != null) && (node.nodeType != 1)) {
            node = node.nextSibling;
        }
    }
    return node;
}
function waCrossBrowser_CancelEvent() {
    try {
        var e = window.event;
        if (!e) e = window.Event;
        if (e) {
            e.returnValue = false;
            e.cancelBubble = true;
            e.stopPropagation();
        }
    } catch (c) { }
    return false;
}

// Date Validator
function waMasterPage_IsAllBlanks(str)
{
	var index;
	for (index = 0; index < str.length; index++)
	{
		if (" " != str.charAt(index)) return false;
	}
	return true;
}
function waMasterPage_ParseCurrency(str)
{
	var ss = str.split(String.fromCharCode(163));       // TODO Locale
	if (ss.length > 1) str = ss[1]; else str = ss[0];
	// remove any embedded ","
	ss = str.split(",");
	str = "";
	var index;
	for (index = 0; index < ss.length; index++) {
	    str = str + ss[index];
	}
	return parseFloat(str);
}
function waMasterPage_FormatCurrency(num, thousandSep)
{
	num = num.toString()
	if (isNaN(num))
		num = "0";
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num * 100 + 0.50000000001);
	pence = num % 100;
	num = Math.floor(num / 100).toString();
	if (pence < 10)
		pence = "0" + pence;
	if ((thousandSep != null) && (thousandSep.length > 0))
	{
		for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
		{
			num = num.substring(0, num.length - (4 * i + 3)) + thousandSep + num.substring(num.length - (4 * i + 3));
		}
	}
	return (((sign) ? '' : '-') + num + '.' + pence);
}
function waMasterPage_ParseDate(str)
{
	// look for 3 sections separated by " ", "/" or "-"
	var ss = str.split(" ");
	if (ss.length == 3) return waMasterPage_ParseDate1(ss);
	ss = str.split("/");
	if (ss.length == 3) return waMasterPage_ParseDate1(ss);
	ss = str.split("-");
	if (ss.length == 3) return waMasterPage_ParseDate1(ss);
	return null;
}
function waMasterPage_ParseDate_YMD(str)
{
	// look for 3 sections separated by " ", "/" or "-"
	var ss = str.split(" ");
	if (ss.length == 3) return waMasterPage_CreateDate(parseInt(ss[0], 10), parseInt(ss[1], 10), parseInt(ss[2], 10));
	ss = str.split("/");
	if (ss.length == 3) return waMasterPage_CreateDate(parseInt(ss[0], 10), parseInt(ss[1], 10), parseInt(ss[2], 10));
	ss = str.split("-");
	if (ss.length == 3) return waMasterPage_CreateDate(parseInt(ss[0], 10), parseInt(ss[1], 10), parseInt(ss[2], 10));
	return null;
}
function waMasterPage_ParseDate1(ss)
{
	// Convert to integers
	// NOTE: There is a known bug with parseInt().  If only one parameter is supplied and it is an integer with a leading 0
	//       then parseInt can return 0 (by trial and error parseInt("08") and parseInt("09") both return 0 but
	//       parseInt("01" etc seem to work
	//       The call works if the second parameter (10 for a base-10 integer) is supplied
	var v0 = parseInt(ss[0], 10);
	var v1 = parseInt(ss[1], 10);
	var v2 = parseInt(ss[2], 10);
	if (ss[2].length <= 2)
	{
		// Assume this was a 2-digit year. Convention for this:
		// 00-30 = 20xx, 31-99 = 19xx
		if (v2 <= 30)
		{
			v2 += 2000;
		}
		else
		{
			v2 += 1900;
		}
	}
	// Call appropriate CreateDate function
	// Note that in javascript month numbers range from 0 to 11
	if (isNaN(v0)) return waMasterPage_CreateDate(v2, waMasterPage_MonthNumberFromName(ss[0]), v1);
	if (isNaN(v1)) return waMasterPage_CreateDate(v2, waMasterPage_MonthNumberFromName(ss[1]), v0);
	if (v0 > 999) return waMasterPage_CreateDate(v0, v1 - 1, v2);
	return waOrganisation.isDMY ? waMasterPage_CreateDate(v2, v1, v0) : waMasterPage_CreateDate(v2, v0, v1);
}
function waMasterPage_MonthNumberFromName(name)
{
	// Return 1-based month number.  THis will be converted to a zero-based month number for javascript by the called
	name = name.toLowerCase();
	var m;
	for (m = 0; m < waOrganisation.ShortMonthNames.length; m++)
	{
		if (name == waOrganisation.ShortMonthNames[m].toLowerCase()) return m + 1;
	}
	for (m = 0; m < waOrganisation.MonthNames.length; m++)
	{
		if (name == waOrganisation.MonthNames[m].toLowerCase()) return m + 1;
	}
	return -1;
}
function waMasterPage_CreateDate(year, month, day)
{
	if (isNaN(year) || isNaN(month) || isNaN(day)) return null;
	var d = new Date();
	month = month - 1;  // Javascript Date() object uses zero based month
	d.setFullYear(year, month, day);
	d.setHours(0, 0, 0, 0);
	if ((year != d.getFullYear()) || (month != d.getMonth()) || (day != d.getDate())) return null;
	return d;
}
function waMasterPage_FormatDate(d)
{
	// TODO - recognise dates other than d MMM yyyy
	return String(d.getDate()) + " " + waOrganisation.ShortMonthNames[d.getMonth()] + " " + String(d.getFullYear());
}
function waMasterPage_FormatDateForSQL(d)
{
    if (d == null) {
        return "";
    }
    else {
        var strDate = (d.getDate() < 10) ? "0" + String(d.getDate()) : String(d.getDate());
        var strMonth = (d.getMonth() < 9) ? "0" + String(d.getMonth() + 1) : String(d.getMonth() + 1);
        return String(d.getFullYear()) + "-" + strMonth + "-" + strDate;
    }
}
// inputCtl       <input> element containing the string to validate
//                        If valid this will be formatted, rounding to 2 dec places
// inputHidden    <input type="hidden" > to receive valid number without any thousands separator
//                        This parameter may be null in which case it is ignored
// elementMessage An DHTML element to contain any error message text
//                      
function waMasterPage_ValidateCurrency(inputCtl, inputHidden, elementMessage)
{
	if ((inputCtl != null) && (elementMessage != null))
	{
		if (waMasterPage_IsAllBlanks(inputCtl.value))
		{
			inputCtl.value = "";
			if (inputHidden != null) inputHidden.value = "";
			elementMessage.style.visibility = "hidden";
		}
		else
		{
			var v = waMasterPage_ParseCurrency(inputCtl.value);
			if (isNaN(v))
			{
				waCrossBrowser_SetTextContent(elementMessage, "Invalid currency value");
				elementMessage.style.visibility = "visible";
				inputCtl.focus();
			}
			else
			{
				inputCtl.value = waMasterPage_FormatCurrency(v, ",");
				if (inputHidden != null) inputHidden.value = waMasterPage_FormatCurrency(v, null);
				elementMessage.style.visibility = "hidden";
			}
		}
	}
}
function waMasterPage_ValidateDate(inputCtl, inputHidden, elementMessage)
{
	if ((inputCtl != null) && (elementMessage != null))
	{
		if (waMasterPage_IsAllBlanks(inputCtl.value))
		{
			inputCtl.value = "";
			if (inputHidden != null) inputHidden.value = "";
			elementMessage.style.visibility = "hidden";
		}
		else
		{
			var d = waMasterPage_ParseDate(inputCtl.value);
			if (d == null)
			{
				waCrossBrowser_SetTextContent(elementMessage, "Invalid date");
				elementMessage.style.visibility = "visible";
				inputCtl.focus();
			}
			else
			{
				inputCtl.value = waMasterPage_FormatDate(d);
				if (inputHidden != null) inputHidden.value = waMasterPage_FormatDateForSQL(d);
				elementMessage.style.visibility = "hidden";
			}
		}
	}
}
// Create XML in javascript
function waXMLWriter()
{
	this.XML = [];
	this.Nodes = [];
	this.State = "";
	this.FormatXML = function(Str)
	{
		if (Str)
			return Str.replace(/&/g, "&amp;").replace(/\"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
		return ""
	}
	this.BeginElement = function(Name)
	{
		if (!Name) return;
		if (this.State == "beg") this.XML.push(">");
		this.State = "beg";
		this.Nodes.push(Name);
		this.XML.push("<" + Name);
	}
	this.EndElement = function()
	{
		if (this.State == "beg")
		{
			this.XML.push("/>");
			this.Nodes.pop();
		}
		else if (this.Nodes.length > 0)
			this.XML.push("</" + this.Nodes.pop() + ">");
		this.State = "";
	}
	this.Attribute = function(Name, Value)
	{
		if (this.State != "beg" || !Name) return;
		this.XML.push(" " + Name + "=\"" + this.FormatXML(Value.toString()) + "\"");
	}
	this.WriteString = function(Value)
	{
		if (this.State == "beg") this.XML.push(">");
		this.XML.push(this.FormatXML(Value));
		this.State = "";
	}
	this.Node = function(Name, Value)
	{
		if (!Name) return;
		if (this.State == "beg") this.XML.push(">");
		this.XML.push((Value == "" || !Value) ? "<" + Name + "/>" : "<" + Name + ">" + this.FormatXML(Value) + "</" + Name + ">");
		this.State = "";
	}
	this.Close = function()
	{
		while (this.Nodes.length > 0)
			this.EndElement();
		this.State = "closed";
	}
	this.ToString = function() { return this.XML.join(""); }
}
/* Save the caret position of the specified text field. */
function waSaveCaretPosition(oField) {

    // Initialise
    var caret = new Object();
    caret.start = 0;
    caret.end = 0;
    // IE Support
    if (document.selection) {

        // Set focus on the element - Here we assume focus has already been set
        //oField.focus();
        if (oField.tagName.toLowerCase() == "textarea") {
            var rangeStart = document.selection.createRange().duplicate();
            rangeStart.setEndPoint('EndToStart', rangeStart);
            var rangeEnd = document.selection.createRange().duplicate();
            rangeEnd.setEndPoint('StartToEnd', rangeEnd);
            var range = document.body.createTextRange();
            range.moveToElementText(oField);
            caret.start = waCalcBookmark(rangeStart.getBookmark()) - waCalcBookmark(range.getBookmark());
            caret.end = waCalcBookmark(rangeEnd.getBookmark()) - waCalcBookmark(range.getBookmark());
            // Caret position counts \r\n as a single character so we need to adjust it
            for (var index = 0; index < caret.start; index++) {
                if (oField.value.charAt(index) == "\r") caret.start++;
            }
            for (var index = 0; index < caret.end; index++) {
                if (oField.value.charAt(index) == "\r") caret.end++;
            }
        }
        else {
            // To get cursor position, get empty selection range
            var oSel = document.selection.createRange();
            var len = oSel.text.length;
            oSel.setEndPoint('EndToStart', oSel);
            // Move selection start to 0 position
            oSel.moveStart('character', -oField.value.length);
            // The caret position is selection length
            caret.start = oSel.text.length;
            caret.end = caret.start + len;
        }
    }
    // Firefox support
    //else if (oField.selectionStart || oField.selectionStart == '0')
    else if (oField.selectionStart) {
        caret.start = oField.selectionStart;
        caret.end = oField.selectionEnd;
    }
    // Save results as a property of the DHTML object
    oField.waCaret = caret;
}
function waSetCaretPosition(oField, start, end) {
    oField.focus();
    // IE Support
    if (document.selection) {
        if (oField.tagName.toLowerCase() == "textarea") {
            // Caret position counts \r\n as a single character so we need to adjust it
            for (var index = 0; index < start; index++) {
                if (oField.value.charAt(index) == "\r") start--;
            }
            for (var index = 0; index < end; index++) {
                if (oField.value.charAt(index) == "\r") end--;
            }
        }
        // Create empty selection range
        var oSel = oField.createTextRange();
        oSel.collapse(true);
        oSel.moveEnd('character', end);
        oSel.moveStart('character', start);
        oSel.select();
    }
    // Firefox support
    //else if (oField.selectionStart || oField.selectionStart == '0')
    else if (oField.setSelectionRange) {
        oField.setSelectionRange(start, end);
    }
}
function waCalcBookmark(bk) {
    return (bk.charCodeAt(0) - 1) + (bk.charCodeAt(3) - 1) * 65536 + (bk.charCodeAt(2) - 1);
}

//
function waMasterPage_Position(element) {
    this.x = 0;
    this.y = 0;
    var node = element;
    while (node != null) {
        if (!isNaN(node.offsetLeft)) this.x += node.offsetLeft;
        if (!isNaN(node.offsetTop)) this.y += node.offsetTop;
        node = node.offsetParent;
    }
}
