﻿/*
 *  Copyright Outpost Technology Frontier Corp.
 *
 */



//-------------------------
//  CONSTANTS
//-------------------------

Date._MONTH_MAXDATES = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
Date._MONTH_FULLNAMES = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
Date._MONTH_SHORTNAMES = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");




//-------------------------
//  STATIC METHODS
//-------------------------

Date.setDate = function (dateObj, date, allowDateOverflow) {
    if (date < 1)
        date = 1;
       
    //  get the difference between the two dates
    var diff = date - dateObj.getDate();
    //  add the difference
    return Date.addDate(dateObj, 0, 0, diff, allowDateOverflow);
};

Date.setYear = function (dateObj, year, allowDateOverflow) {
    //  make sure year is in bound of min & max years
    if (year < 1900)
        year = 1900;
    else if (year > 2050)
        year = 2050;
    
    //  get the difference between the years
    var diff = year - dateObj.getFullYear();
    //  add the difference
    return Date.addDate(dateObj, diff, 0, 0, allowDateOverflow);
};

Date.setMonth = function (dateObj, month, allowDateOverflow) {
    //  get the difference between the months
    var diff = month - dateObj.getMonth();
    //  add the difference
    return Date.addDate(dateObj, 0, diff, 0, allowDateOverflow);
};

Date.addMonth = function (dateObj, month) {
    var d = dateObj.getDate();
    var m = dateObj.getMonth();
    var y = dateObj.getFullYear();
    
    var new_month = (m + month) % 12;
    var quotient = ((m + month) - new_month) / 12;
    quotient = (quotient >= 0)? Math.floor(quotient) : Math.ceil(quotient);
    var new_year = y + quotient;
    
    var new_date = Date.getMonthMaxDate(new_month, new_year);
    if (new_date > d)
        new_date = d;
        
    dateObj.setDate(1);
    dateObj.setMonth(new_month);
    dateObj.setYear(new_year);
    dateObj.setDate(new_date);
}

Date.addDate = function (dateObj, years, months, dates, allowDateOverflow) {
    //  clone passed date object
    var paramDate = new Date(dateObj.getFullYear(), dateObj.getMonth(), dateObj.getDate(), 0, 0, 0);
    
    //  ensure we have something to add, return a clone of passed date object if not
    if (years == 0 && months == 0 && dates == 0)
        return paramDate;
    
    var totalDays = paramDate.getDate() + dates;
    paramDate.setDate(1);
    paramDate.setFullYear(paramDate.getFullYear() + years);
    Date.addMonth(paramDate, months);

    if (allowDateOverflow)
        paramDate.setDate(totalDays);
    else {
        var maxMonthDays = paramDate.getMonthMaxDate(paramDate.getMonth());
        if (totalDays > maxMonthDays)
            totalDays = maxMonthDays;
        paramDate.setDate(totalDays);
    }

    return paramDate;
};

Date.getMonthMaxDate = function (month, year) {
    if (month == 1 && ((0 == (year % 4)) && ( (0 != (year % 100)) || (0 == (year % 400)))))
        return 29;
    else
        return Date._MONTH_MAXDATES[month];
};

Date.ensureDateInRange = function (date, minDate, maxDate) {
    if ( maxDate && date > maxDate )
        return maxDate;
    else if ( minDate && date < minDate )
        return minDate;
    else
        return date;
}

Date.compareDates = function (date1, date2) {
    var d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
    var d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
    
    return d1 - d2;
}


//-------------------------
//  PUBLIC METHODS
//-------------------------

Date.prototype.clearTime = function () {
    this.setHours(0, 0, 0, 0);
}

/**
 * Retrieves the last day of the specified month using the current year as reference
 * @param {numeric} month specifies the month to check
 * @returns {numeric} Number of days in the month
 */
Date.prototype.getMonthMaxDate = function (month) {
    var year = this.getFullYear();
    if (typeof month == "undefined")
        month = this.getMonth();
    if (((0 == (year % 4)) && ( (0 != (year % 100)) || (0 == (year % 400)))) && month == 1)
        return 29;
    else
        return Date._MONTH_MAXDATES[month];
};

/**
 * Compares the current date with the supplied date, ignores time associated with both
 * @param {Date} date to compare to
 * @returns {bool} returns true or false
 */
Date.prototype.equalsToDateOnly = function (date) {
    return ((this.getFullYear() == date.getFullYear()) &&
            (this.getMonth() == date.getMonth()) &&
            (this.getDate() == date.getDate()));
};

/**
 * Prints the current date in string format
 * @params {String} str string pattern
 * @returns {String} date in string format
 */
Date.prototype.print = function (str) {
    //  normalize month number from (0-11) to (1-12)
    var m = this.getMonth() + 1;
    var d = this.getDate();
    var y = this.getFullYear();

    //  array of parameters
    s = {};

    //  date
    s["%d"] = d;
    s["%dd"] = (d < 10)? "0" + d : d;
    //  month
    s["%M"] = m;
    s["%MM"] = (m < 10)? "0" + m : m;
    s["%MMM"] = Date._MONTH_SHORTNAMES[m-1];
    s["%MMMM"] = Date._MONTH_FULLNAMES[m-1];
    //  year
    s["%yy"] = ('' + y).substr(2,2);
    s["%yyyy"] = y;
    
    var re = /%[a-zA-Z]*/g;
    if (!Date.is_ie5 && !Date.is_khtml)
        return str.replace(re, function (p) { return s[p] || p; } );
    
    var a = str.match(re);
    for (var i = 0; i < a.length; i++) {
        var tmp = s[a[i]];
        if (tmp) {
            re = new RegExp(a[i], 'g');
            str = str.replace(re, tmp);
        }
    }
};

Date.prototype.equalsToDateOnly = function (date) {
    return ((this.getFullYear() == date.getFullYear()) &&
        (this.getMonth() == date.getMonth()) &&
        (this.getDate() == date.getDate()));
}

/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

/** Set only the year, month, date parts (keep existing time) */
Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};
