/*******************************************************************************
* $Module-Name:   dateutils.js                                                 *
* $Author:        Dmitry O. Zaitsev <machine@globinfodial.com>                 *
********************************************************************************
* THIS SOFTWARE IS PROVIDED BY THE GLOBINFODIAL ``AS IS'' AND                  *
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,          *
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A                  *
* PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE GLOBINFODIAL OR    *
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,    *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,          *
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  *
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,     *
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR      *
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF       *
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                   *
********************************************************************************
$Id$
*******************************************************************************/

	Date.prototype.monthLengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    Date.prototype.getBeginWeek = function () {
        var dt = new Date(this);
        while ( dt.getDay() != 0 ) dt.setDate(dt.getDate() - 1);
        return dt;
    }

    Date.prototype.getEndWeek = function () {
		var dt = new Date(this);
        while ( dt.getDay() != 6 ) dt.setDate(dt.getDate() + 1);
        return dt;
    }

    Date.prototype.getBeginLastWeek = function () {
		var dt = new Date(this.getBeginWeek());
        dt.setDate(dt.getDate() - 1);
        return dt.getBeginWeek();
    }

    Date.prototype.getEndLastWeek = function () {
        var dt = new Date(this.getBeginWeek());
        dt.setDate(dt.getDate() - 1);
        return dt;
    }

    Date.prototype.nextMonth = function () {
        if (this.getMonth() == 11) {
            this.nextYear();
            this.setMonth(0);
        } else {
            this.setMonth(this.getMonth() + 1);
        }
    }

    Date.prototype.prevMonth = function () {
        if (this.getMonth() == 0) {
            this.prevYear();
            this.setMonth(11);
        } else {
            this.setMonth(this.getMonth() - 1);
        }
    }

    Date.prototype.nextYear = function () {
        this.setFullYear(this.getFullYear() + 1);
    }

    Date.prototype.prevYear = function() {
        this.setFullYear(this.getFullYear() - 1);
    }

    Date.prototype.isLeapYear = function () {
       /** 1. Years divisible by four are leap years, unless...
         * 2. Years also divisible by 100 are not leap years, except...
         * 3. Years divisible by 400 are leap years.
         */

        var year = this.getFullYear();
        return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
    }

    Date.prototype.getMonthLength = function () {
        if (this.getMonth() == 1 && this.isLeapYear()) return 29;
        return this.monthLengths[this.getMonth()];
    }

    Date.prototype.getBeginMonth = function () {
        var dtM = this.getMonth();
        var dtY = this.getFullYear();
        var dt  = new Date(dtY, dtM, 1, 0, 0, 0, 0);

        return dt;
    }

    Date.prototype.getEndMonth = function () {
        var dtM = this.getMonth();
        var dtY = this.getFullYear();
        var dt  = new Date(dtY, dtM, this.getMonthLength(), 23, 59, 59, 999);
        return dt;
    }

    Date.prototype.getBeginYear = function () {
        var dtY = this.getFullYear();
        var dt  = new Date(dtY, 0, 1, 0, 0, 0, 0);
        return dt;
    }

    Date.prototype.getEndYear = function () {
        var dtY = this.getFullYear();
        var dt  = new Date(dtY, 11, 31, 23, 59, 59, 999);
        return dt;
    }
