









        

<!-- version 2012.1 -->






function handleError(msg,errDocUrl,line)
{
    var errorUrl = "/core/pages/logJavascriptError.nl?NS_VER=2010.1.0";
    var postData;

    if (typeof window.errorObj != "undefined" && window.errorObj != null)
        msg = "NLAPI Error " + window.errorObj.code + ": " + window.errorObj.detail;
    window.errorObj = null;

    postData = "mesg=" + escape(msg) + "&";
    postData = postData + "winHref=" + escape(window.location.href) + "&";
    postData = postData + "line=" + escape(line) + "&";
    postData = postData + "isinited=" + escape(window.isinited) + "&";

    
     try { 
    postData = postData + "stcktrc=" + escape(stacktrace());
     } catch (e) { } 

    if (window.parent != window)
    {
        postData = postData + "&parHref=" + escape(window.parent.location.href);
    }

    if (errDocUrl != window.location.href)
    {
        postData = postData + "&errDocUrl=" + escape(errDocUrl);
    }

    // Create a request object and post the xml document
    var xmlReq= new ActiveXObject("Microsoft.XMLHTTP");
    xmlReq.Open("POST", errorUrl, true);
    xmlReq.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlReq.Send(postData);

    return false; // show the default error message
}
window.onerror = handleError;



function debugAlert(sMsg){}
function debugStartTimer(){}
function debugGetTime(){}




if (!Array.prototype.push) {
  Array.prototype.push = function() {
		var startLength = this.length;
		for (var i = 0; i < arguments.length; i++)
      this[startLength + i] = arguments[i];
	  return this.length;
  }
}



try{
    parentAccesible =(typeof parent.encode != "undefined");
}catch(e)
{
    parentAccesible = false;
}

function encode(text)
{
    return escape(text).replace(/\+/g, '%2B');
}

function alphafirst(str)
{
    var re = new RegExp("([A-Za-z].*)");
    return (re.exec(str)!=null && RegExp.$1==str);
}


function stacktrace()
{
    var s = "stacktrace: "
    for (var a=arguments.callee.caller; a!=null; a=a.caller)
    {
        s += getFuncName(a);
        s += getFuncArgs(a) + "\n\n";
        if (a.caller == a) break;
    }
    return s;
}

function getFuncArgs(a)
{
    s = "arguments: {";
    for (i = 0; i < a.arguments.length; i++)
    {
        if (typeof a.arguments[i] == "undefined")
            s += '\'undefined\'';
        else if (a.arguments[i] == null)
            s += 'null';
        else if (typeof a.arguments[i] == "string")
            s += "'" + a.arguments[i].toString() + "'";
        else
            s += a.arguments[i].toString();
        if (i < a.arguments.length -1)
            s += ",";
    }
    s += "}";
    return s;
}

function getFuncName(f)
{
    var s = f.toString();
    if (s.indexOf("anonymous") >= 0)
    {
        if (s.length > 100)
            return s.substr(0, 100) + "\n";
        else
            return s + "\n";
    }
    else
        s = s.match(/function[^{]*/)[0];
    if ((s == null) || (s.length == 0)) return "anonymous \n";
    return s;
}

function scrollDiv()
{


        if( document.getElementById('div__label') ) document.getElementById('div__label').scrollLeft = document.getElementById('div__body').scrollLeft;

}


function getDocumentClientHeight()
{
    var isWindowContainedInDivFrame = (window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    
       // return document.body.clientHeight;
        return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().body.dom.clientHeight : document.body.clientHeight);
    
}

function getDocumentClientWidth()
{
    var isWindowContainedInDivFrame = (window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    
        return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().body.dom.clientWidth : document.body.clientWidth);
    

}

// Do not use the two functions below to get width and height of document client area
// In IE, the value will not include scroll bar; In FF and Safari, the value will include scrollbar
function getDocumentHeight()
{
    if (window.innerHeight)
        return window.innerHeight;
    else if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientHeight != 0)
        return document.documentElement.clientHeight;
    else 
        return document.body.clientHeight;
}
function getDocumentWidth()
{
    if (window.innerWidth)
        return window.innerWidth ;
    else if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0)
        return document.documentElement.clientWidth;
    else  
        return document.body.clientWidth;
}


function getElementContentWidth(element)
{
    return  element.offsetWidth
            - getRuntimeSize(element, "paddingLeft")
            - getRuntimeSize(element, "paddingRight")
            - getRuntimeSize(element, "borderLeftWidth")
            - getRuntimeSize(element, "borderRightWidth")
            - getRuntimeSize(element, "marginLeft")
            - getRuntimeSize(element, "marginRight") ;
}


function getElementContentHeight(element)
{
    return element.offsetHeight
            - getRuntimeSize(element, "paddingTop")
            - getRuntimeSize(element, "paddingBottom")
            - getRuntimeSize(element, "borderTopWidth")
            - getRuntimeSize(element, "borderBottomWidth")
            - getRuntimeSize(element, "marginTop")
            - getRuntimeSize(element, "marginBottom") ;
}


var ieDiffWidth=0;
var ieDiffHeight=0;

function initOuter() {

  var w, h, offW, offH, diffW, diffH;
  var fixedW = 800;
  var fixedH = 600;
  if (document.all) {
    offW = document.body.offsetWidth;
    offH = document.body.offsetHeight;
    window.resizeTo(fixedW, fixedH);
    diffW = document.body.offsetWidth  - offW;
    diffH = document.body.offsetHeight - offH;
    w = fixedW - diffW;
    h = fixedH - diffH;
    ieDiffWidth  = w - offW;
    ieDiffHeight = h - offH;
    window.resizeTo(w, h);
  }
}

function outerWd() {

  if (document.all)
  {
    if (ieDiffHeight==0) initOuter();
    return document.body.offsetWidth  + ieDiffWidth;
  }
  else
    return window.outerWidth;
}

function outerHt() {

  if (document.all)
  {
    if (ieDiffHeight==0) initOuter();
    return document.body.offsetHeight  + ieDiffHeight;
  }
  else
    return window.outerHeight;
}

function onBeforePrint()
{
    var t= document.getElementById('div__label');
    if (t != null)
    {
        t.style.width = null ;
        t.style.height = null;
    };
    t = document.getElementById('div__body');
    if (t != null)
    {
        t.style.width = null;
        t.style.height = null;
    }

    document.body.scroll = 'auto';
}
function onAfterPrint()
{
    
    if(document.getElementById("resetdivwascalled") != null)
        resetDivSizes();
}


window.onbeforeprint = onBeforePrint;
window.onafterprint = onAfterPrint;


function resetDivSizes()
{
    
    if(document.getElementById("resetdivwascalled") == null)
    {
        var hasBeenCalled = document.createElement("input");
        hasBeenCalled.type = "hidden";
        hasBeenCalled.value = "T";
        hasBeenCalled.id = "resetdivwascalled";
        document.body.appendChild(hasBeenCalled);
    }

    var header = document.getElementById('div__header');
    var title = document.getElementById('div__title');
    var banner = document.getElementById('div__banner');
    var messsageBox = document.getElementById('div__alert');
    var prelabel = document.getElementById('div__prelabel'); 
    var label = document.getElementById('div__label'); 
    var list = document.getElementById('div__body');
    var nav = document.getElementById( 'div__nav');
    var footer = document.getElementById('div__footer');

	
	var topBanner = document.getElementById('bannerContainer');
    var topBannerHeight = getHeight(topBanner);
    if (topBannerHeight > 0)  
    	topBannerHeight += 5;  

    if (list == null)
        return; 

    // we never want vertical scroll bars, but horizontal scroll bars are ok if necessary
    // There should never be Y-overflow since we are sizing all of the elements to fit and scrolling individually
    document.body.style.overflowY = "hidden";

    

    
    var nHeight = getDocumentHeight() - 10;
    nHeight -= topBannerHeight + getHeight(header) + getHeight(footer) + getHeight(title) + getHeight(banner)+ getHeight(prelabel)+ getHeight(label) + getHeight(messsageBox) + 4;
    list.style.height = ( nHeight > 0 ? nHeight : 0) + "px";
    
    list.clientWidth;
    
    
    var docwidth = getDocumentWidth();
    var reportDataTable = document.getElementById('_rptdata');
    if ( nav != null )
    {
        list.style.height = ( nHeight - list.offsetTop > 0 ? nHeight - list.offsetTop : 0);
        var tree = document.getElementById('div__nav_tree');
        if (tree)
            tree.style.height = ( nHeight - tree.offsetTop > 0 ? nHeight - tree.offsetTop : 0 );

        docwidth -= isIE ? nav.offsetWidth : nav.scrollWidth;

        
        var node = nav.parentNode;
        var cellSpacing = 0;
        while (node != null)
        {
            if (node.getAttribute("cellspacing"))
            {
                cellSpacing = node.getAttribute("cellspacing");
                break;
            }
            node = node.parentNode;
        }
        docwidth -= 4*cellSpacing;
    }
    
    list.style.width = Math.max( docwidth-18, 0 );

    
    nHeight = getDocumentHeight() - 10;
    nHeight -= topBannerHeight + getHeight(header) + getHeight(footer) + getHeight(title) + getHeight(banner) + getHeight(prelabel) + getHeight(label) + getHeight(messsageBox) + 4;
    list.style.height = ( nHeight > 0 ? nHeight : 0) + "px";
    if ( nav != null )
    {
        list.style.height = ( nHeight - list.offsetTop > 0 ? nHeight - list.offsetTop : 0);
        var tree = document.getElementById('div__nav_tree');
        if (tree)
            tree.style.height = ( nHeight - tree.offsetTop > 0 ? nHeight - tree.offsetTop : 0 );
    }
    
    if (label != null )
    {
        label.style.width = list.clientWidth;
        label.style.left = -document.getElementById('div__body').scrollLeft;
    }

    
    

    
    var bFirst = true;
    var lastCol;
    var lastWidth;
    for (var i=0; i==0 || document.getElementById('div__labcol'+i) != null; i++)
    {
        var col = document.getElementById('div__labcol'+i);
        var lab = document.getElementById('div__lab'+i);
        if (lab != null)
        {
            var width = col.offsetWidth;
            if (bFirst && width > 0)
            {
                bFirst = false;
                width--;
            }
            if (width > 0)
            {
                lastCol = lab;
                lastWidth = width;
            }
            if ( lab.tagName == 'TD' )
            {
                lab.style.width = width;
            }
            else
            {
                lab.offsetParent.style.width = width;
            }
        }
    }
    if (lastCol && lastWidth > 0)
        lastCol.style.width = lastWidth - 1;

    
    makeVisible(label);
    makeVisible(list);
    makeVisible(footer);

    
    var paddingCell = document.getElementById("div__labend");
    if (paddingCell)
    {
        paddingCell.style.width = list.offsetWidth - list.clientWidth;
        if (label)
	        paddingCell.style.height = label.offsetHeight;
        paddingCell.style.left = list.clientWidth - 1;
    }

    hideInvisibleRows();
}



function hideInvisibleRows()
{
    var div = document.getElementById("squeezeBox");
    if (div == null)
        return;
    var trs = div.getElementsByTagName("tr");
    var hiddenHeight = 0;
    for (var i=0; i < trs.length; i++)
    {
        
        if (trs[i].className == "labelRow" && isValEmpty(trs[i].getAttribute("squeezeBox")) )
        {
            hiddenHeight += trs[i].offsetHeight + 1;
            trs[i].setAttribute("squeezeBox","T");
        }
    }
    if (hiddenHeight > 0)
    {
        div.style.overflow = "hidden";
        div.style.height = div.offsetHeight - hiddenHeight + (isIE ? 0 : 28);
    }
}



function resizePopupWindow()
{
    var list = document.getElementById('div__body');
    if (list == null)
        return; 
    var docwidth = getDocumentWidth()-10;
    var maxspanwidth = getMaxContentWidth(list.getElementsByTagName("span"));
    var maxdivwidth = getMaxContentWidth(list.getElementsByTagName("div"));
    var maxwidth = Math.max(list.scrollWidth,Math.max(maxspanwidth,maxdivwidth));
    
    if ( maxwidth > docwidth )
        window.resizeBy(maxwidth -docwidth,0);
}

function getMaxContentWidth(elems)
{
    var size = 0;
    for ( i = 0; i < elems.length; i++ )
    {
        if ( elems[i].scrollWidth > size )
            size = elems[i].scrollWidth;;
    }
    return size;
}


function getHeight(elem)
{
    if (elem == null)
        return 0;
    else
        return elem.offsetHeight ? elem.offsetHeight : 0;
}

function makeVisible(elem)
{
    if (elem != null)
        elem.style.visibility = 'visible';
}

function display(elem, on )
{
    if (elem != null)
        elem.style.display = on ? '' : 'none';
}

function visible(elem, on )
{
    if (elem != null)
        elem.style.visibility = on ? 'inherit' : 'hidden';
}



function endsWith(str, token)
{
	return str != null && token != null && str.length >= token.length && str.substr(str.length-token.length) == token;
}


function format_message(pattern)
{
	var len = format_message.arguments.length;
	var offset = 1;

	
	if (pattern.length >= 3 && pattern.substring(0, 3) == '@@@')
	{
		var choicePatterns = pattern.substring(3).split(/\s*\|\|\s*/);
		var selector = 0;
		if (len >= 2)
		{
			selector = format_message.arguments[1];
			if (typeof(selector) == 'boolean')
				selector = selector ? 0 : 1;
			else if (typeof(selector) == 'string')
				selector = parseInt(selector);
			if (typeof(selector) != 'number')
				selector = 0;
		}
		if (selector >= choicePatterns.length)
			selector = 0;
		pattern = choicePatterns[selector];

		offset = 2;
	}

	else if (pattern.length >= 2 && pattern.substring(0, 2) == '@@')
	{
		
		return '?';
	}

	
	var params = format_message.arguments;
	if (len == (offset + 1) && format_message.arguments[offset].constructor == Array)
	{
		params = format_message.arguments[offset];
		offset = 0;
		len = params.length;
	}

	return pattern.replace(/{(?:(\d+)|:)[^}]*}/g,
		function(match, id)
		{
			var n = id ? (parseInt(id) - 1 + offset) : len;
			return (n < len) ? params[n] : ''
		});
}

function checkzipcode(f, bIsCanada)
{
  var v = f.value;
  var n = bIsCanada ? 6 : 5;
  if(!onlydigits(f) || v.length != n)
  {
    if ( bIsCanada )
        alert('Please enter a valid '+n+' digit Postal Code.');
    else
        alert('Please enter a valid '+n+' digit Zip Code.');
    return false;
  }
  return true;
}

function splitIntoRows( value )
{
    return value != null ? (value.length > 0 ? value.split(String.fromCharCode(2)) : new Array()) : null;
}
function splitIntoCells( value )
{
    return value != null ? (typeof(value) == 'string' ? value.split(String.fromCharCode(1)) : value) : null;
}


function isempty(fld1,nam)
{
	var val = fld1.value;
    return isValEmpty(val,nam);
}


function checknotempty(fld1,nam)
{
    if (!checkvalnotempty(fld1.value, 'Please enter a value for {1}'.replace('{1}',nam)))
    {
        
         try { 
            fld1.focus();
            fld1.select();
         } catch (e) { } 
        return false;
    }

    return true;
}

function amount_string(amount)
{
    var cents = Math.floor((amount-Math.floor(amount))*100+0.5);
    var centstring = (cents < 10) ? '0'+cents.toString() : cents.toString();
    var dollarstring = dollars_string(Math.floor(amount));
    return dollarstring.charAt(0).toUpperCase() + dollarstring.substr(1) + 'and ' + centstring + '/100';
}
function format_rate(a,p)
{
    var returnMe;
    if (isNaN(parseFloat(a)))
    {
        returnMe= '';
    }
    else
    {
    	var precision = get_precision();
                                               
    	if (precision>1 || p)
    	{
            var s=(a<0);
            if (s) a=-a;
            var d=Math.floor(a);
            var c=Math.floor((a-d)*(p?10:100)+0.5);
                             
            if (a == d+c/(p?10:100))
            {
                if (c==(p?10:100)) {d++;c=0;}
                var cs=p?c.toString():((c < 10)?'0'+c.toString():c.toString());
                returnMe = (s?'-':'')+d.toString()+'.'+cs+(p?'%':'');
           }
            else
              returnMe = (s?'-':'')+a+(p?'%':'');
        }
        else if (precision==1)
        {
            var s=(a<0);
            if (s) a=-a;
            var cs = a.toString();
            var n = cs.indexOf('.');
            if (n==-1) cs = cs.toString() + '.0';
            else if (n==0) cs = '0.' + cs.toString() ;
            else if (n==cs.length-1) cs = cs.toString() + '0' ;
      		returnMe = (s?'-':'') + cs ;
        }
        else if (precision==0)
        {
            var s=(a<0);
            if (s) a=-a;
            var cs = a.toString();
            var n = cs.indexOf('.');
            if (n==0) cs = '0.' + cs.toString() ;
            else if (n==cs.length-1) cs = cs.substring(0, cs.length-2);
      		returnMe = (s?'-':'') + cs ;
        }
    }
  return returnMe;
}
function get_precision()
{
var cp = getFormElementViaFormName('main_form', 'currencyprecision');
    var precision = 2;
    if (cp != null) 
    {
  	  var tprecision = parseFloat(cp.value);
      if (!isNaN(tprecision))
      {
          precision=tprecision;
      }
    } 
    return precision;
}
function round_currency(amount, numofdecimals, method)
{
  var precision = numofdecimals;
  if (precision==null) 
    precision = get_precision();
  var amountStr = amount + ''
  if ( amount > 1E10 && amountStr.indexOf('.') >= 0 && (amountStr.length - amountStr.indexOf('.') - 1 <= precision) )
    return amount;
  var b = Math.abs(amount);
  b = Math.floor((b * 100000.0)+0.5) / 100000.0 + 0.000001;
  factor = Math.pow(10,precision);
  if (method == null || method =='OFF') b = Math.floor((b * factor)+0.5) / factor;
  else if (method == 'UP')   b = Math.round(Math.ceil(Math.abs(amount) * factor)) / factor;
  else if (method == 'DOWN') b = Math.round(Math.floor(Math.abs(amount) * factor)) / factor;
  b = b * (amount >= 0.0 ? 1.0 : -1.0);
  if( b == 0.0 )
    return 0.0;
  return b;
}
function round_float(a)
{
  return round_float_to_n_places(a,8);
}
function round_float_to_n_places(a,n)
{
  var str = a + '';
  if(str.indexOf('.') < 0)
    return a;
  if(str.length-str.indexOf('.')-1 <= n)
    return a;
  var b = Math.abs(a);
  b = b + 0.00000000000001;
  var factor = Math.pow(10,n);
  b = Math.floor((b * factor)+0.5) / factor;
  b = b * (a >= 0.0 ? 1.0 : -1.0);
  if( b == 0.0 )
    return 0.0;
  return b;
}
function pad_to_atleast_two_decimal_places(a)
{
  var s;
    if(a == null)
    {
       s = '';
    }
  else
  {
    s = a.toString();
    var n = s.indexOf('.');
    if(n == -1)
    {
      s = s + '.00';
    }
    else if(n == s.length-1)
    {
      s = s + '00';
    }
    else if(n == s.length-2)
    {
      s = s + '0';
    }
    if (n == 0)
    {
      s = '0' + s;
    }
  }
  return s;
}
function pad_decimal_places(a, noOfDecimalPlaces)
{
  var s;
  if(a == null)
  {
     s = '';
  }
  else
  {
    s = a.toString();
    var n = s.indexOf('.');
    if (noOfDecimalPlaces==0) 
    {
      if(a == 0.0)
      {
        s = 0; 
      }
      else if(n > -1)
      {
        s = s.substring(0, n) ;
      } 
    }
    else if (noOfDecimalPlaces==1) 
    {
      if(n == -1)
      {
        s = s + '.0';
      }
      else if(n == s.length-1)
      {
        s = s + '0';
      } 
      else if (n == 0)
      {
        s = '0' + s;
      }
    }
    else
    {
      if(n == -1)
      {
        s = s + '.00';
      }
      else if(n == s.length-1)
      {
        s = s + '00';
      }
      else if(n == s.length-2)
      {
        s = s + '0';
      }
      if (n == 0)
      {
        s = '0' + s;
      }
    }
  }
  return s;
}
function format_currency(a, bDoNotRound)
{
if(isNaN(a))
{
    return '';
}
var cp = getFormElementViaFormName('main_form', 'currencyprecision');
  var noOfDecimalPlaces = 2;
  if (cp != null) 
  {
  	noOfDecimalPlaces = parseFloat(cp.value);
    if (isNaN(noOfDecimalPlaces))
    {
        noOfDecimalPlaces = 2;
    }
  } 
var returnMe;
if( !(bDoNotRound == true)) 
{
    returnMe = round_currency(a, noOfDecimalPlaces);
}
else
{
    returnMe = a;
}
returnMe = pad_decimal_places(returnMe, noOfDecimalPlaces);
return returnMe;
}
function format_currency2(n)
{
  if(isNaN(n))
  {
    return '';
  }
  var returnMe;
  if( (n+'').indexOf('.') < 0 )
    returnMe = n;
  else
    returnMe = round_float_to_n_places(n,8);
  var precision = get_precision();
  if (precision == 2) {
    returnMe = pad_to_atleast_two_decimal_places(returnMe);
  } 
  return returnMe;
}
function format_percent(p) {
  if(typeof p == 'string')
     p = parseFloat(p);
 return p+(p==Math.floor(p) ? '.0%' : '%'); }





function parseCJKNumbers(field)
{
	var val = field.value;
    if (val == null) return null;
	var re = /[\uff01-\uff5e]/g;
	var out = [];
	var m , last = 0;
	re.lastIndex = 0; 
	while ((m = re.exec(val)) != null)
	{
		if (m.index > last) out.push(val.substring(last, m.index));
		last = re.lastIndex;
		out.push(String.fromCharCode(m[0].charCodeAt(0) - 0xfee0));
	}
	if (last == 0) return val;
	if (last < val.length) out.push(val.substring(last));
	return out.join('');
}


function validate_textfield_maxlen(field, maxLen, bAlert, bMaxInChars)
{
	if (field.value == null || field.value.length == 0)
	{
		window.isvalid = true;
		return true;
	}
	var bValid = true, truncOffset = null;
	if (bMaxInChars)
	{
		var len = field.value.length;
		if (len > maxLen)
		{
			if (bAlert)
				alert('You have exceeded the '+maxLen+' character limit for this field. Please shorten your entry by '+(len-maxLen)+' characters.');
			truncOffset = maxLen;
		}
	}
	else
	{
		var toTrim = analyzeUTF8(field.value, maxLen);
		if (toTrim)
		{
			if (bAlert)
				alert('You have exceeded the length limit for this field. Please shorten your entry by '+toTrim+' characters.');
			truncOffset = UTF8toUTF16index(field.value, maxLen);
		}
	}
	if (truncOffset)
	{
		window.focusedTextArea = field;
		setTimeout("try { setSelectionRange(window.focusedTextArea, " + truncOffset + ", " + field.value.length + "); } catch (e) {}",0);
		bValid = false;
	}
	window.isvalid = bValid;
	return bValid;
}

function truncateStringInUnicode(str, maxlen)
{
    var totalnum = 0;
    var sLower = 128;
    var sHigher = 2048;
    var strOut = "";
    for (var i=0; i < str.length; i++ )
    {
        var chnum = str.charCodeAt(i);
        if ( chnum < sLower )
            totalnum += 1;
        else if ( chnum >= sLower && chnum < sHigher )
            totalnum += 2;
        else if ( chnum >= sHigher )
            totalnum += 3;
        if ( totalnum < maxlen )
            strOut = strOut + str.charAt(i);
    }
    return strOut;
}
function UTF8toUTF16index(str, utf8index)
{
    var utf8len = 0;
    var sLower = 128;
    var sHigher = 2048;
    for (var i=0; i<str.length; ++i)
    {
        var chnum=str.charCodeAt(i);
        if (chnum < sLower)
            utf8len += 1;
        else if (chnum < sHigher)
            utf8len += 2;
        else
            utf8len += 3;
        if (utf8len > utf8index)
            return i;
    }
    return 0;
}


function analyzeUTF8(str, maxByteLen)
{
	
    var byteLen = 0, bucket = [null, 0, 0, 0];
    for (var i=0; i<str.length; ++i)
    {
        var ch = str.charCodeAt(i);
		var n = (ch < 128) ? 1 : (ch < 2048 ? 2 : 3); 
		byteLen += n;
		bucket[n] += 1;
	}
	
	var excessBytes = byteLen - maxByteLen;
	var charsToTrim = 0;
	for (var i=1; excessBytes>0 && i<=3; ++i)
	{
		var trimmedFromBucket = Math.min(Math.floor((excessBytes + i - 1) / i), bucket[i]);
		charsToTrim += trimmedFromBucket;
		excessBytes -= trimmedFromBucket * i;
	}
	return charsToTrim;
}

function searchMonth(str, fullName) {
    var tmp_str = str.toLowerCase();
    var months = new Array();
    if (fullName) {
        months = ["january", "february", "march", "april", "may", "june", "july",
                  "august", "september", "october", "november", "december"];
    } else {
        months = ["jan", "feb", "march", "april", "may", "june", "july",
                  "aug", "sept", "oct", "nov", "dec"];
    }
    var idx = 0;
    for(var i = 0; i < months.length(); i++) {
        idx = tmp_str.indexOf(months[i], 0);
        if (idx >= 0) {
            idx = idx + months[i].length;
            while (str.charAt(idx) == ' ')
              idx ++;
            return idx;
        }
    }
    return -1;
}

function getTimeStartIdx(str)
{
    var n = 0, spaceIdx= 0;
    if (window.dateformat == "DD de MONTH de YYYY") {
        spaceIdx = str.lastIndexOf("de", 0);
        n = 2;
    }
    else if (window.dateformat == "DD MONTH, YYYY") {
        spaceIdx = str.indexOf(",", 0);
        n = 2;
    }
    else if (window.dateformat == "DD-MONTH-YYYY") {
        spaceIdx = str.lastIndexOf("-", 0);
        n = 1;
    }
    else if (window.dateformat == "DD MONTH YYYY") {
        spaceIdx = searchMonth(str, true);
        n = 1;
    }
    else if (window.dateformat == "DD. Mon YYYY") {
        spaceIdx = searchMonth(str, false);
        n = 1;
    }
    else if (window.dateformat == "YYYY년 MM월 DD?") {
        spaceIdx = 0;
        n = 3;
    } else {
        spaceIdx = 0;
        n = 1;
    }

    for (var i = 0; i < n; ++i) {
        spaceIdx = str.indexOf(" ", spaceIdx + 1);
        if (spaceIdx < 0)
          break;
    }
    return spaceIdx;
}

function extract_date_time(str, doalert)
{
    var date_time = new Array();
    var tmp_str = trim(str);
    var spaceIdx = getTimeStartIdx(str);
    if (spaceIdx > 0) {
        var date_str = tmp_str.substring(0, spaceIdx);
        var time_str = tmp_str.substring(spaceIdx+1, tmp_str.length);
        return { validflag:true, date:date_str, time: trim(time_str)};
    } else
    {
        alert("Invalid date/time (miss spaces between date and time)");
    }
    return { validflag:false };
}

function validate_date(fldvalue, doalert)
{
    var dt = NLDate_parseString(fldvalue, doalert);
    var ret;
    if(dt == null)
    {
        ret = { validflag:false }
    }
    else
    {
        ret = { validflag:true, value: getdatestring(dt) };
    }
    return ret;
}

function validate_time(fldvalue, doalert, includeSeconds)
{
    
    var fldvalue = hhmmtotimestring( fldvalue );
    var time;
    if (includeSeconds)
       time = regexstringtotime(null, fldvalue, includeSeconds);
    else
       time = stringtotime(null, fldvalue);
    
    var validflag = !isNaN(time);
    var value;
    if (validflag)
    {
        if (includeSeconds)
           value = gettimewithsecondsstring(time, window.datetime_am_string, window.datetime_pm_string);
        else
           value = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
    }
    else if (doalert)
    {
        alert("Invalid time value");
    }
    return {validflag:validflag, value:value};
}
        
function validate_field(field, type, doalert, autoplace, minval, maxval, mandatory, separator)
{
    
    window.isvalid=false;
    type = type.toLowerCase();
    if (field.value == null || field.value.length == 0)
    {
        if (mandatory)
        {
            if (doalert) alert("Field must contain a value.");
            selectAndFocusField(field);
            window.isvalid = false;
            return false;
        }
        else
        {
            window.isvalid = true;
            return true;
        }
    }
    if ( (type != "text" && type != "identifier" && type != "identifieranycase" && type != "address" && type != "visiblepassword") &&
		 ("en" == "ja" || "en" == "ko" || "en" == "zh") )
        field.value = parseCJKNumbers(field);
    var validflag = true;
    if (type =="url")
    {
        var val = trim(field.value.toLowerCase());
        
        
        if (!(val.indexOf('/') == 0 || val.indexOf('http://') == 0 || val.indexOf('https://') == 0 || val.indexOf('ftp://') == 0 || val.indexOf('file://') == 0))
        {
            
            if (val.indexOf('://') != -1)
            {
                if (doalert)
                    alert("Invalid url. Url must start with http://, https://, ftp://, or file://");
                validflag = false;
            }
            else
                field.value = 'http://' + trim(field.value);
        }
        
        if ( val.indexOf( ' ' ) > 0 || val.indexOf( '\t' ) > 0 )
        {
            if (doalert)
                alert("Invalid url. Spaces are not allowed in the URL");
            validflag = false;
        }
    }
    else if (type == "currency" || type == "currency2" || type == "poscurrency")
    {
        var val = field.value.replace(/$/g,"");

        val = val.toLowerCase();
        if(val.charAt(0) == '=')
            val = val.substr(1);
        else if (val.substr(1).search(/[\+\-\*\/]/g) == -1)
            val = NLStringToNumber(val, true) + '';

        

        if (val.substr(1).search(/[\+\-\*\/]/g) != -1)
        {
            
            var c = val.charAt(0);
            if(val.charAt(0) >='a' && val.charAt(0) <='z')
            {
                value = "error";
            }
            else
            {

                
                
                try {
                
                          val = eval(val);
                
                } catch (e) { val = "error"; }
                
                autoplace = false;
            }
        }
        numval = parseFloat(val);
        var totalDigitCount = getTotalDigitCount(val);
        if (isNaN(numval))
        {
			if (doalert)
			   alert('Invalid currency value. Values must be numbers up to 999,999,999,999,999.99');
			validflag = false;
        }
        else if ( maxval != null && !isNaN(maxval) && Math.abs(numval)>=maxval )
        {
			if (doalert)
			{
                var regex  = new RegExp('(-?[0-9]+)([0-9]{3})');
                var preDecimal = (maxval-1).toString();
                while(regex.test(preDecimal))
                {
                   preDecimal = preDecimal.replace(regex, '$1' + ',' + '$2');
                }
                alert('Invalid currency value. Values must be numbers up to '+preDecimal+'.999999999999999'+'');
            }

    		validflag = false;
		}
        
        if ((type == "poscurrency" || minval == 0) && numval < 0)
        {
            if (doalert) alert("Invalid currency value. Value can not be negative.");
            validflag = false;
        }
        if (validflag)
        {
            

            if(autoplace && val.indexOf(".") == -1) numval/=100;
            if(type == "currency" || type == "poscurrency")
                val =format_currency(numval);
            else
                val = format_currency2(numval);
            if (isNLNumericOrCurrencyDisplayField(field))
                val = NLNumberToString(val);
            field.value = val;
        }
    }
    else if (type == "date")
    {
        var ret = validate_date(field.value, doalert);
        validflag = ret.validflag;
        if (validflag)
           field.value = ret.value;
        /*
        var dt = NLDate_parseString(field.value, doalert);

        if(dt == null)
        {
            validflag = false;
        }
        else
        {
            validflag = true;
            field.value = getdatestring(dt);
        }
        */        
    }
    else if (type == "mmyydate")
    {
        // try to read year and month from the field
        var value;
        try
        {
            value = parseMMYYDateString(field.value);
        }
        catch(e) {}

        // check its validity
        if (value != null && value.month >= 1 && value.month <= 12 && value.year > 1900 && value.year < 2100)
        {
			var dDate = validateDate(new Date(value.year, value.month-1), doalert);
			if (dDate)
			{
				field.value = getmmyydatestring(dDate, NLDate_short_months);
                validflag = true;
            }
            else
		    	validflag = false;
		}
        else
        {
            // invalid => show error with suggested date pattern
            var fmterr =  "MMYY, MMYYYY, ";
            if (window.dateformat == "DD-Mon-YYYY")
                fmterr += "Mon-YY, Mon-YYYY";
            else if (window.dateformat == "DD.MM.YYYY")
                fmterr += "MM.YY, MM.YYYY";
            else
                fmterr += "MM/YY, MM/YYYY";

            if (doalert) alert('Invalid date value (must be '+fmterr+')');
            validflag = false;
        }
    }
    else if (type == "ccexpdate" || type == "ccvalidfrom")
    {
        

        validflag = true;
        var m=0, y=0;
        if(field.value.indexOf('/') != -1)
        {
            var dToday = new Date();
            var Y = dToday.getFullYear();
            var M = dToday.getMonth() + 1;
            if(Y <= 999) Y += 1900;         

            var c = field.value.split('/');
            if(onlydigits(c[0])) m = parseInt(c[0],10);
            if(onlydigits(c[1])) y = parseInt(c[1],10);

            if(m<1) m=1; else if(m>12) m=12;
            if(y<100) y+=((y>=70)?1900:2000);

            
            if(type == "ccexpdate" && (y < Y || (y==Y && m < M)) ||
               type == "ccvalidfrom" && (y > Y || (y==Y && m > M)))
            {
                if (doalert) alert("Notice: The credit card appears to be incorrect");
            }
            field.value = (m<10?'0':'')+m+'/'+y;
        }
        else
        {
            if (doalert)
            {
                if (type == "ccexpdate") alert("Please enter an expiration date in MM/YYYY format");
                else alert("Please enter a Valid From / Start Date in MM/YYYY format");
            }
            validflag = false;
        }
    }
    else if (type == "ccnumber") 
    {
		validflag = (field.value.length > 4 &&
						field.value.substring(0, field.value.length-4).replace(new RegExp( "\\*", "g" ), '').length == 0 &&
						field.value.substring(field.value.length-4).replace(new RegExp( "\\*", "g" ), '').length == 4) || checkccnumber(field);
    }
    else if (type == "rate" || type == 'ratehighprecision')
    {
        var numval;

        var val = field.value;
        var pctidx = val.lastIndexOf("%");
        var isPct = (pctidx!=-1);
        if (isPct)
            val = val.substr(0,pctidx);

        numval = NLStringToNumber(val, true);
        if (isNaN(numval))
        {
            if (doalert) alert("Invalid number or percentage");
            validflag = false;
        }
        else
        {
            if (autoplace && !isPct && val.indexOf(".") == -1)
                numval/=100;
            var numstr = format_rate(numval, isPct);  // this is the normalized rate string, i.e. using standard number formatting
            if (isNLNumericOrCurrencyDisplayField(field))
            {
                numstr = NLNumberToString(numstr.replace('%',''));
                if(isPct && numval < 0 && numstr.indexOf('-') < 0)  //other formats used for negative number
                {
                    var positiveNumberStr = NLNumberToString(format_rate(-numval, isPct).replace('%',''));
                    numstr = numstr.replace(positiveNumberStr, positiveNumberStr+'%');
                }
                else
                    numstr = numstr + (isPct?'%':'');
            }
            field.value = numstr;
            validflag = true;
        }
    }
    else if (type == "integer" || type == "posinteger" || type == "float" || type == "posfloat" || type == "percent")
    {
        var numval;
        var custrange=false;
        if ((minval != null || maxval != null) || type == "percent")
          custrange=true;
        var minclip= minval == null ? (type == "percent" ? 0 : -Math.pow(2,32)) : minval;
        var maxclip = maxval == null ?(type == "percent" ? 100 : Math.pow(2,64)) : maxval;
        var val = field.value.replace(/$/g,"");
        val = val.replace(/%/g,"");

        numval = NLStringToNumber(val, true);
        if (type == "integer")
            numval = parseInt(numval,10);
        else if (type == "posinteger")
        {
            numval = parseInt(numval,10);
            minclip=0;
        }
        else if (type == "posfloat" || type == "float")
        {
            if(val.indexOf(".") != -1)
			    numval = round_float(numval);
			if (type == "posfloat")
				minclip=0;
        }
        if (isNaN(numval) || (custrange && (numval > maxclip || numval < minclip)) || (!custrange && (numval >= maxclip || numval <= minclip)))
        {
            if (doalert)
            {
                if (type == "percent")
                {
					alert("Invalid percentage (must be between "+minclip+" and "+maxclip+")");
                }
                else if (custrange == true)
                {
                    if (minval == null)
                        alert("Invalid number (must be at most "+maxclip+")");
                    else if (maxval == null)
                        alert("Invalid number (must be at least "+minclip+")");
                    else
                        alert("Invalid number (must be between "+minclip+" and "+maxclip+")");
                }
                else if (type=="posinteger" || type=="posfloat")
                    alert("Invalid number (must be positive)");
                else if (type=="integer" || type=="float")
                {
                    if (isNaN(numval))
                        alert('You may only enter numbers into this field');
                    else
                        alert("Illegal number: " + numval);
                }
                else
                    alert("Invalid number (must be greater than -4.29B");
             }
             validflag = false;
        }
        else
        {
            var numberStr = numval + '';
            var isPct = (type == "percent");
            if (isPct)
                numberStr = format_percent(numval);   // normalized percent string, i.e. using standard number format
            if (isNLNumericOrCurrencyDisplayField(field))
            {
                numberStr = NLNumberToString(numberStr.replace("%", ""));
                if(isPct && numval < 0 && numberStr.indexOf('-') < 0) //other formats used for negative number
                {
                    var positiveNumberStr = NLNumberToString(format_percent(-numval).replace('%',''));
                    numberStr = numberStr.replace(positiveNumberStr, positiveNumberStr+'%');
                }
                else
                    numberStr = numberStr + (isPct?'%':'');
            }
            field.value = numberStr;
            validflag = true;
        }
    }
    else if (type == "address")
    {
        var err = '';
        if (field.value.length>999)
        {
            err = "Address too long (truncated at 1000 characters)";
            newval = field.value.substr(0,999);
        }
        if (err != '')
        {
            if (doalert) alert(err);
            field.value = newval;
        }
    }
    else if (type == "function")
    {
        if (field.value.indexOf('(') > 0)
            field.value = field.value.substr(0,field.value.indexOf('('));
		var val = field.value;
		var re = /^[0-9A-Za-z_]+(\.[0-9A-Za-z_]+)*$/;
		if (!re.test(val))
		{
			if  (doalert) alert("The Function field must be a valid JavaScript function identifier");
			validflag = false;
		}
	}
    else if (type == "time" || type == "timetrack")
    {
		var hours;
		var minutes;

		var re = /([0-9][0-9]?)?(:[0-9][0-9]+)?/
		var result = re.exec(field.value)
		if (result==null || result.index > 0 || result[0].length != field.value.length)
		{
			timeval = parseFloat(field.value);
			if (isNaN(timeval))
				hours = -1;
			else
			{
				hours = Math.floor(timeval);
				minutes = Math.floor((timeval-hours)*60+0.5);
			}
		}
		else
		{
			if (RegExp.$1.length > 0)
				hours = parseInt(RegExp.$1,10);
			else
				hours = 0;
			if (typeof(RegExp.$2) != "undefined" && RegExp.$2.length > 0)
			{
				minutes = parseInt(RegExp.$2.substr(1),10);
				// if the user entered a value >= 60 for minutes, add the extra hours to the hours var and reduce
				// minutes to be less than 60 (issue 48406)
				if (minutes >= 60)
				{
					var hours_delta = Math.floor(minutes / 60);
					minutes -= (hours_delta * 60);
					hours += hours_delta;
				}
			}
			else
				minutes = 0;
		}
		if (hours >= 0 && minutes >= 0 && minutes < 60)
		{
			field.value = hours + ":" + (minutes < 10 ? "0" : "") + minutes;
			validflag = true;
		}
		else
		{
			if (doalert) alert("Invalid time value (must be hh:mm)");
			validflag = false;
		}
    }
    else if (type == "timeofday")
    {
        var ret = validate_time(field.value, doalert, false);
        validflag = ret.validflag;
        if (validflag)
           field.value = ret.value;
        /*
        var fldvalue = field.value;

        
		fldvalue = hhmmtotimestring( fldvalue );
		var time = stringtotime(null, fldvalue);
		validflag = !isNaN(time);
		if (validflag)
        {
			field.value = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
        }
        else if (doalert)
        {
			alert("Invalid time value");
        }
        */
    }
    else if (type == 'datetimetz')
    {
        var ret_date_time = extract_date_time(field.value, doalert);
        validflag = ret_date_time.validflag;
        if (validflag)
        {
            var ret_date = validate_date(ret_date_time.date, doalert);
            validflag = ret_date.validflag;
            if (validflag)
            {
                var ret_time = validate_time(ret_date_time.time, doalert, true);
                validflag = ret_time.validflag;
                if (validflag)
                {
                    field.value = ret_date.value + "  " + ret_time.value;
                }
            }
        }
    }
    else if (type == "visiblepassword")
    {
        validflag = checkpassword(field.value, field.value, doalert);
    }
    else if (type == "email")
    {
        validflag = checkemail(field.value, true, doalert);
    }
    else if (type == "emails")
    {
        var bademails = new Array();
        var validcount = 0;
        if (!separator) separator = /[,;]/;
        var emails = field.value.split(separator);
		for (var j=0; j < emails.length; j++)
		{
			var semail = trim(emails[j]);
			if (semail)
			{
				if (checkemailvalue(semail, false))
					validcount += 1;
				else
					bademails.push(emails[j]);
			}
		}
        if (bademails.length > 0)
        {
            validflag = false;
            if (doalert) alert('Invalid email(s) found: '+bademails.join('; '));
        }
        else if (validcount < 1)
        {
            validflag = false;
            if (doalert) alert('No valid emails found in \"'+field.value+'\"');
        }
    }
    else if (type == "printerOffset")
    {
        var maxclip =  2.0;
        var minclip = -2.0;
        var val = field.value;
        val = val.replace(/,/g,"");

        numval = parseFloat(val);
        if (isNaN(numval) || numval >= maxclip || numval <= minclip)
        {
      if (doalert)
      {
        if (numval >= maxclip)
            alert("Invalid number (must be lower than " + maxclip + ").");
        else if (numval <= minclip)
            alert("Invalid number (must be greater than " + minclip + ").");
        else
            alert("Illegal number: " + numval);
            }
            validflag = false;
        }
        else
        {
            
            validflag = true;
        }
    }
    else if (type == "metricPrinterOffset")
    {
        var maxclip =  50.0;
        var minclip = -50.0;
        var val = field.value;
        val = val.replace(/,/g,"");

        numval = parseFloat(val);
        if (isNaN(numval) || numval >= maxclip || numval <= minclip)
        {
      if (doalert)
      {
        if (numval >= maxclip)
            alert("Invalid number (must be lower than " + maxclip + ").");
        else if (numval <= minclip)
            alert("Invalid number (must be greater than " + minclip + ").");
        else
            alert("Illegal number: " + numval);
            }
            validflag = false;
        }
        else
        {
            
            validflag = true;
        }
    }
    else if (type == "phone"  || type == "fullphone")
    {
        var val = field.value;
        
        if(val.length!=0 && val.length<7)
        {
            if (doalert) alert("Phone number should have seven digits or more.");
            validflag = false;
        }

        if (validflag && type == "fullphone")
        {
            
            if(val.length!=0 && val.length<10)
            {

                if (doalert) alert("Please include the area code for phone number: " + val);
                validflag = false;
            }
        }
        if (autoplace && validflag)
        {
            var extidx = val.search(/[A-Za-z]/);
            var ext = '';
            if (extidx >= 0)
            {
                ext = ' '+val.substring(extidx);
                val = val.substring(0,extidx);
            }
            var re = /^[0-9()-.\s]+$/;
            if (re.test(val))
            {
			  var digits = val.replace(/[()-.\s]/g,'');
			  var phoneformat = window.phoneformat.replace(new RegExp( "[360]", "g" ),String.fromCharCode(3));
              if (digits.length == 7)
                 field.value=phoneformat.replace(phoneformat.substring(0,phoneformat.indexOf('4')),'').replace('45'+String.fromCharCode(3),digits.substring(0,3)).replace('789'+String.fromCharCode(3),digits.substring(3)) + ext;
              else if (digits.length == 10)
                 field.value=phoneformat.replace('12'+String.fromCharCode(3),digits.substring(0,3)).replace('45'+String.fromCharCode(3),digits.substring(3,6)).replace('789'+String.fromCharCode(3),digits.substring(6)) + ext;
              else if (digits.length == 11 && digits.substring(0,1) == '1')
                 field.value='1 '+phoneformat.replace('12'+String.fromCharCode(3),digits.substring(1,4)).replace('45'+String.fromCharCode(3),digits.substring(4,7)).replace('789'+String.fromCharCode(3),digits.substring(7)) + ext;
            }
        }
    }
    else if (type == "color")
    {
        var val = field.value;
        if (val.substring(0,1) == "#")
            val = val.substring(1);
        
        var re = /^[0-9ABCDEFabcdef]{6,}$/;
        if (val.length > 6 || !re.test(val))
        {
            if (doalert) alert("Color value must be 6 hexadecimal digits of the form: #RRGGBB.  Example: #FF0000 for red.");
            validflag = false;
        }
        else
            field.value = "#"+val;
    }
    else if (type == "identifier" || type == "identifieranycase")
    {
        var val = field.value;
        var re = /^[0-9A-Za-z_]+$/;
        if (!re.test(val))
        {
            if (doalert) alert("Identifiers can contain only digits, alphabetic characters, or \"_\" with no spaces");
            validflag = false;
        }
        else
            field.value = type == "identifier" ? val.toLowerCase() : val;
    }
    else if (type == "furigana")
    {
        var val = field.value;
        var re = /^[\u0020\u3000\u30A0-\u30FF\uFF61-\uFF9F]+$/;
        if (!re.test(val))
        {
			if (doalert) alert("A non-katakana character has been entered.");
            validflag = false;
        }
    }
    if (mandatory == true)
    {
        if (field.value.length == 0)
        {
            if (doalert) alert("Field must contain a value.");
            validflag = false;
        }
    }
    if (!validflag)
        selectAndFocusField(field);
    window.isvalid = validflag;
    return validflag;
}

function getTotalDigitCount(numberString)
{
    numberString = numberString + ''; // convert the parameter to string just in case that it's already a number
    if(numberString == '')
        return 0;
    else
    {
        numberString = numberString.replace('-',''); // remove minus sign
        if(numberString.indexOf(".") > 0)
        	numberString = numberString.replace(/0*?$/, '').replace('.',''); // remove trailing 0's and decimal point
	    return numberString.length;
	}
}

function selectAndFocusField(field)
{
        if (isIE)
        {
            try
            {
                field.focus();
                field.select();
            }
            catch(err)
            {
                //do nothing.
                //issue 206079, field is not visible, IE throws an exception when try to focus on it, Jieping suggested to put try/catch block here
            }
        }
        else
        {
        
            setTimeout("document.getElementById('"+field.id+"').focus();document.getElementById('"+field.id+"').select();",0);
        }
}


function validatePeriodRange(fldPeriodStart, fldPeriodEnd)
{
    if( getSelectIndex(fldPeriodEnd) < getSelectIndex(fldPeriodStart) )
    {
        alert('Please enter a valid date range. The From date must precede the To date.');
        return false;
    }

    return true;
}


function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    input.setSelectionRange(selectionStart, selectionEnd);
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}


var NLDate_months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
if ( 13 > 12 )
NLDate_months.push('');
var NLDate_short_months = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
if ( 13 > 12 )
NLDate_short_months.push('');
function nlGetFullYear(d)
{
    if (window.navigator != null && window.navigator.appName == "Netscape")
    {
        if (d.getFullYear == "undefined")
            return d.getYear();
    }
    return d.getFullYear();
}
function nlSetFullYear(d,val)
{
    if (window.navigator != null && window.navigator.appName == "Netscape")
    {
        if (d.setFullYear == "undefined")
            d.setYear(val);
    }
    d.setFullYear(val);
}

var year_char_cn = "年";
var month_char_cn = "月";
var day_char_cn = "日";

var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";

function getdatestring(d, format)
{
	// if dateformat is specified, use it from the format parameter
	// else use the window property (set from user preference)
	var dateformat;
	if (typeof(format) != "undefined")
		dateformat = format;
	else if (typeof(window.dateformat) != "undefined")
		dateformat = window.dateformat;
	else
		dateformat = "MM/DD/YYYY";

	// replace format literals with date field values
	dateformat = dateformat.replace("YYYY", nlGetFullYear(d));
	dateformat = dateformat.replace("MM", (d.getMonth() + 1));
	dateformat = dateformat.replace("DD", d.getDate());
	dateformat = dateformat.replace(/month/i, NLDate_months[d.getMonth()]);
	dateformat = dateformat.replace(/mon/i, NLDate_short_months[d.getMonth()]);

	// japan specific
	if (dateformat.indexOf("EEYY") == 0)
		dateformat = dateformat.replace("EEYY", get_japanese_imperial_era(d) + get_japanese_imperial_year(d));
	else if (dateformat.indexOf("EYY") == 0)
		dateformat = dateformat.replace("EYY", get_short_japanese_imperial_era(d) + get_japanese_imperial_year(d));

	return dateformat;
}

var heisei_start_date = new Date(1989,0,8);
var shouwa_start_date = new Date(1926,11,25);
var taishou_start_date = new Date(1912,6,30);
var meiji_start_date = new Date(1867,1,3);
function get_japanese_imperial_era(d)
{
	if(d >= heisei_start_date)
		return "平成";
	else if(d >= shouwa_start_date)
		return "昭和";
	else if(d >= taishou_start_date)
		return "大正";
	else
		return "明治";
}
function get_short_japanese_imperial_era(d)
{
	if(d >= heisei_start_date)
		return "H";
	else if(d >= shouwa_start_date)
		return "S";
	else if(d >= taishou_start_date)
		return "D";
	else
		return "M";
}
function get_japanese_imperial_year(d)
{
	if(d >= heisei_start_date)
		return nlGetFullYear(d) - 1988;
	else if(d >= shouwa_start_date)
		return nlGetFullYear(d) - 1925;
	else if(d >= taishou_start_date)
		return nlGetFullYear(d) - 1911;
	else
		return nlGetFullYear(d) - 1867;
}
function get_gregorian_year(ja_imperial_year, era)
{
	if(era == "平成" || era == "H")
		return ja_imperial_year + 1988;
	else if(era == "昭和" || era == "S")
		return ja_imperial_year + 1925;
	else if(era == "大正" || era == "D")
		return ja_imperial_year + 1911;
	else
		return ja_imperial_year + 1867;
}

function getdefaultformatdatestring(d)
{
    return (d.getMonth()+1)+"/"+d.getDate()+"/"+nlGetFullYear(d);
}
function gettimestring(time,amvar,pmvar)
{
	var hours = time.getHours();
	if(typeof(amvar) == "undefined")
	{
		amvar = window.datetime_am_string;
		pmvar = window.datetime_pm_string;
	}
	var ampm = hours < 12 ? amvar : pmvar;
	if(window.timeformat.indexOf("HH24") < 0)
	{
		hours = hours % 12;
		if(hours == 0)
			hours = 12;
	}
	var minutes = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
	var timeStr = window.timeformat;
	timeStr = timeStr.replace("24", "");
	timeStr = timeStr.replace("fmHH", hours);
	timeStr = timeStr.replace("fmMI", minutes);
	if(window.timeformat.indexOf("HH24") < 0)
		timeStr = timeStr.replace("am", ampm);
	return timeStr;
}

function gettimewithsecondsstring(time,amvar,pmvar)
{
	var hours = time.getHours();
	if(typeof(amvar) == "undefined")
	{
		amvar = window.datetime_am_string;
		pmvar = window.datetime_pm_string;
	}
	var ampm = hours < 12 ? amvar : pmvar;
	if(window.timeformatwithseconds.indexOf("HH24") < 0)
	{
		hours = hours % 12;
		if(hours == 0)
			hours = 12;
	}
	var minutes = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
    var seconds = time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds();
	var timeStr = window.timeformatwithseconds.replace(/fm/g, "");
	timeStr = timeStr.replace("24", "");
	timeStr = timeStr.replace("HH", hours);
	timeStr = timeStr.replace("MI", minutes);
    timeStr = timeStr.replace("SS", seconds);
	if(window.timeformatwithseconds.indexOf("HH24") < 0)
		timeStr = timeStr.replace("am", ampm);
	return timeStr;
}

function getdatetimestring(date)
{
    return getdatestring(date) + " " + gettimestring(date);
}

function getdatetimetzstring(date)
{
    return getdatestring(date) + " " + gettimewithsecondsstring(date);
}

/**
 * Convert date to MMYY string.
 * Should behave the same way as NLDateRangeFieldGroup.getInvTurnDate().
 * The result must also be parsable by parseMMYYDateString.
 *
 * @param d
 * @param NLDate_short_months
 */
function getmmyydatestring(d, NLDate_short_months)
{
    if (window.dateformat == "DD-Mon-YYYY")
        return NLDate_short_months[d.getMonth()]+"-"+nlGetFullYear(d);
    else if (window.dateformat == "DD.MM.YYYY")
        return (d.getMonth()+1)+"."+nlGetFullYear(d);
    else if (window.dateformat == "DD/MM/YYYY")
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
    else if (window.dateformat == "YYYY/MM/DD")
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
    else
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
}

/**
 * Parse year and month from a MMYY value.
 * Try to be as benevolent as possible, while keeping unambiguous.
 * Must parse anything produced by getmmyydatestring()
 * and NLDateRangeFieldGroup.getInvTurnDate().
 *
 * @param value the string value
 */
function parseMMYYDateString(value)
{
    var year, month;
    if(!/^[0-9-\/\.]+$/.test(value))
    {
        // contains other chars than numerals and ./- => must contain month short name
        var c = value.split(/[\/-]/);
        if (c.length != 2) {
            return null;
        }
        month = getMonthIndex(c[0]);
        year = parseInt(c[1],10);
    }
    else
    {
        // split it by any of ./-
        var comps = value.split(/[\.\/-]/);
        if (comps.length == 1)
        {
            // without any separator - month is the first 1 or 2 chars,
            // the rest is year (2 or 4 chars)
            var l = value.length;
            month = parseInt(value.substr(0,2-l%2),10);
            year = parseInt(value.substr(2-l%2),10);
        }
        else
        {
            // first month then year
            month = parseInt(comps[0],10);
            year = parseInt(comps[1],10);
        }
    }

    // make the year full year if less then 100
    if (year < 50)
        year += 2000;
    else if (year < 100)
        year += 1900;

    return {
        year: year,
        month: month
    };
}

function stringtodate(arg, dateformat, returnNullIfInvalid, formattype)
{
    var comps;
	var month, day, year;
	var year_char_index, month_char_index, day_char_index, era;
    var d = arg;  // date string, assume it's the whole string for now
	if(dateformat == null)
	{
		if(typeof(window.dateformat) != "undefined")
			dateformat = window.dateformat;
		else
			dateformat = "MM/DD/YYYY";
	}
	var datestring_length = arg.length;
	var end_string; //the end segment in date string (mainly used for date seg since year string's length is always 4)
	var year_length = 4;
	var returnValIfError = returnNullIfInvalid ? null : new Date();

	if(d.length > 0)
	{
		if(dateformat == "MM/DD/YYYY")
		{
			comps = d.split("/");
			if(comps.length != 3)
				return returnValIfError;
			month = parseInt(comps[0]) - 1;
			day = parseInt(comps[1]);
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD/MM/YYYY")
		{
			comps = d.split("/");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0]);
			month = parseInt(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD-Mon-YYYY")
		{
			comps = d.split("-");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0]);
			month = getMonthIndex(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD.MM.YYYY")
		{
			comps = d.split(".");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0]);
			month = parseInt(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD-MONTH-YYYY")
		{
			comps = d.split("-");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0]);
			month = arrayIndexOf(NLDate_months, comps[1], true);
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "YYYY/MM/DD")
		{
			comps = d.split("/");
			if(comps.length != 3)
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string);
			month = parseInt(comps[1]) - 1;
			year = parseInt(comps[0]);
			datestring_length = comps[1].length + end_string.length + year_length + 2;
		}
		else if(dateformat == "YYYY-MM-DD")
		{
			comps = d.split("-");
			if(comps.length != 3)
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string);
			month = parseInt(comps[1]) - 1;
			year = parseInt(comps[0]);
			datestring_length = comps[1].length + end_string.length + year_length + 2;
		}
		else if(dateformat == "EEYY年MM月DD日")
		{
			year_char_index = d.indexOf(year_char_cn);
			month_char_index = d.indexOf(month_char_cn);
			day_char_index = d.indexOf(day_char_cn);
			if(year_char_index < 0 || month_char_index < 0 || day_char_index < 0)
				return returnValIfError;
			day = parseInt(d.substring(month_char_index+1,day_char_index));
			month = parseInt(d.substring(year_char_index+1,month_char_index)) - 1;
			era = d.substring(0, 2);
			year = get_gregorian_year(parseInt(d.substring(2,year_char_index)), era);
			datestring_length = day_char_index + 1;
		}
		else if(dateformat == "YYYY年MM月DD日")
		{
			year_char_index = d.indexOf(year_char_cn);
			month_char_index = d.indexOf(month_char_cn);
			day_char_index = d.indexOf(day_char_cn);
			if(year_char_index < 0 || month_char_index < 0 || day_char_index < 0)
				return returnValIfError;
			day = parseInt(d.substring(month_char_index+1,day_char_index));
			month = parseInt(d.substring(year_char_index+1,month_char_index)) - 1;
			year = parseInt(d.substring(0,year_char_index));
			datestring_length = day_char_index + 1;
		}
		else if(dateformat == "EYY.MM.DD")
		{
			comps = d.split(".");
			if(comps.length != 3)
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string, 10);
			month = parseInt(comps[1]) - 1;
			era = comps[0].substring(0, 1);
			year = get_gregorian_year(parseInt(comps[0].substring(1,comps[0].length)), era);
			datestring_length = comps[0].length + comps[1].length + end_string.length + 2;
		}
		else if(dateformat == "DD. MON YYYY")
		{
			comps = d.split(" ");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0].substring(0, comps[0].length - 1));
			month = arrayIndexOf(NLDate_short_months, comps[1]);
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD de MONTH de YYYY")
		{
			comps = d.split(" de ");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[0]);
			month = getMonthIndex(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 8;
		}
		else if(dateformat == "YYYY년 MM월 DD일")
		{
			comps = d.split(" ");
			if(comps.length != 3)
				return returnValIfError;
			day = parseInt(comps[2].substring(0, comps[2].length-1));
			month = parseInt(comps[1].substring(0, comps[1].length-1)) - 1;
			year = parseInt(comps[0].substring(0, comps[0].length-1));
			datestring_length = year_length + comps[1].length + comps[2].length + 5;
		}
		else if(dateformat == "DD MONTH YYYY")
		{
			comps = d.split(" ");
			if(comps.length < 3) //the format could be "DD MONTH YYYY HH:MI:SS AM" . length =4
				return returnValIfError;
			day = parseInt(comps[0]);
			month = arrayIndexOf(NLDate_months, comps[1], true);
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD MONTH, YYYY")
		{
			comps = d.split(" ");
			if(comps.length < 3) //the format could be "DD MONTH YYYY HH:MI:SS PM" . length = 4
				return returnValIfError;
			day = parseInt(comps[0]);
			month = arrayIndexOf(NLDate_months, comps[1].substring(0, comps[1].length-1), true);
			year = parseInt(comps[2].substring(0, year_length));
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
	}

	if (!isvalidyearmonthday(year, month, day))
		return returnValIfError;
	
	// now handle the time segment
	var result;
    var t = arg.substring(datestring_length);
	if (t != null && t.length > 0)
    {
        if (formattype == 'datetimetz')
            result = regexstringtotime(arg.substring(0,datestring_length),t, true);
        else if (formattype == 'datetime' || formattype == 'timeofday')
            result = regexstringtotime(arg.substring(0,datestring_length),t, false);
        else
            result = stringtotime(arg.substring(0,datestring_length),t);        
    }
    else
        result = new Date(year,month,day);
    if (year < 50)
        nlSetFullYear(result, year+2000);
    else if (year < 100)
        nlSetFullYear(result, year+1900);
    return result;
}

function isvalidyearmonthday(year, month, day)
{
	if(isNaN(year) || year < 0 || isNaN(month) || month < 0 || month > 11 || isNaN(day) || day < 1 || day > 31)
		return false;
	else
		return true;
}

// we need this for sever side script
function trimstring(str)
{
    return str.replace(/^\s+/,"").replace(/\s+$/,"");
}

function regexstringtotime(date, time, includeSeconds)
{
    var flddate = date != null ? stringtodate(date) : new Date();
    if (time != null && new String(time).length != 0 && new String(time).search(/\S/) >= 0)
    {
        var hours, minutes, seconds;
        hours = NaN;
        minutes = NaN;
        seconds = NaN;

        var delimitors = null;
        time = trimstring(time); // remove all leading/trailing spaces

        var TIME_FORMAT_MAP =
        {
            "HH:MI:SS am": { rcase:0, hend:':', mend:':', send:' '},
            "HH-MI-SS am": { rcase:0, hend:'-', mend:'-', send:' '},
            "HH24:MI:SS": { rcase:0, hend:':', mend:':', send:null},
            "HH24-MI-SS": { rcase:0, hend:'-', mend:'-', send:null},
            "amHH時MI分SS秒": { rcase:1, hend:'時', mend:'分', send:'秒'},
            "amHH点MI分SS秒": { rcase:1, hend:'点', mend:'分', send:'秒'},
            "amHH시MI분SS초": { rcase:1, hend:'시', mend:'분', send:'초'},
            "HH24時MI分SS秒": { rcase:1, hend:'時', mend:'分', send:'秒'},
            "HH24点MI分SS秒": { rcase:2, hend:'点', mend:'分', send:'秒'},
            "HH24시MI분SS초": { rcase:2, hend:'시', mend:'분', send:'초'},
            "HH:MI am": { rcase:0, hend:':', mend:' ', send:null},
            "HH-MI am": { rcase:0, hend:'-', mend:' ', send:null},
            "HH24:MI": { rcase:0, hend:':', mend:null, send:null},
            "HH24-MI": { rcase:0, hend:'-', mend:null, send:null},
            "amHH時MI分": { rcase:1, hend:'時', mend:'分', send:null},
            "amHH点MI分": { rcase:1, hend:'点', mend:'分', send:null},
            "amHH시MI분": { rcase:1, hend:'시', mend:'분', send:null},
            "HH24時MI分": { rcase:2, hend:'時', mend:'分', send:null},
            "HH24点MI分": { rcase:2, hend:'点', mend:'分', send:null},
            "HH24시MI분":{ rcase:2, hend:'시', mend:'분', send:null}
        }

        format = includeSeconds ? window.timeformatwithseconds.replace(/fm/g, "") : window.timeformat.replace(/fm/g, "");
        format = trimstring(format);
        delimitors = TIME_FORMAT_MAP[format];

        var m;
        var ampm = null;
        var hend = null, mend = null, send = null;
        if (delimitors != null)
        {
            switch (delimitors.rcase)
            {
                case 0:
                {
                    m = /^(\d+)(\D)(\d+)((\D)(\d+))?\s*(am|pm)?/.exec(time);
                    if (m[0] != null)
                    {
                        hours = parseInt(m[1], 10);
                        hend = m[2];
                        minutes = parseInt(m[3], 10);
                        mend = m[5];
                        if (includeSeconds && m[4] != null)
                            seconds = parseInt(m[6], 10);
                        else
                            seconds = 0;
                        ampm = m[7];
                    }
                    break;
                }
                case 1:
                {
                    m = /^(am|pm)(\d+)(\D)(\d+)(\D)((\d+)(\D))?/.exec(time);
                    if (m[0] != null)
                    {
                        hours = parseInt(m[2], 10);
                        hend = m[3];
                        minutes = parseInt(m[4], 10);
                        mend = m[5];
                        if (includeSeconds && m[6] != null)
                        {
                            seconds = parseInt(m[7], 10);
                            send = m[8];
                        }
                        else
                            seconds = 0;
                        ampm = m[1];
                    }
                    break;
                }
                case 2:
                {
                    m = /^(\d+)(\D)(\d+)(\D)((\d+)(\D))?/.exec(time);
                    if (m[0] != null)
                    {
                        hours = parseInt(m[1], 10);
                        hend = m[2];
                        minutes = parseInt(m[3], 10);
                        mend = m[4];
                        if (includeSeconds && m[5] != null)
                        {
                            seconds = parseInt(m[6], 10);
                            send = m[7];
                        }
                        else
                            seconds = 0;         
                    }
                    break;
                }
            }
            if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) || hours >= 24 || hours < 0 || minutes >= 60 || minutes < 0 || seconds >= 60 || seconds < 0)
                return NaN;

            if (hend != delimitors.hend || (includeSeconds && (mend != null && mend != delimitors.mend) || (send != null && send != delimitors.send)))
                return NaN;

            if (ampm != null)
            {
                var is_pm = (ampm == window.datetime_pm_string);
                if (!is_pm && hours == 12)
                    hours = 0;
                else if (is_pm && hours < 12)
                    hours += 12;
            }
            flddate.setHours(hours, minutes, seconds, 0);
        } else
           flddate = NaN;        
    }
    return flddate;
}



function stringtotime(date, time)
{
    var flddate = date != null ? stringtodate(date) : new Date();
    if (time != null && new String(time).length != 0 && new String(time).search(/\S/) >= 0)
    {
        var hours, minutes, seconds, is_pm;
        var hour_char_index;
        var minute_char_index;
        format = window.timeformat.replace(/fm/g, "");
        if (format == "HH:MI am" || format == "HH-MI am" || format == "HH24:MI" || format == "HH24-MI")
        {
            var m = /^\s*(\d+)[-:](\d+)\s*(.*)/.exec(time);
            if (!m) return NaN;
            hours = parseInt(m[1], 10);
            minutes = parseInt(m[2], 10);
            if (format.substring(6) == "am")
            {
                is_pm = (m[3] == window.datetime_pm_string);
                if (!is_pm && hours == 12)
                    hours = 0;
                else if (is_pm && hours < 12)
                    hours += 12;
            }
        }
        else if(format == "amHH時MI分" || format == "amHH点MI分" || format == "amHH시MI분")
        {
            hour_char_index = time.indexOf("時");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("点");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("시");
            var hour_start_index = 0;
            is_pm = false;
            if(time.indexOf(window.datetime_am_string) == 0)
                hour_start_index = window.datetime_am_string.length;
            else if(time.indexOf(window.datetime_pm_string) == 0)
            {
                hour_start_index = window.datetime_pm_string.length;
                is_pm = true;
            }
            hours = parseInt(time.substring(hour_start_index, hour_char_index));
            if (!is_pm && hours == 12)
                hours = 0;
            else if(is_pm && hours < 12)
                hours += 12;
            minutes = parseInt(time.substring(hour_char_index + 1, time.length - 1));
        }
        else if(format == "HH24時MI分" || format == "HH24点MI分" || format == "HH24시MI분")
        {
            hour_char_index = time.indexOf("時");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("点");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("시");
            hours = parseInt(time.substring(0, hour_char_index));
            minutes = parseInt(time.substring(hour_char_index + 1, time.length - 1));
        }
        if(isNaN(hours) || isNaN(minutes) || hours >= 24 || hours < 0 || minutes >= 60 || minutes < 0 || seconds >= 60 || seconds < 0)
            return NaN;
        flddate.setHours(hours, minutes, 0, 0);
    }
    return flddate;
}

function hhmmtotime( hhmm )
{
    return stringtotime( null, hhmmtotimestring( hhmm ) );
}

// -- handle shorthand time notation i.e. 5p -> 5:00 pm, 18 -> 6:00 pm, 900 -> 9:00 am, 1433p -> 2:33 pm
function hhmmtotimestring( hhmm )
{
    var fldvalue = hhmm;
	var hour, minute;
	if ( window.datetime_am_string.charAt(0) == window.datetime_pm_string.charAt(0) )
		re = new RegExp("^[0-9]{1,4}("+window.datetime_am_string+"|"+window.datetime_pm_string+")*$", "i");
	else
		re = new RegExp("^[0-9]{1,4}(["+window.datetime_am_string.charAt(0)+"|"+window.datetime_pm_string.charAt(0)+"]?)$","i");
    if ( re.test(fldvalue) )
    {
		var aorp = '';
		if ( RegExp.$1 )
		{
			if ( window.datetime_am_string.charAt(0) == window.datetime_pm_string.charAt(0) )
				aorp = RegExp.$1.toLowerCase() == window.datetime_pm_string ? window.datetime_pm_string : window.datetime_am_string;
			else
				aorp = RegExp.$1.toLowerCase().charAt(0) == window.datetime_pm_string.charAt(0) ? window.datetime_pm_string : window.datetime_am_string;
		}
		if ( fldvalue.length < 3 || ( fldvalue.length == 3 && RegExp.$1 ) )
        {
            var hh = RegExp.$1 ? fldvalue.substring(0,fldvalue.length-1) : fldvalue;
            hour = parseInt( hh, 10 ) == 0 ? 12 : ( parseInt( hh, 10 ) > 12 ? parseInt( hh, 10 ) % 12 : hh ) ;
			minute = 0;
            var ampm = RegExp.$1 ? aorp :
					   ( parseInt( fldvalue, 10 ) > 11 ? window.datetime_pm_string : window.datetime_am_string );
        }
		else if (fldvalue.length == 3 || (fldvalue.length == 4 && RegExp.$1) )
        {
            var hh = fldvalue.substring(0,1) == "0" ? "12" : fldvalue.substring(0,1);
			hour = parseInt( hh, 10 );
			var mm = RegExp.$1 ? fldvalue.substring(1,3) : fldvalue.substring(1);
			minute = parseInt( mm, 10 );
			var ampm = RegExp.$1 ? aorp : window.datetime_am_string;
        }
        else
        {
            var hh = fldvalue.substring(0,2);
			hour = parseInt( hh, 10 ) == 0 ? 12 : ( parseInt( hh, 10 ) > 12 ? parseInt( hh, 10 ) % 12 : hh );
			var mm = RegExp.$1 ? fldvalue.substring(2,4) : fldvalue.substring(2);
			minute = parseInt( mm, 10 );            
			var ampm = parseInt( fldvalue.substring(0,2), 10 ) > 11 ? window.datetime_pm_string : window.datetime_am_string;
            ampm = RegExp.$1 ? aorp : ampm;
		}
		if (ampm == window.datetime_am_string && hour == 12)
			hour = 0;
		else if(ampm == window.datetime_pm_string && hour != 12)
			hour = parseInt(hour) + 12;
		var time = new Date();
		time.setHours(hour,minute,0,0);        
        fldvalue = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
	}
	return fldvalue;
}

function adddays(d, daystoadd)
{
    var d2 = new Date(d.getTime() + 86400 * daystoadd * 1000);
    if (d2.getHours() != d.getHours())
    {
        if ((d.getHours() > 0 && d2.getHours() < d.getHours()) || (d.getHours() == 0 && d2.getHours() == 23))
          d2.setTime(d2.getTime() + 3600*1000);
        else
          d2.setTime(d2.getTime() - 3600*1000);
    }
    d.setTime(d2.getTime());
    return d;
}

function daysBetween(dEarly, dLate) // ignores time
{
	return get_julian_date(dLate) - get_julian_date(dEarly);
}

function monthsBetween(dEarly, dLate) // ignores DOM and time
{
	return 12*(dLate.getFullYear() - dEarly.getFullYear()) + (dLate.getMonth() - dEarly.getMonth());
}

function isDOWIM(dDate, nDOWIM)
{
	return (nDOWIM >= 1 && nDOWIM == (1 + Math.floor((dDate.getDate()-1)/7))) ||
		((nDOWIM == -1 || nDOWIM == 5) && daysBetween(dDate, addmonths(new Date(dDate.getFullYear(), dDate.getMonth(), 1), 1)) <= 7);
}

function isLeapYear(year)
{
    return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

MONTH_LENGTH = [[31,28,31,30,31,30,31,31,30,31,30,31],[31,29,31,30,31,30,31,31,30,31,30,31]];

function getMonthLength(year, month)
{
	return MONTH_LENGTH[isLeapYear(year)?1:0][month];
}

/**
 *  setDateComponents: set the month and day of the given date.  If noRollover is given and true,
 *  the day will not exceed the last day of the final month and thus will not trigger a month rollover.
 */
function setDateComponents(theDate, monthsToAdd, theDay, noRollover)
{
  var newDate  = new Date(theDate);

  if (typeof(noRollover) != 'boolean')
      noRollover = false;
  addmonths(newDate,monthsToAdd);
  setDate(newDate, theDay, noRollover);

  return newDate;
}

function addmonths(d, mtoadd)
{
	if (mtoadd != 0)
	{
		var year = nlGetFullYear(d);
		var dom = d.getDate();
		var month = d.getMonth() + mtoadd;
		if (month < 0)
		{
			month += 1;
			year = year + Math.ceil(month / 12) - 1;
			nlSetFullYear(d, year);
			month = 11 + (month % 12);
		}
		else if (month > 11)
		{
			year = year + Math.floor(month / 12);
			nlSetFullYear(d, year);
			month %= 12;
		}
		eom = getMonthLength(year, month);
		if (dom > eom) d.setDate(eom);
		d.setMonth(month);
    }
    return d;
}

function addhours(d, hourstoadd, truncate)
{
    var d2 = new Date(d.getTime() + 3600 * hourstoadd * 1000);
    d.setTime(d2.getTime());
	if (truncate)
	{
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
	}
	return d;
}

function setDate(d, day, noRollover)
{
    if (noRollover)
    {
        var eom = getMonthLength(nlGetFullYear(d), d.getMonth());
        day = Math.min(eom, day);
    }
    d.setDate(day);
}

m_j_d = [[0,31,59,90,120,151,181,212,243,273,304,334],[0,31,60,91,121,152,182,213,244,274,305,335]];

function getMonthJulian(year, month)
{
	return m_j_d[isLeapYear(year)?1:0][month];
}

var j_d=new Array();
j_d[1970]=0;
j_d[1971]=365;
j_d[1972]=730;
j_d[1973]=1096;
j_d[1974]=1461;
j_d[1975]=1826;
j_d[1976]=2191;
j_d[1977]=2557;
j_d[1978]=2922;
j_d[1979]=3287;
j_d[1980]=3652;
j_d[1981]=4018;
j_d[1982]=4383;
j_d[1983]=4748;
j_d[1984]=5113;
j_d[1985]=5479;
j_d[1986]=5844;
j_d[1987]=6209;
j_d[1988]=6574;
j_d[1989]=6940;
j_d[1990]=7305;
j_d[1991]=7670;
j_d[1992]=8035;
j_d[1993]=8401;
j_d[1994]=8766;
j_d[1995]=9131;
j_d[1996]=9496;
j_d[1997]=9862;
j_d[1998]=10227;
j_d[1999]=10592;
j_d[2000]=10957;
j_d[2001]=11323;
j_d[2002]=11688;
j_d[2003]=12053;
j_d[2004]=12418;
j_d[2005]=12784;
j_d[2006]=13149;
j_d[2007]=13514;
j_d[2008]=13879;
j_d[2009]=14245;
j_d[2010]=14610;
j_d[2011]=14975;
j_d[2012]=15340;
j_d[2013]=15706;
j_d[2014]=16071;
j_d[2015]=16436;
j_d[2016]=16801;
j_d[2017]=17167;
j_d[2018]=17532;
j_d[2019]=17897;
j_d[2020]=18262;
j_d[2021]=18628;
j_d[2022]=18993;
j_d[2023]=19358;
j_d[2024]=19723;
j_d[2025]=20089;
j_d[2026]=20454;
j_d[2027]=20819;
j_d[2028]=21184;
j_d[2029]=21550;
j_d[2030]=21915;

function get_julian_date(d)
{
    return j_d[d.getFullYear()]+getMonthJulian(d.getFullYear(),d.getMonth())+d.getDate()-1;   
}

function getMonthIndex(sMonth)
{
    var m = -1;
    sMonth = sMonth.toUpperCase()
    for ( var i=0; i < NLDate_short_months.length; i++ )
    {
        if ( NLDate_short_months[i].toUpperCase() == sMonth )
        {
            m = i + 1; break;
        }
    }
    if(m != -1)
    	return m;
    for ( var i=0; i < NLDate_months.length; i++ )
    {
        if ( NLDate_months[i].toUpperCase() == sMonth )
        {
            m = i + 1; break;
        }
    }
    if(m != -1)
    	return m;
    else
    {
        var ms = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
        m = (ms.indexOf(sMonth)+3)/3;
    }
    return m;
}



function createTDWindow(dest)
{

  var wide = screen.width*(0.35);
  var high = screen.height*(0.3);
  if(wide<150 || high<150)
  {
    wide = 150;
    high = 150;
  }
  var leftpos = screen.width-(wide+20);
  var toppos =  screen.height-(high+60);
  window.open(dest,'test','scrollbars=yes,width='+wide+',height='+high+',left='+leftpos+',top='+toppos);
}

function DoFieldFocus(form)
{
    if (form == null)
        return;
    var i;
    for (i=0;i< form.elements.length;i++)
    {
        var el = form.elements[i];
        if (el.type == "text" || el.type == "select-one" || el.type == "checkbox")
        {
            el.focus();
            return;
        }
    }
}


function clearMultiSelect(sel)
{
    if ( isNLMultiDropDown( sel ) )
        getMultiDropdown( sel ).removeAll();
    else if (sel.type == "select-multiple")
    {
        for ( i=sel.length-1; i >=0 ; i-- )
            sel.options[i].selected = false;
    }
    else
    {
        sel.value='';
        if (sel.form.elements[sel.name+'_display'] != null)
            sel.form.elements[sel.name+'_display'].value='';
    }
}

function getnamevaluelisttext(val,delim,alllabels)
{
    if (val.length == 0)
        return "";
    var nvarray = val.split(String.fromCharCode(4));
    var result = "";
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        var dv = nv.length==5?nv[4]:nv[3];
        if ((dv != null && dv.length > 0) || alllabels == true)
        {
            if (!isValEmpty(result)) result += delim;
            result += nv[2]+": "+dv;
        }
    }
    return result;
}

function getnamevaluelistdata(val)
{
    if (val.length == 0)
        return "";
    var nvarray = val.split(String.fromCharCode(4));
    var result = "";
    for (var i=0; i < nvarray.length; i++)
    {
        if (i>0)
            result += String.fromCharCode(4);
        var nv = nvarray[i].split(String.fromCharCode(3));
        var v = nv.length>3?nv[3]:"";
        result += nv[0]+String.fromCharCode(3)+v;
    }
    return result;
}

function getnamevaluelistvalue(nvlist,name)
{
    if (nvlist.length == 0)
        return null;
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
            return nv[3];
    }
    return null;
}

function getnamevaluelistdisplayvalue(nvlist,name)
{
    if (nvlist.length == 0)
        return null;
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
            return nv.length==5?nv[4]:nv[3];
    }
    return null;
}

function setnamevaluelistvalue(nvlist,name,value)
{
    if (nvlist.length == 0)
        return "";
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
        {
            nv[3] = value;
            nvarray[i] = nv.join(String.fromCharCode(3));
            break;
        }
    }
    return nvarray.join(String.fromCharCode(4));
}

function syncnamevaluelist(list)
{
    var fldDisp = list.form.elements[list.name+"_display"];
    fldDisp.value = getnamevaluelisttext(list.value,"\n", true);
    if(fldDisp.onchange)
    {
        fldDisp.onchange();
    }
}

function syncpopupmachinefield(machine, fld, line, value)
{
    if (machine == null)
        nlapiSetFieldValue(fld, value);
    else if (line != null)
        nlapiSetLineItemValue(machine, fld, line, value);
    else
        nlapiSetCurrentLineItemValue(machine, fld, value);
}


function NLNameValueList_onKeyPress(evt, sFieldName, sOptionHelperSuffix)
{
    var keyCode = getEventKeypress(evt);

    if( keyCode == 32 ) 
    {
        
        var ndAction = document.getElementById(sFieldName + '_helper_' + sOptionHelperSuffix);
        if( ndAction && ndAction.click)
        {
            ndAction.click();
        }
    }
    return true;
}

function synclist(list,val,makedefault)
{
    if (isNLDropDown(list))
    {
        var dd = getDropdown(list);
        if(dd != null)
        {
            var idx = dd.getIndexForValue(val);
            dd.setIndex(idx, true );
            if (makedefault)
            {
                dd.setDefaultIndex(idx);
                list.setAttribute("defaultValue", val); 
            }
        }
    }
    else if (list.type == 'select-one')
    {
        for (var i=0; i < list.length; i++)
        {
            if (list.options[i].value == val)
            {
                list.selectedIndex=i;
                if (makedefault)
                {                                                                                                                                        
                    list.options[i].defaultSelected = true;
                    list.setAttribute("defaultValue", val); 
                }
                break;
            }
        }
    }
    else
    {
        list.value = val;
        if (makedefault)
            list.setAttribute("defaultValue", val); 

    }
}
function syncpopup(list,val,name,makedefault)
{
    var i;
    if (isNLDropDown(list))
    {
        var dd = getDropdown(list);
        var idx = dd.getIndexForValue(val);
        dd.setIndex(idx, true );
        if (makedefault)
            dd.setDefaultIndex(idx);
    }
    else if (isNLMultiDropDown(list))
    {
        var dd = getMultiDropdown(list);
        dd.setValues(val);
    }
    else if (list.type == "select-one" || list.type == "select-multiple")
    {
        for (i=0; i < list.length; i++)
        if (list.options[i].value == val)
        {
            list.selectedIndex=i;
            if (makedefault)
                list.options[i].defaultSelected = true;
            break;
        }
    }
    else if ( isPopupSelect( list ) )
    {
        list.value = val;
        if (makedefault)
            list.defaultValue = val;
        var dispfld = list.form.elements[list.name+"_display"];
        if (val.length > 0 || (name != null && name.length > 0))
        {
            if (typeof name != "undefined" && name != null)
            {
                dispfld.value = name;
                dispfld.style.color='000000';
                if (makedefault)
                    dispfld.defaultValue = name;
            }
        }
        else if (list.getAttribute('onlyAllowExactMatch') == null)
        {
            dispfld.value = dispfld.type == 'text' ? _popup_help : _mult_popup_help;
            dispfld.style.color='999999';
        }
    }
    else
    {
        list.value = val;
        if (makedefault)
            list.defaultValue = val;
    }
}

function syncmultiselectlist(list,val,labels, bDontFireOnChange)
{
    clearMultiSelect(list);
	if ( typeof val != "string" && !isArray(val) )
		val = ""+val;
	if (isNLMultiDropDown(list))
    {
        if ( typeof val != "string" )
            val = val.join( String.fromCharCode(5) );
        var dd = getMultiDropdown(list);
        dd.setValues(val, bDontFireOnChange);
    }
    else if (list.type != "select-multiple")
    {
        list.form.elements[list.name].value = val;
		labels = emptyIfNull(labels);
		var delimiter = labels.indexOf(String.fromCharCode(5)) != -1 ? String.fromCharCode(5) : "\n"
		var labelsfld = list.form.elements[list.name+"_labels"];
		if (labelsfld != null)
			labelsfld.value = isValEmpty(val) ? "" : labels.split(delimiter).join(String.fromCharCode(5));
		var displayfld = list.form.elements[list.name+"_display"];
		if (displayfld != null && list.getAttribute('onlyAllowExactMatch') == null)
			displayfld.value = labels ? labels.split(delimiter).join('\n') : _mult_popup_help;
    }
    else
    {
        if ( typeof val == "string" )
            val = val.split( String.fromCharCode(5) );
        for ( var i=0; i < val.length; i++)
        {
            for ( var j=0; j < list.length; j++)
            {
                if (list.options[j].value == val[i])
                    list.options[j].selected = true;
            }
        }
    }
}



function syncradio(radio,val,makedefault)
{
    var i;
    var selected;
    for (i=0; i < radio.length; i++)
    {
     	selected = radio[i].value == val;
		radio[i].checked=selected;
		if (makedefault)
			radio[i].defaultChecked = selected;
    }
}
function getlisttext(list, val, frommultisel)
{
    if (isNLDropDown(list))
        return getDropdown(list).getTextForValue(val);
    if (list.type != "select-one" && !frommultisel)
        return '';
    for (var i=0; i < list.length; i++)
        if (list.options[i].value == val)
            return list.options[i].text;
    return "";
}
function getmultiselectlisttext(list, val, delim)
{
    if (!delim)
        delim = '<br>';

    if ( isNLMultiDropDown(list) )
    {
        return getMultiDropdown(list).getSelectedTextFromValues(val, delim);
    }
    else if (list.type != "select-multiple")
    {
        return '';
    }
    else
    {
        var selvals = val.split(String.fromCharCode(5));
        var label = '';
        for (var i=0; i < selvals.length; i++)
        {
            if (i > 0) label += delim;
                label += getlisttext(list, selvals[i], true);
        }
        return label;
    }
}
function getradiotext(radio, val)
{
    var i;
    for (i=0;i< radio.length;i++)
        if (radio[i].value == val)
            return radio[i].textValue;
    return "";
}
function getRadioValue(radio)
{
    var val = '';
    if (typeof radio.length=="undefined") 
        radio = radio.ownerDocument.getElementsByName(radio.name);
    for (var i=0; i < radio.length; i++)
    {
        if (radio[i].checked == true)
        {
            val = radio[i].value;
            break;
        }
    }
    return val;
}
function getSelectedRadio(radio)
{
    var val = null;
    if (typeof radio.length == "undefined") 
        radio = radio.ownerDocument.getElementsByName(radio.name);
    for (var i=0; i < radio.length && val == null; i++)
		val = radio[i].checked ? radio[i] : null;
    return val;
}


function getSelectValue(sel)
{
    var returnMe;
    if (sel.type != null && sel.type == "select-one")
        returnMe = (sel.options.length == 0 || sel.selectedIndex == -1 || sel.selectedIndex >= sel.options.length) ? '' :  sel.options[sel.selectedIndex].value;
    else if (isMultiSelect(sel))
        returnMe = getMultiSelectValues(sel);
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).getValue();
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).getSelectedValues();
    else
        returnMe = sel.value;
    return returnMe;
}
function getSelectValueArray(sel)
{
    var returnMe;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        returnMe = new Array(sel.length);
        for ( var i = 0; i < sel.length; i++ )
            returnMe[i] = sel.options[i].value;
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).valueArray;
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).valueArray;
    return returnMe;
}

function getIndexForValue(sel,val)
{
    var returnMe=-1;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        for ( var i = 0; i < sel.length; i++ )
            if(sel.options[i].value==val)
            {
                returnMe=i;
                break;
            }
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).getIndexForValue(val);
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).getIndexForValue(val);
    if (typeof(returnMe) == "undefined")
     	returnMe = -1;
	return returnMe;

}
function getSelectTextForValue(  sel, val )
{

    var textArray = getSelectValueArray(sel);
    var i;
    for (i = 0; i < textArray.length; i++)
    {
        if (textArray[i] == val)
            return getSelectTextAtIndex(sel, i);
    }
    return null;

}
function getSelectTextArray(sel)
{
    var returnMe;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        returnMe = new Array(sel.length);
        for ( var i = 0; i < sel.length; i++ )
            returnMe[i] = sel.options[i].text;
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).textArray;
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).textArray;
    return returnMe;
}
function getSelectText(sel, returnArray)
{
	var val = getSelectValue(sel);
	if (sel.type == "select-one")
        return (sel.options.length == 0 || sel.selectedIndex == -1 || sel.selectedIndex >= sel.options.length) ? null : sel.options[sel.selectedIndex].text;
    else if (isNLDropDown(sel))
        return getDropdown(sel).getText();
    else if ( isMultiSelect(sel) || isPopupMultiSelect( sel ) )
        return getMultiSelectText( sel, null, returnArray );
    else if ( isPopupSelect( sel ) )
        return isValEmpty(val) ? '' : getFormElement(sel.form,sel.name+'_display').value.replace(/\s$/,'');
    else if ( isDisplayOnlySelect( sel ) )
        return getInlineTextValue(document.getElementById(sel.name+"_displayval"));
    else
        return sel.text;
}
function setSelectValue(sel, val)
{
    if (window.virtualBrowser)
    {
        sel.value = val;
    }
    else if (isNLDropDown(sel))
    {
        var dd = getDropdown(sel);
        var idx = dd.getIndexForValue(val);
        if (idx == null)
            return false;
        dd.setIndex(idx, true );
        
        if(dd.isOpen)
            dd.setCurrentCellInMenu(dd.divArray[idx]);

    }
    else if (isNLMultiDropDown(sel))
    {
        var dd = getMultiDropdown(sel);
        var idx = dd.getIndexForValue(val);
        if (idx == null)
            return false;
        dd.setIndex(idx);
    }
    else if (sel.type == "select-one")
    {
        var opt = sel.options;
        for (var i=0; i < opt.length; i++)
        {
            if (opt[i].value==val)
            {
                sel.selectedIndex=i;
                return true;
            }
        }
        return false;
    }
    else if (sel.type == "select-multiple")
    {
        var opts = sel.options;
        var result = false;
        for (var i=0; i < opts.length; i++)
        {
            opts[i].selected = opts[i].value == val;
            result = result || opts[i].value == val;
        }
        return result;
    }
    else
    {
        sel.value = val;
        if (val.length == 0 && isPopupSelect( sel ) )
        {
            var dispfld = sel.form.elements[sel.name+"_display"];
            dispfld.value = dispfld.type == 'text' ? _popup_help : _mult_popup_help;
            dispfld.style.color = '999999';
        }
    }
    return true;
}

function addMultiSelectValue(sel, val, name)
{
    if (isNLMultiDropDown(sel))
    {
        var dd = getMultiDropdown(sel);
        var idx = dd.getIndexForValue(val);
        dd.addIndex(idx);
    }
    else if (sel.type == "select-multiple")
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if ( opts[i].value == val )
                opts[i].selected = true;
    }
    else
    {
        var values = sel.value.split(String.fromCharCode(5));
        for (var i=0;i < values.length;i++)
            if (values[i] == val) return;
        sel.form.elements[sel.name+"_display"].style.color = '000000';
        if (values.length == 0 || values[0].length == 0)
        {
            sel.value = val;
            sel.form.elements[sel.name+"_display"].value = name;
            sel.form.elements[sel.name+"_labels"].value = name;
        }
        else
        {
            sel.value += String.fromCharCode(5)+val;
            sel.form.elements[sel.name+"_labels"].value += String.fromCharCode(5)+name;
            var lines = sel.form.elements[sel.name+"_display"].value.split(/\n|\r/);
            if (lines.length == values.length)
                sel.form.elements[sel.name+"_display"].value += "\n"+name;
            else
            {
                lines[values.length] = name;
                sel.form.elements[sel.name+"_display"].value = lines.join("\n");
            }
        }
    }
}


function getCurrentMultiSelectUserInputValue (inputField)
{
    var selectionStartPos = getSelectedTextRange(inputField)[0];
    var subStrBefore = inputField.value.substr(0, selectionStartPos);
    var startPos = Math.max(subStrBefore.lastIndexOf('\n'), subStrBefore.lastIndexOf('\r')) + 1;
    var endPos = inputField.value.substr(selectionStartPos).search(/\n|\r/);
    endPos = endPos == -1? inputField.value.length : selectionStartPos + endPos;
    userEnteredValue = inputField.value.substring(startPos, endPos);
    return userEnteredValue;
}

function getSelectValueForText(sel, txt)
{
    var textArray = getSelectTextArray(sel);
    var i;
    for (i = 0; i < textArray.length; i++)
    {
        if (textArray[i] == txt)
            return getSelectValueAtIndex(sel, i);
    }
    return null;
}

function deleteAllSelectOptions(sel, win)
{
    if (isNLDropDown(sel))
    {
        getDropdown(sel, win).deleteAllOptions();
    }
    else if (isNLMultiDropDown(sel))
    {
        getMultiDropdown(sel, win).deleteAllOptions();
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        sel.options.length = 0;
    }
    else if ( sel.form.elements[sel.name+"_display"] != null )
    {
        sel.form.elements[sel.name+"_display"].value = "";
        sel.value = "";
    }
}


function deleteOneSelectOption(sel, value, bDontSetWidth)
{
    if (isNLDropDown(sel))
    {
        getDropdown(sel).deleteOneOption(value, bDontSetWidth);
    }
    else if (isNLMultiDropDown(sel))
    {
        getMultiDropdown(sel).deleteOneOption(value);
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if (opts[i].value == value)
                opts[i] = null;
    }
    else if ( sel.form.elements[sel.name+"_display"] != null )
    {
        sel.form.elements[sel.name+"_display"].value = "";
        sel.value = "";
    }
}

function getSelectIndex(sel,win)
{
    if (isNLDropDown(sel))
    {
        return getDropdown(sel,win).getIndex();
    }
    else
    {
        return sel.selectedIndex;
    }
}
function setSelectIndex(sel, val)
{
    if (isNLDropDown(sel))
    {
        return getDropdown(sel).setIndex(val, true );
    }
    else if (isNLMultiDropDown(sel))
    {
        return getMultiDropdown(sel).setIndex(val);
    }
    else
    {
        sel.selectedIndex = val;
    }
}
function setMultiSelectValues(sel, val)
{
    syncmultiselectlist( sel, val );
}
function getMultiSelectValues( sel, returnArray )
{
    var val = null;
    if (isMultiSelect(sel))
    {
        if ( isNLMultiDropDown(sel) )
            val = getMultiDropdown(sel).getSelectedValues();
        else
        {
            val = '';
            for (var i=0; i < sel.length; i++)
            {
                if (sel.options[i].selected)
                    val += ((val == '' ? '' : String.fromCharCode(5)) + sel.options[i].value);
            }
        }
    }
    else
        val = sel.value;
    return returnArray ? (isValEmpty( val ) ? [] : val.split( String.fromCharCode(5) )) : val;
}
function getMultiSelectText(sel,inmachine,returnArray)
{
	var val = '';
	var delim = returnArray ? String.fromCharCode(5) : ", ";
	if ( isMultiSelect(sel) )
    {
		delim = inmachine ? '\n' : delim;
		if ( isNLMultiDropDown(sel) )
            val = getMultiDropdown(sel).getSelectedText( delim );
        else
        {
            var i, numParams = 0;
            for (i=0; i < sel.length; i++)
            {
                if (sel.options[i].selected)
                    val += ((numParams++ == 0 ? '' : ( delim )) + sel.options[i].text);
            }
        }
    }
    else if ( isPopupMultiSelect( sel ) )
    {
        val = getFormElement(sel.form,sel.name+'_labels').value;
        if ( val != null && delim != String.fromCharCode(5) )
            val = val.replace( new RegExp( String.fromCharCode(5), "g" ), delim )
    }
    else
        val = sel.text;
	return returnArray ? (isValEmpty( val ) ? [] : val.split( delim )) : val;
}
function updateMultiSelectValue(fld,displayfld,val,displayval,labelsfld)
{
    fld.value = val;
    labelsfld.value = displayval;
    var sellabels = displayval.split(String.fromCharCode(5));
    var displaytempval = '', numParams = 0;
    for (i=0; i < sellabels.length; i++)
    {
        displaytempval += ((numParams==0 ? '' : '\n') + sellabels[i]) ;
        numParams++;
    }
    displayfld.value = displaytempval;
}

function addSelectOption(doc,sel,text,value,selected,win,idx)
{

    if (isNLDropDown(sel))
	{
		var dd = getDropdown(sel,win);
		dd.addOption(text, value, idx);
		if (selected !== false)
		{
			var idx = dd.getIndexForValue(value);
			dd.setIndex(idx, true );
		}
	}
	else if (isNLMultiDropDown(sel))
	{
		var dd = getMultiDropdown(sel,win);
		dd.addOption(text, value, selected, idx);
	}
	else
	{
		var opt = doc.createElement('OPTION');
		opt.text= text;
		opt.value= value;
		if (isIE)
        {
            if (typeof(idx)=='undefined') idx = sel.length;
            sel.add(opt, idx);
        }
		else
        {
            var optInsertBefore = null;
            if (typeof(idx)!='undefined' && idx >=0 && idx < sel.length)
                optInsertBefore = sel.options[idx];
            sel.add(opt, optInsertBefore);
        }
		if (selected !== false)
		{
			opt.selected = true;
			
			if (isIE)
				sel.selectedIndex = idx;
		}
	}

}

function setSelectOptionText(sel,value,text,win)
{
    if (isNLDropDown(sel))
    {
        var dd = getDropdown(sel,win);
        dd.setOptionText(value,text);
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if (opts[i].value == value)
                opts[i].text = text;
    }
}


function getCascadedStyle(object, property, attribute)
{
    if ( object.currentStyle )
        return object.currentStyle[property];
    else if ( window.getComputedStyle )
    {
        
        if ( object.nodeType != 1 )
            return null;
        var objStyle = window.getComputedStyle(object, "");
        if (objStyle)
            return objStyle.getPropertyValue( attribute );
    }
    return null;
}

function isFocusable( fld )
{
    if ( fld == null || (typeof fld.type == "undefined" && !isNLDropDownSpan(fld)) || fld.type == "hidden" || fld.disabled || fld.type == "button")
        return false;
    return elementIsFocusable(fld);
}


function elementIsFocusable(elem)
{
    while ( elem != null )
    {
        var visibility = getCascadedStyle(elem, "visibility", "visibility");
        var display = getCascadedStyle(elem, "display", "display");
        if ( display == 'none' || visibility == 'hidden' || visibility == 'hide' )
            return false;
        elem = elem.parentNode;
    }
    return true;
}


function NLIsButton(elem)
{
    if (elem)
    {
        if (elem.tagName == "BUTTON" || (elem.tagName == "INPUT" && ( elem.type == "submit" || elem.type == "button" || elem.type == "reset")))
            return true;
    }
    return false;
}

function NLIsSubmitButton(elem)
{
	if (elem)
    {
    	if (elem.tagName == "INPUT" && elem.type == "submit" )
        	return true;
    }
    return false;
}

function NLDisableButton(elem, val)
{
    elem.disabled = val;
    if (elem.className.indexOf("nlbutton") >= 0 || elem.className.indexOf("bgbutton") >= 0 || elem.className.indexOf("nlinlineeditbutton") >= 0)
        elem.className = elem.className.split("Disabled")[0] + (val ? "Disabled" : "");
        
        
    
    if ((elem.className.indexOf('bntBgT') >= 0) && (elem.name))
    {
        var trElem = document.getElementById('tr_' + elem.name);
        if (trElem && trElem.className)
        {
        	if (val)
        	{
        		
        		if (trElem.className.indexOf('Dis') < 0)
        			trElem.className = trElem.className +'Dis';
        	}
        	else
        		trElem.className = trElem.className.replace('Dis', '');
        
        }
    }
}

 
 
function NLInvokeButton(elem)
{
	if (elem)
    {
    	
    	if (elem.disabled)
    		return;

        elem.click();

    }

}

function NLAddButtonDisabledMessage(container, name, message)
{
	var obj = document.getElementById(container);
    var elem = document.getElementById(name);
	if (obj == null || elem == null)
		return;

	var positionX = findGlobalPosX(obj);
	var positionY = findGlobalPosY(obj);
	var objWidth = obj.offsetWidth;
	var objHeight = obj.offsetHeight;
	
	var tDiv = document.createElement('div');
	tDiv.style.position = "absolute";
	tDiv.style.left = positionX + 'px';
	tDiv.style.top = positionY + 'px';
	tDiv.style.width = objWidth  + 'px';
	tDiv.style.height = objHeight  + 'px';
	tDiv.style.background = '#000000';
	tDiv.style.opacity = '0';
	tDiv.style.zindex = '100';
	
	attachEventHandler('mouseover', tDiv, function(){ nlShowMessageTooltip(elem, message);} );
	attachEventHandler('mouseout', tDiv, function(){ closePopup();} );
    attachEventHandler('click', tDiv, function() {if (!elem.disabled)	elem.onClick();} );

	obj.appendChild(tDiv);		
}


function isDisplayOnlySelect(sel)
{
    return sel != null && sel.type == "hidden" && document.getElementById(sel.name+'_displayval' ) != null;
}
function isPopupSelect(sel)
{
    return sel != null && sel.type == "hidden" && getFormElement(sel.form, sel.name+'_display' ) != null && getFormElement(sel.form, sel.name+'_display' ).type == "text";
}
function isPopupMultiSelect(sel)
{
    return sel != null && sel.type == "hidden" && getFormElement(sel.form, sel.name+'_display' ) != null && getFormElement(sel.form, sel.name+'_display' ).type == "textarea" && getFormElement(sel.form, sel.name+'_labels' ) != null;
}

function NLPopupSelect_setExactMatchQuery(sel, b)
{
    sel.setAttribute('exactMatchQuery', b ? 'T' : 'F');
}
function NLPopupSelect_getExactMatchQuery(sel)
{
    return sel.getAttribute('exactMatchQuery') == 'T';
}
function isSelect(sel)
{
    return  sel != null && ( sel.type == "select-one" || isNLDropDown( sel ) );
}
function isNLDropDown(sel)
{
    return sel.className && sel.className.indexOf('nldropdown')>=0;
}
function isNLDropDownSpan(span)
{
    return span != null && span.tagName == 'SPAN' && window.getDropdown != null && getDropdown(span) != null;
}
function isMultiSelect(sel)
{
    return  sel != null && (isNLMultiDropDown(sel) || sel.multiple || sel.type == 'select-multiple');
}
function isNLMultiDropDown(sel)
{

    return sel != null && sel.getAttribute && !isValEmpty(sel.getAttribute("nlmultidropdown"));
}
function isRichTextEditor(fld)
{
	return  fld != null && window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null;
}

function isSummaryField(fld)
{
	return  fld.className && fld.className.indexOf('nlsummary')>=0;
}

function resetlist(sel)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == 'select-multiple')
        {
            var i;
            for (i=0; i < sel.length; i++)
            {
                if (sel.options[i].defaultSelected)
                {
                    sel.selectedIndex=i;
                    return;
                }
            }
            sel.selectedIndex=0;
        }
        else if (isNLDropDown(sel))
        {
            getDropdown(sel).resetDropDown();
        }
        else if (isNLMultiDropDown(sel))
        {
            getMultiDropdown(sel).resetDropDown();
        }
        else
        {
            sel.value = sel.defaultValue;
            sel.form.elements[sel.name+"_display"].value = sel.form.elements[sel.name+"_display"].defaultValue;
        }
    }
}

function setFieldFocus(fld)
{
    if ( isSelect( fld ) || isMultiSelect( fld ) || isPopupSelect( fld ) || isPopupMultiSelect( fld ) )
        setSelectFocus( fld )
    else if ( window.getHtmlEditor != null && window.getHtmlEditor( fld.name ) != null )
        window.getHtmlEditor( fld.name ).setFocus();
    else if ( isFocusable( fld ) )
        fld.focus();
}

function setSelectFocus(sel,win)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ( isFocusable( sel ) )
                sel.focus();
        }
        else if (isNLDropDown(sel))
        {
            if ( isFocusable( getDropdown(sel,win).getContainer( ) ) )
                getDropdown(sel,win).setFocus();
        }
        else if (isNLMultiDropDown(sel))
        {
            if ( isFocusable( getMultiDropdown(sel,win).getContainer( ) ) )
                getMultiDropdown(sel,win).setFocus();
        }
        else
        {
            if ( isFocusable( sel.form.elements[sel.name+"_display"] ) )
                sel.form.elements[sel.name+"_display"].focus();
        }
    }
}


function restoreSelectToOriginalValue(sel, win)
{
    if(sel != null)
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            var valueWhenRendered = sel.getAttribute("valuewhenrendered");
            if(valueWhenRendered != null && valueWhenRendered.length > 0)
                setSelectValue(sel, valueWhenRendered);
        }
        else if (isNLDropDown(sel))
        {
            getDropdown(sel, win).restoreToOriginalValue();
        }
    }
}

function disableSelect(sel, val, win)
{

    if ( sel != null )
    {
        var doc = win != null ? win.document : sel.document != null ? sel.document : window.document;
        if (sel.type == "select-one" || sel.type == "select-multiple")
            sel.disabled = val;
        else if (isNLDropDown(sel))
            getDropdown(sel, win).setDisabled(val);
        else if (isNLMultiDropDown(sel))
            getMultiDropdown(sel, win).setDisabled(val);
        else
        {
            var displaytext = sel.form.elements[sel.name+"_display"];
            if (displaytext != null)
                displaytext.disabled=val;
            var listlink = doc.getElementById(sel.name+"_popup_list");
            if (listlink != null)
                listlink.style.visibility = val ? "hidden" : "inherit";
            var searchlink = doc.getElementById(sel.name+"_popup_search");
            if (searchlink != null)
                searchlink.style.visibility = val ? "hidden" : "inherit";
            var alllink = doc.getElementById(sel.name+"_popup_all");
            if (alllink != null)
                alllink.style.visibility = val ? "hidden" : "inherit";
        }
        var newlink = isNS4x ? null : doc.getElementById(sel.name+"_popup_new");
        if (newlink != null)
            newlink.style.visibility = val ? "hidden" : "inherit";
        var linklink = isNS4x ? null : doc.getElementById(sel.name+"_popup_link");
        if (linklink != null)
            linklink.style.visibility = val ? "hidden" : "inherit";
    }

}

function getSelectValueAtIndex(sel, idx)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ((sel.options != null) && (sel.options.length > idx))
                return sel.options[idx].value;
            else
                return null;
        }
        else if (isNLDropDown(sel))
        {
            return getDropdown(sel).getValueAtIndex(idx);
        }
        else if (isNLMultiDropDown(sel))
        {
            return getMultiDropdown(sel).getValue(idx);
        }
    }
}

function getSelectTextAtIndex(sel, idx)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ((sel.options != null) && (sel.options.length > idx))
                return sel.options[idx].text;
            else
                return null;
        }
        else if (isNLDropDown(sel))
        {
            return getDropdown(sel).getTextAtIndex(idx);
        }
        else if (isNLMultiDropDown(sel))
        {
            return getMultiDropdown(sel).getText(idx);
        }
    }
}


function setNLCheckboxValue( fld, value)
{
	if (!fld)
    	return;
    
    if (typeof(value) == 'string')
	    fld.checked = value == 'T';
	else
    	fld.checked = value;
        
    
    NLCheckboxOnChange(fld);
}


function getNLCheckboxValue( fld )
{
	if (!fld)
    	return;

	return fld.checked;
}

function getNLCheckboxSpan(fld)
{
	var span = fld.parentNode;
    if (span && span.nodeName == 'SPAN' && span.className && (span.className.indexOf('checkbox') == 0))
    	return span;

	return null;
}

function setNLCheckboxDisabled( fld, bDisabled)
{
	if (!fld || fld.type != 'checkbox')
		return;

	var sClassName = 'checkbox'+(bDisabled? '_disabled' : '')+(fld.checked? '_ck' : '_unck');
	fld.disabled = bDisabled;

	var span = getNLCheckboxSpan(fld);
    if (span)
	    span.className = sClassName;	
}

function setNLCheckboxReadOnly(fld, bReadOnly)
{
	if (!fld || fld.type != 'checkbox')
		return;

	var sClassName = 'checkbox'+(bReadOnly? '_read' : '')+(fld.checked? '_ck' : '_unck');
	fld.readonly = bReadOnly;

	var span = getNLCheckboxSpan(fld);
    span.className = sClassName;	
}


function NLCheckboxOnClick(span)
{
    var origSpanClass = span.className;
	var inpt = null;
    
	// Find the input.
    for (var i=0; i<span.childNodes.length; i++)
    {
    	if (span.childNodes[i].type == 'checkbox')
        {
        	inpt = span.childNodes[i]; 
            break;
        }
	}            
    
    if (!inpt || inpt.disabled)
		return;    
    
	if (inpt.type == 'checkbox' && inpt.checked) {
        
	    span.className = span.className.replace('_ck', '_unck');
		inpt.checked = false;
	}
	else {
        
	    span.className = span.className.replace('_unck', '_ck');
		inpt.checked = true;
	}

    	
	var origChecked = inpt.checked;
	if (inpt.onclick)
        inpt.onclick();
	var newChecked = inpt.checked;
    
    
    if (origChecked != newChecked)
    	span.className = origSpanClass;
    else if (inpt.onchange)
    	inpt.onchange();
}


function NLCheckboxOnChange(fld)
{
    if (!fld)
		return;
	
	var span = getNLCheckboxSpan(fld);
    if (span)
    {
        if (fld.checked)
            span.className = span.className.replace('_unck', '_ck'); 
        else
            span.className = span.className.replace('_ck', '_unck');
    }
}

function NLCheckboxSetParentState(fld, state)
{
    if (!fld)
		return;
	
	var span = getNLCheckboxSpan(fld);
    if (span)
    {
    	if (state)
			span.className = span.className.replace('_unck', '_ck'); 
    	 else
       		 span.className = span.className.replace('_ck', '_unck');
     }
}

function NLCheckboxOnKeyPress(evt)
{
	if(window.event) // IE
	{
    	evt = getEvent(evt);
		if(evt.keyCode == 32 && evt.srcElement) 
        {
           if (evt.srcElement.onclick)  evt.srcElement.onclick();
    		NLCheckboxSetParentState(evt.srcElement, !evt.srcElement.checked);
        }
	}
    
    return true;
}


function getNLSummaryFieldContent(fld)
{
	if (!isSummaryField(fld))
		return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement && textElement.parentNode)
        return textElement.parentNode.innerHTML;
     return "";
}


function setNLSummaryFieldTextValue(fld, val)
{
    if (!isSummaryField(fld))
        return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement)
        textElement.innerHTML = val;
}

function getNLSummaryFieldTextValue(fld)
{
	if (!isSummaryField(fld))
		return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement)
        return textElement.innerHTML;
     return "";
}

function setNLSummaryFieldDisabled( fld, bDisabled)
{
	if (!isSummaryField(fld))
		return;

	fld.disabled = bDisabled;

    var docObj = (fld.document) ? fld.document : document;
    var helperLink = docObj.getElementById(fld.name+"_helper_popup");
    if(helperLink != null)
        helperLink.style.visibility = bDisabled ? "hidden" : "inherit";
}


function isNLNumericOrCurrencyDisplayField( fld )
{
    if (!fld)
        return false;
    if (!(isNumericField(fld) ||isCurrencyField(fld)))
        return false;

    return (fld.name.indexOf("_formattedValue")>0);
}

function getNLNumericOrCurrencyDisplayField( fld )
{
    if (!fld)
        return null;
    return fld.form.elements[fld.name+"_formattedValue"];
}

function getNLNumericOrCurrencyValueField( fld )
{
    if (!fld)
        return null;
    return fld.form.elements[fld.name.replace("_formattedValue", "")];
}

function isCurrencyField( fld )
{
    if (!fld)
        return false;
    var dataType = "";
    if(typeof fld.getAttribute != 'undefined')
        dataType = fld.getAttribute("dataType");
    if (dataType == "currency" || dataType == "poscurrency" || dataType == "currency2")
        return true;
    return false;
}

function setNLCurrencyValue(fld, value)
{
    fld.value = value;
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.value = NLNumberToString(value);
}

function isNumericField( fld )
{
    if (!fld)
        return false;
    var dataType = "";
    if(typeof fld.getAttribute != 'undefined')
        dataType = fld.getAttribute("dataType");
    if (dataType == "float" || dataType == "posfloat" || dataType == "integer" || dataType == "posinteger" || dataType == "rate" || dataType == "ratehighprecision" || dataType == "percent")
        return true;
    return false;
}

function setNLNumericValue(fld, value)
{
    fld.value = value;
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.value = NLNumberToString(value);
}

function setNLNumericOrCurrencyFieldDisabled(fld, val)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.disabled = val;
}

function getNLNumericOrCurrencyFieldDisabled(fld)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return displayField.disabled;
}

function isNLNumericOrCurrencyFieldRequired(fld)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return isRequiredFieldClassName(displayField);
}

function setNLNumericOrCurrencyFieldRequired(fld)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return setRequired(displayField);
}

function setRequired(fld,required)
{
    if ( isNLDropDown(fld))
        getDropdown(fld).setRequired(required);
    else if ( isNLMultiDropDown( fld ) )
        getMultiDropdown(fld).setRequired(required);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null && getHtmlEditor(fld.name).setMandatory)
        getHtmlEditor( fld.name ).setMandatory( required );
    else if ( fld.form != null && fld.form.elements[fld.name+"_display"] != null )
    {
        if (typeof fld.form.elements[fld.name+"_display"].className == "undefined")
           fld.form.elements[fld.name+"_display"].className = "";
        var className = fld.form.elements[fld.name+"_display"].className;
        var fromClassName = (getRequired(fld) ? 'inputreq' : 'input');
        var toClassName = (required ? 'inputreq' : 'input');
        if (className.indexOf(fromClassName) < 0)
            className = toClassName + " " + className;
        else
            className = className.replace(fromClassName, toClassName);
        fld.form.elements[fld.name+"_display"].className = className;
        setFieldLabelRequired(fld.id, required);
    }
    else if (isNumericField(fld) || isCurrencyField(fld))
        return setNLNumericOrCurrencyFieldRequired(fld);
    else
    {
        if (typeof fld.className == "undefined")
           fld.className = "";
        var className = fld.className;
        var fromClassName = (getRequired(fld) ? 'inputreq' : 'input');
        var toClassName = (required ? 'inputreq' : 'input');
        if (className.indexOf(fromClassName) < 0)
            className = toClassName + " " + className;
        else
            className = className.replace(fromClassName, toClassName);
        fld.className= className;
        setFieldLabelRequired(fld.id, required);
    }
}


function setFieldLabelRequired(fldName, required, fldForm)
{
	if (fldName)
	{
		fldName = fldName.replace('inpt_', '');
        fldName = fldName.replace('hddn_', '');
        fldName = fldName.replace('_fs', '');

		var label = document.getElementById(fldName + '_fs_lbl');
        	
		if (label)
		{
		    
		    if (label.parentNode && label.parentNode.firstChild != label)
		    	return;
		
        	
            if (fldForm)
            {
	        	var labelForm = getParentElementByTag("form", label);
                if (labelForm && labelForm != fldForm)
                {
                    return;
                }
            }
		
		    var images = label.getElementsByTagName("img");
		    var reqImage;
		    for (var i = 0; i < images.length; i++) 
		    {
		    	var image = images[i];
		    	if (image.className && image.className == 'required_icon')
		    	{
		    		reqImage = image;
		    		break;
		    	}
		    }
		    
		    if (required && !reqImage)
		    {
		    	reqImage = document.createElement('img');
		    	reqImage.className = 'required_icon';
		    	reqImage.src = '/images/chiles/pageTitle/required.png';
		    	label.insertBefore(reqImage, label.firstChild);
		    
		    }
		    else if (!required && reqImage)
		    {
		    	label.removeChild(reqImage);
		    }
		}
	}
}


function setDefaultOrNotRequired(fld, val)
{
    setRequired(fld, val ? hasAttribute(fld, 128) : false);
}

function hasAttribute(fld,flag)
{
    if ( isNLDropDown(fld) )
        return getDropdown(fld).hasAttribute(flag);
    else if ( isNLMultiDropDown( fld ) )
        return getMultiDropdown(fld).hasAttribute(flag);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        return getHtmlEditor(fld.name).hasAttribute(flag);
    else
        return (fld.getAttribute("flags") & flag) != 0;
}

function getRequired(fld)
{
    if ( isNLDropDown(fld) )
        return getDropdown(fld).getRequired( );
    else if ( isNLMultiDropDown( fld ) )
        return getMultiDropdown(fld).getRequired( );
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) )
        return getHtmlEditor( fld.name ).getMandatory( );
    else if ( fld.form != null && fld.form.elements[fld.name+"_display"] != null )
        return fld.form.elements[fld.name+"_display"].className != null && fld.form.elements[fld.name+"_display"].className.indexOf('inputreq') != -1;
    else if ( (isNumericField(fld) || isCurrencyField(fld)) && fld.name.indexOf("_formattedValue")==-1)
        return isNLNumericOrCurrencyFieldRequired(fld);
    else
        return isRequiredFieldClassName(fld);

}


function isRequiredFieldClassName(fld){
       return fld.className != null && (fld.className.indexOf('inputreq') != -1 || fld.className.indexOf('inputrtreq') != -1);
}

function disableField(fld, val)
{

    if (fld == null)
        return;
    
    
    if (!isSelect( fld ) && fld.length > 1)
    {
        for ( var i = 0; i < fld.length; i++ )
            if ( fld[i].type == 'radio' )
                disableField( fld[i], val);
    }
    else if (isSelect( fld ) || isPopupSelect( fld ) || isMultiSelect( fld ) || isPopupMultiSelect(fld))
        disableSelect(fld, val);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        getHtmlEditor( fld.name ).setDisabled( val );
    else if (NLIsButton( fld ))
        NLDisableButton(fld, val);
    else if (fld.type=='checkbox')
        setNLCheckboxDisabled(fld, val);
    else if (isSummaryField(fld))
        setNLSummaryFieldDisabled(fld, val);
    else if (isNumericField(fld) || isCurrencyField(fld))
        setNLNumericOrCurrencyFieldDisabled(fld, val);
    else
    {
        fld.disabled = val;
        
        var docObj = (fld.document) ? fld.document : document;
        var datelink = docObj.getElementById(fld.name+"_helper_calendar");
        if(datelink != null)
            datelink.style.visibility = val ? "hidden" : "inherit";
    }

}
function getFieldDisabled(fld)
{
    if (fld == null)
        return;
    
    
    if (!isSelect( fld ) && fld.length > 1)
    {
        for ( var i = 0; i < fld.length; i++ )
            if ( fld[i].type == 'radio' )
                return fld[i].disabled;
    }
    else if (isSelect( fld ) || isPopupSelect( fld ) || isMultiSelect( fld ))
	{
		if (fld.type == "select-one" || fld.type == "select-multiple")
			return fld.disabled;
		else if (isNLDropDown(fld))
			return getDropdown(fld, window).disabled;
		else if (isNLMultiDropDown(fld))
			return getMultiDropdown(fld, window).disabled;
		else if ( isPopupSelect( fld ) )
			return getFormElement(fld.form, fld.name+'_display' ).disabled
	}
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        return getHtmlEditor( fld.name ).disabled;
    else if (isNumericField(fld) || isCurrencyField(fld))
        getNLNumericOrCurrencyFieldDisabled(fld);
    else
        return fld.disabled;
	return false;
}

function isDisplayOnlyField(fld)
{
    if (fld == null)
        return;
	if ( isDisplayOnlySelect(fld) )
		return true;
	else if (fld.type == "hidden" && document.getElementById(fld.name+'_val') != null)
		return true;
	return false;
}

function setOptionsFromMachineField( machine_name, field_name, selectObject, alternate_label, test_field, test_value )
{
    deleteAllSelectOptions( selectObject, window );
    var doc = window.document;
    var mch = eval( machine_name + '_machine');
    addSelectOption( doc, selectObject, "",  "", true, window );
    var bNewOptions = false;
    for ( var i = 1; i <= getLineCount(machine_name); i++)
    {
        if (mch.getMachineIndex() == i || ( test_field != null && getEncodedValue( machine_name, i, test_field) != test_value ) )
            continue;
        bNewOptions = true;
        addSelectOption( doc, selectObject,  getEncodedValue( machine_name,i, alternate_label != null ? alternate_label :field_name + '_display'),  getEncodedValue( machine_name,i,field_name ), false, window);
    }
    return bNewOptions;
}


function getSyncFunctionName(fldname, machine)
{
    var syncFuncName = "Sync"+fldname;
    if ( machine != null )
    {
        var machSyncFunc = syncFuncName + machine;
        if ( eval( "window." + machSyncFunc ) != null )
            return machSyncFunc;
    }
    return syncFuncName;
}

function safeSetDocumentLocation(url)
{
     try { 
        document.location = url;
     } catch (e) {} 
}

function addParamToURL(url, param, value,replace)
{
    if ( url == null )
        return null;
    if (url.length && url.charAt(url.length - 1) == '#')
        url = url.substring(0, url.length - 1);
    if ( isValEmpty( param ) )
        return url;
    if (replace == true)
        url = removeParamFromURL(url,param);
    return addNextParamPrefixToURL( url ) + param + "=" + emptyIfNull(value);
}

function addNextParamPrefixToURL( url )
{
    return url + ( url.indexOf("?") == -1 ? "?" : "&" );
}

function removeParamFromURL(url, param)
{
    var sep = "&";
    var startIndex = url.indexOf("&"+param+"=");
    if (startIndex == -1)
    {
        startIndex = url.indexOf("?"+param+"=")
        sep = "?";
    }
    if (startIndex != -1)
    {
        var endIndex = url.indexOf("&",startIndex+1);
        return url.substring(0,startIndex)+ (endIndex > 0 ? (sep == "?" ? "?"+url.substr(endIndex+1) : url.substr(endIndex)) : "");
    }
    return url;
}
function formEncodeURLParams( params )
{
    var paramString = '';
    for ( var param in params )
        paramString += (isValEmpty(paramString) ? '' : '&') + escape( param ) + '=' + escape( emptyIfNull( params[param] ) );
    return paramString;
}
function previewMedia(mediaid, bIsHref, document)
{
    if (bIsHref)
        mediaid = mediaid.substr(mediaid.lastIndexOf('/')+1);
    var url = '/core/media/previewmedia.nl?id='+mediaid;
    preview(url, 'prevmedia');
}

function previewTemplate(id, entity)
{
    var url = '/app/crm/common/merge/previewtemplate.nl?id='+id;
    if ( !isValEmpty(entity) )
        url = addParamToURL( url, 'entity', entity );
    preview(url, 'previewtemplate');
}

function siteMedia(mediaid, bIsHref, document)
{
    if (bIsHref)
        mediaid = mediaid.substr(mediaid.lastIndexOf('/')+1);
    var url = '/app/site/media/sitemedia.nl?id='+mediaid;
    preview(url, 'sitemedia');
}

function preview(url, winname)
{
    var prms = 'location=no,width=600,height=500,menubar=yes,scrollbars=yes,resizable=yes';
    var win = window.open(url, winname, prms);
    win.focus();
}

function getCookieVal(offset)
{
    var endstr = document.cookie.indexOf (';', offset);
    if (endstr == -1)
        endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie(name)
{
    var arg = name + '=';
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen)
    {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg)
        {
            
            return getCookieVal(j);
        }
        i = document.cookie.indexOf(' ', i) + 1;
        if (i == 0) break;
    }
    return null;
}

function getStickyTag( pageName )
{
    var cbody = GetCookie('stickytags');
    if (cbody != null)
    {
        
        var b=cbody.indexOf(','+pageName+':') + 1;
        if (b>=1)
        {
             var e=cbody.indexOf(',',b);
             if (e<0)
                e=cbody.length;
             return unescape(cbody.substring(b+pageName.length+1, e));
        }
    }
    return null;
}

function addStickyTagToUrl(url, pageName)
{
    return url + (url.indexOf('?') >= 0 ? '&t=' : '?t=') + getStickyTag(pageName);
}

function redirectToStickyPage(url,pageName,framed)
{
    var newUrl = addStickyTagToUrl(url, pageName);
    
     try { 
        if (typeof(framed) == "number")
            parent.frames[framed].document.location = newUrl;
        else if (framed)
            parent.document.location = newUrl;
        else
            document.location = newUrl;
    
     } catch (e) { } 
}



var SelectKeyPressMaxKeyPause = 2000;   
function SelectKeyPressHandler (evnt, sorted)
{
    keyString = String.fromCharCode (getEventKeypress(evnt)).toUpperCase();
    if (!(keyString >= " "  &&  keyString <= "_"))
    {
        SelectKeyPressTypedString = "";
        return true;
    }
    if (SelectKeyPressTimeoutID != null)
        window.clearTimeout (SelectKeyPressTimeoutID);
    SelectKeyPressTimeoutID = window.setTimeout ("SelectKeyPressTimeout()",
                                                SelectKeyPressMaxKeyPause);
    SelectKeyPressTypedString += keyString;
    if (sorted)
    {
        if (SelectKeyPressTypedString.length == 1)
            option = SelectKeyPressLookupFirst (evnt, SelectKeyPressTypedString);
        else
            option = SelectKeyPressLookupNext (evnt, SelectKeyPressTypedString);
    }
    else
        option = SelectKeyPressLookupLinear (evnt, SelectKeyPressTypedString);
    setEventPreventDefault(evnt);
    if (option != -1)
    {
        getEventTarget(evnt).selectedIndex = option;
        getEventTarget(evnt).onchange();
    }

    return false;
}
var SelectKeyPressTypedString = "";
    SelectKeyPressTimeoutID = null;
function SelectKeyPressTimeout ()
{
    SelectKeyPressTypedString = "";
    SelectKeyPressTimeoutID = null;
}
function SelectKeyPressLookupFirst (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;
    low = 0;
    high = options.length;
    while (high - low > 1)
    {
        i = Math.floor ((high + low) / 2);
        if (str.charAt(0) <= options(i).text.charAt(0).toUpperCase())
            high = i;
        else
            low = i;
    }
    while (high > 0  &&
            str.charAt(0) == options(high - 1).text.charAt(0).toUpperCase())
        --high;
    if (high < options.length  &&
        str.charAt(0) == options(high).text.charAt(0).toUpperCase())
        return high;
    else
        return -1;
}
function SelectKeyPressLookupNext (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;

    selIndex = select.selectedIndex;
    while (selIndex < options.length - 1  &&
            options(selIndex).text.toUpperCase() < str)
        ++selIndex;
    if (selIndex < options.length - 1  &&
            options(selIndex).text.substr(0, str.length).toUpperCase() == str)
        return selIndex;
    else
        return -1;
}
function SelectKeyPressLookupLinear (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;

    for (i = 0; i < options.length; ++i)
        if (options(i).text.substr(0, str.length).toUpperCase() == str)
            return i;

    return -1;
}
function disableFilter(radio, disableVal, fld1,fld2)
{
    if (getRadioValue(radio) == disableVal)
    {
        fld1.disabled = true;
        if (fld2)
            fld2.disabled = true;
    }
    else
    {
        fld1.disabled = false;
        if (fld2)
            fld2.disabled = false;
    }
}


function NLDate_parseString(sDate, bDoAlert)
{
    var m=0;
    var d=0;
    var y=0;
    var val = sDate;
    var fmterr = "";
    var year="";
    var year_char_index, month_char_index, day_char_index;
    var rtnDate = null;

    if(!window.dateformat)
        window.dateformat = "MM/DD/YYYY";   

    if(sDate == "")
    {
        return new Date();
    }
    else if(window.dateformat == "MM/DD/YYYY")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) m = parseInt(c[0],10);
            if(onlydigits(c[1])) d = parseInt(c[1],10);
    
            if ( d > 1970 )
            {
                year = y = d;
                d = 1;
            }
            else
            {
                if(onlydigits(c[2])) y = parseInt(c[2],10);
                year=c[2];
            }
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD/MM/YYYY")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "YYYY/MM/DD")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) y = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) d = parseInt(c[2],10);
            year=c[0];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) y = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) d = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD.MM.YYYY")
    {
        if (val.indexOf(".") != -1)
        {
            var c = val.split(".");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=parseInt(str,10);
        }
    }
    else if(window.dateformat == "DD-Mon-YYYY")
    {
        if (val.indexOf("-") != -1)
        {
            var c = val.split("-");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            m = getMonthIndex(c[1]);
            <!--alert('month index....'+m+','+c[1]);-->
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,1+l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(1+l%2,3);
            m = getMonthIndex(str);
            str = val.substr(4+l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD-MONTH-YYYY")
    {
        var comps = val.split("-");
        if(onlydigits(comps[0]))
            d = parseInt(comps[0]);
        m = arrayIndexOf(NLDate_months, comps[1], true) + 1;
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
    else if(window.dateformat == "YYYY-MM-DD")
    {
        var comps = val.split("-");
        if(onlydigits(comps[2]))
            d = parseInt(comps[2]);
        if(onlydigits(comps[1]))
            m = parseInt(comps[1]);
        if(onlydigits(comps[0]))
        {
            y = parseInt(comps[0]);
            year = y;
        }
    }
	else if(window.dateformat == "EEYY年MM月DD日")
    {
        year_char_index = val.indexOf(year_char_cn);
        month_char_index = val.indexOf(month_char_cn);
        day_char_index = val.indexOf(day_char_cn);
        if(onlydigits(val.substring(month_char_index+1,day_char_index)))
            d = parseInt(val.substring(month_char_index+1,day_char_index));
        if(onlydigits(val.substring(year_char_index+1,month_char_index)))
            m = parseInt(val.substring(year_char_index+1,month_char_index));
        var era = val.substring(0, 2);
        if(onlydigits(val.substring(2,year_char_index)))
        {
            y = get_gregorian_year(parseInt(val.substring(2,year_char_index)), era);
            year = y;
        }
    }
	else if(window.dateformat == "YYYY年MM月DD日")
    {
        year_char_index = val.indexOf(year_char_cn);
        month_char_index = val.indexOf(month_char_cn);
        day_char_index = val.indexOf(day_char_cn);
        if(onlydigits(val.substring(month_char_index+1,day_char_index)))
            d = parseInt(val.substring(month_char_index+1,day_char_index));
        if(onlydigits(val.substring(year_char_index+1,month_char_index)))
            m = parseInt(val.substring(year_char_index+1,month_char_index));
        if(onlydigits(val.substring(0,year_char_index)))
        {
            y = parseInt(val.substring(0,year_char_index));
            year = y;
        }
    }
    else if(window.dateformat == "EYY.MM.DD")
    {
        comps = val.split(".");
        if(onlydigits(comps[2]))
            d = parseInt(comps[2]);
        if(onlydigits(comps[1]))
            m = parseInt(comps[1]);
        var era = comps[0].substring(0, 1);
        if(onlydigits(comps[0].substring(1,comps[0].length)))
        {
            y = get_gregorian_year(parseInt(comps[0].substring(1,comps[0].length)), era);
            year = y;
        }
    }
    else if(window.dateformat == "DD. Mon YYYY")
    {
        comps = val.split(" ");
        if(onlydigits(comps[0].substring(0, comps[0].length - 1)))
            d = parseInt(comps[0].substring(0, comps[0].length - 1));
        m = getMonthIndex(comps[1]);
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
    else if(window.dateformat == "DD de MONTH de YYYY")
    {
        comps = val.split(" de ");
        if(onlydigits(comps[0]))
            d = parseInt(comps[0]);
        m = arrayIndexOf(NLDate_months, comps[1]) + 1;
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
	else if(window.dateformat == "YYYY년 MM월 DD?")
    {
        comps = val.split(" ");
        if(onlydigits(comps[2].substring(0, comps[2].length-1)))
            d = parseInt(comps[2].substring(0, comps[2].length-1));
        if(onlydigits(comps[1].substring(0, comps[1].length-1)))
            m = parseInt(comps[1].substring(0, comps[1].length-1)) - 1;
        if(onlydigits(comps[0].substring(0, comps[0].length-1)))
        {
            y = parseInt(comps[0].substring(0, comps[0].length-1));
            year = y;
        }
    }
	else if(window.dateformat == "DD MONTH YYYY")
	{
		comps = val.split(" ");
		if(onlydigits(comps[0]))
			d = parseInt(comps[0]);
		m = arrayIndexOf(NLDate_months, comps[1], true) + 1;
		if(onlydigits(comps[2]))
		{
			y = parseInt(comps[2]);
			year = y;
		}
	}
	else if(window.dateformat == "DD MONTH, YYYY")
	{
		comps = val.split(" ");
		if(onlydigits(comps[0]))
			d = parseInt(comps[0]);
		m = arrayIndexOf(NLDate_months, comps[1].substring(0, comps[1].length-1), true) + 1;
		if(onlydigits(comps[2]))
		{
			y = parseInt(comps[2]);
			year = y;
		}
	}

    if(m==0 || d==0)
    {
        if(bDoAlert)
        {
            if(fmterr == "")
                fmterr = window.dateformat;
            alert("Invalid date value (must be "+window.dateformat+")");
        }
    }
    else
    {
        if (y==0 && !onlydigits(year)) y = (new Date()).getFullYear();  
        if(m<1) m=1; else if(m>12) m=12;
        if(d<1) d=1; else if(d>31) d=31;
        if(y<100) y+=((y>=70)?1900:2000);
        if(y<1000) y*=10;
        if (y > 9999) y = (new Date()).getFullYear();

        year = y;
		rtnDate = validateDate(new Date(y, m-1, d), bDoAlert);
		if (y != nlGetFullYear(rtnDate) || m != rtnDate.getMonth() + 1 || d != rtnDate.getDate())
		{
			rtnDate = validateDate(new Date(y, m-1, d, 12, 30), bDoAlert);
			if (y != nlGetFullYear(rtnDate) || m != rtnDate.getMonth() + 1 || d != rtnDate.getDate())
			{
				rtnDate = null;
			}
		}        
    }

    return rtnDate;
}

function validateDate(dDate, bDoAlert)
{
	if (dDate.getTime() < -11636672400000)
	{
		dDate = null;
		if (bDoAlert)
			alert("Invalid date value (must be on or after "+getdatestring(new Date(-11636672400000))+")");
	}
	return dDate;
}


var NLDate_pnDaysInMonths = new Array(31,28,31,30,31,30,31,31,30,31,30,31);


function NLDate_getLastDayOfMonth(dDate)
{
    var m = dDate.getMonth();
    var days = NLDate_pnDaysInMonths[m];

    if(m == 1) 
    {
        var y = dDate.getYear();
        if ( (y% 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)) )
            days++;
    }
    return days;
}

function setDisabledState(elementid,enable)
{
    
    elem = document.getElementById(elementid);
    if (typeof elem.disabled != "undefined" )
    {
        elem.disabled=!enable;
        return;
    }
    var childnodes=document.getElementById(elementid).getElementsByTagName('INPUT');
    for(var i=0;i< childnodes.length;i++)
    {
        if(childnodes[i].name.indexOf('_send')==-1)
            childnodes[i].disabled=!enable;
    }
    
    var childnodes=document.getElementById(elementid).getElementsByTagName('A');
    for(var i=0;i< childnodes.length;i++)
    {
        if(!enable && !childnodes[i].disabled)
        {
            childnodes[i].enabledonclick=childnodes[i].onclick;
            childnodes[i].onclick= new Function('return false;');
        }
        else if (enable && childnodes[i].enabledonclick!=null && childnodes[i].disabled)
        {
            childnodes[i].onclick=childnodes[i].enabledonclick;
        }
        childnodes[i].disabled=!enable;
    }
}

var NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_BETWEEN_13_AND_20_DIGITS = "Credit card numbers must contain between 13 and 20 digits.";
var NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_ONLY_DIGITS = "Credit card numbers must contain only digits.";
var NLAlertContext_EMAIL_ADDRESSES_MUST_MATCH = "Email addresses must match.";
var NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS = "NetSuite does not accept email addresses with quotation marks, commas, colons, spaces, or greater than or less than signs.";
var NLAlertContext_PASSWORDS_DONT_MATCHN = "Passwords don\'t match.\n";
var NLAlertContext_PASSWORDS_CANNOT_BE_EMPTYN = "Passwords cannot be empty.\n";
var NLAlertContext_PASSWORDS_MUST_BE_AT_LEAST_1_CHARACTERS_LONGN = "Passwords must be at least {1} characters long.\n";
var NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_LETTER_AZN = "Passwords must contain at least one letter (A-Z).\n";
var NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_NUMBER_OR_SPECIAL_CHARACTERN = "Passwords must contain at least one number or special character.\n";
var NLAlertContext_PASSWORDS_MAY_CONTAIN_ONLY_LETTERS_NUMBERS_AND_SPECIAL_CHARACTERSN = "Passwords may contain only letters, numbers, and special characters.\n";
var NLAlertContext_OLD_AND_NEW_PASSWORDS_ARE_TOO_SIMILAR = "Old and new passwords are too similar.";
var NLAlertContext_PASSWORD_MUST_NOT_BE_THE_SAME_AS_THE_EMAIL_ADDRESS = "Password must not be the same as the email address";
var NLAlertContext_CREDIT_CARD_NUMBER_IS_NOT_VALID__PLEASE_CHECK_THAT_ALL_DIGITS_WERE_ENTERED_CORRECTLY = "Credit card number is not valid.  Please check that all digits were entered correctly.";
var NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS = "NetSuite does not accept email addresses with quotation marks, commas, colons, spaces, or greater than or less than signs.";
var NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS = "Please enter a valid email address.";
var NLValidationUtil_SIMPLE_EMAIL_PATTERN = /^[-a-z0-9!#$%&'*+\/=?^_`{|}~]+(?:\.[-a-z0-9!#$%&'*+\/=?^_`{|}~]+)*@(?:[a-z0-9]+(?:-+[a-z0-9]+)*\.)+(?:ac|ad|aero|ae|af|ag|ai|al|am|an|ao|aq|arpa|ar|asia|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|biz|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|cat|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|com|coop|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|info|int|in|io|iq|ir|is|it|je|jm|jobs|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mobi|mo|mp|mq|mr|ms|mt|museum|mu|mv|mw|mx|my|mz|name|na|nc|net|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pro|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|travel|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)$/i;
var NLAlertContext_THE_SPECFIED_ROUTING_NUMBER_FAILED_VALIDATION_FOR_ABA_ROUTING_NUMBERS = "The specfied routing number failed validation for ABA Routing Numbers.";
var NLAlertContext_ABA_ROUTING_NUMBERS_MUST_BE_NINE_CHARACTERS = "ABA Routing Numbers must be nine characters.";
/**
 * check if the value is empty
 * @param val String being tested for whether it is empty (null or "")
 */
function isValEmpty(val)
{
    if (val == null)
        return true;
    val = new String(val);
    return (val.length == 0) || !/\S/.test(val);
}

/**
 * isHTMLValEmpty() returns true if the given string is empty or contains only whitespace, ignoring HTML markup
 * @param val String being tested for whether it is empty (null or "")
 */
function isHTMLValEmpty(val)
{
    if (isValEmpty(val))
        return true;
    val = val.replace(/&nbsp;|<(?!NL)[^>]*>/gi, '');
    return !/\S/.test(val);
}

/* works just like the SQL NVL function */
function nvl(val,val2)
{
    return val == null ? val2 : val;
}
// emptyIfNull(): return empty string if vall is null.
function emptyIfNull(val)
{
    return val == null ? '' : val;
}
// nullIfEmpty(): return null if val is null or empty.
function nullIfEmpty(val)
{
    return isValEmpty(val) ? null : val;
}
/*
 * Trims leading and trailing whitespace from a string.
 * Similar to Java's String.trim(), see corresponding doc there.
 */
function trim(str)
{
    return str.replace(/^\s+/,"").replace(/\s+$/,"");
}
function onlydigitsandchars(str)
{
    var re = new RegExp("([A-Za-z0-9]+)");
    return (re.exec(str)!=null && RegExp.$1==str);
}
function onlydigits(str)
{
    return /^[0-9]+$/.test(str);
}

/**
 * returns true if the value is null, empty, or evaluates to a math equivalent value of zero.
 * @param fieldval String being tested for whether it is empty or zero
 */
function isemptyorzero(fieldval)
{
    var val = fieldval;
    var isempty = isValEmpty(val);
    var iszero = val==0;
    return (isempty || iszero);
}

/**
 * returns true if the value is null, empty, or evaluates to a math equivalent value of zero.
 * @param fieldval String being tested for whether it is empty or zero
 */
function isNewRecord()
{
	var id = typeof nlapiGetField != undefined && nlapiGetField("id") != null ? nlapiGetFieldValue("id") :
			 typeof document != undefined && document.forms['main_form'].elements['id'] != null ? document.forms['main_form'].elements['id'] : "";
	return isValEmpty(id) || id == -1
}
/**
 * returns true if the current record is an existing record
 */
function isExistingRecord()
{
    return !isNewRecord();
}
/**
 * returns true if the current record is an existing record
 */
function getEditFlag()
{
    return isExistingRecord();
}
/**
 * Perform mandatory field check
 *
 * @param fields	Array of field names or field references (UI)
 * @param labels  	Array of field labels
 * @param values	Array of field values (only used during dynamic scripting contexts)
 * @param type		Sublist name if this is called for a machine (current line on an edit machine)
 */
function checkMandatoryFields(fields,labels,values,type)
{
	var result = "";
	for (var i=0; i < fields.length; i++)
	{
		if (fields[i] == null)
			continue;
		var val = values != null ? values[i] : fields[i].value;
		if ((new String(val)).indexOf(String.fromCharCode(3)) != -1)
		{
			var nvarray = val.split(String.fromCharCode(4));
			for (var j=0; j < nvarray.length; j++)
			{
				var nv = nvarray[j].split(String.fromCharCode(3));
				if (nv[1] == 'T' && nv[3].length == 0)
					result += (result.length ? ", " : "") + nv[2];
			}
			continue;
		}

		if ( values != null )
		{
			if ( (type != null && !Machine_isMandatoryOnThisLine(type, fields[i], nlapiGetCurrentLineItemIndex(type))) || (type == null && !nlapiGetFieldMandatory(fields[i])) )
				continue;
			if ( isValEmpty( val ) )
				result += (result.length ? ", " : "") + labels[i];
		}
		else
		{
            if ( !getRequired(fields[i]))
				continue;
            if (isSelect(fields[i]))
			{
				val = getSelectValue(fields[i]);
				if (isValEmpty(val))
					result += (result.length ? ", " : "") + labels[i];
			}
			else if ( window.getHtmlEditor != null && getHtmlEditor( fields[i].name ) != null )
			{
				if ( isValEmpty( fields[i].value.replace("<DIV></DIV>","") ) )
					result += (result.length ? ", " : "") + labels[i];
			}
			else
			{
				if ( isempty(fields[i]) )
					result += (result.length ? ", " : "") + labels[i];
			}
		}
	}
	return result;
}

/**
 * Perform unique field validation on an edit machine (executed during validateLine)
 *
 * @param name			machine name
 * @param uniquefields	Array of field names for unique fields
 * @param uniquelabels	Array of field labels for unique fields
 *
 * @return An array of the unique field labels if there is a validation error or null
 */
function checkUniqueFields(name, uniquefields, uniquelabels)
{
	if ( uniquefields == null || uniquefields.length == 0 )
		return null;
	for (var i=1; i<= nlapiGetLineItemCount(name)+1; i++)
	{
		if (i == nlapiGetCurrentLineItemIndex(name)) continue;
		var bAllEmpty = true, bMatch = true;
		for (var j=0; j < uniquefields.length; j++)
		{
			var f = uniquefields[j];
			if (!isValEmpty(getEncodedValue(name,i,f))) bAllEmpty = false;
			if (getEncodedValue(name,i,f) != nlapiGetCurrentLineItemValue(name, uniquefields[j]))
			{
				bMatch = false;
				break;
			}
		}
		if (bAllEmpty || !bMatch) continue;
		var labels = new Array();
		for (var k=0; k < uniquefields.length; k++)
		{
			labels.push(uniquelabels[k]);
		}
		return labels;
	}
    return null;
}

// checkccnumber(): check if value in form fld is valid credit card. If this is called from the UI (i.e. webstore) then fld is a DOM field
//					reference. Otherwise it is a String containing the name of the field (use SuiteScript API for setting field)
//               NOTE: this is not a perfect check by any means. it does
//                  not check that amex is 15 and visa/other is 16. it also
//                  doesn't do the visa checksum.
//            	DJ11sep2000 -- I added code to do the luhn checksum check.
//				YF10Nov2008 -- moved to NLRecordUtil.js from NLUtil.js (please keep this in sync with NLValidationUtil.luhnCheck(s))
function checkccnumber(fld)
{
//  Remove all spaces and dashes.
//  you must check for length 0 up front. if you don't
//  mac ie5 will crashes on the replace call below.
	var cardnum = typeof(fld) != "string" ? fld.value : nlapiGetFieldValue(fld);	
	if(cardnum.length > 0) cardnum = cardnum.replace(/ /gi,'');
    if(cardnum.length > 0) cardnum = cardnum.replace(/-/gi,'');

    if (cardnum.length<13 || cardnum.length>20)
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_BETWEEN_13_AND_20_DIGITS);
        return false;
    }
    if (!onlydigits(cardnum))
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_ONLY_DIGITS);
        return false;
    }

    // Perform Luhn check
    // http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
    var no_digit = cardnum.length;
    var oddoeven = no_digit & 1;
    var sum = 0;

    for (var count = 0; count < no_digit; count++)
    {
        var digit = parseInt(cardnum.charAt(count),10);
        if (!((count & 1) ^ oddoeven))
        {
            digit *= 2;
            if (digit > 9)
            digit -= 9;
        }
        sum += digit;
    }
    if (sum % 10 != 0)
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBER_IS_NOT_VALID__PLEASE_CHECK_THAT_ALL_DIGITS_WERE_ENTERED_CORRECTLY);
        return false;
    }

	eval( typeof(fld) != "string" ? "fld.value = cardnum" : "nlapiSetFieldValue(fld, cardnum, false)" );
    return true;
}

/**
 * Set preferred fields following the addition of a new line on an edit machine (executed after validateLine but before recalc)
 *
 * @param name 	sublist name
 * @param preferredfield	preferred field name
 * @param linenum	line number being added
 */
function setPreferredFields(name, preferredfield, preferredwithinfield, linenum)
{
	if (getEncodedValue(name,linenum,preferredfield) == 'T')
	{
		for (var i=1; i <= getLineCount(name)+1; i++)
		{
			if (i != linenum && getEncodedValue(name,i,preferredfield) == 'T')
            {
                if(preferredwithinfield == null || getEncodedValue(name,linenum,preferredwithinfield) == getEncodedValue(name,i,preferredwithinfield))
                    setEncodedValue(name,i,preferredfield,'F');
            }
        }
	}
	return true;
}

function escapeJSONChar(c)
{
    if(c == "\"" || c == "\\") return "\\" + c;
    else if (c == "\b") return "\\b";
    else if (c == "\f") return "\\f";
    else if (c == "\n") return "\\n";
    else if (c == "\r") return "\\r";
    else if (c == "\t") return "\\t";
    var hex = c.charCodeAt(0).toString(16);
    if(hex.length == 1) return "\\u000" + hex;
    else if(hex.length == 2) return "\\u00" + hex;
    else if(hex.length == 3) return "\\u0" + hex;
    else return "\\u" + hex;
}

function escapeJSONString(s)
{
    /* The following should suffice but Safari's regex is b0rken
       (doesn't support callback substitutions)
       return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
       escapeJSONChar) + "\"";
    */

    /* Rather inefficient way to do it */
    var parts = s.split("");
    for(var i=0; i < parts.length; i++) {
	var c =parts[i];
	if(c == '"' ||
	   c == '\\' ||
	   c.charCodeAt(0) < 32 ||
	   c.charCodeAt(0) >= 128)
	    parts[i] = escapeJSONChar(parts[i]);
    }
    return "\"" + parts.join("") + "\"";
}
toJSON = function toJSON(o)
{
    if (o == null) // note: if o is undefined, this statement is true
		return "null";
    else if(o.constructor == String || o.constructor.name == "String")
		return escapeJSONString(o);
    else if(o.constructor == Number || o.constructor.name == "Number")
		return o.toString();
    else if(o.constructor == Boolean || o.constructor.name == "Boolean")
		return o.toString();
    else if(o.constructor == Date || o.constructor.name == "Date")
		return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
    else if(o.constructor == Array || o.constructor.name == "Array"  || o.length >= 0)
	{
	    var v = [];
	    for (var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
	    return "[" + v.join(", ") + "]";
    }
	else
	{
		var v = [];
		for(attr in o)
		{
	        if(o[attr] == null) v.push("\"" + attr + "\": null");
	        else if(typeof o[attr] == "function"); /* skip */
	        else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
		}
		return "{" + v.join(", ") + "}";
    }
}
// Used to parse quantity price schedules
function getQtyRate(schedstr,qty,marginal)
{
    var sched = schedstr.split(String.fromCharCode(5));
    var i;
    var cum_amount=0;
    var rate;
    for (i=0;i < sched.length;i+=2)
    {
       if (qty >= parseFloat(sched[i]) && (i+2>=sched.length || qty < parseFloat(sched[i+2])))
       {
          if (marginal && qty>0)
          {
            cum_amount+=(qty-parseFloat(sched[i]))*parseFloat(sched[i+1]);
            rate=cum_amount/qty;
          }
          else
            rate=sched[i+1];
          break;
       }
       else if (marginal && qty > 0)
          cum_amount += (parseFloat(sched[i+2])-parseFloat(sched[i]))*parseFloat(sched[i+1]);
    }
    return rate;
}

function parseFloatOrZero(f)
{
   var r=parseFloat(f);
   return isNaN(r) ? 0 : r;
}

function isValidUSZipCode(value)
{
    var re = /^\d{5}([\-]\d{4})?$/;
    return (re.test(value));
}

function checkemail(email,emptyok,alrt)
{
    // mirrors Java's String.trim() - remove leading and trailing whitespace
    email = trim(email);
    return checkemail2(email,email,emptyok,alrt);
}

function checkemail2(email_1,email_2,emptyok,alrt)
{
    var s_email = email_1;

    if (s_email != email_2)
    {
        alert(NLAlertContext_EMAIL_ADDRESSES_MUST_MATCH);
        return false;
    }
    if (emptyok && s_email.length==0)
    {
        return true;
    }
    return checkemailvalue(s_email,alrt);
}

function checkemailvalue(s_email,alrt)
{
	alrt = true;
	if (/\s|[,":<>]/.test(s_email))
	{
		if (alrt)
		{
			alert(NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS
					+ " " + NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS);
		}
		return false;
	}

	if (!NLValidationUtil_SIMPLE_EMAIL_PATTERN.test(s_email))
	{
		if (alrt)
		{
			alert(s_email + ' ' + NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS);
		}
		return false;
	}

	return true;
}

function checkemailprefix(s_email)
{
	/*
	Return true if string appears to be an email prefix (eg. wbailey@netl).  Used by uber search.
	- Must have exactly one '@' preceded by one or more chars
	- Must not contain any of these chars: <space> , " : < >
	- Must not contain ".."
	NOTE: This is a rudimentary check, not full email validation. It can be upgraded to full validation by
	reusing logic from checkemailvalue().
	*/
	return /^[^@]+@[^@]*$/.test(s_email) && !/\s|[,":<>]|[.][.]/.test(s_email);
}


// checknotempty(): validate that field is not empty and return focus to offending field. %>
function checkvalnotempty(val,alertMessage)
{
	if (isValEmpty(val))
	{
		if (alertMessage)
		{
			alert(alertMessage);
		}
        return false;
    }
    return true;
}

function checkpassword(pwd1,pwd2,alrt,strictcheck,prevpwd,len,email)
{
    var strict = (strictcheck == true || strictcheck == null);
    var msg = getpassworderror(pwd1,pwd2,strict,prevpwd,len,email);
    if (msg != null)
    {
        if (alrt) alert(msg);
        return false;
    }
    else
        return true;
}

function getpassworderror(pwd1,pwd2,strictcheck,prevpwd,len,email)
{
    var strict = (strictcheck == true || strictcheck == null);
    var val = pwd1;
    if (len == null)
        len = 6;
    msg = "";

    if (pwd1 != pwd2)
    {
        msg += NLAlertContext_PASSWORDS_DONT_MATCHN;
    }
    else if (!strict)
    {
        if (val.length == 0)
            msg = NLAlertContext_PASSWORDS_CANNOT_BE_EMPTYN;
    }
    else
    {
        if (val.length < len)
        {
            msg += NLAlertContext_PASSWORDS_MUST_BE_AT_LEAST_1_CHARACTERS_LONGN.replace("{1}", String(len));
        }
        if (!/[A-Za-z]/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_LETTER_AZN;
        }
        if (!/[0-9!@#$%^&*.:;~'`*",_|= \<\>\/\\\+\?\-\(\)\[\]\{\}]/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_NUMBER_OR_SPECIAL_CHARACTERN;
        }
        if (!/^[A-Za-z0-9!@#$%^&*.:;~'`*",_|= \<\>\/\\\+\?\-\(\)\[\]\{\}]+$/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MAY_CONTAIN_ONLY_LETTERS_NUMBERS_AND_SPECIAL_CHARACTERSN;
        }
    }
    if (msg.length == 0 && prevpwd != null)
    {
        var oldval = prevpwd;
        var charDiffCount = 0;
        for (var i=0;i < val.length; i++)
        {
            var c = val.charAt(i);
            if (oldval.indexOf(c) == -1)
                charDiffCount++;
        }
        if (charDiffCount < 2)
            msg = NLAlertContext_OLD_AND_NEW_PASSWORDS_ARE_TOO_SIMILAR;
    }
	if (msg.length == 0 && email != null)
	{
		if (email == pwd1)
			msg = NLAlertContext_PASSWORD_MUST_NOT_BE_THE_SAME_AS_THE_EMAIL_ADDRESS;
	}
	if (msg.length > 0)
        return msg;
    else
        return null;
}

function validate_AbaRoutingNumber(routing)
{
	if (routing == null || routing.length == 0)
    {
        window.isvalid = true;
        return true;
    }
	var maxlen = 9;
	var validflag = true;
    var err = '';
    if (routing.length != maxlen)
    {
        err = NLAlertContext_ABA_ROUTING_NUMBERS_MUST_BE_NINE_CHARACTERS;
        validflag = false
    }
	var t = routing;
	var n = 0;
    for (i = 0; i < t.length; i += 3)
    {
        n += parseInt(t.charAt(i), 10) * 3 + parseInt(t.charAt(i + 1), 10) * 7 +  parseInt(t.charAt(i + 2), 10);
    }

	if (n != 0 && n % 10 == 0)
	{
        validflag = true;
	}
	else
	{
		err = NLAlertContext_THE_SPECFIED_ROUTING_NUMBER_FAILED_VALIDATION_FOR_ABA_ROUTING_NUMBERS +"("+routing+")";
        validflag = false;
	}


    if (err != '')
    {
		alert(err);
    }
    window.isvalid = validflag;
    return validflag;
}

//check if a character has Chinese/Japanese/Korean characters
function stringContainsCJKChar(str)
{
   if(str == null || str.length == 0)
      return false;
   var cjk = false;
   for (var i=0; i<str.length; i++)
   {
     var charcode = str.charCodeAt(i);
     if( (charcode >= 12352 && charcode <= 40959) || (charcode >= 44032 && charcode <= 55215))
     {
       cjk = true;
       break;
     }
   }
   return cjk;
}



function nlOpenWindow(url, winname, widthOrFeatures, height, fld, scrollbars)
{
    if ( window.doPageLogging ) 
        logStartOfRequest( 'popup' );
    if ( isValEmpty( widthOrFeatures ) )
        return window.open(url, winname);
    else if ( isNaN(parseInt( widthOrFeatures )) )
        return window.open(url, winname, widthOrFeatures);
    else if ( isIE )
        return window.open(url, winname, 'scrollbars='+(scrollbars ? 'yes' : 'no')+',width='+Math.min(screen.availWidth,widthOrFeatures)+',height='+Math.min( screen.availHeight-40,height)+',left='+Math.min(screen.availWidth-widthOrFeatures,getObjectLeft(fld))+',top='+Math.min( (screen.availHeight-40)-height,getObjectTop(fld))+',resizable=yes');
    else
        return window.open(url, winname, 'scrollbars='+(scrollbars ? 'yes' : 'no')+',width='+widthOrFeatures+',height='+height+',resizable=yes');
}



function nlExtOpenWindow(url, winname, widthOrFeatures, height, fld, scrollbars, winTitle, listeners)
{
    //alert('start of nlExtOpenWindow');
    //TODO: is the following needed for this style of popup?
    url = addParamToURL (url, "ifrmcntnr", "T", true );
    if (!listeners)
        listeners = new Object();

    if ( window.doPageLogging ) 
        logStartOfRequest( 'extpopup' );
    //original implementation before managediframe
    if ( isValEmpty( widthOrFeatures ) )
    {
        new Ext.Window({
            title: (winTitle != undefined ? winTitle : winname),
            id: winname,
            name: winname,
            stateful: false,
            bodyCfg: {
                tag: 'iframe',
                name: winname+'_frame',
                id: winname+'_frame',
                src: url,
                style: 'border: 0 none; background-color: #FFFFFF;'
             }
         }).show();
    }
    else if ( isNaN(parseInt( widthOrFeatures )) )
    {
        //TODO: not sure what features we need to parse out
        new Ext.Window({
            title: (winTitle != undefined ? winTitle : winname),
            id: winname,
            name: winname,
            stateful: false,
            //autoScroll: scrollbars,
            //width: ''+Math.min(screen.availWidth,widthOrFeatures)+'px',
            //height: ''+Math.min( screen.availHeight-40,height)+'px',
            //left: ''+Math.min(screen.availWidth-widthOrFeatures,getObjectLeft(fld))+'px',
            //top: ''+Math.min( (screen.availHeight-40)-height,getObjectTop(fld))+'px'
            //resizable: true,
            bodyCfg: {
                tag: 'iframe',
                name: winname+'_frame',
                id: winname+'_frame',
                src: url,
                style: 'border: 0 none; background-color: #FFFFFF;'
             }
         }).show();
    }
    else if ( isIE )
    {
        new Ext.Window({
            title: (winTitle != undefined ? winTitle : winname),
            id: winname,
            name: winname,
            stateful: false,
           autoScroll: scrollbars,
            width: ''+Math.min(screen.availWidth,widthOrFeatures+20)+'px',
            height: ''+Math.min( screen.availHeight-40,height+20)+'px',
            left: ''+Math.min(screen.availWidth-widthOrFeatures,getObjectLeft(fld))+'px',
            top: ''+Math.min( (screen.availHeight-40)-height,getObjectTop(fld))+'px',
            style: 'background-color: #FFFFFF;',
            bodyStyle: 'background-color: #FFFFFF;', 
            resizable: true,
            modal: true,
            listeners : listeners,
            bodyCfg: {
                tag: 'iframe',
                name: winname+'_frame',
                id: winname+'_frame',
                src: url,
                width: ''+Math.min(screen.availWidth,widthOrFeatures+4)+'px',
                height: ''+Math.min( screen.availHeight-40,height)+'px',
                style: 'border: 0 none; background-color: #FFFFFF;'
             }
         }).show();
    }
    else
    {
        new Ext.Window({
            title: (winTitle != undefined ? winTitle : winname),
            id: winname,
            name: winname,
            stateful: false,
            modal: true,
            autoScroll: scrollbars,
            width: (parseInt(''+widthOrFeatures)+20)+'px',
            height: (parseInt(''+height)+20)+'px',
            style: 'background-color: #FFFFFF;',
            bodyStyle: 'background-color: #FFFFFF;',
            resizable: true,
            listeners : listeners,
            bodyCfg: {
                tag: 'iframe',
                name: winname+'_frame',
                id: winname+'_frame',
                src: url,
                width: (widthOrFeatures+4)+'px',
                height: height+'px',
                style: 'border: 0 none; background-color: #FFFFFF;'
             }
         }).show();
    }
    //End of Original Implementation before ManagedIFrame

    
    //////////////////////////////////////////////////////////////////////////////////////////


    

        
        
        
        
        
        
        
    
    

///////////////////////////////////////////////////////////////////////////


}


function getObjectLeft(obj)
{
    var offset=0;
    while (obj != null && obj != document.body)
    {
        offset += obj.offsetLeft;
        obj = obj.offsetParent;
    }
    return offset + (isIE ? window.screenLeft : window.screenX + window.outerWidth - window.innerWidth);
}


function getObjectTop(obj)
{
    var offset=0;
    while (obj != null && obj != document.body)
    {
        offset += obj.offsetTop;
        obj = obj.offsetParent;
    }
    if (isIE)
    return offset + window.screenTop;

    //mozilla browsers
    var statusbarHeight = 0;
    if (typeof window.statusbar != "undefined" && window.statusbar != null && window.statusbar.visible)
        statusbarHeight = 20; //rough number

    return offset + window.screenY + window.outerHeight - window.innerHeight - statusbarHeight;

}

function setFieldVisibility ( spanId, on )
{
    var spanInput = document.getElementById( spanId  );
    visible ( spanInput, on );
}
function setLabelVisibility ( spanId, on )
{
    var spanLabel = document.getElementById( spanId + "_lbl" );
    visible( spanLabel, on );
}
function setFieldAndLabelVisibility( spanId, on )
{
    setLabelVisibility( spanId, on );
    setFieldVisibility( spanId, on );
}
function showField ( spanId, on )
{
    var spanInput = document.getElementById( spanId  );
    display ( spanInput, on );
    if ( spanInput != null && spanInput.parentNode.nodeName == "TD" && spanInput.parentNode.style.height == "22px" )
        display ( spanInput.parentNode, on )
}
function showLabel ( spanId, on )
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
    display( spanLabel, on );

}
function showHelperText ( spanId, on )
{
    var spanLabel = document.getElementById( spanId + "_hlp" );
    display( spanLabel, on );
}
function setLabel( spanId, label)
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
    if (spanLabel == null)
    	return;
    spanLabel.innerHTML = label;

}
function getLabel( spanId )
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
	if (spanLabel == null)
		return null;
	// cm: span often contains a link, which itself contains the label
	else if (spanLabel.getElementsByTagName('a') != null && spanLabel.getElementsByTagName('a').length == 1)
		return spanLabel.getElementsByTagName('a').item(0).innerHTML;
	else
		return spanLabel.innerHTML;

}
function showFieldAndLabel( spanId, on )
{

    if (window.nlentryform)
    	window.nlentryform.trackFieldVisibility(spanId, on);

    showLabel( spanId, on );
    showField( spanId, on );

}

function hideTab( tabName, hide )
{
    var displayVal = hide ? 'none' : '';

    var elem = document.getElementById(tabName + 'upperlt');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'uppermiddot');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'uppermid');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'upperrt');
    if (elem != null)
        elem.style.display = displayVal;

    var elem = document.getElementById(tabName + 'lt');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'lnkdot');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'lnk');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + 'rt');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + '_layer');
    if (elem != null)
        elem.style.display = displayVal;

    elem = document.getElementById(tabName + '_umh');
    if (elem != null)
        elem.style.display = displayVal;
}
function setFormValue(fld,value,text,firefieldchanged,synchronous)
{
	if (fld == null)
        return;
	if (fld.type == 'checkbox')
    {
     	setNLCheckboxValue(fld, value);
    }
    else if (fld.type == 'radio' || (fld.length > 0 && fld[0].type == "radio"))
        syncradio(fld,value);
	else if (fld.type == 'select-one')
        synclist(fld,value);
    else if (isNLDropDown(fld))
        getDropdown(fld).setValue(value, true );
    else if (isMultiSelect(fld))
        syncmultiselectlist(fld, value, null, true );
    
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null && (fld == getHtmlEditor(fld.name).hddn))
        return getHtmlEditor( fld.name ).setValue( value, true );
    else if (fld.nodeName == 'INPUT' || fld.nodeName == 'TEXTAREA' || window.virtualBrowser)
    {
		var val = value != null && value.join != null && (isPopupMultiSelect( fld ) || isArray(value)) ? value.join( String.fromCharCode(5) ) : value;
        if ( isPopupSelect( fld ) )
            syncpopup( fld, val, text );
        else if ( isPopupMultiSelect( fld ) )
            syncmultiselectlist( fld, val, text, true );
        else if ( isCurrencyField(fld) )
            setNLCurrencyValue(fld, value);
        else if ( isNumericField(fld) )
            setNLNumericValue(fld, value);
        else
        {
            fld.value = val;
            if ( isDisplayOnlySelect( fld ) && typeof text != "undefined" )
                document.getElementById(fld.name+'_displayval').innerHTML = text != null ? text.replace( new RegExp( String.fromCharCode(5), "g" ), '<BR>' ) : "";
        }
    }
    else
		fld.innerHTML = value;

    if(fld.machine)
        fld.machine.setFieldInputValue(fld.name, value, firefieldchanged, text);
    else if (fld.uiform)
        fld.uiform.setFieldInputValue(fld.name ,value, firefieldchanged, text);

	if (firefieldchanged)
	{
		try
		{
			if (synchronous)
				setSlavingAsync(false)
			fireProperOnChange(fld);
		}
		finally
		{
			setSlavingAsync(true)
		}
	}
}
function getFormValue(fld, returnArray)
{
    if (fld == null)
        return null;
    if (fld.type == "checkbox")
        return fld.checked ? 'T' : 'F';
    else if (fld.type == "radio" || (fld.length > 0 && fld[0].type == "radio"))
        return getRadioValue(fld);
    else if (fld.type == "select-one" || isNLDropDown(fld))
        return getSelectValue(fld);
    else if (isMultiSelect(fld))
        return getMultiSelectValues(fld, returnArray);
    
    else if ( isRichTextEditor( fld ) )
        return getHtmlEditor( fld.name ).getValue( );
    else
        return returnArray && fld.value != null && isPopupMultiSelect( fld ) ? fld.value.split( String.fromCharCode(5) ) : fld.value;
}


function getParameter( param, doc )
{
    if (typeof doc == "undefined" || doc == null)
        doc = document;
    var re = new RegExp(".*[?&]"+param+"=([^&]*)");
    var matches = re.exec( doc.location.href.toString() ) ;
    return matches != null && matches.length > 0 ? matches[1] : null;
}


function getBooleanParameter( param )
{
    return getParameter( param ) == "T";
}

function getParameterValuesArray( )
{
    var url = document.location.href.toString();
    if ( url.indexOf('?') < 0 )
        return null;

    var pairs = url.substring( url.indexOf('?')+1 ).split("&");
    var a = new Array();
    for ( var i = 0; i < pairs.length; i++ )
    {
        var pair = pairs[i].split("=");
        a[a.length] = pair[0];
        a[a.length] = pair.length > 0 ? pair[1] : null;
    }
    return a;
}

function getFormElement(frm,fldname)
{
    var returnMe = null;
    if ( frm != null )
    {
        if ( fldname == 'language' || (!isIE && (fldname == 'item' || fldname == 'cash')) )
        {
            for ( var i = 0; i < frm.elements.length; i++ )
                if ( frm.elements[i].name == fldname )
                {
                    returnMe = frm.elements[i];
                    break;
                }
        }
        else if  (frm.elements != null)
            returnMe = frm.elements[fldname];
    }
    return returnMe;
}

function getFormElementViaFormName(frmName,fldname)
{
    return getFormElement( document.forms[ frmName ], fldname  );
}


var isIE = document.all ? true : false;
var isNS = document.addEventListener ? true : false;
var isNS4x = document.layers ? true : false ;

var NODE_TD = "TD";
var NODE_TR = "TR";
var NODE_TEXT = "#text";
var NODE_TABLE = "TABLE";




function findGlobalPosX(obj, container)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetLeft;
            obj = obj.offsetParent;
        }

        if (obj.document!=null && obj.document.parentWindow != null && obj.document.parentWindow.frameElement)
            curtop += findGlobalPosX(obj.document.parentWindow.frameElement)
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}


function findGlobalPosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }

        if (obj.document!=null && obj.document.parentWindow != null && obj.document.parentWindow.frameElement)
            curtop += findGlobalPosY(obj.document.parentWindow.frameElement)
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}


function findAbsolutePosX(obj)
{
    var curleft = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curleft += obj.offsetLeft;
            if (obj.offsetParent != document.body)
                curleft -= obj.offsetParent.scrollLeft;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curleft += obj.x;
    var isWindowContainedInDivFrame = window.parentAccesible && false; //(typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().x+curleft : curleft);
}


function findAbsolutePosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            if (obj.offsetParent != document.body)
                curtop -= obj.offsetParent.scrollTop;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curtop += obj.y;

    var isWindowContainedInDivFrame = window.parentAccesible && false; //(typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().y+curtop : curtop);
    //return curtop;
}


function findPosX(obj)
{
    var curleft = 0;
    var isExtLoaded = (window.parentAccesible && parent && parent.Ext); //adding check for webstore Issue #203781
    var isWindowContainedInDivFrame = (isExtLoaded ?  parent.Ext.WindowMgr.getActive()!=null : false);
    //following conditional logic attempts to address Issue #200936 regarding date pickers in Chrome and Safari within new Ext popups
    if (isWindowContainedInDivFrame && (parent.Ext.isSafari || parent.Ext.isChrome)) {
        curleft = obj.offsetParent.offsetLeft;
    }
    else if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curleft += obj.x;

    return curleft;
}


function findPosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}

function getParentElementByTag(tag, element)
{
    if(!tag)
        return null;

    var elem = element;

    while(elem != null)
    {
        if (elem.tagName.toLowerCase() == tag.toLowerCase())
            return elem;
        if (elem == elem.parentNode)
            break;
        elem = elem.parentNode;
    }
    return null;
}


function contains(parentElem, childElem)
{
    var elem = childElem;

    while(elem != null)
    {
        if (elem == parentElem)
            return true;
        elem = elem.parentNode;
    }
    return false;
}


function fireProperOnChange(elem, win)
{

    if (elem != null)
    {
        if (win == null)
            win = window;
        if (elem.getAttribute('onChangeFunc'))
            win.localEval(elem.getAttribute('onChangeFunc').replace(/this/g,'document.forms.'+elem.form.name+'.'+elem.name));
        else if ((elem.type == "checkbox" || elem.type == "radio") && elem.onclick)
            elem.onclick();
        else if (elem.onchange)
            elem.onchange();
    }

}


function getInlineTextValue(node)
{

 if (( typeof node == 'undefined') || node == null)
        return "";


        var textValue = "";
        if(node.innerText){ // IE, Chrome, Opera
            textValue = node.innerText;
        } else {
            // Firefox
            // Note: there's no need to check <BR>, <br/> etc. as innerHTML unifies that to <br>
            textValue = node.innerHTML.replace(/<br>/gi, '\n').replace(/(<([^>]+)>)/gi,"");
        }
        return textValue;

}

function setInlineTextValue(node, value)
{
    if ( node == null )
        return;
    node.innerHTML = value;

}

function findUp(node, type)
{
    while ((node != null) && (node.nodeName != type))
        node = node.parentNode;
    return node;
}




function getEvent(evnt)
{
    return (typeof(evnt)!='undefined' && evnt) ? evnt : ((typeof(event)!='undefined' && event) ? event : null);
}


function getEventKeypress(evnt)
{
    evnt = getEvent(evnt);

    return (evnt) ? evnt.keyCode : null;

}


function getEventAltKey(evnt)
{
    evnt = getEvent(evnt);
    return (evnt) ? evnt.altKey : false;
}

function getEventMacCommandKey(evnt)
{
	
		return false;
	
}

function getEventCtrlKey(evnt)
{
    evnt = getEvent(evnt);
    return (evnt) ? evnt.ctrlKey : false;
}

function getEventShiftKey(evnt)
{
    evnt = getEvent(evnt);
    return (evnt) ? evnt.shiftKey : false;
}


function getEventTarget(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.srcElement)
            return evnt.srcElement;         
        if (evnt.target)
            return evnt.target;             
    }

    return null;                            
}


function getEventTargetType(evnt)
{
    evnt = getEventTarget(evnt);
    return (evnt) ? evnt.type : null;
}


function setEventPreventDefault(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.preventDefault)
            evnt.preventDefault();
        else
            evnt.returnValue = false;
    }
}


function setEventCancelBubble(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.stopPropagation)
            evnt.stopPropagation();
        else
            evnt.cancelBubble = true;
    }
}


function restoreHtmlEditors( frm )
{
    //if ( window.htmleditors != null )
    if ( typeof NetSuite == "object" && typeof NetSuite.RTEManager == "object" )
    {
		var vfFunc = document.forms['main_form'] != null && document.forms['main_form'].elements.nlapiVF != null ? document.forms['main_form'].elements.nlapiVF.value : null;
		try
		{
			if (vfFunc != null)
				document.forms['main_form'].elements.nlapiVF.value = '';
             NetSuite.RTEManager.getMap().eachKey(function (key, value) {
                var editor = value.obj;
				if ( frm == null || editor.hddn.form == frm ) {
					//NLExtHtmlEditor.setValue( key, editor.hddn.value );
                    editor.setValue( editor.hddn.value );
                }
             });
		}
		finally
		{
			if (vfFunc != null)
				document.forms['main_form'].elements.nlapiVF.value = vfFunc;
		}
	}
}

function nlFieldHelp(db,p,f,fld)
{
    var url = '/core/help/fieldhelp.nl?fld='+f+'&perm='+p;
    if ( window.isOLC )
        url = '/offline/pages/core/help/offlinefieldhelp.html?field='+f+'&recordType='+p.toLowerCase();
    var winname = 'fieldhelp';
    var width = 350;
    var height = 150;
    if (fld != null)
    {
        var left= Math.min(screen.availWidth-width,getObjectLeft(fld));
        var top = Math.min((screen.availHeight-40)-height,getObjectTop(fld) + fld.offsetHeight);
    }
    var win = window[winname];
    
    if (typeof win == "undefined" ||  win == null || win.closed )
        win = window.open(url, winname, 'scrollbars='+(isIE ? 'no' : 'yes')+',width='+Math.min(screen.availWidth,width)+',height=50,left=' + left + ',top=' + top + ',resizable=yes');
    else
    {
        win.location = url;
        win.moveTo(left, top);
    }
    win.focus();
    window[winname] = win;

    return false;
}


function dumpObj(obj)
{
    for(var prop in obj)
    {
        var str = prop + ": " + obj[prop];
        document.body.appendChild(document.createTextNode(str));
        document.body.appendChild(document.createElement("BR"));
    }
    if (obj.style)
    {
        document.body.appendChild(document.createTextNode("STYLE:"));
        document.body.appendChild(document.createElement("BR"));
        dumpObj(obj.style);
    }
}


function NLAlert(msg,ignoreServerSide)
{
    alert(msg);
}



/** helper extensions to Array object **/
function arrayIndexOf(array, val, ignorecase)
{
    for ( var i = 0; array != null && i < array.length; i++ )
        if ( val == array[i] || (ignorecase && val != null && array[i] != null && val.toLowerCase() == array[i].toLowerCase()) )
            return i;
    return -1;
}
function arrayContains(array, val)
{
    return arrayIndexOf(array, val) >= 0;
}
function arrayAdd(array, val)
{
    if ( !arrayContains(array, val) )
        array.push(val);
}
function arrayRemove(array, val)
{
    var newarray = new Array();
    for ( var i = 0; i < array.length; i++ )
        if ( val != array[i] )
            newarray.push(array[i]);
    return newarray;
}

function getArrayIntersection(array1, array2)
{
    var resultArray = new Array();
    for (var i = 0; i < array1.length; i++)
    {
        for (var j = 0; j < array2.length; j++)
        {
            if (array1[i] == array2[j])
            {
                resultArray[resultArray.length] = array1[i];
                array2[j] = null;
                break;
            }
        }
    }
    return resultArray;
}
function isArray(obj) 
{
   if (typeof obj == "undefined" || obj == null)
      return false;
   if (obj.constructor != null)
      return obj.constructor.toString().substring(0, obj.constructor.toString().indexOf('{')).indexOf("Array") != -1;

   if (typeof obj != "string" && obj.length > 0 )
      return true;
}




function nlInsertCanvas(insertCanvasDiv)
{
    
}

function nlSyncCanvas(syncCanvasDiv)
{
    
}

function nlRemoveCanvas(div)
{
    
}

function getCanvasId(div)
{
    return div.id+'_canvas';
}

function findClassUp(node, clss)
{
    
    while ((node != null) && (node.className != clss && node.classAlias != clss))
        node = node.parentNode;
    return node;
}

function getScrollLeftOffset(btn)
{
    
    var scrollLeftOffset = 0;
    var scrollDiv;
    if(btn != null && (scrollDiv = findClassUp(btn,'scrollarea')) != null)
    {
        scrollLeftOffset = scrollDiv.scrollLeft;
    }
    else if ( (scrollDiv = document.getElementById('div__body')) != null )
    {
        scrollLeftOffset = scrollDiv.scrollLeft;
    }

    return scrollLeftOffset;
}

function getScrollTopOffset(btn)
{
    
    var scrollTopOffset = 0;
    var scrollDiv;
    if(btn != null && (scrollDiv = findClassUp(btn,'scrollarea')) != null)
    {
        scrollTopOffset = scrollDiv.scrollTop;
    }
    else if ( (scrollDiv = document.getElementById('div__body')) != null )
    {
        scrollTopOffset = scrollDiv.scrollTop;
    }

    return scrollTopOffset;
}

/**
 * remove all the child nodes
 */
function removeAllChildren(obj)
{
    while (obj.childNodes[0])
    {
        obj.removeChild(obj.childNodes[0]);
    }
}


function StringBuffer() { this.buffer = []; }
StringBuffer.prototype.append = function(string)
{
    this.buffer.push(string);
    return this;
}
StringBuffer.prototype.toString = function()
{
    return this.buffer.join("");
}


function setObjectOpacity(opacity, styleElem)
{
    var style = styleElem.style;
    style.opacity = (opacity / 100);
    style.MozOpacity = (opacity / 100);
    style.filter = "alpha(opacity=" + opacity + ")";
}

function fadeObjectOpacity(styleElem, startOpacity, endOpacity, elapsedTime)
{
    var speed = Math.round(elapsedTime / 100);
    var timer = 0;

    if(startOpacity > endOpacity)
    {
        for(i = startOpacity; i >= endOpacity; i--)
        {
            setTimeout(function(){setObjectOpacity(i, styleElem);}, (timer * speed));
            timer++;
        }
    }
    else if(startOpacity < endOpacity)
    {
        for(i = startOpacity; i <= endOpacity; i++)
        {
            setTimeout(function(){setObjectOpacity(i, styleElem);}, (timer * speed));
            timer++;
        }
    }
}

function tellafriend(strSubject, strAddress, strBodyMain, strBodyName, strBodyPrice, strBodyLink, strPrice)
{
var strBody = escape(strAddress)+ ",%0d%0a%0d%0a";
strBody += escape(strBodyMain) + escape(location.hostname) + ".%0d%0a%0d%0a";
strBody += escape(strBodyName) + escape(document.title) + ".%0d%0a";
strBody += escape(strBodyPrice) + escape(strPrice)+ "%0d%0a";
strBody += escape(strBodyLink) + escape(location.href) + "%0d%0a";
location.href = "mailto:?subject=" + escape(strSubject) + "&body=" + strBody;
}


function isLeftButtonDown(evnt)
{
    var bLeftClick = false;
    var e = getEvent(evnt);

    if(isIE && e.button==1 || (!isIE && e.button==0))
        bLeftClick = true;

    return bLeftClick;

}

function isRightButtonDown(evnt)
{
    var bRightClick = false;
    var e = getEvent(evnt);

    if(e.button==2) // ie, mozilla (ctrl-click on mac)
        bRightClick = true;

    return bRightClick;

}


function getSelectedTextRange (elem)
{
    var startPos;
    var endPos;
    if (document.all)
    {
        var selectedText = document.selection.createRange();
        var range = selectedText.duplicate();
        range.moveToElementText(elem);
        range.setEndPoint('EndToEnd', selectedText);
        startPos = range.text.length - selectedText.text.length;
        endPos   = startPos + selectedText.text.length;
    }
    else
    {
        startPos = elem.selectionStart;
        endPos   = elem.selectionEnd;
    }
    var range = new Array();
    range[0] = startPos;
    range[1] = endPos;
    return range;
}


function insertTextAtCursor (elem, text)
{
    elem.focus();
    if (document.all)
    {
        var sel = document.selection.createRange();
        sel.text = text;
        sel.scrollIntoView(true);
    }
    else
    {
        var startPos = elem.selectionStart;
        var endPos   = elem.selectionEnd;
        elem.value = elem.value.substring(0, startPos) + text + elem.value.substring(endPos);
        
        elem.selectionEnd = elem.selectionStart + text.length;
        elem.selectionStart = elem.selectionEnd;
    }
}

function setWindowChanged(win, bChanged)
{
    if(win==null) win = window;
    win.ischanged = bChanged;
}


function escapeHTML (text)
{
    var div = document.createElement('div');
    var textNode = document.createTextNode(text);
    div.appendChild(textNode);
    return div.innerHTML;
}

function escapeHTMLAttr (text)
{
    var text = escapeHTML(text);
    return text.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}


function getRuntimeSize(el, styleProp)
{
    var val = getRuntimeStyle(el, styleProp);
    if (!val)
        return 0;
    val = val.replace("px", "")
    if (isNaN(val)) 
        return 0;
    return val*1.0; //return number only
}


function getRuntimeStyle(el, styleProp)
{
    var val = null
    if (typeof el == "string")
        el = document.getElementById(el);
    if (el == null)
        return val;

    
	if (window.getComputedStyle)
	    val = document.defaultView.getComputedStyle(el, null)[styleProp];
    else if (el.currentStyle)
        val = el.currentStyle[styleProp];

    if (val == "auto")
    {
        if (styleProp == "height")
            val = el.offsetHeight;
        else if (styleProp == "width")
            val = el.offsetWidth;
    }
	return val;
}



function camelize(str)
{
    var parts = str.split('-')
    var len = parts.length;
    if (len == 1) return parts[0];

    var camelized = str.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
}

function eval_js(sScript)
{
	sScript = sScript.replace(/^\s*<!--[\s\S]*?-->\s*$/gm, '');
	return eval(sScript);
}

var slave_machines = new Array();
function process_slaving_result(response)
{
    var sText = response.getBody();
    var components=sText.split("<machine");
	for (var i=1;i<components.length;i++)
    {
		var idx = components[i].indexOf("name='")+6
		var name = components[i].substring(idx, components[i].indexOf("'>", idx))
		slave_machines[name] = components[i].substring(components[i].indexOf("'>")+2, components[i].lastIndexOf("</machine>"));
    }
    var script = components[0];
	eval_js(script);
	slave_machines = new Array();
}
var process_slaving_result_original = process_slaving_result;

var performSlavingAsync = true;
function setSlavingAsync(async)
{
    performSlavingAsync = async;
}
function getSlavingAsync()
{
    return performSlavingAsync;
}


function loadSlavingResults(url)
{

	nlXMLRequestURL(url, null, null, process_slaving_result, getSlavingAsync());

}

function execute_js(response, postResponseFn)
{
	eval_js(response.getBody());
	if (postResponseFn)
		postResponseFn();
}


function NLGetCurrentScriptFileHostName()
{
   var scripts = document.getElementsByTagName('script');
   if (!scripts || scripts.length == 0)
       return null;

   var currentScriptFileUrl = scripts[scripts.length - 1].src;
   if (!currentScriptFileUrl)
       return null;

   var hostName = currentScriptFileUrl.match(/^((http|https):\/\/)?[^\/]+/g);
   if (hostName && hostName.length>0)
       hostName = hostName[0];
   if (!hostName)
       hostName = "";

   return hostName;
}


function NLLoadScriptInScriptTag(sUrl, id, doc)
{
   if (!doc)
       doc = document;

   var script = doc.getElementById(id);
   if (!script)
   {
       var head= doc.getElementsByTagName('head')[0];   
       script= doc.createElement('script');
       script.type= 'text/javascript';
       head.appendChild(script);
   }
   script.src= sUrl;
}

function loadXMLJSDoc(url, postResponseFn)
{
	nlXMLRequestURL(url, null, null, function(response) { execute_js(response, postResponseFn); }, true);
}

/*
issue a GET or POST request for an Internal URL resource
support for external resources can be added later if needed.
copied from nlapiRequestURL to avoid unnecessary dependency
*/
function nlXMLRequestURL(url, postdata, headers, responseHandler, async)
{
    var request = new NLXMLHttpRequest();
    if ( responseHandler instanceof Function )
        request.setResponseHandler( responseHandler );
    var nsResponse = request.requestURL( url, postdata, headers, async )
    return nsResponse;
}

/*--------------- NLHttpXMLRequest class definition ------------*/
function NLXMLHttpRequest( ignoreErrors )
{
	this.requestPending = false;
	this.callbackFunc = null;
    this.ignoreResponseErrors = ignoreErrors;
    if ( window.XMLHttpRequest )
		this.xmlrequest = new XMLHttpRequest();
	else
	{
		try	{ this.xmlrequest = new ActiveXObject("Msxml2.XMLHTTP.4.0"); }
		catch ( e )	/* OLC requires at least MSXML v4.0 */	{ this.xmlrequest = isOffline() ? null : new ActiveXObject("Msxml2.XMLHTTP"); }
	}
}
NLXMLHttpRequest.prototype.setResponseHandler = function( callbackFunc )
{
    this.callbackFunc = typeof callbackFunc == "function" ? callbackFunc : null;
}
NLXMLHttpRequest.prototype.requestURL = function( url, postdata, requestHeaders, async, httpMethod )
{
	if ( this.requestPending )
		return;

	this.requestPending = true;
	var method;

	if (!isValEmpty(httpMethod))
	    method = httpMethod;
	else
	    method = postdata != null ? "POST" : "GET";

	this.xmlrequest.open( method, url, (async != null ? async : false) );
	for ( var header in requestHeaders )
		this.xmlrequest.setRequestHeader( header, requestHeaders[ header ] );
    this.xmlrequest.setRequestHeader("NSXMLHttpRequest", "NSXMLHttpRequest");
    if ( method == 'POST' || method == 'PUT')
    {
        if ( postdata instanceof String || typeof postdata == "string" || nsInstanceofDocument( postdata ) )
            this.xmlrequest.setRequestHeader("Content-Type", "text/xml; charset=UTF-8");
        else
        {
            postdata = formEncodeURLParams( postdata );
            this.xmlrequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        }
    }
    var response = null;
	if ( async )
	{
		this.xmlrequest.onreadystatechange = this.handleResponse.bindAsEventListener( this );
		this.xmlrequest.send( postdata );
	}
	else
	{
		this.xmlrequest.send( postdata );
		response = this.handleResponse( );
	}
	return response;
}
NLXMLHttpRequest.prototype.handleResponse = function()
{
	var response = null;
	if ( this.xmlrequest.readyState == 4 )  /* For now, we'll not worry about the Loading, Loaded, Interactive readyStates  */
	{
		var responseCode = this.xmlrequest.status;
		var responseBody = this.xmlrequest.responseText;
		var responseHeaders = new Array();
		var responseHeadersArray = this.xmlrequest.getAllResponseHeaders();
		responseHeadersArray = responseHeadersArray.replace(/^\s+/,"").replace(/\s+$/,"").split("\n");
		for ( var i = 0; i < responseHeadersArray.length; i++ )
		{
			var responseArray = responseHeadersArray[i].split(":");
			var header = responseArray[0];
            var valueArray = responseHeaders[ header ];
            if ( valueArray == null )
            {
                valueArray = new Array();
                responseHeaders[ header ] = valueArray
            }
            valueArray[valueArray.length] = responseArray[1];
		}
        /* Extract Netsuite Server Error (if one exists)  */
        /*
            kevinng 4/7/2011
            responseCode must be 200 or 206 with non-empty responseBody (see NLErrorPage.prepResponse())
            the changes include the fix for issue 193944 (CL 401296)
         */
		var responseError = null;
        if (responseBody!=null && responseBody.toLowerCase().indexOf('error')>=0)
        {
            if ( responseBody.indexOf('<onlineError>') >= 0 )
            {
                var onlineError = nsStringToXML( responseBody );
                responseError = new NLXMLResponseError( nsSelectValue( onlineError, '/onlineError/code' ), nsSelectValue( onlineError, '/onlineError/detail' ), nsSelectValue( onlineError, '/onlineError/id' ) );
            }
            else if ( responseBody.indexOf('<error>') >= 0 )
            {
                var onlineError = nsStringToXML( responseBody );
                responseError = new NLXMLResponseError( nsSelectValue( onlineError, '/error/code' ), nsSelectValue( onlineError, '/error/message' ) );
            }
            else if ( responseBody.indexOf('{"error"') >= 0 )
            {
                var onlineError = JSON.parse( responseBody );
                responseError = new NLXMLResponseError( onlineError.error.code, onlineError.error.message );
            }
            else if ( responseBody.indexOf('error code:') >= 0 && responseBody.indexOf('error message:') >= 0 )
            {
                var onlineError = responseBody.split("\n");
                responseError = new NLXMLResponseError( onlineError[0].substring("error code: ".length), onlineError[1].substring("error message: ".length) );
            }
        }
        else if ( responseCode != 200 && responseCode != 206 )
            responseError = new NLXMLResponseError( 'SERVER_RESPONSE_ERROR', responseBody );
		try
		{
			if ( responseError != null && this.callbackFunc == null && !this.ignoreResponseErrors )
				throw responseError;
			response = new NLXMLResponse( responseCode, responseBody, responseHeaders, responseError );
			if ( this.callbackFunc != null )
			    this.callbackFunc( response );
		}
		finally
		{
			this.requestPending = false;
		}
	}
	return response;
}
/*--------------- NLXMLResponse class definition ------------*/
function NLXMLResponse( responseCode, responseBody, responseHeaders, responseError )
{
	this.code = responseCode;
	this.body = responseBody;
	this.headers = responseHeaders;
	this.error = responseError;

	this.getCode = function() { return this.code };
	this.getBody = function() { return this.body };
	this.getError = function() { return this.error };
	this.getHeaders = function() { return this.headers };
}
/*--------------- NLXMLResponse class definition ------------*/
function NLXMLResponseError( errorCode, errorBody, errorId )
{
	this.id = errorId;
	this.code = errorCode;
	this.details = errorBody;

	this.getId = function() { return this.id };
	this.getCode = function() { return this.code };
	this.getDetails = function() { return this.details };
}

/**
 * @param url URL of request handler
 * @param methodName method name on remote object to call
 * @param methodParams an array of parameters to the method
 * @param asyncCallback a callback if this is to be an async request.  Callback signature should be: callback(result, error)
 * @param httpMethod Specify GET or POST.  GET is the default.
 */
function nsServerCall(url, methodName, methodParams, asyncCallback, httpMethod)
{
	var client = new NLJsonRpcClient(url);
	return client.sendRequest(methodName, methodParams, asyncCallback, httpMethod);
}

NLJsonRpcClient = function (serverURL)
{
	if (serverURL.indexOf("?") > 0)
		serverURL = serverURL + "&jrr=T";
	else
		serverURL = serverURL + "?jrr=T";
	this.serverURL = serverURL;
	this.responseCallbackMap = {};
};
NLJsonRpcClient.requestId = 0;
NLJsonRpcClient.prototype =
{
	sendRequest : function (methodName, args, callback, httpMethod)
	{
		httpMethod = httpMethod || "GET";
		var jsonRpcReq = {
			id : NLJsonRpcClient.requestId++,
			method : "remoteObject." + methodName,
			params : args || []
		};
		if (callback != null)
			this.responseCallbackMap[jsonRpcReq.id] = callback;
		var request = new NLXMLHttpRequest();
		if (callback != null)
			request.setResponseHandler(this.handleResponseAsync.bindAsEventListener(this));

		var url = this.serverURL;
		var postData = null;
		if ("GET" == httpMethod)
		{
		 	url += "&jrid=" + jsonRpcReq.id;
		 	url += "&jrmethod=" + jsonRpcReq.method;
		 	if (jsonRpcReq.params.length > 0)
		 		url += "&jrparams=" + encode(toJSON(jsonRpcReq.params));
		}
		if ("POST" == httpMethod || ("GET" == httpMethod && url.length > 2083)) // 2083 is max url length in IE
		{
			url = this.serverURL;
			postData = toJSON(jsonRpcReq);
		}
       	var response = request.requestURL(url, postData, null, callback != null ? true : false);
		if (callback == null)
		{
			var jsonRpcResp = this.getJsonRpcResponse(response);
			if (jsonRpcResp.error)
				throw new NLXMLResponseError(jsonRpcResp.error.code, jsonRpcResp.error.trace, jsonRpcResp.error.msg);
			response = jsonRpcResp.result;
		}
		return response;
	},

	getJsonRpcResponse : function (nlXMLResponseObj)
	{
		var jsonRpcResp = nlXMLResponseObj.getBody();
		if (jsonRpcResp != null)
			jsonRpcResp = jsonRpcResp.replace(/^\s*<!--[\s\S]*?-->\s*$/gm, '');
		eval("jsonRpcResp = " + jsonRpcResp + ";");
		return jsonRpcResp;
	},

	handleResponseAsync : function (nlXMLResponseObj)
	{
		var jsonRpcResp = this.getJsonRpcResponse(nlXMLResponseObj);
		var callback = this.responseCallbackMap[jsonRpcResp.id];
		this.responseCallbackMap[jsonRpcResp.id] = null;
		callback(jsonRpcResp.result, jsonRpcResp.error);
	}
}

Function.prototype.bind = function(object) {
  var __method = this;
  return function() {
    __method.apply(object, arguments);
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this;
  return function(event) {
    __method.call(object, event || window.event);
  }
}

function isOffline()
{
	return window.isOLC != null;
}
function clone(srcobj)
{
	if(typeof(srcobj) != 'object') return srcobj;
	if(srcobj == null) return srcobj;

	var newObj = new Object();

	for(var i in srcobj)
		newObj[i] = clone(srcobj[i]);

	return newObj;
}

function hoverEffectOnFocus(fld)
{
    if (fld.parentNode.className.indexOf('_focus') >= 0)
        return;

    if (fld.parentNode.className.indexOf('_roll') == -1)
    {
        fld.parentNode.className=fld.parentNode.className+'_focus';
    }
    else
    {
       fld.parentNode.className=fld.parentNode.className.replace('_roll', '_focus');
    }
}


function hoverEffectOnBlur(fld)
{
  fld.parentNode.className = fld.parentNode.className.replace('_focus', '');
}

function leftPadWithWrapping(input, pad, colsAvail)
{
    // safety-inits, and check for edge cases
    if(pad==null) pad = '';
    if(input==null)
        input = '';
    else
        input = trim(input);

    // if colsAvail not longer than pad, we will never get through input.
    // input just gets truncated in this case and we return one line of pad
    if( colsAvail <= pad.length )
        return pad.substring(0,colsAvail);


    var newlen =  pad.length+input.length;  // len after padding
    if( newlen <= colsAvail ) { // we need not wrap
        return pad+input;
    }
    else{                       // we must wrap
        var i = input.length- (newlen-colsAvail);
        return (pad+input.substring(0,i)) + '\n' + leftPadWithWrapping(input.substring(i), pad, colsAvail);
    }
}

function nlFireEvent(element,event){
    if (document.createEventObject){
        // dispatch for IE
        var evt = document.createEventObject();
        return element.fireEvent('on'+event,evt)
    }
    else
    {
        // dispatch for firefox + others
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent(event, true, true ); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
    }
}
function getOuterHTML(object)
{
    var element;
    if (!object) return null;

    if (object.outerHTML)
        return object.outerHTML;
    element = document.createElement("div");
    element.appendChild(object.cloneNode(true));
    return element.innerHTML;
}

function NLNumberToString(number)
{
    str = number + '';
    parts = str.split('.');
    integerPart = parts[0];
    decimalPart = parts.length > 1 ? window.decimalseparator + parts[1] : '';
    var regex = /(\d+)(\d{3})/;
    while (regex.test(integerPart))
    {
        integerPart = integerPart.replace(regex, '$1' + window.groupseparator + '$2');
    }

    if(number < 0 && window.negativeprefix != '-')
        return window.negativeprefix + integerPart.replace('-', '') + decimalPart + window.negativesuffix;
    else
        return integerPart + decimalPart;
}

function NLStringToNumber(str, addZeroPadding)
{
    if(isValEmpty(str))
        return "";
    // handle percentage string
    if(str.indexOf('%') >= 0)
        return NLStringToNumber(str.replace('%',''),addZeroPadding) + '%';
    str = str.replace(new RegExp( '\\' + window.groupseparator, 'g'), '');
    if(window.negativeprefix != '-' && str.indexOf(window.negativeprefix) == 0)
        str = '-' + str.replace(window.negativeprefix, '').replace(window.negativesuffix, '');
    if(window.decimalseparator == ',')
        str = str.replace(',', '.');

    var number = parseFloat(str);

    if (addZeroPadding)
    {
        var paddingLength = 0;
        var decimalSeperatorIndex = str.indexOf(".");
        if (decimalSeperatorIndex != -1)
            paddingLength = str.length - decimalSeperatorIndex - 1;
        number = number.toFixed(paddingLength);
    }
    return number;
}

// first convert string to number, then pad trailing 0's to match the original string's trailing 0's
function NLStringToNormalizedNumberString(str)
{
    var decimalSeperatorIndex = str.indexOf(window.decimalseparator);
    return NLStringToNumber(str, decimalSeperatorIndex != -1) + "";
}

