//*********************************
function Replicate(str,n){
  if (str==null) return ""
  if (typeof str != 'string') return ""
  if (n==null) n=1
  if (typeof n != 'number') n=1
  var r=""
  for(var i=0;i<n;i++) {
    r=r+str
  }
  return r
}

//*********************************
function Space(n){
  return Replicate(" ",n)
}

//*********************************
function Trim(str){
  if (str==null) return ""
  var i=1
  var l=str.length
  while (i<=l && str.charAt(l-i)==' ')
    i=i+1
  return str.substring(0,l-i+1)
}

//*********************************
function RTrim(str){
  return Trim(str)
}

//*********************************
function LTrim(str){
  var i=0
  var l=str.length
  while (i<l && str.charAt(i)==' ')
    i=i+1
  return str.substring(i)
}

//*********************************
function LRTrim(str){
  return LTrim(Trim(str))
}

//*********************************
function Left(str,len) {
  if (typeof str=='string' && typeof len=='number') {
    return(str.substr(0,len))
  } else {
    return ''
  }
}

//*********************************
function Right(str,len) {
  if (typeof str=='string') {
    return(str.substr(str.length-len))
  } else {
    return ''
  }
}

//********************************
function Strtran(src,find,repl){
  var i,l=find.length
  var res=""
  i=src.indexOf(find)
  while(i!=-1) {
    res=res+src.substring(0,i)+repl
    src=src.substring(i+l)
    i=src.indexOf(find)
  }
  return res+src
}

//*********************************
function Substr(str,pos,cnt) {
  if (typeof str!='string') return ''
  if (typeof pos=='number') {
    pos-=1
    if (pos<0) return ""
    if (typeof cnt=='number') {
      if (cnt<1) return ""
      return str.substr(pos,cnt)
    } else {
      return str.substr(pos)
    }
  } else if (pos==null) {
    return str.substr()
  } else {
    return ''
  }
}

//*********************************
function Upper(str) {
  if (typeof str=='string') return str.toUpperCase(); else return ''
}

//*********************************
function Lower(str) {
  if (typeof str=='string') return str.toLowerCase(); else return ''
}

//*********************************
function Val(str) {
  if (typeof str=='string') {
    var n=parseFloat(str);
    if (isNaN(n)) {
      return(0);
    }
    else {
      return(n);
    }
  } else {
    return(0)
  }
}

//*********************************
function Str(p_n,len,dec) {
  if (p_n==null) {p_n=0}
  if (typeof p_n != 'number') {p_n=0}
  if (len==null) {len=10}
  if (typeof len != 'number') {len=10}
  if (dec==null) {dec=0}
  if (typeof dec != 'number') {dec=0}
  var res=p_n.toString()
  var point=At(".",res)
  if (point==0) res=res+".0"
  res+=Replicate("0",dec-Len(res)+At(".",res));
  point=At(".",res)
//document.write("res:"+res+" point:"+point+" len:"+len+"<BR>");
  if (point<=len+1) {
    res=Substr(res,1,dec>0 ? point+dec: point-1);
//document.write("res:"+res+"<BR>");
    if (res.length> len) {
      res=Substr(res,1,len)
      if (res.charAt(len-1)=='.')
        res=Substr(res,1,len-1);
    }
    len=len-res.length
    for(;len>0;len--) {
      res=" "+res
    }
  } else {
    res="";
    for(;len>0;len--)
      res+="*"
  }
  return res
}

//*********************************
function At(p_cStrFind,p_cStr,cnt) {
  // Resituisce la posizione di una stringa in un'altra.
  // Il param opz. "cnt" indica quale occorrenza è richiesta
  if (cnt<=0 || typeof cnt!='number') {cnt=1}
  if (p_cStrFind==null || p_cStrFind=="") {return 0}
  var l=0
  var pos=-1;
  while (l<cnt) {
    pos=p_cStr.indexOf(p_cStrFind, pos+1) ;
    l++;
  }
  return pos+1;
}

//*********************************
function RAt(strFind,str,cnt) {
  // Resituisce la posizione di una stringa in un'altra iniziando la ricerca da destra.
  // Il param opz. "cnt" indica quale occorrenza è richiesta
  var pattern,result,pos=new Array()
  var index=0, strTest
  if (typeof strFind!='string' || typeof str!='string') return 0
  if (cnt<=0 || typeof cnt!='number') cnt=1
  if (navigator.appName=='Netscape') {
    pattern = new RegExp(strFind,"g")
    while ((result=pattern.exec(str))!=null) {
      pos[pos.length]=result.index+1
    }
  } else {
    // In Internet Explorer si deve usare una tecnica diversa
    // in quanto l'oggetto RegExp ha un baco !!!
    pattern = new RegExp(strFind)
    strTest=str
    while ((result=strTest.search(pattern))>=0) {
      index=index+result+strFind.length
      strTest=str.substr(index)
      pos[pos.length]=index-strFind.length+1
    }
  }
  pos.reverse()
  if (cnt<=pos.length) {
    return(pos[cnt-1])
  } else {
    return 0
  }
}

//*********************************
function ZeroPad(str,size) {
  //if (typeof str!='string') return ''
  while (str.length<size) {
   str='0'+str
  }
  return str
}

//*********************************
function Len(obj) {
  //Resituisce la lunghezza di una stringa o array
  return obj.length
}

//*********************************
function Asc(str) {
  if (str==null || str.length()==0) return -1
  return str.charCodeAt(0)
}

//MAX******************************
function Max(a,b) {
  if (Gt(a,b)) {
    return a
  } else {
    return b
  }
}

//*********************************
//function Stuff(str,len,fillerChar) {
//  while (str.length<len) {
//    str=fillerChar+str
//  }
//  return(str)
//}

//*********************************
function IsNumber(kCode) {
  //44-->Comma ascii code , 45-->Minus ascii code, 46-->Point ascii code
  if (!((kCode >47 && kCode <58) || kCode==44 || kCode==45 || kCode==46)) {
    return(false);
  } else {
    return(true);
  }
}

//*********************************
function BoolToChar(b) {
  if (typeof b=='boolean') {
    return b ? "t" : "f"
  }
  return "f"
}

//*********************************
function CharToBool(s) {
  s = Trim(Lower(s))
  if (s=='true')
    return true
  else
    return false
}

//*********************************
function NullDate() {
  return new Date(100,0,1,0,0,0,0)
}

//*********************************
function NullDateTime() {
  return NullDate()
}

//*********************************
function DateToChar(obj) {
  // Restituisce true se obj è una stringa uguale a "true" ignorando il maiusc/minusc.
  // Restituisce false se obj è una stringa uguale a "false" ignorando il maiusc/minusc.
  // Restituisce false se obj vale 0, NaN, null, undefined,stringa vuota
  // Restituisce true se obj vale 1 o qualsiasi altro valore.
  if (typeof obj=='object' && obj.constructor==Date) {
    return zeroFill(''+obj.getFullYear(),4)+zeroFill(''+(obj.getMonth()+1),2)+zeroFill(''+obj.getDate(),2)
  }
  return ''
}

//*********************************
function CharToDate(obj) {
  if (Empty(obj)) return ''
  if (typeof obj=='string') {
    return new Date(Val(Substr(obj,1,4)),Val(Substr(obj,5,2))-1,Val(Substr(obj,7,2)),0,0,0,0)
  }

  return new Date(100,0,1,0,0,0,0)
}

//*********************************
function CharToDateTime(obj) {
  if (Empty(obj)) return ''
  if (typeof obj=='string') {
    return new Date(Val(Substr(obj,1,4)),Val(Substr(obj,5,2))-1,Val(Substr(obj,7,2)),
                    Val(Substr(obj,9,2)),Val(Substr(obj,11,2)),Val(Substr(obj,13,2)),0)
  }

  return new Date(100,0,1,0,0,0,0)
}

//*********************************
function DayOfWeek(obj) {
  if (Eq(obj,NullDate())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getDay()+1
  }
  return 0
}

//*********************************
function Sec(obj) {
  if (Eq(obj,NullDateTime())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getSeconds()
  }
  return 0
}
//*********************************
function Minute(obj) {
  if (Eq(obj,NullDateTime())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getMinutes()
  }
  return 0
}
//*********************************
function Hour(obj) {
  if (Eq(obj,NullDateTime())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getHours()
  }
  return 0
}
//*********************************
function Day(obj) {
  if (Eq(obj,NullDate())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getDate()
  }
  return 0
}

//*********************************
function Month(obj) {
  if (Eq(obj,NullDate())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getMonth()+1
  }
  return 0
}

//*********************************
function Year(obj) {
  if (Eq(obj,NullDate())) return 0
  if (typeof obj=='object' && obj.constructor==Date) {
    return obj.getFullYear()
  }
  return 0
}

//*********************************
function Week(obj) {
  if (Eq(obj,NullDate())) return 0
  if (typeof(obj)=='object' && obj.constructor==Date) {
    var dayOfWeek=DayOfWeek(obj)
    var MinimalDaysInFirstWeek=4
    var rem = [0]
    var EPOCH_JULIAN_DAY = 2440588
    var ONE_DAY=1000*60*60*24
    var JAN_1_1_JULIAN_DAY = 1721426
    var gregorianEpochDay=EPOCH_JULIAN_DAY + floorDivide(obj.getTime(), ONE_DAY)- JAN_1_1_JULIAN_DAY
    var n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
    var n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
    var n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
    var n1 = floorDivide(rem[0], 365, rem);
    //var rawYear = 400*n400 + 100*n100 + 4*n4 + n1;
    var dayOfYear = rem[0]; // zero-based day of year
    if (n100 == 4 || n1 == 4) {
      dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
    } else {
      //++rawYear;
    }
    var firstDayOfWeek=1
    var relDow = (dayOfWeek + 7 - firstDayOfWeek) % 7; // 0..6
    var relDowJan1 = (dayOfWeek - dayOfYear + 701 - firstDayOfWeek) % 7; // 0..6
    var woy = Math.floor((dayOfYear - 1 + relDowJan1) / 7); // 0..53
    if ((7 - relDowJan1) >= MinimalDaysInFirstWeek)
      ++woy;

    // XXX: The calculation of dayOfYear does not take into account
    // Gregorian cut over date. The next if statement depends on that
    // assumption.
    if (dayOfYear > 359) { // Fast check which eliminates most cases
      // Check to see if we are in the last week; if so, we need
      // to handle the case in which we are the first week of the
      // next year.
      var lastDoy = yearLength(Year(obj));
      var lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
      if (lastRelDow < 0)
        lastRelDow += 7;
      if (((6 - lastRelDow) >= MinimalDaysInFirstWeek) &&
          ((dayOfYear + 7 - relDow) > lastDoy))
        woy = 1;

    } else if (woy == 0) {
      // We are the last week of the previous year.
      var prevDoy = dayOfYear + yearLength(rawYear - 1);
      woy = weekNumber(prevDoy, dayOfWeek);
    }
    return woy
  }
  return 0
}

function isLeapYear(year) {
  var gregorianCutoverYear = 1582
  return year >= gregorianCutoverYear ?
    ((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))) : // Gregorian
    (year%4 == 0); // Julian
}
function yearLength(year) {
  return isLeapYear(year) ? 366 : 365;
}

function floorDivide( numerator, denominator,  remainder) {
  if (remainder==null) remainder=[0]
  if (numerator >= 0) {
    remainder[0] = numerator % denominator
    return Math.floor(numerator / denominator)
  }
  var quotient = Math.floor((numerator + 1) / denominator) - 1;
  remainder[0] = numerator - (quotient * denominator);
  return quotient
}

//*********************************
function iif(expr,trueExpr,falseExpr) {
  if (expr) {
    return trueExpr
  } else {
    return falseExpr
  }
}

//*********************************
function zeroFill(varValue,len) {
  if ("123456789".indexOf(varValue.charAt(0)) > -1) {
    while (varValue.length < len)
      varValue = '0' + varValue;
  }
  return varValue
}

//*********************************
function Round(varValue,len) {
  var res
  var l=Math.pow(10,Math.abs(len))
  if (len>0) {
    res=Math.round(varValue*l)/l
  } else if (len<0) {
    res=Math.round(varValue/l)*l
  } else
    res=Math.round(varValue)
  return(res)
}

//*********************************
function Int(varValue) {
  return Math.floor(varValue,0)
}

//*********************************
function SystemDate(){
  var d=new Date()
  d.setHours(0)
  d.setMinutes(0)
  d.setSeconds(0)
  d.setMilliseconds(0)
  return d
}

//*********************************
function DateTime(){
  var d=new Date()
  d.setMilliseconds(0)
  return d
}

//*********************************
function EmptyString(str) {
  return str.match(/\S/) == null || str==null
}

//*********************************
function EmptyNumber(num) {
  return num==0
}

//*********************************
function EmptyDate(date) {
  if (date==null) {
    return true
  }
  if (date.getFullYear()==100) {
    if (date.getMonth()==0) {
      if (date.getDate() == 1) {
        return true
      }
    }
  }
  return false
}

//*********************************
function EmptyDateTime(date) {
  return EmptyDate(date)
}

//*********************************
function EmptyBoolean(yesno) {
  return yesno==false
}

//*********************************
function Empty(any) {
  switch(typeof any) {
    case 'number':
      return EmptyNumber(any)
    case 'boolean':
      return EmptyBoolean(any)
    case 'string':
      return EmptyString(any)
    case 'object':
      if (any==null) return true
      if(any.constructor==Date) {
          return EmptyDate(any)
      }
      break;
  }
  return false
}

function IsNull(any) {
  return Empty(any);
}

//*********************************
function finetypeof(any) {
  if (typeof any=='object' && any.constructor==Date) return 'Date';
  return typeof any
}

//*********************************
function Eq(a,b) {
  if (a!=null && a.constructor==Date){
    if (a!=null && typeof(a)=='string')
      return (a==FormatDate(b))
    else
      return (a.getTime()==b.getTime())
  }
  if (a!=null && typeof(a)=='string' && b!=null && b.constructor==Date){
    return (a==FormatDate(b))
  }
  return (a==b)
}


//*********************************
function Ne(a,b) {
  return !Eq(a,b)
}

function Lt(a,b){
  if (a!=null && a.constructor==Date){
    return (a.getTime()<b.getTime())
  }
  return (a<b)
}

function Le(a,b){
  if (a!=null && a.constructor==Date){
    return (a.getTime()<=b.getTime())
  }
  return (a<=b)
}

function Ge(a,b){
  if (a!=null && a.constructor==Date){
    return (a.getTime()>=b.getTime())
  }
  return (a>=b)
}

function Gt(a,b){
  if (a!=null && a.constructor==Date){
    return (a.getTime()>b.getTime())
  }
  return (a>b)
}

//*********************************
function DateFromApplet(date) {
  return new Date(date.getYear()+1900,date.getMonth(),date.getDate(),0,0,0,0)
}

function DateTimeFromApplet(date) {
  return new Date(date.getYear()+1900,date.getMonth(),date.getDate(),date.getHours(),
                  date.getMinutes(),date.getSeconds(),0)
}

function Format(any, len, dec, picture) {
  if (picture==null && typeof(len)=='string') {
    picture=len
    len=0
  }
  switch (typeof(any)) {
    case 'string':
      return FormatChar(any, len, picture)
      break
    case 'number':
      return FormatNumber(any, len, dec, picture)
      break
    case 'boolean':
      return FormatBoolean(any, picture)
      break
    case 'object':
      if (any.constructor==Date) {
        if (any.getHours() > 0 || any.getMinutes() > 0 || any.getSeconds() > 0)
          return FormatDateTime(any, picture)
        else
          return FormatDate(any, picture)
        //return ApplyPictureToDate(any, picture)
      }
      break
    default:
      return any
      break;
  }
}
