//=============================================================================================
//...
//=============================================================================================
function showLoading() {
    document.getElementById('overlay').style.height   = f_clientHeight() + "px";
    document.getElementById('overlay').style.top      = f_scrollTop() + "px";
    document.getElementById('Loading').style.top      = (f_clientHeight() / 2 + f_scrollTop() - 25) + "px";
    document.getElementById('showLoad').style.width   = f_clientWidth();
    document.getElementById('showLoad').style.display = "";
}
function hideLoading() {
    document.getElementById('showLoad').style.display = "none";
}
function ltrim(str) {
    return str.replace(/^\s+/, '');
}
function rtrim(str) {
    for (var i = str.length - 1; i >= 0; i--) {
        if (/\S/.test(str.charAt(i))) {
            str = str.substring(0, i + 1);
            break;
        }
    }
    return str;
}
function trim(str) {
    return ltrim(rtrim(str));
}


function textMaxLength(obj, maxLength, evt)
{
    var charCode=(evt.which) ? evt.which : event.keyCode
    var max = maxLength - 0;
    var text = obj.value;
    if(text.length >= max)
    {
        var ignoreKeys = [8,46,37,38,39,40,35,36];
        for(i=0;i<ignoreKeys.length;i++)
        {
            if(charCode==ignoreKeys[i])
            {
                return true;
            }
        }
        return false;
    }
    else
    {
        return true;
    }
}
function alterWindow(winRef) 
{
   	maximiseWindow(winRef);
	winRef.focus();
}

function maximiseWindow(winRef) 
{
	if (window.screen) 
	{
		winRef.moveTo(0,0);
		winRef.resizeTo(screen.availWidth,screen.availHeight);
	}
}

function open_window_full(strUrl)
{
	var winRef;
	winRef=window.open(strUrl);
	if (window.screen) 
		{
			winRef.moveTo(0,0);
			winRef.resizeTo(screen.availWidth,screen.availHeight);
		}
}

function fnURLEncode(strTmpURL) 
{
	var strNewURL;
	var re;
	
	strNewURL = strTmpURL;
	
	re = /#/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%23");
	
	re = /$/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%24");
	
	//re = /+/g; //Create regular expression pattern.
	//strNewURL = strTmpURL.replace(re, "%2B");
	
	re = /,/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%2C");
	
	//re = /\/g; //Create regular expression pattern.
	//strNewURL = strTmpURL.replace(re, "%2F");
	
	re = /:/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%3A");
	
	re = /;/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%3B");
	
	re = /</g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%3C");
	
	re = />/g; //Create regular expression pattern.
	strNewURL = strTmpURL.replace(re, "%3E"); 
	
	return strNewURL;
}

//RN:04/01/05 -- opens help file in a seperate window
function openhelpwindow(helpfilename)
{
	window.open(helpfilename,"pshelp");
    //wopen.moveTo(0,0);
    //wopen.resizeTo(screen.availWidth,screen.availHeight);
}

//BT:19/01/05 -- checks if parameter is numeric
function isNumeric_decimal(x) 
{			
	var numbers="0123456789.";
	// is x a String or a character?
	if(x.length>1) 
	{				
		x=Math.abs(x)+"";
		for(j=0;j<x.length;j++) 
			{
			// call isNumeric_decimal recursively for each character
			number=isNumeric_decimal(x.substring(j,j+1));
			if(!number) return number;
			}
		return number;
	}
	else 
	{
		// if x is number return true
		if(numbers.indexOf(x)>=0) return true;
		return false;
	}
}
//FK:29/08/06 -- get combo results, returns empty string if element not found
function getCbo(id, retValue) {
	if (document.getElementById(id) != null)
		var cbo = document.getElementById(id);
		if (retValue.toLowerCase() == "value")
			return cbo.value;
		else if (retValue.toLowerCase() == "text")
			return cbo.options[cbo.selectedIndex].text;
		else if (retValue.toLowerCase() == "index")
			return cbo.selectedIndex;
	else
		return "";
}
function isNumeric(x) 
{			
	var numbers="0123456789";
	// is x a String or a character?
	if(x.length>1) 
	{				
		x=Math.abs(x)+"";
		for(j=0;j<x.length;j++) 
			{
			// call isNumeric recursively for each character
			number=isNumeric(x.substring(j,j+1));
			if(!number) return number;
			}
		return number;
	}
	else 
	{
		// if x is number return true
		if(numbers.indexOf(x)>=0) return true;
		return false;
	}
}



//BT:19/01/05
function left(str, n)
	/*
	str - the string we are LEFTing
	n - the number of characters we want to return        
	*/
	{
        if (n <= 0)							// Invalid bound, return blank string
			return "";
        else if (n > String(str).length)	// Invalid bound, return
			return str;						// entire string
        else								// Valid bound, return appropriate substring
			return String(str).substring(0,n);
	}

//BT:19/01/05
function right(str, n)
/*
str - the string we are RIGHTing
n - the number of characters we want to return
*/
{
    if (n <= 0)						// Invalid bound, return blank string
        return "";
    else if (n > String(str).length)// Invalid bound, return
        return str;                 // entire string
    else {							// Valid bound, return appropriate substring
        var iLen = String(str).length;
        return String(str).substring(iLen, iLen - n);
    }
}


//BT:19/01/05	
function midstring(str, start, len)
/*
    str - the string we are LEFTing
    start - our string's starting position (0 based!!)
    len - how many characters from start we want to get
*/
{
    // Make sure start and len are within proper bounds
    if (start < 0 || len < 0) return "";

    var iEnd, iLen = String(str).length;
    if (start + len > iLen)
		iEnd = iLen;
    else
		iEnd = start + len;

    return String(str).substring(start,iEnd);
}	


//BT:19/01/05        
function instr(sSearch, sSearchFor) 
//Requires use of: Mid function Len function 	
{ 
	var intcount = 0;
	
	//This code segment checks for single values
	for (i=0; i < sSearch.length; i++) 
	{ 
		//alert(midstring(sSearch, i, 1));
		if (sSearchFor == midstring(sSearch, i, 1)) 
		{
		
			intcount = 1;
			break;			
		}
	}		
	return intcount; 
} 
	
function monthInt(month)
{
	if (month == "January"){
		return "1";}
	else if (month == "February"){
		return "2";}
	else if (month == "March"){
		return "3";}
	else if (month == "April"){
		return "4";}
	else if (month == "May"){
		return "5";}
	else if (month == "June"){
		return "6";}
	else if (month == "July"){
		return "7";}
	else if (month == "August"){
		return "8";}
	else if (month == "September"){
		return "9";}
	else if (month == "October"){
		return "10";}
	else if (month == "November"){
		return "11";}
	else {
		return "12";}
}

function monthName(mShort)
{
	if (mShort == "Jan"){
		return "January";}
	else if(mShort == "Feb"){
		return "February";}
	else if(mShort == "Mar"){
		return "March";}
	else if(mShort == "Apr"){
		return "April";}
	else if(mShort == "May"){
		return "May";}
	else if(mShort == "Jun"){
		return "June";}
	else if(mShort == "Jul"){
		return "July";}
	else if(mShort == "Aug"){
		return "August";}
	else if(mShort == "Sep"){
		return "September";}
	else if(mShort == "Oct"){
		return "October";}
	else if(mShort == "Nov"){
		return "November";}
	else {
		return "December";}	
}
var hD="0123456789ABCDEF";
function decimal2Hex(d)
{
	var h = hD.substr(d&15,1);
	
	while(d<15)
	{
		d>>=4; 
		h=hD.substr(d&15,1)+h;
	}
	return h;
}
function MoveOption(objSourceElement, objTargetElement)
{        
    var aryTempSourceOptions = new Array();
    var x = 0;
    
    //looping through source element to find selected options
    for (var i = 0; i < objSourceElement.length; i++) 
    {   	
        if (objSourceElement.options[i].selected)
        {   
            //need to move this option to target element                
            var intTargetLen = objTargetElement.length++;
            objTargetElement.options[intTargetLen].text = objSourceElement.options[i].text;
            objTargetElement.options[intTargetLen].value = objSourceElement.options[i].value;
        }
        else 
        {
            //storing options that stay to recreate select element
            var objTempValues = new Object();
            objTempValues.text = objSourceElement.options[i].text;
            objTempValues.value = objSourceElement.options[i].value;
            aryTempSourceOptions[x] = objTempValues;
            x++;
        }
    }
    //resetting length of source
    objSourceElement.length = aryTempSourceOptions.length;
    //looping through temp array to recreate source select element
    for (var i = 0; i < aryTempSourceOptions.length; i++) 
    {
        objSourceElement.options[i].text = aryTempSourceOptions[i].text;
        objSourceElement.options[i].value = aryTempSourceOptions[i].value;
        objSourceElement.options[i].selected = false;
    }
    
/*    if(sortDestination)
    {
		var aryTempDestinationOptions = new Array();
		var objTempValues;
		for (var i = 0; i < objTargetElement.length; i++) 
		{
			objTempValues = new Object();
            objTempValues.text = objTargetElement.options[i].text;
            objTempValues.value = objTargetElement.options[i].value;
            aryTempDestinationOptions[x] = objTempValues;
		}
		aryTempDestinationOptions.sort();
		objTargetElement.options.length = 0;
		for (var i = 0; i < aryTempDestinationOptions.length; i++) 
		{
			objTargetElement.options[i] = new Option(aryTempDestinationOptions[i].text, aryTempDestinationOptions[i].value);
		}
    }
 */   
}

//Added by Dave
//25/05/2007
function ExistingCheck(objSourceElement, objTargetElement)
{
	var bExisting = false;
	
	for (var i = 0; i < objSourceElement.length; i++) 
    {  
		if (objSourceElement.options[i].selected)
		{
			for (var j = 0; j < objTargetElement.length; j++) 
			{	
				if(objSourceElement.options[i] &&
					objTargetElement.options[j] &&
					objTargetElement.options[j].value == objSourceElement.options[i].value)
				{
					bExisting = true;
					break;
				}
			}
		}
		
		if(bExisting == true)
			break;
    }
    
    return bExisting;
}
//Add Ended

//YD/08/03/07
function URLEncode(strTmpURL) 
{
	var strNewURL;
	strNewURL = strTmpURL;

	strNewURL = strTmpURL.replace(new RegExp(/#/g), "%23");
	strNewURL = strNewURL.replace(new RegExp(/,/g), "%2C");
	strNewURL = strNewURL.replace(new RegExp(/:/g), "%3A");
	strNewURL = strNewURL.replace(new RegExp(/;/g), "%3B");
	strNewURL = strNewURL.replace(new RegExp(/</g), "%3C");
	strNewURL = strNewURL.replace(new RegExp(/>/g), "%3E"); 
	strNewURL = strNewURL.replace(new RegExp(/&/g), "%26"); 
	strNewURL = strNewURL.replace(new RegExp(/~/g), "%7E"); 

	return strNewURL;
}
//YD/26/02/08
function isValidInteger(value)
{
    if(value < 2147483647)
        return true;
    return false;
}

//Added by Rumesh MM on 30-06-2008 validate an e-mail address
function checkEmail(inputvalue)
{	
    var pattern=/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/;
    if(pattern.test(inputvalue))
    {         
		return true  
    }else
    {   
		return false;
    }
}

function round(number,X) {
// rounds number to X decimal places, defaults to 2
    X = (!X ? 2 : X);
    var num = Math.round(number*Math.pow(10,X))/Math.pow(10,X);
    return num;
}

//=============================================================================================
//...
//=============================================================================================

function f_clientWidth() {
    return f_filterResults(
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}
function f_clientHeight() {
    return f_filterResults(
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
function f_scrollLeft() {
    return f_filterResults(
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
    return f_filterResults(
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
    var n_result = n_win ? n_win : 0;
    if (n_docel && (!n_result || (n_result > n_docel)))
        n_result = n_docel;
    return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}
//=============================================================================================
//key down event. only allow digits. we also need to allow for a few other keys...
//=============================================================================================
function txtNumericOnly_KeyDown(e)
{
    var keynum;
    var keychar;
    var numcheck;
    if(window.event) // IE
        keynum = e.keyCode;
    else if(e.which) // Netscape/Firefox/Opera
        keynum = e.which;

    keychar = String.fromCharCode(keynum);
    numcheck = /\d/;
    return numcheck.test(keychar);
}

// 10 aug 2010 modified by daniels: a var for return value is not enough, a callback function is required instead coz async operations.
// also, the var smuCommonMsg is no longer necessary when it can be transfered through a function param
// call back function: funcName(smuCommonMsg)
//===========================================================================
//This is used to validate the SMU reading is in an acceptable range and should be used in common
//Need a var smuCommonMsg to store result 
var validate_smu_common_validate_smu_common;    // call back function
function validate_smu_common(iUnitNo, dStartDate, sNewSMU, tNewDist, iHour, iMin,currentsmuauto, onValidatedCallback)
{
    validate_smu_common_validate_smu_common = onValidatedCallback;
    
    var strParams = ""    
    strParams += "?processtype=" + "validate_smu";
    strParams += "&equipmentid_auto=" + iUnitNo;
    strParams += "&date_reading=" + dStartDate;
    strParams += "&smu_reading=" + sNewSMU;
    strParams += "&distance_reading=" + tNewDist;
    strParams += "&hour=" + iHour;
    strParams += "&min=" + iMin;
    strParams += "&smureading_auto=" + currentsmuauto;
		
    xhpUpdateValidate = new ActiveXObject("Microsoft.XMLHTTP");
    xhpUpdateValidate.onreadystatechange = returnValidateSMUCommon;

    xhpUpdateValidate.open("POST", "GetSMUReading.reliability" + strParams, true);
    xhpUpdateValidate.send();	
}

function returnValidateSMUCommon()
{ 
	if (xhpUpdateValidate.readyState == 4) 
	{ 
	    //NOTE THE Messages need to be added to language files and passed.
        var msg ='';
        var measure_unit = xhpUpdateValidate.responseText.split("$")[0].split("~")[0];
        var dist_uom = xhpUpdateValidate.responseText.split("$")[0].split("~")[1];
        var result = xhpUpdateValidate.responseText.split("$")[1];
        if(measure_unit =="1")//for smu reading
        {
	   	    switch (result.split("!")[0].split("~")[0])
		    {
		        case "A" :		
		            msg="Error A! \nLower limit, The SMU for the date "+document.getElementById("txtStartDate").value+" to be inserted is less than the SMU of "+result.split("!")[0].split("~")[1]+" for the first date "+result.split("!")[0].split("~")[2]+" immediately prior to this date. \nAccept reading anyway?";
		            break;
		        case "B" :			
		            msg="Check B! \nLower limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		            break;
                case "C" :			
		            msg="Check C! \nLower limit, Reading is more than "+result.split("!")[0].split("~")[3]+" forecast operating h/day, but less than 24 h/day. \nAccept reading anyway?";
		            break;
                case "D" :			
		            msg="Error D! \nLower limit, Reading is more than 24h/day from the last input. \nAccept reading anyway?";
		            break;
                case "G" :			
		            msg="Error G! \nUpper limit, The SMU is too large for the date entered. It should be less than or equal to "+result.split("!")[0].split("~")[4];
		            break;			    
		        case "H" :			
		            msg="Error H! \nUpper limit, The SMU is too small for the date entered. It should be greater than "+result.split("!")[0].split("~")[6];
		            break;
		        case "J" :			
		            msg="Check J! \nUpper limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		            break;			    
		        case "K" :			
		            msg="Error K! \nDate, SMU reading already exists on the selected date and time. \nPlease adjust your entry.";
		            break;			    
	        }
	        try{
	            switch (result.split("!")[1].split("~")[0])
		        {
                    case "G" :			
		                msg=msg+"\n\nError G! \nUpper limit, The SMU is too large for the date entered. It should be less than or equal to "+result.split("!")[1].split("~")[4];
		                break;			    
		            case "H" :			
		                msg=msg+"\n\nError H! \nUpper limit, The SMU is too small for the date entered. It should be greater than "+result.split("!")[1].split("~")[6];
		                break;
		            case "J" :			
		                msg=msg+"\n\nCheck J! \nUpper limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		                break;			    
			            
	            }
	        }
	        catch (e) {
		     
            }
        }
        if(measure_unit =="2")//for distance reading
        {
            var uom = "km";
            var message_km_mile = "3840 km/day";
            var dist_per_hr = 160;
            if(dist_uom == "1")
            {
                uom = "miles";
                message_km_mile = "2400 miles/day";
                dist_per_hr = 100;
            }
	   	    switch (result.split("!")[0].split("~")[0])
		    {
		        case "A" :		
		            msg="Error A! \nLower limit, The Distance for the date "+document.getElementById("txtStartDate").value+" to be inserted is less than or equal to the Distance of "+(result.split("!")[0].split("~")[1])+" for the first date "+result.split("!")[0].split("~")[2]+" immediately prior to this date. \nAccept reading anyway?";
		            break;
		        case "B" :			
		            msg="Check B! \nLower limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		            break;
                case "C" :			
		            msg="Check C! \nLower limit, Reading is more than "+(result.split("!")[0].split("~")[3]*dist_per_hr)+" forecast " + uom + "/day, but less than " + message_km_mile + " \nAccept reading anyway?";
		            break;
                case "D" :			
		            msg="Error D! \nLower limit, Reading is more than " + message_km_mile + " from the last input. \nAccept reading anyway?";
		            break;
                case "G" :			
		            msg="Error G! \nUpper limit, The Distance is too large for the date entered. It should be less than or equal to "+(result.split("!")[0].split("~")[4]);
		            break;			    
		        case "H" :			
		            msg="Error H! \nUpper limit, The Distance is too small for the date entered. It should be greater than "+result.split("!")[0].split("~")[6];
		            break;
		        case "J" :			
		            msg="Check J! \nUpper limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		            break;			    
		        case "K" :			
		            msg="Error K! \nDate, Distance reading already exists on the selected date and time. \nPlease adjust your entry.";
		            break;			    
	        }
	        try{
	            switch (result.split("!")[1].split("~")[0])
		        {
                    case "G" :			
		                msg=msg+"\n\nError G! \nUpper limit, The Distance is too large for the date entered. It should be less than or equal to "+(result.split("!")[1].split("~")[4]);
		                break;			    
		            case "H" :			
		                msg=msg+"\n\nError H! \nUpper limit, The Distance is too small for the date entered. It should be greater than "+(result.split("!")[1].split("~")[6]);
		                break;
		            case "J" :			
		                msg=msg+"\n\nCheck J! \nUpper limit, Reading and date input acceptable. \nContinuing will save the record into the Meter Readings Screen.";
		                break;			    
			            
	            }
	        }
	        catch (e) {
		     
            }
        }
        //smuCommonMsg = msg;
        
        if (validate_smu_common_validate_smu_common)
            validate_smu_common_validate_smu_common(msg);
	}
}