/* global dialoglangForm, $j, langServletUrl, langManager, bootbox, nuf.contextPath, ajaxCaller */
//NOTE: this script requires prototypes.js!!
if(typeof(nuf)==='undefined'){
	nuf = {};
}

var jroAttributes = new Array();
var validationFunctions = new Array();

nuf.formIsQuerymode = false;

nuf.arrEmptyMandatoryFields = new Array(); // array holding required fields that were found empty

nuf.jroValErrors = [];
var focusCtrl = null;
var isMSIE = typeof(window.addEventListener)=='undefined'; //window.addEventListener only works in Firefox
nuf.confirmDialogsTitle = '';
nuf.formReadOnly = false; // flag to indicate whether form is in read only mode
nuf.formOriginalValues = ''; // data at time of loading the form!
nuf.checkForChangedValues = true ; // should we check and war the user for changed data on page? Used in combination with nuf.formOriginalValues
nuf.debug = 0;  // debug flag
nuf.submitBtn = null; // submit button control, disbaled in validateJroAttributes function to disable double clicks!
nuf.checkEmpty = true; // by default, we check if form is empty and we show error message!
nuf.requiredBackColor = '';  // the required controls back color, set to light yellow
nuf.notRequiredBackColor = 'transparent'; // the NOT required controls back color, set to white yellow
nuf.csrfTokenName='_CTKN_';
nuf.datePattern='dd/mm/yyyy';  // the date pattern.  it is printed in Before Render of cgl base web page
nuf.dateSep = '/'; // date separator
nuf.bFocusFirst=true;  //set tp false not to auto-focus the first control on the page 

var CTLTYPE_DEFAULT =1;
var CTLTYPE_COMBO= 2;
var CTLTYPE_CHECKBOX = 3;
var CTLTYPE_LISTBOX = 4;
var CTLTYPE_DATE =5;
var CTLTYPE_TIME =6;
var CTLTYPE_INTEGER =7;
var CTLTYPE_DECIMAL =8;
var CTLTYPE_EMAIL = 10;
var CTLTYPE_DATETIME = 11;
var CTLTYPE_CHECKBOX2 = 13;
var CTLTYPE_AUTOSUGGEST_COMBO = 106;
var CTLTYPE_RADIO= 107;
var CTLTYPE_LOV= 14;
var CTLTYPE_LOV_SECURE = 15;
var tdy = new Date().today().getTime();

/*****************************************************/
/** object used to represent controls on form       **/
/*****************************************************/
function jroAttribute() {

  function oValue() {
  //alert(this.ctype + ' ' + this.name);
    if (this.ctype==CTLTYPE_TIME) {
      return this.contents.parseTime();
	  
    } else if ( this.ctype==CTLTYPE_DATE || this.ctype==CTLTYPE_DATETIME) {
      return this.contents.parseDateTime();
	
	} else if ( this.ctype==CTLTYPE_INTEGER || this.ctype==CTLTYPE_DECIMAL) {
		return this.contents.parseNumber();
			  	  	  
	} else if (this.ctype==CTLTYPE_CHECKBOX) {
		if (this.control.checked ) {
			return this.control.value;
		} else {
			return 0;
		}
	} else if (this.ctype==CTLTYPE_CHECKBOX2) {
		return this.control.value;
		
    } else {
      return this.contents;
    }
	
  }

  function setValue(newVal) {
	//alert(this.ctype + ' ' + this.name);
    
	if($('display_'+this.control.id)){
		// we have a readonly control. set value and exit!
		$('display_'+this.control.id).innerHTML = newVal;
		return;
	}
	
	
	if (this.ctype==CTLTYPE_COMBO || this.ctype==CTLTYPE_LISTBOX) {
		setPickListIndexFromValue(this.control,newVal)
    
	} else if (this.ctype==CTLTYPE_RADIO) {
		setRadioListValue(this.control,newVal);

	} else if (this.ctype==CTLTYPE_LOV) {
		this.control.value = newVal;
		fireBlurEvent(this.control);
		
	} else if (this.ctype==CTLTYPE_LOV_SECURE) {
		this.control.value = newVal;
		fireBlurEvent(this.control);
		
    } else if (this.ctype==CTLTYPE_CHECKBOX2) {
		//checkbox 2 is a checkbox with id [id]Temp and a hidden textbox with id: [id]
		if(this.control ) {
			
			if(!$(this.control.id+'Temp'))alert('Error: checkbox with id:\''+this.control.id+'Temp\' does not exist!');
			if(newVal== $(this.control.id+'Temp').value){
				$(this.control.id+'Temp').checked=true;
			} else {
				$(this.control.id+'Temp').checked=false;
			}
			__Checkbox2Click(this.control.id);
		}
	} else if (this.ctype==CTLTYPE_CHECKBOX) {
		if (newVal) {
			this.control.checked = true;
		} else {
			this.control.checked = false;
		}
		 
	} else {
      this.control.value = newVal;

    }

  }
  
  function setNoError() {
	  this.jroValErrors = [];
	  $j(this.control).removeClass("inErrorControl");
  }
  
  function setInError(msg) {
	  this.jroValErrors.push(msg);
	  $j(this.control).addClass("inErrorControl");
  }
    /* this function only validates time, date and number boxes. */	     		
  function isvalid2() {
		var ret = true;
       
		if (this.ctype===CTLTYPE_EMAIL) {
			
			 if (! validateEmail(this.contents)) {
				this.setInError(showError2(25, this.label));
				if(! focusCtrl) focusCtrl = this.control;
                nuf.jroValErrors.push( showError2(25, this.label));
                ret = false;
            }
			
		}
		
        if (this.ctype===CTLTYPE_TIME) {    
			if (this.isEmpty()==false) { // do not parse empty values
				var dt = this.contents.parseTime();
				if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
					nuf.jroValErrors.push( showError2(22, this.label));
					this.setInError(showError2(22, this.label));
					ret = false;                    
				} else {
					this.control.value = dt.formatTime();
				}
			}
        }
        
		if (this.ctype==CTLTYPE_DATE) {
			//debugger;
		    if (this.isEmpty()==false) { // do not parse empty values
                
                var dt = this.contents.parseDate();
				
                if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
                    nuf.jroValErrors.push(showError2(0, this.label));
					this.setInError(showError2(0, this.label));
                    ret = false;
					
                } else {
					this.control.value = dt.formatDate();
                }
            }
		}
		
        if ( this.ctype==CTLTYPE_DATETIME ) {
            if (this.isEmpty()==false) { // do not parse empty values
                
                var dt = this.contents.parseDateTime();
				
                if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
                    nuf.jroValErrors.push( showError2(0, this.label));
					this.setInError(showError2(0, this.label));
                    ret = false;
					
                } else {
					this.control.value = dt.formatDateTime();
                }
            }
        }//end check if date
            
        if (this.isNumber()) {
            
            if (this.checkNumber() === false) {
				if(! focusCtrl) focusCtrl = this.control;
                ret = false;
            }
            
        }//end check if number
		
		return ret;
  }
	
  function isvalid() {
		
		var ret = true;

		if (this.isMandatory) {
        	
            if (this.isEmpty()) {
				if(! focusCtrl) focusCtrl = this.control;
				__arrEmptyMandatoryFields[__arrEmptyMandatoryFields.length] = this.label;
                ret = false;                    
            }
            
        }//end check if mandatory
        
		if (this.ctype==CTLTYPE_EMAIL) {
			 if (! validateEmail(this.contents)) {
				if(! focusCtrl) focusCtrl = this.control;
                nuf.jroValErrors.push(showError2(25, this.label))
				this.setInError(showError2(25, this.label));
                ret = false;                    
            }
		}
		
        if (this.ctype==CTLTYPE_TIME) {    
			if (this.isEmpty()==false) { // do not parse empty values
				var dt = this.contents.parseTime();
				if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
					nuf.jroValErrors.push( showError2(22, this.label));
					this.setInError(showError2(22, this.label));
					ret = false;                    
				} else {
					if (this.minValue && this.maxValue )  {
						
						if (!checkDateIsBetween(dt, this.minValue, this.maxValue)) {
							this.setInError(showError2(31, this.label));
							nuf.jroValErrors.push( showError2(31, this.label, this.minValue.formatTime(), this.maxValue.formatTime()));
							if (!focusCtrl) focusCtrl = this.control;
							ret = false;
						}
					}
					
					this.control.value = dt.formatTime();
				}
			}
        }
        
		if (this.ctype==CTLTYPE_DATETIME) {
            if (this.isEmpty()==false) { // do not parse empty values
                
                var dt = this.contents.parseDateTime();
				
                if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
					this.setInError(showError2(0, this.label));
                    nuf.jroValErrors.push( showError2(0, this.label));
                    ret = false;
					
                } else {
					
                    if (this.minValue && this.maxValue && 
							!checkDateIsBetween(dt, this.minValue, this.maxValue)) {
						
						this.setInError(showError2(23, this.label));
						nuf.jroValErrors.push( showError2(23, this.label, this.minValue.formatDateTime(), 
																		  this.maxValue.formatDateTime()));
						if (!focusCtrl) focusCtrl = this.control;
						ret = false;
						
					} else {
						this.control.value = dt.formatDateTime();
                	} 
                }
            }
        }//end check if date
		
        if (this.ctype==CTLTYPE_DATE) {
            if (this.isEmpty()==false) { // do not parse empty values
               
                var dt = this.contents.parseDate();
				
                if (dt == null) {
					if(! focusCtrl) focusCtrl = this.control;
                    nuf.jroValErrors.push( showError2(0, this.label));
					this.setInError(showError2(0, this.label));
                    ret = false;
					
                } else {
					
                    if (this.minValue && this.maxValue && 
							!checkDateIsBetween(dt, this.minValue, this.maxValue)) {
						var msg =  showError2(23, this.label, this.minValue.formatDate(), this.maxValue.formatDate());
						this.setInError(msg);
						nuf.jroValErrors.push(msg);
						if (!focusCtrl) focusCtrl = this.control;
						ret = false;
						
					} else {
						this.control.value = dt.formatDate();
                	} 
                }
            }
        }//end check if date
            
        if (this.isNumber()) {
            
            if (this.checkNumber() == false) {
				if(! focusCtrl) focusCtrl = this.control;
                ret = false;
            }
            
        }//end check if number
		
        //alert(this.name + ' isMandatory:' + this.isMandatory + 'contents: ' + this.contents  + ' valid:' + ret);
        
		if (this.control && this.control.value ) {
		
			if (this.control.value.length > this.maxLen) {
				if(! focusCtrl) focusCtrl = this.control;
				nuf.jroValErrors.push( showError2(28, this.label,this.maxLen,this.control.value.length ));
				this.setInError(showError2(28, this.label,this.maxLen,this.control.value.length ));
				ret = false;
			}
			
		}
		if(! this.validateRegularExpressionPattern()) {
			if(! focusCtrl) focusCtrl = this.control;
			nuf.jroValErrors.push( showError2(36, this.label, this.regularExpressionPattern));
			this.setInError( showError2(36, this.label, this.regularExpressionPattern ));
			ret=false;
		}
		return ret;
    }
	
    function checkNumber() {
	
        if (this.isEmpty()) {
            return true; //return true if it is an empty value.
        }
				
		if (this.contents.isNumeric()) {
			var bscale =  this.checkScale();		
			if(bscale==false){
				return false;
			}
        	
			// we put +0 below to force math values
			if ( this.contents.parseNumber() < this.minValue) {
				nuf.jroValErrors.push( showError2(24, this.label, this.minValue));
				this.setInError(showError2(24, this.label, this.minValue) );
				return false;
			} else {
				//alert( this.name + ': min val'+ this.minValue + ' min val ok');
			}
			
			if ( this.contents.parseNumber() > this.maxValue ) {
				nuf.jroValErrors.push( showError2(17, this.label, this.maxValue));
				this.setInError( showError2(17, this.label, this.maxValue) );
				return false;
			} else {
				
			}
			
            this.control.value = this.contents;
            return true;
            
        } else {
			var msg = showError2(2, this.label, this.control.value);
            nuf.jroValErrors.push(msg );
			this.setInError( msg  );
            return false;
        }
    }
    
    function checkScale() {
		
		var numparts = this.contents.NumParts();
		
		if  ( this.scale == 0 ) { 
            // we should not have decimal numbers
            if (numparts.length > 1) { // if split found decimal numbers 
            
                // we should not accept any decimals
                nuf.jroValErrors.push( showError2(20, this.label, this.scale));
				this.setInError( showError2(20, this.label, this.scale) );
                return false;
            }
			
            if (this.precision >0 && (this.contents.length > this.precision)) {
                // we should not accept any decimals
                nuf.jroValErrors.push( showError2(21, this.label, this.precision)) ;
				this.setInError(  showError2(21, this.label, this.precision));
                return false;
            }
        } else {
            // check scale
            if (numparts.length > 1) { // if split found decimal numbers 
                
                if (numparts[1].length > this.scale) {
                    nuf.jroValErrors.push( showError2(19, this.label, this.scale));
					this.setInError(showError2(19, this.label, this.scale));
                    return false;
                }
            }
        }
        
        
        return true;        
    }
    
    function isEmpty() {
        var res = true;
        
        if (this.ctype==CTLTYPE_COMBO) {  
            res = isEmptyPickList(this.control);
            
        } else if (this.ctype==CTLTYPE_RADIO) {  
            res = isEmptyRadioList(this.name,this.formname);
            
        } else if (this.ctype==CTLTYPE_CHECKBOX) {                       
            res = false;
            
        } else {       
            res = ((this.contents == "" || this.contents==null));  
        } 
        return res;
    }
    
    function isNumber() {
    	return this.ctype==CTLTYPE_INTEGER || this.ctype==CTLTYPE_DECIMAL;
    }
    
    function loadValueFromHtml() {
		
        if(!this.control) this.control = $(this.name); 
        if(this.ctype == CTLTYPE_CHECKBOX) {
			if (this.control.checked) {
				this.contents = this.control.value
			} else {
				this.contents = '';
			}
		
		} else if (this.ctype==CTLTYPE_RADIO) {
			this.control = $$(this.name);  // special case!! for radio buttons
			this.contents = getRadioSelValue(this.control);
			
		} else {
			this.contents = this.control.value;
		}
			
    }
    
	function setMandatory(isRequired) {
        this.isMandatory = isRequired;
			
        if (this.control) {
            if (this.ctype == CTLTYPE_RADIO || this.ctype == CTLTYPE_CHECKBOX) {

            } else {
                colorRequiredControl(this.control,isRequired);
            }
        }

    }
    
    function getMandatory() {
        return this.isMandatory;
    }
    
	/**
	 * Validates against a regular expression pattern.
	 * If control's value is blank or regularExpressionPattern is blank it returns true (valid)
	 * The test is done only if the control has value in both  regularExpressionPattern and oValue()
	 */
	function validateRegularExpressionPattern(){ 
		if(!this.regularExpressionPattern)return true;
		if(!this.oValue())return true;
		//var modifiers='i';
		//var patt=new RegExp(this.regularExpressionPattern, modifiers);
		//return patt.test(this.oValue());
		
		var r = new RegExp(this.regularExpressionPattern);
		var match = this.oValue().match(r);
		var ret = (match != null && this.oValue() == match[0]);
        
		return ret;
	}
	
    this.ctype = 100; 
    this.control=null; // this is a reference to the control object, obtained during validation.
    this.contents='';  // the content of the control.  Automatically set via  this.control.value
    this.formname='';  // the formname that this control belongs to.  Since there coule be multiple forms on a page
                       // we pass this so we can validate each for individually 
    this.name = '';            // name of control
    this.label='';             // label of control
    this.isNumber=isNumber;       // if the control is a number
    this.isMandatory = false;  // if it is required
    this.isLov = false;         //if this is a lov field
    this.isvalid = isvalid;
	this.isvalid2 = isvalid2;
    this.precision = 0;
    this.scale = 0;
	this.maxLen = 0;
	
	this.postbackdone=false;// used in ajax autopostback
	this.ajaxPostbackHandler = null;// used in ajax autopostback must be a reference to a function
	this.checkNumber = checkNumber;
	this.isEmpty=isEmpty;
    this.checkScale = checkScale;
    this.loadValueFromHtml = loadValueFromHtml;
    this.oValue = oValue; // value of control as per data type.  IE, if date control, the date object, if text, the text in the field, etc
	this.setValue = setValue;
	this.setMandatory = setMandatory;
    this.getMandatory = getMandatory;
	this.regularExpressionPattern = '';
	this.validateRegularExpressionPattern = validateRegularExpressionPattern;
    this.forceUpperCase = false;
	this.checkForEmpty = true;
    this.globalLovKey = ''; // added 3/6/2014, ti support global keys of lov secure controls, which store their datasource in the servletContext
	this.includeInDirtyCheck = true;
	// whether this field will be included in the 'dirty' check. See jroAttributesChanged
	
	this.includeInClearForm = true;
	// whether this field will be omitted in the 'clearFormFields' function. See clearFormFields
	
    this.setForceUpperCase = function(val /* boolean */) {
        this.forceUpperCase = val;
        if(val) {
            assignUpperCaseBlurToControl(this.control);
        }
    };
	
	this.setNoError = setNoError;
	this.setInError = setInError;
	this.jroValErrors = [];
  
}

function setAttrMandatory(sFieldname, isMandatory) {
    getJroAttr(sFieldname).setMandatory(isMandatory);
}

function requireFieldIf(sFieldName, bCondition) {
    setAttrMandatory(sFieldName, bCondition);
    
}
function checkDateIsInThePast(dt1) {
    
    var ret = checkDate1IsAfterDate2('<today>',dt1, 1);
    if (ret == false) {
        alert(showError2(11, getJroAttrlabel(dt1)));
    }
    return ret;
    
}

function checkDateIsInTheFuture(dt1) {
    var ret = checkDate1IsAfterDate2(dt1, '<today>',1);
    if (ret == false) {
        alert( showError2(6, getJroAttrlabel(dt1)));
    }
    return ret;
}

function jsCompareDates(dt1,dt2) {

    var dtFrom; 
    var dtTo; 
    var dtToval;
    var ret = true;
    
    if (dt1 == '<today>') {
        dtFrom=tdy;
        dtFromval = getTodaysDate();
    } else {
        dtFromval = getJroAttr(dt1).contents;
        if (dtFromval==''){return true;}
        dtFrom=getDateObject(dtFromval).getTime();
    }
    
    if (dt2 == '<today>') {
        dtTo=tdy;
        dtToval = getTodaysDate();
    } else {
        dtToval = getJroAttr(dt2).contents;
        if (dtToval==''){return true;}
        dtTo=getDateObject(dtToval).getTime();
    }
    
    if (dtFrom > dtTo) {
        ret = 1;
    }

    if (dtFrom < dtTo) {
        ret = -1;
    }

    if (dtFrom == dtTo) {
        ret = 0;
    }
    
    return ret;
}




function checkJroDateIsBetween(dt1,dtFrom,dtTo, showMsg) {

	var ret = true;
	var odt1 = getJroAttr(dt1).oValue();
	var odtFrom = getJroAttr(dtFrom).oValue();
	var odtTo = getJroAttr(dtTo).oValue();
	
	//alert('dt1:'+odt1 ) // + getJroAttr(dtTo).value);
	
	if (odt1 && odtFrom && odtTo) {
		
		ret = checkDateIsBetween(odt1 ,odtFrom, odtTo);
		if (ret==false && showMsg ){
            alert(showError2(23, getJroAttrlabel(dt1),getJroAttr(dtFrom).contents, getJroAttr(dtTo).contents));
        }
	}
	return ret;
}

function checkDateIsBetween(dt1,dtFrom,dtTo) {
	//alert(dt1 + ' ' + dtFrom + ' ' + dtTo);
	if (dt1 >= dtFrom && dt1 <= dtTo) {
		return true;
	} else {
		return false;
	}
}

function checkDate1IsAfterDate2(dt1,dt2, skipMsg) {

    var dtFrom; 
    var dtFromVal;
    var dtTo; 
    var dtToval;
    var ret = true;
    var errcode = 13;
    
    if (dt1 == '<today>') {
        dtFrom=tdy;
        dtFromval = getTodaysDate();
    } else {
        dtFromval = getJroAttr(dt1).control.value;
        if (dtFromval==''){return true;}
        dtFrom=getDateObject(dtFromval).getTime();
    }
    
    if (dt2 == '<today>') {
        dtTo=tdy;
        dtToval = getTodaysDate();
    } else {
        dtToval = getJroAttr(dt2).control.value; // do not call "contents"
        if (dtToval==''){return true;}
        dtTo=getDateObject(dtToval).getTime();
    }
    
    if (dtFrom >= dtTo) {
        // good. it is after
    } else {
        if (skipMsg == null){
            alert(showError2(errcode, getJroAttrlabel(dt1),getJroAttrlabel(dt2), dtToval ));
        }
        ret = false;
    }
    return ret;
}

function checkDateTime1IsAfterDateTime2(dt1, dt2, skipMsg) {

    var dtFrom; 
    var dtFromVal;
    var dtTo; 
    var dtToval;
    var ret = true;
    var errcode = 13;
    
    if (dt1 == '<today>') {
        dtFrom=tdy;
        dtFromval = getTodaysDate();
    } else {
        dtFromval = getJroAttr(dt1).contents;
        if (dtFromval==''){return true;}
        dtFrom=getDateTimeObject(dtFromval).getTime();
    }
    
    if (dt2 == '<today>') {
        dtTo=tdy;
        dtToval = getTodaysDate();
    } else {
        dtToval = getJroAttr(dt2).contents;
        if (dtToval==''){return true;}
        dtTo=getDateTimeObject(dtToval).getTime();
    }
    
    if (dtFrom >= dtTo) {
        // good. it is after
    } else {
        if (skipMsg == null){
            alert(showError2(errcode, getJroAttrlabel(dt1),getJroAttrlabel(dt2), dtToval ));
        }
        ret = false;
    }
    return ret;
}

function checkDateInFuture(dtValFieldName) {

    //pass a date value. the function will parse it and make an object out of it.
    var fval = getJroAttr(dtValFieldName).contents;
    var ret = true;
    
    if (fval == '' || fval == null) {
    
        var odtVal = getDateObject(fval).getTime();

        if (odtVal>tdy ){ //date should be AFTER today
            //we're good
        } else {
            alert(showError2(6, getJroAttrlabel(dtValFieldName)));
            getJroAttr(dtValFieldName).control.focus();
            ret=false;   
        }
    }
    return ret;
}

function checkDateInPast(dtValFieldName) {

    //pass a date value. the function will parse it and make an object out of it.
    var fval = getJroAttr(dtValFieldName).contents;
    var ret = true;
    
    if (fval == '' || fval == null) {
    } else {
    
        var odtVal = getDateObject(fval).getTime();
    
        if ( odtVal < tdy ){ //date should be BEFORE today
        } else {
            alert(showError2(11, getJroAttrlabel(dtValFieldName)));
            getJroAttr(dtValFieldName).control.focus();
            ret=false;
        
        }
    }
    
    return ret;
}

function checkDateInPastOrToday(dtValFieldName) {

    //pass a date value. the function will parse it and make an object out of it.
    var fval = getJroAttr(dtValFieldName).contents;
    var ret = true;
    
    if (fval == '' || fval == null) {
    } else {
        var odtVal = getDateObject(fval).getTime();
        if (odtVal <= tdy ){ 
            //we're good
        } else {
            alert(showError2(12, getJroAttrlabel(dtValFieldName)));
            getJroAttr(dtValFieldName).control.focus();
            ret=false;   
        }
    }
    return ret;

}

function checkDateInFutureOrToday(dtValFieldName) {

    //pass a date value. the function will parse it and make an object out of it.
    
    var fval = getJroAttr(dtValFieldName).contents;
    var ret = true;
    var odtVal = getDateObject(fval).getTime();
    
    if (odtVal >= tdy ){ //date should be AFTER OR today
        //we're good
    } else {
        alert(showError2(7, getJroAttrlabel(dtValFieldName)));
        getJroAttr(dtValFieldName).control.focus();
        ret=false;   
    }
    return ret;

}
/** 
* creates a new jroAttribute object with 'newName' and copies over attributes from existing jro attribute 'name'
*/
function copyJroAttribute(name,newName) {
	
	var existing = $f(name);
	return addJroAttribute(newName, existing.isMandatory, 
                                    existing.label, 
                                    existing.ctype, 
                                    existing.maxLen, 
                                    existing.minValue, 
                                    existing.maxValue, 
                                    existing.precision,
                                    existing.scale,
                                    existing.forceUpperCase);
	
}

function assignUpperCaseBlurEventToJroAttrs() {

   for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        var c = ja.control;
		if (c.type=='text' || c.type=='textarea') {
    		AddEvent(c,'onblur', function(ev){upperCaseField(ev?ev:event)} );
			//AddEvent(jAtt.control,'onblur', function(ev){dateBlur(ev?ev:event)});
        }
    }
}

/** 
* removes a jroAttribute object with 'name' 
*/
function removeJroAttribute(name) {
	var newjroAttributes = new Array();
	
	for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        if (ja.name!=name) {
			newjroAttributes[newjroAttributes.length] = ja;
        }
    }
	jroAttributes= newjroAttributes;
    return;
	
}

function addJroAttribute(name,isMandatory,label,ctype,maxlen,minVal,maxVal,prec,scale, forceUpperCase) {

    var jAtt;
	
    jAtt = new jroAttribute();
    
	if (isMandatory===-1) {
      isMandatory = true; // this is in case we use this in Microsoft applications, where -1 equals to true
    }
    if (isMandatory===0) {
      isMandatory = false;
    }
    
    jAtt.isMandatory=isMandatory;
    jAtt.name=name;
    jAtt.label=label;
    jAtt.maxLen=maxlen;	
	
    if (minVal) {
		jAtt.minValue = minVal;
    }
    
    if (maxVal && maxVal !== 0) {
		jAtt.maxValue = maxVal;
    }
    //alert(jAtt.minValue+' ' +jAtt.maxValue);
    if (ctype !== null) {
		jAtt.ctype = ctype;
	} else {
		jAtt.ctype = CTLTYPE_DEFAULT;
	}
    
    if (document.getElementById(jAtt.name)) {
		jAtt.control = document.getElementById(jAtt.name);
		//alert(jAtt.control.type);
	} else {
		alert('addJroAttribute: document.getElementById(\''+jAtt.name+'\') failed!');
		return null;
	}
    
	if (jAtt.control.type==='select-one') {
		jAtt.ctype = CTLTYPE_COMBO;
		//alert('jAtt.ctype = CTLTYPE_COMBO');
	}
	
	if (ctype === CTLTYPE_DATE) {
        
		$j('#'+jAtt.name).blur( dateBlur    );
        $j('#'+jAtt.name).keydown( dateKeyDown    );

        if (minVal) {
			
			if( Object.prototype.toString.call(minVal) === '[object Date]' ) {
				jAtt.minValue = minVal;
			} else {
				jAtt.minValue = minVal.parseDateTime();
			}
        } else {
            jAtt.minValue = '1/1/1800'.parseDate();
        }
        if (maxVal) {
			if( Object.prototype.toString.call(maxVal) === '[object Date]' ) {
				jAtt.maxValue = maxVal;
			} else {
				jAtt.maxValue = maxVal.parseDateTime();
			}	
        } else {
            jAtt.maxValue = '1/1/3000'.parseDate();
        }

    } else if (ctype === CTLTYPE_DATETIME) {
		
		$j('#'+jAtt.name).blur( dateTimeBlur    );
        $j('#'+jAtt.name).keydown( dateTimeKeyDown    );
	
        if (minVal && minVal.isDate()) {
            jAtt.minValue = minVal.parseDateTime();
        } else {
            jAtt.minValue = '1/1/1800'.parseDate();
        }
        if (maxVal && maxVal.isDate()) {
            jAtt.maxValue = maxVal.parseDateTime();
        } else {
            jAtt.maxValue = '1/1/3000'.parseDate();
        }

    } else if (ctype === CTLTYPE_TIME) {
		$j('#'+jAtt.name).blur( timeBlur    );
        $j('#'+jAtt.name).keydown( timeKeyDown    );
	
	
        if (minVal && minVal.isTime()) {
            jAtt.minValue = minVal.parseTime();
        } else {
            jAtt.minValue = '00:00'.parseTime();
        }
        if (maxVal && maxVal.isTime()) {
            jAtt.maxValue = maxVal.parseTime();
        } else {
            jAtt.maxValue = '23:59'.parseTime();
        }

    } else if (jAtt.isNumber()) {

        // the framework always passes the min val as a string, with a dot decimal separator, so we can just call parseFloat
        //do not call parseNumber() of the string prototype, since that will parse the number 
        // taking into account the system configuration decimal symbol, shich may or may not be a dot
        if (minVal) {
            jAtt.minValue = parseFloat(minVal);
        } else {
            jAtt.minValue =  - 100000000000;
        }
        if (maxVal) {
            jAtt.maxValue = parseFloat(maxVal);
        } else {
            jAtt.maxValue = 100000000000;
        }

        jAtt.control.onkeydown = function (ev) {
            numKeyDown(ev ? ev : event);
        };
    }
    
    
    if (prec !== null) {
    	jAtt.precision = prec;
    }
    if (scale!==null) {
    	jAtt.scale = scale;
    }
	
	jAtt.loadValueFromHtml();
	
	if (isMandatory === false) { 
		for (var i=0; i<jroAttributes.length; i++) {
			var oldJAtt = jroAttributes[i]; 
			if (oldJAtt.name === jAtt.name) { 
				if (oldJAtt.isMandatory === true) { 
					jroAttributes.splice(i, 1); 
				}
			}
		}
	}
	
    nuf.formOriginalValues = nuf.formOriginalValues + jAtt.contents;
	jAtt.setMandatory(isMandatory);
    jAtt.setForceUpperCase(forceUpperCase);
    jroAttributes[jroAttributes.length] = jAtt;
    return jAtt;
}

// convinience, shortcut function for getting a jro atttribute
function $f(sFieldname) {
	return getSafeJroAttr(sFieldname);
}

function getSafeJroAttr(sFieldname) {
    
    for (var i=0; i<jroAttributes.length; i++) {
    
        var ja = jroAttributes[i];
        if (ja.name==sFieldname) {
            return ja;
        }
    }

    return null;
}

function setFirstFocus() {
	
	if (! __bFocusFirst)return;
	
	for (var i=0; i<jroAttributes.length; i++) {
    
        var ja = jroAttributes[i];
		
		try {    
			//alert('set first:'+ja.control);
			ja.control.focus();
			return;
			
		} catch (e) {
			//don;t care about errors...
		}    
    }
	
	
}

function $fe(sFieldname) {
	return getJroAttr(sFieldname);
}
function getJroAttr(sFieldname) {
    
    var jo = getSafeJroAttr(sFieldname);
    
    if (jo==null) {
        alert('formValidation Library Error: Attribute ' +  sFieldname + ' does not exist.  Call getAttrSafe() if you do not want this error to appear.');   
        return null;
    } else {
        jo.loadValueFromHtml();
        return jo;
    }
    
}

function setJroAttrValue(sFieldname,val) {

    var ja = getJroAttr(sFieldname);
    ja.value = val;
    ja.control.value = val;
    return;
}

function getJroAttrValue(sFieldname) {
    
    var ja = getJroAttr(sFieldname);
    return ja.contents;

}

function getJroAttrlabel(sFieldname) {
    
    for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        if (ja.name==sFieldname) {
            return ja.label;
        }
    }
    return '';
}

function loadJroAttributes() {
    // loads jro attributes from data on the html form but does not do any validation
    // must be called before valiation.

    for (var i=0; i<jroAttributes.length; i++) {

        var ja = jroAttributes[i];
        ja.control = document.getElementById(ja.name); 
        ja.contents=ja.control.value;
    }
    
    return true;
    
}

function loadJroAttributeValues() {

    for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        ja.control = document.getElementById(ja.name); 
        ja.contents=ja.control.value;
    }
    return;
}

function jroAttributesChanged(){
	// return false if nuf.checkForChangedValues is false, ie we do not care about changed values
	if(!nuf.checkForChangedValues)return false;
	
	nuf.valuesnow = '';
	for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
		if(ja.includeInDirtyCheck) {
			ja.loadValueFromHtml();
			nuf.valuesnow = nuf.valuesnow + ja.contents;
		}
        //alert(ja.name);
    }
	
	return (nuf.valuesnow != nuf.formOriginalValues);		
}
/**
 * Resets the nuf.formOriginalValues variable which holds all
 * data on page to compare if values have changed.
**/
function jroAttributesResetChangedFlag(){

	nuf.valuesnow = '';
	for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
		if(ja.includeInDirtyCheck) {
			ja.loadValueFromHtml();
			nuf.valuesnow = nuf.valuesnow + ja.contents;
		}
    }
	
	var tmp = $$('__hdFormIsDirty');
	if(tmp) {
		for (i = 0; i < tmp.length; i++)  {
			tmp[i].value='';
		}
	}
	
	tmp = $$('__gridIsDirty');
	if(tmp) {
		for (i = 0; i < tmp.length; i++)  {
			tmp[i].value='';
		}
	}
	nuf.formOriginalValues = nuf.valuesnow;
		
}

/**
* Modified validateJroAttributes to validate an array of Jro Attributes, instead 
* of the fixed jroAttributes array
* 
*/
function validateJroAttrsArray(jroArray /* Array of jroAttribute objects */) {
	
	if(!jroArray)jroArray=jroAttributes;
	
	__arrEmptyMandatoryFields = new Array();
	
	 for (var i=0; i<jroArray.length; i++) {
        var ja = jroArray[i];
        ja.loadValueFromHtml();
		ja.isvalid();   
    }
	
	if(__arrEmptyMandatoryFields.length > 1) {
		nuf.jroValErrors.push( showError2(34, __arrEmptyMandatoryFields.join(", ")) );
		
	} else if(__arrEmptyMandatoryFields.length == 1) {
		nuf.jroValErrors.push(  showError2(35, __arrEmptyMandatoryFields[0]));
	}
	
	logMessage('values changed:' + jroAttributesChanged());
	return (nuf.jroValErrors.length === 0);
    
}


function showJroValidationErrors() {
	
	if ( (nuf.jroValErrors.length > 0)) {
        alert( "<ul><li>"+ nuf.jroValErrors.join("<li>") + "</ul>");
		
    }
}

function focusErrorControl() {
	if (focusCtrl && focusCtrl.type!=='hidden') {
		try {
			focusCtrl.focus();
		} catch (e) {
			// just ignore the error 
		}
	}
}
function validateJroAttributes() {
        
	//logMessage('nuf.formOriginalValues: *' + nuf.formOriginalValues + "*") ;	
	nuf.jroValErrors = [];
    focusCtrl = null;

	if (validateJroAttrsArray(jroAttributes)) {
		return true;
	} else {
		return false;
	}

}

function __formIsDirty() {
	if(nuf.formIsQuerymode)return false; // if form is in query mode we do not check!!
	var tmp = jroAttributesChanged();
	if(tmp){
		logMessage('DEBUG MESSAGE:in __formIsDirty: Form data in controls have changed' );
		return true;
	}
	
	tmp = $$('__hdFormIsDirty');
	if(tmp) {
		for (var i = 0; i < tmp.length; i++)  {
			if(tmp[i].value=='true'){
				logMessage('DEBUG MESSAGE:in __formIsDirty: DataObject is dirty' );
				return true;
			}
		}
	}
	
	tmp = $$('__gridIsDirty');
	if(tmp) {
		for ( i = 0; i < tmp.length; i++)  {
			if(tmp[i].value=='true') {
				logMessage('DEBUG MESSAGE:in __formIsDirty: Grid is dirty' );
				return true;
			}

		}
	}
	return false;
}


function isNumeric(sText){
	
	return sText.toString().isNumeric();

}


	function isEmptyPickList(t) {
	
		var isempty = true;
	
		for (var i=0; i<t.length; i++) {
			if (t.options[i].selected) {
			//alert('found selected with value:**' + t.options[i].value+'*');
				if (  t.options[i].value == '') {
				  // if found the @please select@ item, do not 
				  // consider it as selected
				} else {
					isempty = false;
					break;
				}
			}
		}
		return isempty;
	}
	
	function getRadioSelValue(ctrl) {
        var ret = "";
        for (var i=0; i<ctrl.length; i++) {
            found = ctrl[i].checked;
            if (found == true) {
                ret = ctrl[i].value;
                break;
            }
        }
        
        return ret;
    }
            
    function getRadioSelValue1(cname, fname) {
        var ctrl = eval("document." + fname+ "." + cname);
        var found = false;
        var ret = '';      
        for (var i=0; i<ctrl.length; i++) {
            found = ctrl[i].checked;
            if (found == true) {
                ret = ctrl[i].value;
                break;
            }
        }
        return ret;
    }
    
	
function setRadioListValue(ctrl, val) {

	//alert(cname+'-'+ctrl+':ctrl.length: '+ctrl.length);
  
  // clear all first
  for (var i=0; i<ctrl.length; i++) {
	    ctrl[i].checked = false;
	}
  
  // loop and check the appropriate radio button
	for (var i=0; i<ctrl.length; i++) {
	    if(ctrl[i].value==val){
        ctrl[i].checked = true;
        return true;
        
	    }
	}
  return false;
	
}

function isEmptyRadioList(cname) {

	var isempty = true;
	var ctrl = document.getElementsByName(cname); //eval("document." + fname+ "." + cname);
  //alert(cname+'-'+ctrl+':ctrl.length: '+ctrl.length);
	for (var i=0; i<ctrl.length; i++) {
	    if(ctrl[i].checked){
        isempty = false;
        //alert('checked '+i);
        break;
	    }
	}

	return isempty;
}

function getTimeObject(tm) {

	return tm.toString().parseTime();
}

function getDateObject(dte) {
	return dte.toString().parseDate();
}

function getDateTimeObject(dte) {
	return dte.toString().parseDateTime();
}


function getTodaysDate() {
	//returns today's date as a string
	//useful when comparing dates w/o the time component.
	return new Date().formatDate();
	
}

function getTodaysDateObj() {

	//returns today's date as a Date object
	//useful when comparing dates w/o the time component.
	var dt=new Date().trunc();
	
}


function compareDates(dt1,dt2) {

dt1 = getDateObject(dt1).getTime();
dt2 = getDateObject(dt2).getTime();
if (dt1>dt2)return 1;
if (dt1==dt2)return 0;
if (dt1<dt2)return -1;

}

function checkDatesInPeriod(vPeriodsArr, dtFrom, dtTo ) {

var newperiod = "[" + dtFrom + "] - [" + dtTo + "]"; 
var ret = false;
var exPeriods = '';
for (var i=0; i<vPeriodsArr.length; i++) {

    var pDates = vPeriodsArr[i];
    //alert(pDates);
    var dtPerFrom = pDates.dateFrom;
    var dtPerTo = pDates.dateTo;
    exPeriods = exPeriods + "[" + pDates.dateFrom + "] - [" + pDates.dateTo + "]\n";

    if (
	(compareDates(dtFrom,dtPerFrom) >=0 && compareDates(dtFrom,dtPerTo) <=0) && 
	(compareDates(dtTo, dtPerFrom) >=0 && compareDates(dtTo, dtPerTo) <=0) && 
	(compareDates(dtTo, dtFrom) >0 ) 
	) {

	ret = true;
	break;
     }
}

if (ret == false) {
    alert(showError2(15, newperiod,exPeriods ));
}

return ret;

}

function checkOverlappingPeriods(vPeriodsArr, dtFrom, dtTo , recPk) {
	var newperiod = dtFrom + " - " + dtTo;    
	
	for (var i=0; i<vPeriodsArr.length; i++) {
	
		var pDates = vPeriodsArr[i];
		
		if (pDates.id==recPk) {
			//alert('skip record ' + pDates.dateFrom + " - " + pDates.dateTo);
			continue;
		}
		
		//alert(pDates);
		var dtPerFrom = pDates.dateFrom;
		var dtPerTo = pDates.dateTo;
		var experiod = pDates.dateFrom + " - " + pDates.dateTo;
	
		if (compareDates(dtFrom,dtPerFrom) >=0 && compareDates(dtFrom,dtPerTo) <=0) {
		// checks that the date from inserted is within a pre entered period
		alert(showError2(14,newperiod,experiod  ));
		return false;
		 }
	
		if  (compareDates(dtTo, dtPerFrom) >=0 && compareDates(dtTo, dtPerTo) <=0) {
		// checks that the date to inserted is within a pre entered period
		alert(showError2(14, newperiod,experiod ));
		return false;
    }
}

return true;
}



function YearAdd(startDate, numYears) {
	return startDate.add('year', numYears);
}

function MonthAdd(startDate, numMonths) {
	return startDate.add('month', numMonths);
}

function DayAdd(startDate, numDays) {
	return startDate.add('day', numDays);
}

function isValidTime(str) {
	return /^([01]?[0-9]|[2][0-3])(:[0-5][0-9])?$/.test(str) ;
}
  
function showError2(ind) {
	var error_msg;
	if (__lang == "EL"){
		error_msg = msg_EL2[ind];
	}
	if (__lang == "EN") {
		error_msg = msg_EN2[ind];
	}
	return error_msg;
}


function showError2(ind, fieldname){
	var error_msg;
	if (__lang == "EL") {
		error_msg = msg_EL2[ind].replace("%1", fieldname);
	}
	if (__lang == "EN") {
		error_msg = msg_EN2[ind].replace("%1", fieldname);
	}

	return error_msg;
}

function showError2(ind, fieldname1, fieldname2){
	var error_msg;
	if (__lang == "EL"){
		error_msg = msg_EL2[ind].replace("%1", fieldname1);
	}
	if (__lang == "EN"){
		error_msg = msg_EN2[ind].replace("%1", fieldname1);
	}
	error_msg = error_msg.replace("%2", fieldname2)
	return error_msg;
}

function showError2(ind, fieldname1, fieldname2, fieldname3){
	var error_msg;
	if (__lang == "EL"){
		error_msg = msg_EL2[ind].replace("%1", fieldname1);
	}
	if (__lang == "EN") {
		error_msg = msg_EN2[ind].replace("%1", fieldname1);
	}
	error_msg = error_msg.replace("%2", fieldname2);
	error_msg = error_msg.replace("%3", fieldname3);
	return error_msg;
}

function __SaveEntry(postBackParam, pastBackArgs) {
        
	var bValid = jroValidateForm();
	
	if (bValid==true ) {
		__doPostBack(postBackParam, pastBackArgs);
    }
    
}
        
function jroValidateForm(bSetFocusOnError /* boolean */) {
    
    var bValid = false;
	try {  
		
		if( nuf.checkEmpty && ( ! atLeastOneControlHasData())) {
			alert(showError2(32)); 
			return false;
		}
		
		disableSubmit();
		
		var bPrepared = true;
		
		// function to enable "preparation" of validation
		if (typeof(__page__validate_prepare)==='function') {
			bPrepared = __page__validate_prepare();
		}
		
		if (!bPrepared)return false;
		
		bValid = validateJroAttributes();
		
		if (bValid===true ) {
			for(var i=0;i<validationFunctions.length;i++) {
				 if (typeof(validationFunctions[i])==='function') {
					bValid = bValid && validationFunctions[i]();
				 }
			}	  
		}
		
		if (bValid===true ) {
		  if (typeof(__page__validate)==='function') {
			//allow custom page validation if function __page__validate is defined
			var tmp = __page__validate();
            
            // block below added 10/4/2014 to protect against cases where a programmer forgets to return a value 
            // in __page__validate. If this happens, the return value was undefined and this caused the 
            // code at line 1500 to have unexpected behavior
            if(tmp===true || tmp===false) {
                bValid = tmp; 
            } else {
                bValid = true;
            }
            
		  }
		}
		
		
	} catch (e) {
		alert('Error validating form:' + e.description + '\n' + e.stack );
		console.log(e.stack);
		return false;
	}

    // if form is not valid, we enable back the submit button
	//else we let it go
	if(!bValid){
		showJroValidationErrors(); // moved to bottom 18/3/2020, we now have asynchronous messages so we need to show this in the end
		if(bSetFocusOnError){
			focusErrorControl();
		}
		enableSubmit();
	}
	
	return bValid;
	
}



function Trim(String) {

	if (String == null || String=='') {
		return '';
	} else {
		return String.replace(/(^\s+)|(\s+$)/g,"");
	}
}

function dateTimeBlur(e) {
	
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	
	if (ctl.value) {
		var dt = ctl.value.parseDateTime();
		if (dt) {
			ctl.value = dt.formatDateTime();
		}
	}
	
    return;
}

function dateBlur(e) {
	
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	if (ctl.value) {
		var dt = ctl.value.parseDate();
	
		if (dt) {
			
			ctl.value = dt.formatDate();
		}
		
	}
	
    return;
}

function __yearKeyDown(ctrlid, e) {
    	
	var ctl = document.getElementById(ctrlid);
	e = e?e:window.event;
	
	var curYear;
	if (isNumeric(ctl.value)) {
        curYear = ctl.value;
    } else {
		curYear = new Date().getFullYear();
    }
	
	if (e.keyCode==107 || e.keyCode==187) {
		//+ sign: go forward one year
        ctl.value = Math.abs(curYear)+1;
        cancelEvent(e);
		
    } else if ( e.keyCode == 84)  {
        // "t", "T" ->> goto today's date year"
        ctl.value = new Date().getFullYear();
        cancelEvent(e);
		
    } else if (e.keyCode==109 || e.keyCode==189) {
		// - sign, go back one year
        ctl.value = curYear-1;        
		cancelEvent(e);
   }
  	
}

function nextYear(ctrlid) {
	var ctl = document.getElementById(ctrlid);
	var curYear;
	if (isNumeric(ctl.value)) {
        curYear = ctl.value;
    } else {
		curYear = new Date().getFullYear();
    }
	ctl.value = Math.abs(curYear)+1;
	__doPostBack(ctrlid, '');
}

function prevYear(ctrlid) {
	var ctl = document.getElementById(ctrlid);
	var curYear;
	if (isNumeric(ctl.value)) {
        curYear = ctl.value;
    } else {
		curYear = new Date().getFullYear();
    }
	ctl.value = Math.abs(curYear)-1;
	__doPostBack(ctrlid, '');
}


function __monthKeyDown(ctrlid, e) {
    	
	var ctl = document.getElementById(ctrlid);
	e = e?e:event;
	
	var curMonth;
	if (isNumeric(ctl.value)) {
        curMonth = ctl.value;
    } else {
		curMonth = new Date().getMonth();
    }
	
	if (e.keyCode==107 || e.keyCode==187) {
		//+ sign: go forward one month
        if ( curMonth < 12 ) {
			ctl.value = curMonth+1;
		}
        cancelEvent(e);
		
    } else if ( e.keyCode == 84)  {
        // "t", "T" ->> goto today's date month"
        ctl.value = new Date().getMonth();
        cancelEvent(e);
		
    } else if (e.keyCode==109 || e.keyCode==189) {
		// - sign, go back one month
        if ( curMonth > 1 ) {
			ctl.value = curMonth-1;        
		}
		cancelEvent(e);
   }
  	
}

function dateTimeKeyDown(e) {
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	
    if (e.keyCode==107 || e.keyCode==187) {
		//+ sign: go forward one day
     	var dt = ctl.value.parseDateTime();
        if (dt == null) {
            dt = new Date();
        }        
        ctl.value = dt.add('day', 1).formatDateTime();
        cancelEvent(e);
		
    } else if ( e.keyCode == 84)  {
        // "t", "T" ->> goto today's date"
        ctl.value = new Date().formatDateTime();
        cancelEvent(e);
		
    } else if (e.keyCode==113 ) {
		// f2 key, bring up the calendar
		setDate(ctl.name)		
		
    } else if (e.keyCode==109 || e.keyCode==189) {
		// - sign, go back one day
        var dt = ctl.value.parseDateTime();
		
		// in case of - as separator, only do this if contents of field are dd-mm-yyyy (ie 10 characters long)
		if (nuf.dateSep=='-' && ctl.value.length!=10){
			return;
		}
		
        if (dt == null ) {
			if (nuf.dateSep!='-') {
				dt = new Date();
			} else {
				return false;
			}
		}
        
		ctl.value = dt.add('day', -1).formatDateTime();
        cancelEvent(e);
		
   } else {
	
   }
}
function cancelEvent(e) {
	if (isMSIE){
		e.keyCode =0;
	} else {
		e.stopPropagation();
		e.preventDefault();
	}
	e.returnValue = false;
}

function dateKeyDown(e) {
    	
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	if(isCtrlCOrV(e))return;
    
	//alert('dateKeyDown');
	//alert(e.keyCode);
    if (e.keyCode==107 || e.keyCode==187) {
		//+ sign: go forward one day
		
     	var dt = ctl.value.parseDateTime();
        if (dt == null) {
            dt = new Date();
        }        
        
		ctl.value = dt.add('day', 1).formatDate();
        cancelEvent(e);
		
    } else if ( e.keyCode == 84)  {
        // "t", "T" ->> goto today's date"
        ctl.value = new Date().formatDate();
        cancelEvent(e);
				    	
    } else if (e.keyCode==113 ) {
		// f2 key, bring up the calendar
		eval(ctl.id + '_setDate()');
		
    } else if (e.keyCode==109 || e.keyCode==189) {
		// - sign, go back one day
        
		var dt = ctl.value.parseDateTime();
				
		// in case of - as separator, only do this if contents of field are dd-mm-yyyy (ie 10 characters long)
		if (nuf.dateSep=='-' && ctl.value.length!=10)return;
				
        if (dt == null ) {
			if (nuf.dateSep!='-') {
				dt = new Date();
			} else {
				return;
			}
		}      
        
		ctl.value = dt.add('day', -1).formatDate();
        cancelEvent(e);
	
	} else if (e.keyCode>=65 && e.keyCode<=90) {
		//letters! cancel the key down
		cancelEvent(e);
	
	} else {
		//e.returnValue = false; 
	}
   
  	
}

function timeKeyDown(e) {

	var ctl;
	
	e = e?e:event;
	//alert('timeKeyDown e:'+e);
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	if(isCtrlCOrV(e))return;
	if (e.keyCode==110 || e.keyCode==78) {
		ctl.value = new Date().formatTime();
        cancelEvent(e);
	
	} else if (e.keyCode==109 || e.keyCode==189) {
		// - sign, go back one hour
		var dt = ctl.value.parseTime();
        if (dt == null) {
        	dt = new Date();
        }
        
        var tmp = dt.addMinutes( -60);
		ctl.value = tmp.formatTime();
		cancelEvent(e);
        
	} else if (e.keyCode==107 || e.keyCode==187) {
		var dt = ctl.value.parseTime();
        if (dt == null) {
        	dt = new Date();
        }
        
		//+ sign: go forward one hour
        var tmp = dt.addMinutes( 60);
		ctl.value = tmp.formatTime() ;
		cancelEvent(e);
	
	} else if (e.keyCode>=65 && e.keyCode<=90) {
		//letters! cancel the key down
		cancelEvent(e);
	}
	
	return;       
}

function timeBlur(e) {
    
    var ctl;
	e = e?e:event;
	//alert('timeBlur e:'+e);
	
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	
    if (ctl) {
        var dt = ctl.value.parseTime();
        if (dt == null) {
        } else {
            if (getSafeJroAttr(ctl.name)) {
                getSafeJroAttr(ctl.name).dateObject = dt;
            }
            ctl.value = dt.formatTime();
        }
    }
    return;
}

function numKeyDown(e){
	
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	if (!ctl)return;
	
	if(isCtrlCOrV(e))return;
	var isshift = e.shiftKey;
	
   	if (e.keyCode===109 || e.keyCode===189) {
		//minus sign, allow it unless the number must be positive;
		var jatt = getSafeJroAttr(ctl.name);
		if (jatt && jatt.minValue > 0	) {
				cancelEvent(e);
		}
	} else if (e.keyCode===110 || e.keyCode===190 || e.keyCode===188) {
		// telia or comma! Disable if precision = 0, ie IntBox
		var jatt = getSafeJroAttr(ctl.name);
		if (jatt) {
			//alert(jatt.label + ' ' + jatt.scale);
			if (jatt.scale == 0	) {
				cancelEvent(e);
			}
		}
		
	} else if (e.keyCode === 16) {
		// let this one go
	} else if ( ( isshift && ( e.keyCode >= 48 && e.keyCode <= 60 )) ||
				e.keyCode === 222||e.keyCode === 221||e.keyCode === 106||
				e.keyCode === 220||e.keyCode === 219||e.keyCode === 32||
				e.keyCode === 186||e.keyCode === 191||e.keyCode === 107||
				e.keyCode === 187||e.keyCode === 189) {
			
		cancelEvent(e);
		
	} else if (e.keyCode>=65 && e.keyCode<=90) {
		//letters! cancel the key down
		cancelEvent(e);
	
	} else {
		//let all else go
		//alert(e.keyCode);
    }
    
}

function numericOnly(e) {
var iKeyCode;
if (!e) {
	var e = window.event;
}
if (e.keyCode) {
	iKeyCode = e.keyCode;
} else {
	if (e.which) {
		iKeyCode = e.which;
	}
}

switch(iKeyCode) {
	case 8:
	case 9:
	case 37:
	case 38:
	case 39:
	case 40:
	case 46:
		break;
	case 48:
	case 49:
	case 50:
	case 51:
	case 52:
	case 53:
	case 54:
	case 55:
	case 56:
	case 57:
		if (e.shiftKey || e.altKey){
			return false;
		}
		break;
	case 96:
	case 97:
	case 98:
	case 99:
	case 100:
	case 101:
	case 102:
	case 103:
	case 104:
	case 105:
		//return correct numeric from keypad
		return iKeyCode - 48; break;
	case 110:
	case 190:
		//if you are supporting decimal points
		return '.'; 
		break;
	default: 
		return false;
	}
}

function numBlur(e) {
	var ctl;
	e = e?e:event;
	ctl =(e.target)? e.target : e.srcElement; //e.srcElement;
	
	dt = eval(ctl.value);
    if (dt == null || dt < 0) {
		var dt = 0;}
	else {
		dt = ctl.value;}
		
	ctl.value=dt;
}

function __Cancel(cancelUrl) {
	
	var confirmMsg = showError2(8);
	
	// see http://bootboxjs.com/documentation.html
    bootbox.confirm(confirmMsg, function(result){
		if (result) {
			if (typeof(cancelUrl)==='function') {
				cancelUrl();
			} else {
				document.location=cancelUrl;
			}
		}
    });
    
}

function validateJroDateAndNumberAttributes() {
        
    //validates ONLY date and Number javascript objects.
	//it skips the mandatory check
    
    nuf.jroValErrors = [];
    focusCtrl = null;
	
    for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        
        ja.control = document.getElementById(ja.name);
        ja.contents=ja.control.value
        ja.isvalid2();
        //alert(ja.name);
    }
    //alert('jroValErrors:' + jroValErrors);
    if (nuf.jroValErrors.length === 0) {
        return true;
    } else {
        alert( "<ul><li>"+ nuf.jroValErrors.join("<li>") + "</ul>");
		if(focusCtrl){
			
			try {    
				focusCtrl.focus();
			} catch (e) {
				//don;t care about errors...
			}
			
			
		}
		
        return false;
    }

}


function validateJroDateAndNumberAttributesNoFocus() {
        
     //validates ONLY date and Number javascript objects.
	//it skips the mandatory check

    nuf.jroValErrors = [];
    focusCtrl = null;
	
    for (var i=0; i<jroAttributes.length; i++) {
        var ja = jroAttributes[i];
        
        ja.control = document.getElementById(ja.name);
        ja.contents=ja.control.value
        ja.isvalid2();
        //alert(ja.name);
    }
    //alert('jroValErrors:' + jroValErrors);
    if (nuf.jroValErrors.length === 0) {
        return true;
    } else {
        alert( "<ul><li>"+ nuf.jroValErrors.join("<li>") + "</ul>");
        return false;
    }
}


function OpenModalDialog(webAddress, title){
	
	jQuery.ajax({
		type: 'get',
		url:  webAddress,
		success: function(data) {
				bootbox.dialog({
					message: data,
					title: title||nuf.confirmDialogsTitle ,
					buttons: {
						success: {
							label: "OK",
							className: "btn-success"
						}
					}
				});
		}
	});
	
}

function launchCenter(url, name, height, width, other) {

  var win = null;
  var str = "height=" + height + ",innerHeight=" + height;
  
  if(!name)name='win';
  if(!width)width='600';
  if(!height)height='1000';
  if(!other)other='status=1,scrollbars=1';
  str += ",width=" + width + ",innerWidth=" + width;
  if (name.indexOf(' ')==-1) {	
	// good!!!
	  
	if (window.screen) {
	  
  		var ah = screen.availHeight - 30;
		var aw = screen.availWidth - 10;

		var xc = (aw - width) / 2;
		var yc = (ah - height) / 2;

		str += ",left=" + xc + ",screenX=" + xc;
		str += ",top=" + yc + ",screenY=" + yc;
		
    		str += ',' + other;
	    
	}
	  
	try {
		//alert(str);
		win = window.open(url, name, str);
	}catch (e) {
		
	}
	  
	if (!win) {
		alert('Failed to open new window. Please enable pop ups (check your popup blocker)');
		return null;
	}
	  
	win.opener = this;
	win.focus();
	return win;
	
  } else {
	alert('No spaces allowed in name argumenet, function launchCenter');
	return null;
  }
  
}

function __dopostback(eventTarget, eventArgument) {
	__doPostBack(eventTarget, eventArgument);
}

function prepareEvent(eventTarget, eventArgument) {
	$('__EVENTTARGET').value = eventTarget;
	if(eventArgument) {
		$('__EVENTARGUMENT').value = eventArgument;
	} else {
		$('__EVENTARGUMENT').value = '';
	}
}

function __doPostBack(eventTarget, eventArgument) {
    prepareEvent(eventTarget, eventArgument);
    document.forms[0].submit();
    
}



	function jroPrintRecord(gridName) {
		if (typeof(__page__jroPrintRecord)=='function') {
			__page__jroPrintRecord(gridName);
		} else {
			__doPostBack('FACTION=LISTPRINT', gridName);
		}
	}

	

	function getPickListText(t) {
        //alert('in text');
		for (var i=0; i<t.length; i++) {
			if (t.options[i].selected==true) {
				return t.options[i].text;
			}
		}

		return '';
	}

	function getPickListValue(t) {

		for (var i=0; i<t.length; i++) {
			if (t.options[i].selected==true) {
				return t.options[i].value;
			}
		}

		return '';
	}


	function addToSelect(select, id,value, doc) {
	//adds an item to a <select>
	    if (!doc)doc=document;
		var browser = navigator.appName.substring ( 0, 9 );

        for (var i = 0; i < select.options.length; i++) {
            if (select.options[i].value == id) {
                return;
            }
        }

        if (browser == 'Netscape') {
            var oOption = new Option(value,id);
            select.options[select.options.length] = oOption;
        } else {
            var oOption = doc.createElement("OPTION");
            select.options.add(oOption);
            oOption.innerText = value;
            oOption.value = id;
            //alert ("ovalue: " + oOption.value + " id: " + id) ;
            
        }
        return;

    }
    function removeFromSelect(select, id,doc) {
	//adds an item to a <select>
	    if (!doc)doc=document;
		var browser = navigator.appName.substring ( 0, 9 );

        for (var i = 0; i < select.options.length; i++) {
            if (select.options[i].value == id) {
                select.remove(i);
            }
        }
      
        return;

    }
	
	function clearPickList(select,doc) {
	//adds an item to a <select>
		if (!doc)doc=document;
		 
		var selectControl = null;
		if (typeof(select)=='string') {
			selectControl = doc.getElementById(select);
		} else if (typeof(select)=='select-one') {
			selectControl = select;
		} else {
			alert('Error in passed value select');
		}
				
		
	    while (selectControl.options.length>0) {
            selectControl.remove(0);
        }
        return;

    }
	
    function setPickListIndexFromText(t,text) {

		var found = false;
	    
		for (var i=0; i<t.length; i++) {
			t.options[i].selected=false;
		}

		for (var i=0; i<t.length; i++) {
			if (t.options[i].innerText==text) {
				t.options[i].selected=true;
				found = true;
				break;
			}
		}

		return found;
	}
	
	 /**
	 * This function checks a combo box and if it only has one 
	 * item, it autoselects it.  Note that the "Please Select" is skipped
	 **/
	 function autoSelectComboBoxIfOneItem(t) {

		var numValues = 0;
	    
		for (var i=0; i<t.length; i++) {
			t.options[i].selected=false; // diselect item
			if(t.options[i].value) {
				// if the item has a value, eg <option value="1">XXX</option> is true, 
				// <option value="">Please Select</option> is false
				numValues++;
			}
		}
		// if only one item has value, loop again and select it
		if(numValues==1) {
			for (var i=0; i<t.length; i++) {
				if(t.options[i].value) {
					t.options[i].selected = true;
					// select item and break the loop
					break;
				}
			}	
		}
		return;
	}
	
	function setPickListIndexFromValue(t,val) {
        if(!t)return false;
		var found = false;
	    
		for (var j=0; i<j.length; j++) {
			t.options[j].selected=false;
		}

		for (var i=0; i<t.length; i++) {
			if (t.options[i].value==val) {
				t.options[i].selected=true;
				found = true;
				break;
			}
		}

		return found;
	}

 function ShowElementIf( sElement , bCondition) {
    if (bCondition == true) {
        ShowElement(sElement);
    } else {
        HideElement(sElement);
    }
  }

  function HideElement(el) {
      var r1 = $(el);
      if (r1) {
          r1.style.display ="none";
      }
  }

  function ShowElement(el) {
      var r1 = $(el);
      if (r1) {
          r1.style.display ="inline";
      }
  }

  function captureMouseCoords(e){
    e = e?e:event;
    if (e.pageX || e.pageY)   {
      window.posx = e.pageX;
      window.posy = e.pageY;
    }
    else if (e.clientX || e.clientY)   {
      window.posx = e.clientX + document.body.scrollLeft;
      window.posy = e.clientY + document.body.scrollTop;
    }
    //alert('window.posx'+window.posx);
  }

  function __checkMonth(id) {
    var ctrl = $(id);
    if (!ctrl) {
      alert(id + ' does not exist');
    } else {
      if (!isNumeric(ctl.value)) {
        ctrl.value = new Date().getMonth();
      }
    }
  }

  function __checkYear(id) {
    var ctrl = $(id);
    if (!ctrl) {
      alert(id + ' does not exist');
    } else {
      if (!isNumeric(ctrl.value)||!ctrl.value) {
        ctrl.value = new Date().getFullYear();
      }
      
    }
  }

  function TxtAreaAddCols(txtarea) {
        if ((txtarea.cols + 10)<1000 &&  (txtarea.cols + 10)> 0){         
            txtarea.cols = txtarea.cols + 10;
        }
  }

  function TxtAreaRemCols(txtarea) {
      if ((txtarea.cols - 5)<1000 &&  (txtarea.cols - 5)> 0){         
          txtarea.cols = txtarea.cols - 5;
      }

  }
    function TxtAreaAddRows(txtarea) {
        if ((txtarea.rows + 5)<1000 &&  (txtarea.rows + 5)> 0){         
            txtarea.rows = txtarea.rows + 5;
            
        }

    }

    function TxtAreaRemRows(txtarea) {
        if ((txtarea.rows - 5)<1000 &&  (txtarea.rows - 5)> 0){         
            txtarea.rows = txtarea.rows - 5;  
        }

    }
    
function __openTextAreaWindow(txtAreaId) {
	
	var label = 'Text Area';
	if($f(txtAreaId)) {
		label = $f(txtAreaId).label;
	}
    var t = $(txtAreaId);
    var data = t.value;
    var maxLen = $f(txtAreaId).maxLen;
    var newWin = window.open("", "newWin", "resizable=1,width=700,height=550,scrollbars=yes"); //location=yes
    if (!newWin.opener) newWin.opener = self;
    
	newWin.focus();
    newWin.document.write("<!DOCTYPE html><html>\n");
    newWin.document.write("<head>\n");
    newWin.document.write("<title>Update "+label+"</title>\n");
    
    newWin.document.write("</head>\n");
    newWin.document.write('<body style=\"padding:0px\" bgcolor="white">\n');
    newWin.document.write('<form name="taform">\n');
    newWin.document.write("<table width='98%' height='100%' cellspacing=0 cellpadding=0 align=\"center\"><tr><td height='30' align='center'>");
    newWin.document.write('<input type="button" style=\"width:200px\" value="Update" onClick="opener.document.getElementById(\''+txtAreaId+'\').value=document.getElementById(\'ta\').value;opener.CountLeft(\''+txtAreaId+'\','+maxLen+'); self.close()" />\n');
    newWin.document.write('<input type="button" style=\"width:200px\" value="Cancel" onClick="window.close()" />\n');
    newWin.document.write('</td></tr><tr><td>\n<textarea rows="29" tabindex="1" id="ta" name="ta" style="outline:none;width:100%;margin:2px;height:100%;border:3px solid #cccccc;" onkeyup="CountLeft(\'ta\','+maxLen+');">' + data + '</textarea>\n');
    
	newWin.document.write('</td></tr>');
    newWin.document.write('</table></form>\n<script>document.getElementById(\'ta\').focus();</script></body>\n');
    newWin.document.write("</html>\n");
       
    
}
	
	// called by ComboBox jsp tag class to set a hidden field with the 
	// text from a combo box.
	function __setComboDescription(cid,cdescr) {
		var combo = document.getElementById(cid);
		var comboDescr;
		
		if(cdescr) {
			comboDescr = document.getElementById(cdescr);
		} else {
			comboDescr = document.getElementById(cid+'Descr');
		}
		
		if(cid ) {
			if (getPickListValue(combo)) { 
				comboDescr.value = getPickListText(combo);
				//alert('Set comboDescr.value to: ' + comboDescr.value);
			} else {
				comboDescr.value = '';
			}
		}
	}
 
	function openLangServlet(skey) {
		var loc = nuf.contextPath + "/language?rec_key="+skey;
		var w = launchCenter(loc, 'lang', '600', '600') ;
		w.focus();
		
	}
	
	// limit the contents of textarea to certain number of characters
	// field: textarea field
	// count: span that will depslay num of characters in textarea
	// max  : limit of characters in textarea
	function CountLeft(areaName, max) {
		console.log("CountLeft");
		var field = $j('#'+areaName);
		var count = $j('#'+areaName+'charsLf');

		if (field.length === 0) {
			alert('Error: Text Area '+ areaName +' not found.');
			return;
		}
		
		if (count.length === 0) {
			alert('Error: Field '+ areaName+'charsLf' +' not found.');
			return;
		}
		
		var fieldval = normalizeTextArea(field.val()); // take normalized text
		var fieldLen = fieldval ? fieldval.length : 0; // take normalized text length
		
		if ( fieldLen > max){ // check normalized text if more than max
			// if more than max allowed, limit the normalized version to the max allowed
			fieldval = fieldval.substring(0, max);
			field.val( fieldval );
		}

		var fieldLenText = "( " + fieldval.length.toString() + " ) " +  (max - fieldval.length).toString();
		//var fieldLenText = "normalized Length:( " + fieldval.length.toString() + " ), Raw Lengh:" + field.val().length.toString()  ;
		count.html(fieldLenText);

	}
	
	function normalizeTextArea(value) {
		var newV = value.replace(/\n/g, "\r\n");
		return newV;
	}
	
	function disableAndClearFieldIf(sFieldName, bCondition) {
		disableFieldIf(sFieldName, bCondition);
		clearFieldIf(sFieldName, bCondition);
	}

function disableFieldIf(sFieldName, bCondition) {
    var dob = getJroAttr(sFieldName);
    dob.control.disabled = bCondition;
}


function clearFieldIf(sFieldName, bCondition) {
    if (bCondition) {
        setJroAttrValue(sFieldName, '');
    }
}

function addonload(myfunc) {
	AddOnload(myfunc);
}
function AddOnload(myfunc) {
       
    if (window.addEventListener)
        window.addEventListener('load', myfunc, false);
        
    else if (window.attachEvent)
        window.attachEvent('onload', myfunc);

}

function RemoveEvent(docElement,strEvent,myfunc) {
       
	// firefox
    if (window.addEventListener) {
        var fireFoxEv = strEvent;
		// firefox does not like 'on' prefix
		if(fireFoxEv.startsWith('on')) {
			fireFoxEv = fireFoxEv.substring(2);	
	}
		docElement.removeEventListener(fireFoxEv, myfunc, false);
        
    } else if (window.attachEvent) {
        docElement.detachEvent(strEvent, myfunc);
}
}

		
function AddEvent(docElement,strEvent,myfunc) {
    
	// firefox
    if (window.addEventListener) {
        var fireFoxEv = strEvent;
		// firefox does not like 'on' prefix
		if(fireFoxEv.startsWith('on')) {
			fireFoxEv = fireFoxEv.substring(2);	
	}
		docElement.addEventListener(fireFoxEv, myfunc, false);
        
    } else if (window.attachEvent) {
        docElement.attachEvent(strEvent, myfunc);
}
}


function upperCaseFieldC(str) {

	str = str.replace(/\u03C2/g,'\u03A3' ); // small final sigma to upper case sigma
	
	str = str.toUpperCase();
    str = str.replace(/\u03AA/g,'\u0399' ); // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
    str = str.replace(/\u03AB/g,'\u03A5' ); // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA 
	str = str.replace(/\u0386/g,'\u0391' ); //	U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS (U+0386) ? 
	str = str.replace(/\u0388/g,'\u0395' ); //	U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS (U+0388) ? arial_unicode_ms 
	str = str.replace(/\u0389/g,'\u0397' ); //	U+0389 GREEK CAPITAL LETTER ETA WITH TONOS (U+0389) ? arial_unicode_ms 
	str = str.replace(/\u038A/g,'\u0399' ); //	U+038A GREEK CAPITAL LETTER IOTA WITH TONOS (U+038A) ? arial_unicode_ms 
	str = str.replace(/\u038C/g,'\u039F' ); //	U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS (U+038C) ? arial_unicode_ms 
	str = str.replace(/\u038E/g,'\u03A5' ); //	U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS (U+038E) ? arial_unicode_ms 
	str = str.replace(/\u038F/g,'\u03A9' ); //	U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS (U+038F)  
	
    return str;
}

function upperCaseField(e) {
	e = e?e:event;
	var ctl =(e.target)? e.target : e.srcElement;
    ctl.value = upperCaseFieldC(ctl.value);
}

function assignUpperCaseBlurEvent(theForm) {

    var len = theForm.elements.length;
    var i;
    for(i=0; i<len; i++) {
        var c = theForm.elements[i];
        if (c.type==='text' || c.type==='textarea') {
    		AddEvent(c,'onblur', function(ev){upperCaseField(ev?ev:event)} );
			
        }
    }
}

function assignUpperCaseBlurToControl(c) {
    if (c.type==='text' || c.type==='textarea') {
        AddEvent(c,'onblur', function(ev){upperCaseField(ev?ev:event)} );
    }
}

function assignCheckDirtyBlurEvent(theForm) {
	if(!theForm)return;
	var len = theForm.elements.length;
    var i;
    for(i=0;i<len;i++) {
        var c = theForm.elements[i];
		
        if (c.type=='text' || c.type=='textarea' ) {
    		AddEvent(c,'onblur', colorSubmitIfDirty);
        
		}else if (c.type=='select-one'|| c.type=='select-multiple' ) {
			AddEvent(c,'onchange', colorSubmitIfDirty);
			
		}else if (c.type=='checkbox' || c.type=='radio' ) {
    		AddEvent(c,'onclick', colorSubmitIfDirty);
        }
    }
}

function colorSubmitIfDirty() {
	var isDirty = __formIsDirty();
	if(isDirty) {
		eval("isTransactionDirty =true;"); // this function is here for jbo purposes! It is enclosed in an eval block to avoid runtime errors
	}
	
	if(! nuf.submitBtn)return;
	
	if (isDirty) {
		
	
		// code added 23/5/2014 to support multiple nuf.submitBtns on a page
		if( typeof(  nuf.submitBtn['length'])=='undefined') {
			$j(nuf.submitBtn).addClass('formDirtySubmitButton');

		} else {
			for (i = 0; i < nuf.submitBtn['length']; i++) {
				$j(nuf.submitBtn[i]).addClass('formDirtySubmitButton')
			}
		}
	} else {
		if( typeof(  nuf.submitBtn['length'])=='undefined') {
			$j(nuf.submitBtn).removeClass('formDirtySubmitButton');

		} else {
			for (i = 0; i < nuf.submitBtn['length']; i++) {
				$j(nuf.submitBtn[i]).removeClass('formDirtySubmitButton')
			}
		}
	}
}

function enableSubmit() {
	if(!nuf.submitBtn)return;
	if( typeof(  nuf.submitBtn['length'])=='undefined') {
		nuf.submitBtn.disabled = false;
	} else {
		for (i = 0; i < nuf.submitBtn['length']; i++) {
			nuf.submitBtn[i].disabled = false;
		}
	}
}

function disableSubmit() {
	if(!nuf.submitBtn)return;
	if( typeof(  nuf.submitBtn['length'])=='undefined') {
		nuf.submitBtn.disabled = true;
	} else {
		for (i = 0; i < nuf.submitBtn['length']; i++) {
			nuf.submitBtn[i].disabled = true;
		}
	}
}

function clearTableRowFieldsIf(tr, bCondition) {
    
	if (bCondition) {
    
	    var allinputs = tr.getElementsByTagName("input");
	
		for (var j = 0; j < allinputs.length; j++)  {
			allinputs[j].value='';
		}
	
		var sels = tr.getElementsByTagName("select");
		for (var j = 0; j < sels.length; j++)  {
			sels[j].value='';
		}
    }
	
}

function getJroAttributesMap() {
	var jroArray = {};

	for (var i = 0; i < jroAttributes.length; i++) {
        var ja = jroAttributes[i];
		ja.loadValueFromHtml();

		if (!ja.isEmpty()) {
			jroArray[ja.name] = encodeURIComponent(ja.control.value);
        }
    }
		
	jroArray['__EVENTTARGET'] = $('__EVENTTARGET').value;
	jroArray['__EVENTARGUMENT'] =  $('__EVENTARGUMENT').value;
	
	return jroArray;
}

function atLeastOneControlHasData( jroArray ) {
	
	if(!jroArray)jroArray=jroAttributes;
	
	if (jroArray.length == 0) {
		return true;
	}

	var atLeastOneControlRequiresData = false;
	
	for (var i = 0; i < jroArray.length; i++) {
		if(jroArray[i].checkForEmpty) {
			atLeastOneControlRequiresData = true;
			break;
		}
	}
	
	if (!atLeastOneControlRequiresData)
		return true; // return atLeastOneControlHasData = true so that validation continues
	
	for (var i = 0; i < jroArray.length; i++) {
        var ja = jroArray[i];
		if(ja.checkForEmpty) {
			ja.loadValueFromHtml();
			if (!ja.isEmpty()) {
				return true;
			}
		}
    }
	
	return false; // controls have been checked and none was found with data
}

//adds a function reference to be executed during 
//validation of page
	function registerValidationFunction(f) {
	validationFunctions[validationFunctions.length] = f;
}

function viewSource() {
	d=window.open();
	d.document.open('text/plain').write(document.documentElement.outerHTML);
	return false;
}

function colorRequiredControl(ctrl, isRequired) {
	if (isRequired) {
		$j(ctrl).addClass("requiredControl");
			//set back color to light yellow 
	} else {
		$j(ctrl).removeClass("requiredControl");
			//set back color to white
	}
}


/** 
this function checks if the user has changes on the form he/she is editing
if changes are found, the user is asked to confirm and then is taken to destURL parameter
The destURL must be relative to the java web application context root.
**/
function checkDirtyAndGo(destinationUrl) {

	var dirty = false;

	if (typeof(__formIsDirty)==='function') {
		dirty = __formIsDirty();
	}

	if (dirty) {
		var msg = showError2(30);
		var fnc = function() { 
			GoToPage(destinationUrl); 
		};
		
		confirm2( msg , fnc);
		
	} else {
		GoToPage(destinationUrl);
	}
}

function GoToPage(destinationUrl) {
	//if we are here, it means that the user has answered yes to go or there were no changes to the page
	if(destinationUrl) {
		document.location = destinationUrl.indexOf(nuf.contextPath) > -1 ? destinationUrl :  nuf.contextPath + destinationUrl;
	} else {
		return true;
	}

}

/** 
 * This is the same function as as ;checkDirtyAndGo; above, only it does not 
 * append the context path to the front of the destination url
 * 
 * **/
function checkDirtyAndGo2(destinationUrl) {
	
	if(checkDirtyAndGo()) {
		document.location = destinationUrl;
	} else {
		return true;
	}
}


function __SaveLabelForm() {

	// langServletUrl is set in the LabelManageTag class
	var doc = langManager.langServletUrl;
	var recKey = $j('#rec_key').val();
	var Re = new RegExp("\\.","g");
	var normalizedRecKey = recKey.replace(Re,"_");
    var data = { "sAction":"SAVE","rec_key": recKey, "descr_gr": $j('#descr_gr').val(), "descr_en": $j('#descr_en').val() };
	
	$j.post({
		url:doc,
		data:data,
		success:function(result){
			if (result=='1') {
				$j('#lang_el_'+normalizedRecKey).html( $j('#descr_gr').val() );
				$j('#lang_en_'+normalizedRecKey).html( $j('#descr_en').val() );
				langManager.dialoglangForm.dialog("close");
			} else {
				alert('Error occured saving label');
			}
		}
	});
}

function __EditLabelForm(recKey) {

	// langServletUrl is set in the LabelManageTag class
	var doc = langManager.langServletUrl +'?rec_key=' + recKey;
    
	$j.ajax({
		url:doc,
		success:function(result){
		  $j('#dialog-editForm').html(result);
		  langManager.dialoglangForm.dialog("open");
		}
	});
    
}

function getCSRFToken() {

	var url = nuf.contextPath + '/CSRFTokenServlet';
	var vars = {};
		
	ajaxCaller.shouldDebug = false;
	ajaxCaller.postForPlainText(url, vars, OnCSRFTokenServlet, "CSRFTokenServlet");
}

function OnCSRFTokenServlet(content) {

	if (content ) {
		//note: nuf.csrfTokenName is set in Form.java
		$(nuf.csrfTokenName).value=content;
	} else {
		alert("Unable to get CSRFToken");
	}
}

//adds the CSRF token to a query string.
//used in function chckdirtyandgo
function addCSRFToUrl(url) {
	if(!$(nuf.csrfTokenName))return url;
	return addToUrl(url, nuf.csrfTokenName +'='+$(nuf.csrfTokenName).value);
}

//
// This fucntion is used to add parameter 'qryaddition' to the 'qry' string.
// The 'qry' paraemeter will be used to construct a query string
function addToUrl(qry /*String*/, qryaddition/*String*/) {
	var sep = (qry.indexOf("?")===-1)?"?":"&";
	return qry + sep + qryaddition;
}



function setDocTitle(pageTitle, systemTitle, labelKey) {
	
    if(!document.getElementById('pageTitle'))return;
	if( typeof pageTitle!=="string") {
		pageTitle = pageTitle.innerHTML;
	}
    try {
        document.getElementById('pageTitle').innerHTML = pageTitle;
        if(systemTitle) {
            document.title= systemTitle + ' - ' + pageTitle;
        } else {
            document.title= pageTitle;
        }

        if(labelKey) {
            document.getElementById('pageTitle').setAttribute('labelKey',labelKey);
        }
    } catch (e) { 
        if(window.console) {
            window.console.log('Error in setting DocTitle');
        }
    }
    return;
}

/**
 * Function added 15/2/2013, this is to create an autocomplete textbox.
 * Id: id of textbox, 
 * datasourceId: The key of a servlet context attribute that has the sql statement of the autosuggest.
 *               The SQL Statement stored in the servlet context must be in the classic form of "select code, descr_gr, descr_en from ..."
 * iMinlength: Lenght of text to start autocomplete search, default 3.
 * dropDownWidth: with of dropdown menu
 */
function __autosuggestText(id, datasourceId, iMinlength, dropDownWidth ,selectFunction) {
		
    if(!iMinlength)iMinlength=3;
    if(!dropDownWidth)dropDownWidth = $j("#" + id).width();

    $j("#" + id).autocomplete( { 

            source:  nuf.contextPath + "/LovServlet?action=autocompleteTxt&datasourceId="+datasourceId , 
            minLength: iMinlength,
            max: 10,
            delay: 100,
            open: function() {
                $j("#" + id).autocomplete("widget").width(dropDownWidth+5); 
            },
			select: function( event, ui ) {
                
				if(selectFunction) {
					selectFunction();
				}
                return false;
            },
            search: function( event, ui ) {
                //Triggered before a search is performed, after minLength and delay are met. If canceled, then no request will be started and no items suggested.
                __currentAjaxControl = $(id);
            }
    });
    __setupAjaxActivity();    
}

function __autosuggestTextWithIds(id, datasourceId, iMinlength, dropDownWidth, selectFunction ) {
		
    if(!iMinlength)iMinlength=3;
    var acwidget = $j("#Display_" + id);
    var acwidgetId = $j("#" + id); //reference to the hidden input control
    
    if(!dropDownWidth)dropDownWidth = acwidget.width();

    acwidget.autocomplete( { 
            source:  nuf.contextPath + "/LovServlet?action=autocompleteWithIds&datasourceId="+datasourceId , 
            minLength: iMinlength,
            max: 10,
            delay: 100,
            open: function() {
                acwidget.autocomplete("widget").width(dropDownWidth+5); 
            },
            select: function( event, ui ) {
                // get the value and put in the hidden textbox
                acwidgetId.val( ui.item.id );
				if(selectFunction) {
					selectFunction();
				}
                return false;
            },
            search: function( event, ui ) {
                //Triggered before a search is performed, after minLength and delay are met. If canceled, then no request will be started and no items suggested.
                __currentAjaxControl = $(id);
            }
      });
      __setupAjaxActivity();
}

function validateEmail(str) {

	var at="@";
	var dot=".";
	var lat=str.indexOf(at);
	var lstr=str.length;
	
	if ( str == '' || str == null || str=='undefined') {
		return true; 
		//return true if it is an empty vALUE.
	}

	if (str.indexOf(at)==-1){
		return false;
	}

	if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
		return false;
	}

	if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
		return false;
	}

	if (str.indexOf(at,(lat+1))!=-1){
		return false;
	}

	if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
		return false;
	}
	if (str.indexOf(dot,(lat+2))==-1){
		return false;
	}

	if (str.indexOf(' ')!=-1){
		return false;
	}
	var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]]/;

	if (str.match(illegalChars)) {
		return false;
	}
	
	return true;
}

// returns true if CTRL+C or CTRL+V was pressed
function isCtrlCOrV(e) {
	var ctrl = (isMSIE) ? e.ctrlKey : e.modifiers & Event.CONTROL_MASK;
    
	if (ctrl && e.keyCode == 86)
		return true;//CTRL+V, allow

	if (ctrl && e.keyCode == 67)
		return true;//CTRL+C, allow

	return false;
}


function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i=0; i<ca.length; i++) {
        var c = ca[i].trim();
        if (c.indexOf(name)==0) {
            return c.substring(name.length,c.length);
        }
    }
    return "";
 }
 
 function __Checkbox2Click(chkbxid) {
     var checkboxCtrl = $(chkbxid + 'Temp');
     //logMessage("chkbx2 on click, id: " + chkbxid)
	 if(checkboxCtrl) {
         if(checkboxCtrl.checked){
			logMessage("chkbx2 was checked " )	
             $(chkbxid).value = checkboxCtrl.value;
         } else {
             $(chkbxid).value = checkboxCtrl.getAttribute('valueWhenNotChecked');
         }
		 //logMessage("checkboxCtrl.checked: ,"+checkboxCtrl.checked+", value: "+$(chkbxid).value );
		 //logMessage("---------------");
		 
     }
 }
 
 function prepareFormValuesForAjax(eventTarget, eventArgument) {
	var vars = getJroAttributesMap();
	if(eventTarget)vars['__EVENTTARGET'] = eventTarget;
	if(eventArgument)vars['__EVENTARGUMENT'] = eventArgument;
	if(nuf.formReadOnly){vars["readonly"] = "1";}
	return vars;
}


/**
 * Loops thru all jroAttributes fields and clears them
 * If you want to omit fiedls, pass them on the call
 * clearFormFields('effectiveDate') : Will clear all form fields except field 'effectiveDate'
 * clearFormFields('effectiveDate','ToDate') : Will clear all form fields except field 'effectiveDate','ToDate'
 * 
 */
function clearFormFields() {

	for (var i=0; i<jroAttributes.length; i++) {
    
        var ja = jroAttributes[i];
		var clearit = ja.includeInClearForm;
		
		if(clearit) {
			for(var j=0; j<arguments.length; j++) {  
				if(arguments[j]===ja.name ) {
					clearit = false;
					break;
				}
			}
		}
		if(clearit) {
			ja.setValue('');
		}	
    }
}



/**
 * Updates a field from a value of the model obejct in the session
 * This is usefull in the case where we have a jsp, we open a popup and 
 * on the popup we update the model object.
 * To reflect these changes, we can call this function and pass
 * the clientId the id of the field in the DOM of the html
 * 
 * controllerURL: the server side servlet to handle the UpdateUIField grid action
 * If not present, we take the current form's action 
 * */
function updateUiField( clientId, controllerURL) {
	if(!$(clientId)) {
		alert('Error: ' + clientId + ' does not exist on page');
		return;
	}
	var vars = {};
	if(!controllerURL)controllerURL=document.forms[0].action;
	
	vars['__EVENTTARGET'] = 'UpdateUIField';
	vars['__EVENTARGUMENT'] = clientId;
	ajaxCaller.postForPlainText(controllerURL, vars, function(responseText){
		
		if($('display_'+clientId) && (typeof($('display_'+clientId).value)=='undefined')) {
			$('display_'+clientId).innerHTML = responseText;
		}
		if( $(clientId).value ) {
			$(clientId).value = responseText;
					
		}
	});
	
	
}

/**
 * MoveNext: Loop thru the controls until you find the ctl control.
 * Then loop until the next control is not a hidden control 
 * @param ctl 
 */
function MoveNext(ctl /*input*/) {

	var baFound = false; //flag to indicate that we found the current control ctl

	for (var i = 0;i < jroAttributes.length;i++) {
		var ja = jroAttributes[i];
		if(ja.name == ctl.id) {
			baFound = true;
			//set flag for the next iteration
		} else {
			// if baFound flag is true, means the current jro attribute is 
			// after the 'ctl' input control
			if( baFound ) {
				//if next cotnrol is hidden, don't do anything
				//but contrinue the loop until you find a non hidden
				//control
				if (jroAttributes[i].control.type != 'hidden') {
					//if not a hidden, move focus to next control!
					jroAttributes[i].control.focus();
					return;
				}
			}
		}
	}	
}

/**
 * Default error handler for ajax jquery requests
 */
function defaultAjaxErrorHandler(x, t, errorThrown) {

	if(t==="timeout") {
		alert("Timeout occured.");
	} else if(t==="error") {
		if(x.status=='401') {
			alert( x.responseText );
		} else {
			alert( "Ajax call failed with error: " +errorThrown );
		}
		
	} else {
		alert( "Ajax call failed with error: " +t );
	}
	enableSubmit();
}


function logMessage(msg) {
	if( window.log ) {
		if(window.log)window.log(msg);
	}
}

function fireBlurEvent(node){
	if ( document.createEvent ) {
		var evt = document.createEvent('MouseEvents');
		evt.initEvent('blur', true, false);
		node.dispatchEvent(evt);	
	} else if( document.createEventObject ) {
		node.fireEvent('onblur') ;	
	} else if (typeof node.onblur == 'function' ) {
		node.onblur();	
	}
}


/**
 *Class that encupsulates calls to ajax for Save/Edit/Delete model objects
 */
var ajaxCRUD = {
	
	prepareAjaxGridAction: function (eventTarget, eventArg) {
		var vars={"__EVENTTARGET":eventTarget, "__EVENTARGUMENT":eventArg};
		return vars;
	},

	associationExists: function(fieldName, fieldvalue, vurl){
		
		if(!fieldvalue)fieldvalue = $(fieldName).value;
		if(!fieldvalue){
			alert('Error in associationExists check: fieldvalue is null!!');
			return false;
		}
		
		var vars=ajaxCRUD.prepareAjaxGridAction("CheckIfAssociationExists", fieldName);
		vars["fieldCheckValue"] = fieldvalue;
		vars["fieldName"] = fieldName;
		vars["currentAssociation"] = $('currentAssociation').value;
		if(!vurl) vurl = document.forms[0].action;
		var retvalue;
		
		$j.ajax(
			{	cache: false,
				async: false,
				type: "POST",  
				url: vurl, 
				success: function(data){
					retvalue = ( data==='1');
				},
				data: vars,
				timeout: 20*1000, // allow up to 20 seconds
				error: defaultAjaxErrorHandler
			});
			
		return retvalue;
	},
	
	clearSession: function(vurl){
		if(!vurl) vurl = document.forms[0].action;
		var vars = { gridaction: "CLEAR_SESSION" };
		$j.ajax(
			{	cache: false,
				async: true,
				type: "POST",  
				url: vurl, 
				data: vars,
				timeout: 20*1000, // allow up to 10 seconds
				error: defaultAjaxErrorHandler
			});
	},
	
	clearForm: function(ask) {
		
		if(ask) {
			if( __formIsDirty() && !confirm(showError2(30)))return false;
		}
		
		clearFormFields()
		disableSubmit();
		jroAttributesResetChangedFlag();
		colorSubmitIfDirty();
		return true;
	},
	
	fillPageFieldsFromJsonObject: function(json) {
		for (var i = 0;i < jroAttributes.length;i++) {
			var ja = jroAttributes[i];
			var ctrlid = ja.name;
			//alert(ja.name);
			if (json.value[ctrlid]) {
				var chgValue = json.value[ctrlid].value;
				var dataType = json.value[ctrlid].type;
					
				if (chgValue ) {
					if (dataType == 'java.util.Date') {
                        ja.setValue(chgValue); 
						// we don;t parse dates since JSONTranformer formats that date
						// as a standard framework date string, as per SystemConfiguration.Date_format
                    } else {
						ja.setValue(chgValue);
					}
				} else {
					ja.setValue('');
				}
			}
		}
		
		enableSubmit();
		jroAttributesResetChangedFlag();
		colorSubmitIfDirty();	
	},
	
	retrieveAssociatedAjaxModelObjectAndFillPage: function( 
					objectId, associationName, afterFillFunctionRef, vurl, otherVars) {
						
		if(! vurl) vurl = document.forms[0].action;
		if(! ajaxCRUD.clearForm())return false;
		
		ajaxCRUD.retrieveAjaxModelObject(objectId,  
				function(data,textStatus,jqXHR){
					
					ajaxCRUD.fillPageFieldsFromJsonObject(data);
					if(afterFillFunctionRef) {
						afterFillFunctionRef();
					}
					
				},vurl,'RETRIEVE_AJAX_ASSD_'+associationName,otherVars );
				
		return true;
	},
	
	retrieveAjaxModelObjectAndFillPage: function( objectId , otherVars ) {

		if(!ajaxCRUD.clearForm())return false;
		ajaxCRUD.retrieveAjaxModelObject(objectId,  
				function(data,textStatus,jqXHR){
					//var json = jQuery.parseJSON( data );
					ajaxCRUD.fillPageFieldsFromJsonObject(data);
				},null,null,otherVars);
		return true;
	},
	
	retrieveAjaxModelObject: function( objectId, successFunction, vurl, theGridaAction, otherVars) {
		if (! vurl) vurl = document.forms[0].action;
		if (!theGridaAction)theGridaAction = "ACTION_AJAX_RETRIEVE_MO";
		var vars= {__EVENTTARGET: theGridaAction, __EVENTARGUMENT: objectId};
		if(otherVars) {
			for (var itm in otherVars) {
				vars[itm] = otherVars[itm];
			}
		}
		
		$j.ajax(
				{	cache: false,
					async: true,
					type: "POST",  
					dataType:'json',
					url: vurl, 
					proccessData: false, 
					data: vars,
					timeout: 20*1000, // allow up to 1o seconds
					success:successFunction,
					error: defaultAjaxErrorHandler
				});
	},
	
	sentAjaxFormRequest: function ( 
						successFunction /** a function to be executed when call is sucessfull **/ , 
						vars, 
						vurl /** optional, the url to post data, default the url of the forms' action servlet **/,
						type /** optional, POST or GET, default is POST**/) {
		
		if(!type) type = 'POST';
		if(!vars) vars = $j(document.forms[0]).serialize(); // serialize the form data
		disableSubmit();   // disable the submit button while we are saving

		if(!vurl) vurl = document.forms[0].action;	  // if url to sent data was not sent, sent to default servlet

		$j.ajax(
				{	cache: false,
					async: true,
					type: type,  
					url: vurl, 
					data: vars,
					proccessData: false, 
					timeout: 10*1000, // allow up to 10 seconds
					success: successFunction,
					error: defaultAjaxErrorHandler
				});

	}
};
window.alert = function(msg,winTitle) {
	bootbox.alert({
		title: winTitle||nuf.confirmDialogsTitle, 
		message: msg,
		backdrop: true
	});
};

window.confirm2 = function(msg, fcallback, winTitle) {
	bootbox.confirm({
		title: winTitle||nuf.confirmDialogsTitle, 
		message: msg,
		backdrop: true,
		buttons: {
			cancel: {
				label: '<i class="fa fa-times"></i> '+ showError2(38)
			},
			confirm: {
				label: '<i class="fa fa-check"></i> '+ showError2(37)
			}
		},
		callback: function(result){ 
			if(result) {
				fcallback();
			}
		}
		
	});
}

window.confirm = function(msg, fcallback, winTitle) {
	
	bootbox.confirm({
		title: winTitle||nuf.confirmDialogsTitle, 
		message: msg,
		backdrop: true,
		buttons: {
			cancel: {
				label: '<i class="fa fa-times"></i> '+ showError2(38)
			},
			confirm: {
				label: '<i class="fa fa-check"></i> '+ showError2(37)
			}
		},
		callback: function(result){ 
			if(result) {
				fcallback();
			}
		}
		
	});

};


