function replace(strString, strReplace, strReplaceWith)
{
	var nIndex = strString.indexOf(strReplace)
	var nLenRep = strReplace.length
	var nLenRepWith = strReplaceWith.length
	
	while(nIndex > -1)
	{
		strString = strString.substring(0, nIndex) + strReplaceWith + strString.substring(nIndex + nLenRep)
		nIndex = strString.indexOf(strReplace, nIndex + nLenRepWith)
	}
	return strString
}

function IsNumeric(str, currencySymbol, thousandSep)
{
	var strRep = str
	strRep = replace(strRep, currencySymbol, "")
	strRep = replace(strRep, thousandSep, "")
	var val = parseFloat(strRep)
	return (!isNaN(val))
}

function AddPrototypes()
{
	AddStringPrototypes()
}

function AddStringPrototypes()
{
	String.prototype.startsWith = function(s)
	{
		return (this.substring(0, s.length) == s)
	}
}

function f_ReturnFalse()
{
	return false
}

function IsInt(NumberString, AllowNegative, AllowBlank)
{
	var start = 0
	
	if(!AllowBlank && NumberString.length==0)
	{
		return false
	}

	if(NumberString.charAt(0)=="-")
	{
		if(!AllowNegative)
		{
			return false
		}
		start++
	}
	
	for(var i=start; i<NumberString.length; i++)
	{
		if(NumberString.charAt(i)<"0" || NumberString.charAt(i)>"9")
		{
			return false
		}
	}
	return true
}

function IsFloat(NumberString, AllowNegative, AllowBlank)
{
	var start = 0
	var blnGotCur = false
	var blnGotDp = false

	if(!AllowBlank && NumberString.length==0)
	{
		return false
	}

	if(NumberString.charAt(0)=="-")
	{
		if(!AllowNegative)
		{
			return false
		}
		start++
	}
	
	for(var i=start; i<NumberString.length; i++)
	{
		if(NumberString.charAt(i)<"0" || NumberString.charAt(i)>"9")
		{
			if(!blnGotCur && NumberString.charAt(i)==srv_CurrencySymbol)
			{
				blnGotCur = true
			}
			else if(!blnGotDp && NumberString.charAt(i)==srv_DecimalPoint)
			{
				blnGotDp = true
			}
			else if(!blnGotDp && NumberString.charAt(i) == srv_ThousandSeparator)
			{
				//Ok
			}
			else
			{
				return false
			}
		}
	}
	return true
}

function Round(fltNumber, intDP)
{
	var strRet = Math.round(fltNumber * Math.pow(10, 2)) / Math.pow(10, 2)
	
	strRet += "" //Converts to a string	
	strRet = strRet.replace(".", srv_DecimalPoint) //Localise
	
	if(intDP > 0 && strRet.indexOf(srv_DecimalPoint)==-1)
	{
		strRet += srv_DecimalPoint
	}
	
	for(var i=0; i<intDP; i++)
	{
		strRet += "0"
	}
	
	if(intDP > 0)
	{
		strRet = strRet.substring(0, strRet.indexOf(srv_DecimalPoint) + (intDP+1) )
	}
	return strRet
}

function GetDDValue(oDD)
{
	if(oDD.selectedIndex==-1)
	{
		return null
	}
	else
	{
		return oDD.options[oDD.selectedIndex].value
	}
}

function SetDDValue(oDD, val)
{
	for(var i=0; i<oDD.options.length; i++)
	{
		if(oDD.options[i].value==val)
		{
			oDD.selectedIndex = i
			return
		}
	}
	oDD.selectedIndex = -1
}

function MakeArray()
{
	this.length=16;
	for(var i=1; i<=16; i++)
	{
		this[i] = i - 1
	}
	return this
}

function ToHex(x)
{
	var high = x / 16
	var s = high + ""
	s = s.substring(0, 2)
	high = parseInt(s, 10)
	var nLeft = hex[high + 1]
	var low = x - high * 16
	s = low + ""
	s = s.substring(0, 2)
	low = parseInt(s, 10)
	var nRight = hex[low + 1]
	var str = nLeft + "" + nRight
	return str
}

function ToDec(x)
{
	var l1 = x.substring(0, 1).toLowerCase()
	var l2 = x.substring(1, 2).toLowerCase()
	
	var n1, n2
	
	var i
	for(i=0; i<aHtoD.length; i++)
	{
		if(l1==aHtoD[i])
		{
			n1 = i * 16
		}
	}
	for(i=0; i<aHtoD.length; i++)
	{
		if(l2==aHtoD[i])
		{
			n2 = i
		}
	}
	return n1 + n2
}

var hex = new MakeArray(16)
hex[11]="A"
hex[12]="B"
hex[13]="C"
hex[14]="D"
hex[15]="E"
hex[16]="F"

var aHtoD = new Array()
aHtoD[0] = "0"
aHtoD[1] = "1"
aHtoD[2] = "2"
aHtoD[3] = "3"
aHtoD[4] = "4"
aHtoD[5] = "5"
aHtoD[6] = "6"
aHtoD[7] = "7"
aHtoD[8] = "8"
aHtoD[9] = "9"
aHtoD[10] = "a"
aHtoD[11] = "b"
aHtoD[12] = "c"
aHtoD[13] = "d"
aHtoD[14] = "e"
aHtoD[15] = "f"


var oTopFrame = null
function GetTopFrame()
{
	if(oTopFrame==null)
	{
		var oWin = window
		var oParent
		var oBody
		
		while(true)
		{
			try
			{
				oBody = oWin.document.body
			}
			catch(e)
			{
				//if report opened from a direct link in another site
				//we can't do this .document.body bit
				//so we don' have a top frame, return null
				return null
			}
			var jBody = $(oBody);
			if(jBody.attr("name")=="XLCubedWebTopFrame")
			{
				break
			}
			
			oParent = oWin.parent
			
			if(oWin==oParent || oParent==null)
			{
				oWin = null
				break
			}
			
			oWin = oParent
		}
		oTopFrame = oWin
	}
	return oTopFrame
}

function GetBannerFrame()
{
	var oFrame = GetTopFrame()
	if(oFrame)
	{
		return oFrame.frames[0]
	}
	else
	{
		return null
	}
}

function GetSidebarFrame()
{
	var oFrame = GetTopFrame()
	if(oFrame)
	{
		return oFrame.frames[1].frames[0]
	}
	else
	{
		return null
	}
}

function GetTabFrame() {
    var oFrame = GetTopFrame()
	if(oFrame)
	{
		return oFrame.frames[1].frames[1].frames[0]
	}
	else
	{
		return null
	}
}

function GetMainWindowFrame()
{
	var oFrame = GetTopFrame()
	if(oFrame)
	{
		return oFrame.frames[1].frames[1].frames[1]
	}
	else if(window.f_GetCurrentTabId)
	{
		//we are in the preview window, this is the MainWindowFrame
		return window
	}
	else
	{
		return null
	}
}

function SubmitForm(strAction, strTarget, strMethod, aNames, aValues)
{
	var oForm = document.createElement("FORM")
	
	for(var i=0; i<aNames.length; i++)
	{
		var oInput = document.createElement("INPUT")
		oInput.type = "hidden"
		oInput.name = aNames[i]
		oInput.value = aValues[i]
		oForm.appendChild(oInput)
	}
	
	oForm.action = strAction
	oForm.target = strTarget
	oForm.method = strMethod
	
	document.body.appendChild(oForm)
	
	oForm.submit()
	
	document.body.removeChild(oForm)
}

//if we submit to the same form to a new window then make sure we dont display this message
var blnShowWaitMessage = true
var nWaitMessageTimeout = 2000
var oWaitMessagePointer = null


function f_PrepWaitMessage()
{
	if(blnShowWaitMessage)
	{
		oWaitMessagePointer = window.setTimeout("evt_DoShowWaitMessage()", nWaitMessageTimeout)
	}
}

function evt_DoShowWaitMessage()
{
	f_ShowWaitMessage()
}

function f_CancelWaitMessage()
{
	if(oWaitMessagePointer)
	{
		window.clearTimeout(oWaitMessagePointer)
		oWaitMessagePointer = null
	}
}

function f_ShowWaitMessage()
{
	var oDiv = document.createElement("DIV")
	oDiv.innerText = "Processing..."
	
	oDiv.style.backgroundColor = "#ECE9D8"
	oDiv.style.padding = "20px"
	oDiv.style.position = "absolute"
	oDiv.style.border = "2px solid Silver"
	oDiv.style.fontFamily = "Tahoma"
	oDiv.style.fontSize = "1em"
	oDiv.style.color = "#000000"
	oDiv.style.zIndex = "999"
	oDiv.style.textAlign = "center"
	oDiv.style.verticalAlign = "text-bottom"

	document.body.appendChild(oDiv)
	
	var nWidth = oDiv.offsetWidth
	var nHeight = oDiv.offsetHeight

	var jBody = $(document.body);
	var nLeft = (jBody.width() - nWidth) / 2;
	var nTop = (jBody.height() - nHeight) / 2;

	oDiv.style.top = nTop
	oDiv.style.left = nLeft
}



function f_AddOptionGroups(oDD, strAttribute)
{
	var strValue = GetDDValue(oDD)

	var aOptionGroups = new Array()
	var strCurrentGroup = ""
	var strGroup
	var i
	var grp, node
	for(i=0; i<oDD.options.length; i++)
	{
		strGroup = $(oDD.options[i]).attr(strAttribute)
		if(strGroup!=strCurrentGroup)
		{
			aOptionGroups[aOptionGroups.length] = new OptionGroup(strGroup)
		}
		strCurrentGroup = strGroup
	}
	
	while(oDD.options.length>0)
	{
		node = oDD.options[0]
		strGroup = $(node).attr(strAttribute)
		grp = f_GetOptionGroup(aOptionGroups, strGroup)
		node = oDD.removeChild(node)
		grp.OptGroup.insertBefore(node, null)
	}

	for(i=0; i<aOptionGroups.length; i++)
	{
		oDD.insertBefore(aOptionGroups[i].OptGroup, null)
	}

	oDD.value = strValue
}

function f_GetOptionGroup(aOptionGroups, strGroup)
{
	for(var i=0; i<aOptionGroups.length; i++)
	{
		if(aOptionGroups[i].Name==strGroup)
		{
			return aOptionGroups[i]
		}
	}
	return null
}

function OptionGroup(strName)
{
	this.Name = strName
	this.OptGroup = document.createElement("OPTGROUP")
	this.OptGroup.label = strName
}

function f_DelocaliseNumber(localString)
{
	//takes a localised number string and converts it to a javascript-compatible format
	
	var jsString;
	
	jsString = localString.replace(srv_DecimalPoint, "#DP#");
	jsString = jsString.replace(srv_ThousandSeparator, ",");
	jsString = jsString.replace("#DP#", ".");
	
	return jsString;
}

function f_LocaliseNumber(jsString)
{
	//takes a JS-compatible number and localises it
	
	var localString;
	
	localString = jsString.replace(".", "#DP#");
	localString = localString.replace(",", srv_ThousandSeparator);
	localString = localString.replace("#DP#", srv_DecimalPoint);
	
	return localString;
}

function f_DetectDpi()
{
	var oSpan = document.createElement("SPAN")
	oSpan.style.position = "absolute";
	oSpan.style.width = "1in";
	document.body.appendChild(oSpan)
	var retVal = oSpan.offsetWidth
	document.body.removeChild(oSpan)
	return retVal
}

function f_GetElementIndex(oElem)
{
	var oParent = oElem.parentNode
	for(var i=0; i<oParent.childNodes.length; i++)
	{
		if(oParent.childNodes[i]==oElem)
		{
			return i
		}
	}
	return -1
}

function LCase(str)
{
	if((str) && typeof(str)=="string")
	{
		return str.toLowerCase()
	}
	return str
}

function UCase(str)
{
	if((str) && typeof(str)=="string")
	{
		return str.toUpperCase()
	}
	return str
}
