Date.prototype.Add = function(interval, increment) {
    var intervals = " Y M D h m s uY uM uD uh um us ";
    
    if ( intervals.indexOf(interval) == -1 ) {
        throw("Date.Add: Interval parameter must be: Y, M, D, h, m, s, uY, uM, uD, uh, um or us");
    }

    if ( typeof(increment) != "number" ) {
        throw("Date.Add: Increment parameter must be a number");
    }

    increment = parseInt(increment);

    switch(interval) {
        case "Y":
                this.setYear(parseInt(this.getFullYear()) + increment);
            break;
        case "M":
                this.setMonth(parseInt(this.getMonth()) + increment);
            break;
        case "D":
                this.setDate(parseInt(this.getDate()) + increment);
            break;
        case "h":
                this.setHours(parseInt(this.getHours()) + increment);
            break;
        case "m":
                this.setMinutes(parseInt(this.getMinutes()) + increment);
            break;
        case "s":
                this.setSeconds(parseInt(this.getSeconds()) + increment);
            break;
        case "uY":
                this.setUTCFullYear(parseInt(this.getUTCFullYear()) + increment);
            break;
        case "uM":
                this.setUTCMonth(parseInt(this.getUTCMonth()) + increment);
            break;
        case "uD":
                this.setUTCDate(parseInt(this.getUTCDate()) + increment);
            break;
        case "uh":
                this.setUTCHours(parseInt(this.getUTCHours()) + increment);
            break;
        case "um":
                this.setUTCMinutes(parseInt(this.getUTCMinutes()) + increment);
            break;
        case "us":
                this.setUTCSeconds(parseInt(this.getUTCSeconds()) + increment);
            break;
    }

    return this;
}

Date.Diff = function(upperDate, lowerDate) {
    if ( this.prototype.isPrototypeOf(upperDate) && this.prototype.isPrototypeOf(lowerDate) ) {
        return Math.round( ( Date.UTC(upperDate.getFullYear(), upperDate.getMonth(), upperDate.getDate()) - Date.UTC(lowerDate.getFullYear(), lowerDate.getMonth(), lowerDate.getDate()) ) / ( 1000 * 60 * 60 * 24 ) );
    } else {
        throw("Date.Diff: not valid dates");
    }
}

var DateCal = function() {
    this.defaultDateFrom = (new Date).Add("D", 1);
    this.defaultDateUntil = (new Date).Add("D", 8);
    this.dateFormat = 'dd/mm/yy';
}

DateCal.prototype.setDateFormat = function( dateFormat ) {
    this.dateFormat = dateFormat;
}

DateCal.prototype.isValidDate = function( dd, mm, yyyy ) {

    var isValid = true;
    dd		= parseInt(dd.replace(/^0*/g, ''));
    mm		= parseInt(mm.replace(/^0*/g, ''));
    yyyy	= parseInt(yyyy);

    var isLeapYear = ( yyyy % 4 ) == 0 ? true : false;

    if ( dd >= 1 && ( mm >= 1 && mm <= 12 ) ) {
        switch ( mm ) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                if ( dd > 31 ) {
                    isValid = false;
                }

                break;
            case 2:
                if ( isLeapYear ) {
                    if ( dd > 29 ) {
                        isValid = false;
                    }
                } else {
                    if ( dd > 28 ) {
                        isValid = false;
                    }
                }

                break;
            case 4:
            case 6:
            case 9:
            case 11:
                if ( dd > 30 ) {
                    isValid = false;
                }

                break;
        }
    } else {
        isValid = false;
    }

    return isValid;
}

DateCal.prototype.getDateTokens = function( dateString ) {

    var dateTokens  = dateString.split('/');

    if ( dateTokens.length == 3 ) {
        if ( this.dateFormat == 'mm/dd/yy' ) {
            dd  = dateTokens[1].replace(/^0*/, '');
            mm  = dateTokens[0].replace(/^0*/, '');
            yy  = dateTokens[2].replace(/^0*/, '');
        } else {
            dd  = dateTokens[0].replace(/^0*/, '');
            mm  = dateTokens[1].replace(/^0*/, '');
            yy  = dateTokens[2].replace(/^0*/, '');
        }

        return { 'dd' : dd, 'mm' : mm, 'yy' : yy };
    }
}

DateCal.prototype.getDateString = function( yy, mm, dd ) {

    if ( dd.toString().length == 1 ) {
        dd = "0" + dd;
    }
    
    if ( mm.toString().length == 1 ) {
        mm = '0' + mm;
    }

    return ( this.dateFormat == 'mm/dd/yy' ? mm + '/' + dd + '/' + yy : dd + '/' + mm + '/' + yy );
}

DateCal.prototype.checkDate = function( formIndex ) {

    var dateFromObj     = document.forms[formIndex].dateFrom;
    var dateUntilObj    = document.forms[formIndex].dateUntil;

    var ddFrom, mmFrom, yyFrom, ddUntil, mmUntil, yyUntil;
    var tokensFrom  = this.getDateTokens(dateFromObj.value);
    var tokensUntil = this.getDateTokens(dateUntilObj.value);

    ddFrom  = tokensFrom['dd'];
    mmFrom  = tokensFrom['mm'];
    yyFrom  = tokensFrom['yy'];
    ddUntil = tokensUntil['dd'];
    mmUntil = tokensUntil['mm'];
    yyUntil = tokensUntil['yy'];
    
    try {
        //return ( Math.round( ( Date.UTC(yyUntil, mmUntil - 1, ddUntil) - Date.UTC(yyFrom, mmFrom - 1, ddFrom) ) / ( 1000 * 60 * 60 * 24 ) ) > 0 ? true : false );
        
        if ( this.isValidDate(ddFrom, mmFrom, yyFrom) && this.isValidDate(ddUntil, mmUntil, yyUntil) ) {
            
            var dateFrom    = new Date(yyFrom, (mmFrom - 1), ddFrom);
            var dateUntil   = new Date(yyUntil, (mmUntil - 1), ddUntil);
            
            if ( Date.Diff(dateUntil, dateFrom) < 1 ) {
                dateUntil = (new Date(yyFrom, (mmFrom - 1), ddFrom)).Add('D', 7);
                dateUntilObj.value = this.getDateString(dateUntil.getFullYear(), dateUntil.getMonth() + 1, dateUntil.getDate());
            }
            
            if ( Date.Diff(dateFrom, this.defaultDateFrom) >= 0 && Date.Diff(dateUntil, dateFrom) >= 1 ) {
                return true;
            } else {
                throw DATE_ERROR_MSG;
            }
        } else {
            throw DATE_ERROR_MSG;
        }
    } catch ( errMsg ) {
        alert(errMsg);
        return false;
    }
}

DateCal.prototype.checkDateCalTop = function() {
    return this.checkDate(0);
}

DateCal.prototype.checkDateCalDetail = function() {
    return this.checkDate(1);
}


