﻿// JScript File
if(window["CheckDefs"])
    window.AddDef("Dates");

Dates = {
    TimeModes : { _12Hour: 0, _24Hour : 1 },
    DayOfWeek : Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"),
    LastDayOfMonth : function(month, year)
    {
        if(month == 2 && year % 4 == 0)
            return 29;
        else
            return this.MonthDays[month - 1];
    },
    MonthDays : Array (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
    MonthNames : Array ("January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"),
    MonthsFromText : { January : 0, Febuary : 1, March : 2, April : 3, May : 4, June : 5, July : 6, August : 7, September : 8, October : 9, November : 10, December : 11 },
    MonthsBetween : function(xstart, xend) {
        var start;
        var end;

        if(xstart > xend)
        {
            start = xend;
            end = xstart;
        }
        else
        {
            start = xstart;
            end = xend;
        }
        return (12 * (end.getFullYear() - start.getFullYear() - 1)) + (12 - start.getMonth()) + end.getMonth();
    },
    DayOfYear : function(date) {
        var culmDaysInYear = Array (0); //this array indicates the number of days culmulative days elapsed at the beginning of each month.
        var m = date.getMonth();
        var y = date.getFullYear();
        var d = date.getDate();
        var leap = y % 4 == 0;
        
        for(var i = 1; i < Dates.MonthDays.length && i <= m; i++)
            culmDaysInYear[i] = culmDaysInYear[i - 1] + Dates.MonthDays[i - 1] + (i - 1 == 1 && leap ? 1 : 0);
            
        return { 
            dayNumber : d + culmDaysInYear[m],
            daysRemaining : (365 + (leap ? 1 : 0)) - d + culmDaysInYear[m]
        }
    }
}

Date.prototype.Equals = function(dt)
{
    if(dt != null)
        return dt.getTime() == this.getTime();
    else
        return false;
}

Date.prototype.Format = function(format)
{
    var sb = new Text.StringBuilder();
    
    for(var i = 0; i < format.length; i++)
    {
        switch(format.charAt(i))
        {
            case '%':
                i++;
                switch(format.charAt(i))
                {
                    case '%': sb.Append(format.charAt(i)); break;
                    case 'a': sb.Append(Dates.DatesGlobilizationAbbr[Dates.DayOfWeek[this.getDay()]]); break;
                    case 'A': sb.Append(Dates.DatesGlobilization[Dates.DayOfWeek[this.getDay()]]); break;
                    case 'b': sb.Append(Dates.DatesGlobilizationAbbr[Dates.MonthNames[this.getMonth()]]); break;
                    case 'B': sb.Append(Dates.DatesGlobilization[Dates.MonthNames[this.getMonth()]]); break;
                    case 'c': sb.Append(this.Format("%a %b %d %R %Y")); break;
                    case 'd': sb.Append(this.getDate()); break;
                    case 'D': sb.Append(PadLeft(this.getDate() + '', 2, '0')); break;
                    case 'e': sb.Append(this.Format("%m/%d/%y")); break;
                    case 'E': sb.Append(this.Format("%m/%d/%Y")); break;
                    case 'h': sb.Append(PadLeft(this.getHours() > 0 ? (this.getHours() > 12 ? this.getHours() - 12 : this.getHours()) : "12", 2, '0')); break;
                    case 'H': sb.Append(PadLeft(this.getHours(), 2, '0')); break;
                    case 'I': sb.Append(PadLeft((12 - (this.getHours() + 1) % 12), 2, '0')); break;
                    case 'm': sb.Append(this.getMonth() + 1); break;
                    case 'M': sb.Append(PadLeft((this.getMinutes() + ""), 2, '0')); break;
                    case 'p': sb.Append(this.getHours() >= 12 ? "PM" : "AM"); break;
                    case 'q': sb.Append(this.Format("%h:%M %p")); break;
                    case 'Q': sb.Append(this.Format("%H:%M")); break;
                    case 'r': sb.Append(this.Format("%h:%M:%S %p")); break;
                    case 'R': sb.Append(this.Format("%H:%M:%S")); break;
                    case 'S': sb.Append(PadLeft((this.getSeconds() + ""), 2, '0')); break;
                    case 'y': sb.Append(this.getFullYear() % 100); break;
                    case 'Y': sb.Append(this.getFullYear()); break;
                }
                break;
            default:
                sb.Append(format.charAt(i));
                break;
        }
    }
    
    return sb.toString();
}
Date.prototype.DayOfWeekText = function ()
{
    return Dates.DayOfWeek[this.getDay()];
}

/* safari safe implementations of date math 
    safari set**** methods are not relative to current time, so date.set****(date.get****() + X) does not work
*/
Date.prototype.AddYears = function(years)
{
    this.AddMonths(years * 12);
    return this;
}

Date.prototype.Copy = function() {
    var dt = new Date();
    dt.setTime(this.getTime());
    return dt;
}

Date.prototype.AddMonths = function(months)
{
    var newYear = Math.floor(months / 12) + this.getFullYear();
    //Debug.Write("newYear=" + newYear);
    var leftOver = months % 12;
    //Debug.Write("leftOver=" + leftOver);
    var newMonth = (leftOver + (this.getMonth() == 0 ? 12 : this.getMonth())) % 12;
    //Debug.Write("newMonth=" + newMonth);
    if(newMonth < this.getMonth())
        newYear ++;
    //Debug.Write("newYear=" + newYear);
   
   var newDay = this.getDate();
   var ldom  = this.LastDayOfMonth();
   if(newDay > ldom)
        newDay = ldom;
        
   var ret = new Date(newYear, newMonth, newDay);
   //Debug.Write("Adding " + months + " months to date '" + this.toYYYYMMDDHHMM() + "' resulted in '" + ret.toYYYYMMDDHHMM());
   
   this.setYear(newYear);
   this.setMonth(newMonth);
   this.setDate(newDay);
   
   return ret;
}

Date.prototype.AddDays = function(days)
{
    var hours = this.getHours();
    var minutes = this.getMinutes();
    var seconds = this.getSeconds();
    var milliseconds = this.getMilliseconds();
    
    this.AddHours(days * 24);
    
    this.setHours(hours);
    this.setMinutes(minutes);
    this.setSeconds(seconds);
    this.setMilliseconds(milliseconds);
    
    return this;
}

Date.prototype.AddHours = function(hours)
{
    this.AddMinutes(hours * 60);
    
    return this;
}

Date.prototype.AddMinutes = function(minutes)
{
    this.AddSeconds(minutes * 60);
    
    return this;
}

Date.prototype.AddSeconds = function(seconds)
{
    this.AddMilliseconds(seconds * 1000);
    
    return this;
}

Date.prototype.AddMilliseconds = function(milliseconds)
{
    //getTime returns milliseconds elapsed since 1/1/1970
    //setTime sets milliseconds elapsed since 1/1/1970
    //this is the only safe way to set date/time through build in javascript functions.
    this.setTime(this.getTime() + milliseconds);
    
    return this;
}

if(!Date.prototype.getFullYear) {
    Date.prototype.getFullYear = function() {
        var y = this.getYear();
        if(y > 999)
            return y;
        else
            return y + 1900;
    }
}
Date.prototype.toYYYYMMDDHHMM = function() {
    var s = this.getFullYear() + 
        PadLeft((this.getMonth() + 1) + "", 2, '0') + 
        PadLeft(this.getDate() + "", 2, '0') + 
        PadLeft(this.getHours() + "", 2, '0') +
        PadLeft(this.getMinutes() + "", 2, '0');
    return s;
}

Date.parseYYYYMMDDHHMM = function(yyyymmddhhmm) {
    var s = yyyymmddhhmm;
    var d = new Date(
        parseInt(s.substring(0, 4)),
        parseInt(s.substring(4, 6)) - 1,
        parseInt(s.substring(6, 8)),
        parseInt(s.substring(8, 10)),
        parseInt(s.substring(10, 12))) ;
    return d;
}

Date.prototype.LastDayOfMonth = function() {
    return Dates.LastDayOfMonth(this.getMonth() + 1, this.getFullYear());
}