Math.randomFloat = function (min, max){ return min + (max - min) * Math.random(); };
Math.randomInt = function (min, max){ return Math.floor(Math.randomFloat(min, max)); };

Number.prototype.round = function(d){
    var f,w,fr;
    if(d===undefined||d===0){return Math.round(dec);}
    if(d<0){
        f=Math.pow(10,-d);
        return Math.round(this/f)*f;
    }
    f=Math.pow(10,d);
    h=Math.floor(this);
    fr=this-h;
    return new Number(h+Math.round(fr*f)/f);
}
Number.prototype.format = function(d,ts,ds){
    var s,h,fr,regex;
    if(d===undefined){dec=0;}
    if(ts===undefined){ts=',';}
    if(ds===undefined){ds='.';}
    regex=/(\d+)(\d{3})/;
    h=Math.floor((d<0)?this.round(d):this);
    s=h+'';
    while(regex.test(s)){s=s.replace(regex,'$1'+ts+'$2');}
	if(d>0){
	    fr=(1+(this-h).round(d))*Math.pow(10,d)+'';
	    s+=ds+fr.substring(1);
	}
	return s;
};

var date={
    getDaysOfMonth:function(y,m){return 32-new Date(y,m, 32).getDate();},
    isLeapYear:function(y){return (y%4)==0&&(y%100)!=0||(y%400)== 0;}};
    
Date.prototype.Age = function(dt){
    var cur,sign,keep,ms,s,mn,h,m;
    cur=this;
    var sign=1;
    if (dt<cur){
        sign=-1;
        keep=dt;
        cur=dt;
        dt=keep;
    }
    ms=dt.getMilliseconds()-cur.getMilliseconds();
    s=dt.getSeconds()-cur.getSeconds();
    if(ms<0){
        s--;
        ms+=1000;
    }
    mn=dt.getMinutes()-cur.getMinutes();
    if(s<0){
        mn--;
        s+=60;
    }
    h=dt.getHours()-cur.getHours();
    if(mn<0){
        h--;
        mn+=60;
    }
    if (((h>0)||((h==0)&&((mn>0)||((mn==0)&&((s>0)||((s==0)&&(ms>=0)))))))&&
        (cur.getMonth()==1)&&(cur.getDay()==29)&&(dt.getMonth()==1)&&(dt.getDay()==28)&&!Date.isLeapYear(dt.getFullYear())){
        d=0;
        m=0;
    }
    else{
        d = dt.getDate()-cur.getDate();
        if(h<0){
            d--;
            // TODO day-light-saving-time !?
            h+=24;
        }
        m=dt.getMonth()-cur.getMonth();
        if(d<0){
            m--;
            d+=date.getDaysOfMonth(dt.getFullYear(),dt.getMonth());
        }
    }
    y=dt.getYear()-cur.getYear();
    if(m<0){
        y--;
        m+=12;
    }
    return new DateSpan(sign*y,sign*m,sign*d,sign*h,sign*mn,sign*s,sign*ms);
};
Date.prototype.Diff = function(dt){
    return new TimeSpan(this-dt);
};

TimeSpan = function(d,h,mn,s,ms)
{
    if(h===undefined&&mn===undefined&&s===undefined&&ms===undefined){
        this.t=d;
        this.ms=d%1000;d=(d-this.ms)/1000;
        this.s=d%60;d=(d-this.s)/60;
        this.mn=d%60;d=(d-this.mn)/60;
        this.h=d%24;d=(d-this.h)/24;
        this.d=d;   
    }
    else{
        this.d=d;   
        this.h=h;   
        this.mn=mn; 
        this.s=s;   
        this.ms=ms;
        this.t=d*86400000+h*3600000+mn*60000+s*1000+mm;
    }
    this.getDays=function(){return this.d;};
    this.getHours=function(){return this.h;};
    this.getMinutes=function(){return this.mn;};
    this.getSeconds=function(){return this.s;};
    this.getMilliseconds=function(){return this.ms;};
    this.getTotalDays=function(){return this.t/86400000;};
    this.getTotalHours=function(){return this.t/3600000;};
    this.getTotalMinutes=function(){return this.t/60000;};
    this.getTotalSeconds=function(){return this.t/1000;};
    this.getTotalMilliseconds=function(){return this.t;};
};
DateSpan = function(y,m,d,h,mn,s,mm)
{
    this.y=y;
    this.m=m;
    this.d=d;
    this.h=h;
    this.mn=mn;
    this.s=s;
    this.mm=mm;
    this.getYears=function(){return this.y;};
    this.getMonths=function(){return this.m;};
    this.getDays=function(){return this.d;};
    this.getHours=function(){return this.h;};
    this.getMinutes=function(){return this.mn;};
    this.getSeconds=function(){return this.s;};
    this.getMilliseconds=function(){return this.mm;};
};

Format = new function()
{
    this.number=function(n,d,ts,ds){return (new Number(n)).format(d,ts,ds); }
};
