// Check that the given value is in the float range specified.
// Note that these values are INCLUSIVE
// It returns true if i's ok and false otherwise
function validateInt(value,minval,maxval)
{
  var v=parseInt(value);
  if(v != value) return(false);
  if((v>maxval) || (v<minval)) return(false);
  return(true);
}

// Check that the given value is in the integer range specified.
// Note that these values are EXCLUSIVE. If there is a problem
// an alert is given and the entry is set to empty. The source
// is the reference for which source.value contains the value
// to check
function assertInt(s,minval,maxval)
{
  var v=s.value;
  if(validateInt(v,minval,maxval)) return(true);;
  alertOn(s);
  alert('Invalid value: '+v+'\n valid values are: '+minval+'< Int <'+maxval);
  s.value="";
  alertOff(s);
  return(false);
}

function reassertInt(s,minval,maxval,def) 
{
    if(assertInt(s,minval,maxval)==false) s.value=def;
}

// Check that the given value is in the float range specified.
// Note that these values are INCLUSIVE
// It returns true if i's ok and false otherwise
function validateFloat(value,minval,maxval)
{
  var v=parseFloat(value);
  if(v != value) return(false);
  if((v>maxval) || (v<minval)) return(false);
  return(true);
}

// Check that the given value is in the integer range specified.
// Note that these values are EXCLUSIVE. If there is a problem
// an alert is given and the entry is set to empty. The source
// is the reference for which source.value contains the value
// to check
function assertFloat(s,minval,maxval)
{
  var v=s.value;
  if(validateFloat(v,minval,maxval)) return(true);
  alertOn(s);
  alert('Invalid value: '+v+'\n valid values are: '+minval+'< Float <'+maxval);
  s.value="";
  alertOff(s);
  return(false);
}
function reassertFloat(s,minval,maxval,def) 
{
    if(assertFloat(s,minval,maxval)==false) s.value=def;
}

// This is as for assertFloat but also permits the field to be empty
function assertOptFloat(source,minval,maxval)
{
  if(source.value!="") assertFloat(source,minval,maxval);
}

// This checks that a string is not empty. Returns true if ok and false otherwise
function astNNS(s)
{
  var v=s.value;
  if(v != "") return(true);
  alertOn(s);
  alert('Field must not be empty');
  s.value='';
  alertOff(s);
  return(false);
}

// This checks that the date is valid. The date is xx-yyy-zzzz where
// xx is day,yyy is month (text) and zzzz is year. It returns -1 if
// a problem, 0 if empty and 
function validateDate(s)
{
    if(s=="") return(0);
    s=s.replace(/\s/g,"-");
	while(s.indexOf("/")!=-1)
	{
		s=s.replace("/","-");    
	}
    var e=(s.toUpperCase()).split('-');
    if(e.length!=3) return(-1);
    
    if(e[0].charAt(0)=='0') e[0]=e[0].substr(1);
    var d=parseInt(e[0]);
    
    if((d != e[0]) || (d > 31) || (d<1)) return(-1);
    var m=-1;
    switch(e[1]) {
        case('JAN') : {m=0;break;}
        case('01') : {m=0;break;}
        case('FEB') : {m=1;if(d>29) return(-1); else break;}
        case('02') : {m=1;if(d>29) return(-1); else break;}
        case('MAR') : {m=2;break;}
        case('03') : {m=2;break;}
        case('APR') : {m=3;if(d>30) return(-1); else break;}
        case('04') : {m=3;if(d>30) return(-1); else break;}
        case('MAY') : {m=4;break;}
        case('05') : {m=4;break;}
        case('JUN') : {m=5;if(d>30) return(-1); else break;}
        case('06') : {m=5;if(d>30) return(-1); else break;}
        case('JUL') : {m=6;break;}
        case('07') : {m=6;break;}
        case('AUG') : {m=7;break;}
        case('08') : {m=7;break;}
        case('SEP') : {m=8;if(d>30) return(-1); else break;}
        case('09') : {m=8;if(d>30) return(-1); else break;}
        case('OCT') : {m=9;break;}
        case('10') : {m=9;break;}
        case('NOV') : {m=10;if(d>30) return(-1); else break;}
        case('11') : {m=10;if(d>30) return(-1); else break;}
        case('DEC') : {m=11;break;}
        case('12') : {m=11;break;}
    }
    if(m==-1) return(-1);
    var y=parseInt(e[2]);
    if((y<1900) || (y>2100)) return(-1);
    var y4=4*Math.floor(y/4),y100=100*Math.floor(y/100),y400=400*Math.floor(y/400);
    if(((m==1) && (d==29)) && ((y4 != y) || ((y100==y) && (y400 != y)))) return(-1);
    return(d+31*(m+12*(y-1900)));
}

function changeDateFormat(s) {
    s=s.replace(/\s/g,"-");
	while(s.indexOf("/")!=-1)
	{
		s=s.replace("/","-");    
	}
    var e=(s.toUpperCase()).split('-');
    if(e.length!=3) return(s);
    
   	s = e[0]+"-";
   	if(getMonth(e[1])=='') {
		s = s + e[1] + "-";;
   	} else {
		s = s + getMonth(e[1]) + "-";
   	}
   	s = s + e[2];
   return(s);
}

function getMonth(m) {
	
	var M="";
	switch(m) {
        case('01') : {M='Jan'; break;}
        case('02') : {M='Feb'; break;}
        case('03') : {M='Mar'; break;}
        case('04') : {M='Apr'; break;}
        case('05') : {M='May'; break;}
        case('06') : {M='Jun'; break;}
        case('07') : {M='Jul'; break;}
        case('08') : {M='Aug'; break;}
        case('09') : {M='Sep'; break;}
        case('10') : {M='Oct'; break;}
        case('11') : {M='Nov'; break;}
        case('12') : {M='Dec'; break;}
	}
	return(M);
}

function validateSwapTenorInput(s)
{
	if (s=="") return 0;
	
	s=s.toUpperCase();
	
	var re = new RegExp(/^\s*[0-9]+[DWMY]\s*(\+\s*[0-9]+[DWMY])*\s*$/);
	
	if (!re.test(s))
	{
		return -1;
	}
	
	return 0;
}

function astDat(s)
{
    if(validateDate(s.value)>=0) return(true);
    alertOn(s);
    alert('Not a valid date: Use dd-mmm-yyyy,\ne.g., 06-Jan-1967');
    alertOff(s);
    s.value="";
    return(false);
}

// Check a tenor. Return false if bad
function validateTenor(s)
{
    if(s=="") return(true);
    s=s.toUpperCase();
    if((s=='ON') || (s=='TN') || (s=='SN')) return(true);
    var v=s.substr(0,s.length-1);
    if(v != parseInt(v)) return(false);
    if((v<1) || (v>40)) return(false);
    v=s.substr(s.length-1);
    if((v!='D') && (v != 'W') && (v != 'M') && (v != 'Y')) return(false);
    return(true);
}

function astTen(s)
{
    if(validateTenor(s.value)>=0) return(true);
    alertOn(s);
    alert('Not a valid tenor');
    alertOff(s);
    s.value="";
    return(false);
}
// Check a future is ok or empty - should be XYY where YY is 01-99 and
// X is 'F,G,H,J,K,M,N,Q,U,V,X,Z' or 'Jan,Feb ...' Blank is also ok
function validateFuture(s)
{
    if(s.replace(/\s/g,"")=="") return(true);
    s=s.toUpperCase();
    if(s.length != 3) return(false);
    var c=s.substr(0,1),d=s.substr(1,2);
    if((parseInt(d)<0) || (parseInt(d)>99)) return(false);
//    if((c!="F") && (c!="G") && (c!="H") && (c!="J") && (c!="K") && (c!="M") &&
//       (c!="N") && (c!="Q") && (c!="U") && (c!="V") && (c!="X") && (c!="Z")) return(false);
    if((c!="H") && (c!="M") &&
       (c!="U") && (c!="Z")) return(false);
    return(true);
}
function astFut(s)
{
    if(validateFuture(s.value)) return(true);
    alertOn(s);
//    alert("Not a valid future: Use XYY where\nX is the month code (F=Jan, G=Feb, H=Mar,\nJ=Apr, K=May, M=Jun, N=Jul, Q=Aug, U=Sep,\nV=Oct, X=Nov, Z=Dec) and YY is the year\ne.g., M20 for Jun '20");
    alert("Not a valid future: Use XYY where\nX is the month code (H=Mar, M=Jun, U=Sep, Z=Dec) and YY is the year\ne.g., M20 for Jun '20");
    alertOff(s);
    s.value="";
    return(false);
}
    
// Validate an interest rate maturity
function validateOptMaturity(s)
{
    if(s=="") return(true);
    s=s.toUpperCase();
    if((s!="1M") && (s!="3M") && (s!="6M") && (s!="1Y") && (s!="2Y") && (s!="3Y") &&
       (s!="4Y") && (s!="5Y") && (s!="7Y") && (s!="10Y") && (s!="15Y")) return(false);
    return(true);
}
function assertOptMaturity(s)
{
    if(validateOptMaturity(s.value)) return(true);
    alertOn(s);
    alert("Not a valid Option Maturity");
    alertOff(s);
    s.value="";
    return(false);
}
// Validate an interest swap rate maturity
function validateSwpMaturity(s)
{
    if(s=="") return(true);
    s=s.toUpperCase();
    if((s!="3M") && (s!="6M") && (s!="1Y") && (s!="2Y") && (s!="3Y") &&
       (s!="4Y") && (s!="5Y") && (s!="7Y") && (s!="10Y") && (s!="15Y") &&
       (s!="20Y") && (s!="25Y") && (s!="40Y")) return(false);
    return(true);
}
function assertSwpMaturity(s)
{
    if(validateSwpMaturity(s.value)) return(true);
    alertOn(s);
    alert("Not a valid Swap Maturity");
    alertOff(s);
    s.value="";
    return(false);
}
// Check for percent
function astPct(t) {assertFloat(t,0,100);}
function astPctB(t) {if(t.value.replace(/\s/g,"")!="") astPct(t);}
function astPctD(t) {reassertFloat(t,0,100,"0.00");}

// Permit blanks
function astMil(t) {if(t.value.replace(/\s/g,"")!="") assertFloat(t,0,1000000);}

// Check for correlations
function astCor(t) {assertFloat(t,-100,100);if(t.value=="") t.value="0.00";}
function astCorB(t) {if(t.value.replace(/\s/g,"")!="") assertFloat(t,-100,100);}
function astCorC(t) {reassertFloat(t,-100,100, "0.0");}
 
// Check an integer
function astInt(t,x,y) {assertInt(t,x,y);}

// Permit blanks in the bps 0-10000 or not
function astBpsB(t) {if(t.value.replace(/\s/g,"")!="") astBps(t);}
function astBps(t) {assertFloat(t,0,10000);}

// Volatilities can be 0 to 200 %
function astVolB(t) {if(t.value.replace(/\s/g,"")!="") assertFloat(t,0,200);}

// Fixings can be any float or space
function astFix(t) {if(t.value.replace(/\s/g,"")!="") assertFloat(t,-100000000,100000000);}

// Assert that there's no whitespace in the text
function astNS(t)
{
    if(t.value=="") return;
    if(t.value.replace(/\s/g,"") != t.value) {
        alertOn(t);
        alert('Macro names may not contain spaces');
        alertOff(t);
        t.value="";
    }
}

// ---------------------- Check that a name is valid. Set to an empty string if it is not ----------------------------
function astNm(t)
{
    var v=t.value;
    if((v.indexOf('#')==-1) && (v.indexOf('*')==-1) && (v.indexOf('&')==-1) && (v.indexOf(':')==-1) && (v.indexOf(' ')==-1)) return(true); // All ok
    alertOn(t);
    alert('Names may not contain spaces, #, *, & or :');
    alertOff(t);
    t.value="";
    return(false);
}

function disableForms(n, bool)
{
    for(var i=0; i < n.length; i++) {
     form = document[n[i]];
     for (var j=0; j < form.length; j++) {
            form.elements[j].disabled = bool;
     }
    }
}

// validate the IR calc parameter
function validCP(t) {
    var mod = document.fcalci.md.value;
    switch(getOption(document.fcalci.irs)) {
        case ("Tree"): {reassertInt(t,40,300,120);break;}
        case ("Monte Carlo"): {reassertInt(t,1,20000,2000);break;}
        case ("Lattice"): {
            if (mod=="Hull & White 1F") reassertInt(t,50,200,80);
            if (mod=="HJM 2F") reassertInt(t,15,60,30);
            else reassertInt(t,70,300,120);
        }        
    } 
}

//validate steps / nodes in IRCal
function validIrCal(t) {
    var mod = getOption(document.fncalib.md);
    if (mod=="Markov Functional LN 1F") reassertInt(t,70,300,120);
    else if (mod=="HJM 2F") reassertInt(t,15,60,30);
    else reassertInt(t,50,200,120);
}
        
    
// ensure value is either 1,2, or 3 for HJM 2F model
function assertDataCols(t) {
    var v = t.value;
    if ((v == '1') || (v == '2') || (v == '3')) return(true);
    //else
    t.value = '3'; 
    alertOn(t);
    alert('HJM 2F can only accept 1,2, or 3 data columns');
    alertOff(t);
}

// Highlight a panel with the alert style
function alertOn(t) {t.className='inalert';}
function alertOff(t) {
        t.className = '';
	t.focus();
}

function getMonthNum(mnth)
{
	var month = (mnth.toString()).toUpperCase(); 
//	alert("month  " +	month);
	var m = "";
    switch(month)
     {
        case('JAN') : {m=1;break;}
        case('FEB') : {m=2;break;}
        case('MAR') : {m=3;break;}
        case('APR') : {m=4;break;}
        case('MAY') : {m=5;break;}
        case('JUN') : {m=6; break;}
        case('JUL') : {m=7;break;}
        case('AUG') : {m=8;break;}
        case('SEP') : {m=9;break;}
        case('OCT') : {m=10;break;}
        case('NOV') : {m=11; break;}
        case('DEC') : {m=12;break;}
    }
	return (m);	
}
/* Function to remove the leading & trailing spaces */
function Trim(strInput) {	
//alert('1');
     strInput = LTrim(strInput);
     strInput = RTrim(strInput);	
     return strInput;
     }
     
     /* Function to remove the leading spaces */
     
     function LTrim(strInput){	
     //alert('2');
     
     var intCntr;	
     for (intCntr=0; intCntr < strInput.length; intCntr++) 	{		
     if (strInput.charAt(intCntr) != " ") 			
     break;								
     }	
     //alert("intCntr" + intCntr);
     return strInput.substr(intCntr, strInput.length);
     }
     
     /* Function to remove the trailing spaces */
     function RTrim(strInput){	
          //alert('3');
     var intCntr;	
     for (intCntr=strInput.length-1; intCntr > -1; intCntr--)	{		
     if (strInput.charAt(intCntr) != " ") 			
     break;								
     }	
     return strInput.substr(0, intCntr + 1);
     }
     
