var DateTimeI18NGerman = {
    weekDaysOne : new Array('S', 'M', 'D', 'M', 'D', 'F', 'S'),
    weekDaysFull : new Array('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'),
    monthNames : new Array('Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'),
    yyRoll : 20
};

var DateTimeI18NEnglish = {
    weekDaysOne : new Array('S', 'M', 'T', 'W', 'T', 'F', 'S'),
    weekDaysFull : new Array('Sunday', 'Monday', 'Thuesday', 'Wednesday', 'Thursday', 'Friday', 'cd'),
    monthNames : new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
    yyRoll : 20
};

var DateTimeClass = function() {

    this.i18n = DateTimeI18NGerman;

    this.formatDate = function(format, date) {
        // d dd M MM MMM MMMM yy yyyy HH mm ss
        var f = format;
        var d;
        var m;
        var y;
        var result = "";
        while (f.length > 0) {
            if (f.substr(0, 4) == "yyyy") {
                result += date.getFullYear();
                f = f.substr(4);
            } else if (f.substr(0, 2) == "yy") {
                y = date.getYear() % 100;
                result += (y < 10) ? "0" + y : y;
                f = f.substr(2);
            } else if (f.substr(0, 4) == "MMMM") {
                result += this.i18n.monthNames[date.getMonth()];
                f = f.substr(4);
            } else if (f.substr(0, 3) == "MMM") {
                result += date.getMonth();
            // todo: i18n display
                f = f.substr(3);
            } else if (f.substr(0, 2) == "MM") {
                m = date.getMonth() + 1;
                result += (m < 10) ? "0" + m : m;
                f = f.substr(2);
            } else if (f.substr(0, 1) == "M") {
                result += date.getMonth() + 1;
                f = f.substr(1);
            } else if (f.substr(0, 2) == "dd") {
                d = date.getDate();
                result += (d < 10) ? "0" + d : d;
                f = f.substr(2);
            } else if (f.substr(0, 1) == "d") {
                result += date.getDate();
                f = f.substr(1);
            } else if (f.substr(0, 2) == "HH") {
                d = date.getHours();
                result += (d < 10) ? "0" + d : d;
                f = f.substr(2);
            } else if (f.substr(0, 2) == "mm") {
                d = date.getMinutes();
                result += (d < 10) ? "0" + d : d;
                f = f.substr(2);
            } else if (f.substr(0, 2) == "ss") {
                d = date.getSeconds();
                result += (d < 10) ? "0" + d : d;
                f = f.substr(2);
            } else if (f.substr(0, 4) == "EEEE") {
                result += this.i18n.weekDaysFull[date.getDay()];
                f = f.substr(4);

            } else {
                result += f.substr(0, 1);
                f = f.substr(1);
            }
        }

        return result;
    };


    this.parseDate = function(format, dateStr) {
        if (!dateStr) {
            return null;
        }
    // d dd M MM MMM MMMM yy yyyy HH mm ss
        var now = new Date();
        var d = now.getDate();
        var m = now.getMonth();
        var y = now.getFullYear();
        var hh = 0;
        var mm = 0;
        var ss = 0;

        var f = format;
        var s = dateStr;
        var r;

        while (f.length > 0) {
            if (f.substr(0, 4) == "yyyy") {
                if (!/[0-9]{4}.*/.test(s)) {
                    return null;
                } else {
                    y = parseInt(s.substr(0, 4));
                    f = f.substr(4);
                    s = s.substr(4);
                }
            } else if (f.substr(0, 2) == "yy") {
                if (!/[0-9]{2}.*/.test(s)) {
                    return null;
                } else {
                    y = parseInt(s.substr(0, 2));
                    if (y <= this.i18n.yyRoll) {
                        y = 2000 + y;
                    }
                    f = f.substr(2);
                    s = s.substr(2);
                }
            } else if (f.substr(0, 2) == "MM" || f.substr(0, 1) == "M") {
                r = /([0-9]{1,2}).*/.exec(s);
                if (!r) {
                    return null;
                } else {
                    m = parseIntLeadingZero(r[1]) - 1;
                    f = f.substr(f.substr(0, 2) == "MM" ? 2 : 1);
                    s = s.substr(r[1].length);
                }
            } else if (f.substr(0, 2) == "dd" || f.substr(0, 1) == "d") {
                r = /([0-9]{1,2}).*/.exec(s);
                if (!r) {
                    return null;
                } else {
                    d = parseIntLeadingZero(r[1]);
                    f = f.substr(f.substr(0, 2) == "dd" ? 2 : 1);
                    s = s.substr(r[1].length);
                }
            } else if (f.substr(0, 2) == "HH") {
                r = /([0-9]{1,2}).*/.exec(s);
                if (!r) {
                    return null;
                } else {
                    hh = parseIntLeadingZero(r[1]) - 1;
                    f = f.substr(2);
                    s = s.substr(r[1].length);
                }
            } else if (f.substr(0, 2) == "mm") {
                r = /([0-9]{1,2}).*/.exec(s);
                if (!r) {
                    return null;
                } else {
                    mm = parseIntLeadingZero(r[1]) - 1;
                    f = f.substr(2);
                    s = s.substr(r[1].length);
                }
            } else if (f.substr(0, 2) == "ss") {
                r = /([0-9]{1,2}).*/.exec(s);
                if (!r) {
                    return null;
                } else {
                    ss = parseIntLeadingZero(r[1]) - 1;
                    f = f.substr(2);
                    s = s.substr(r[1].length);
                }
            } else {
                f = f.substr(1);
                s = s.substr(1);
            }
        }

        function parseIntLeadingZero(str) {
            while (str.substr(0, 1) == "0") {
                str = str.substr(1);
            }

            return parseInt(str);
        }

        return new Date(y, m, d, hh, mm, ss);
    };


    var monthDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

// Returns the number of days in a month (handles leap-years)
    this.getDayCount = function(SomeYear, SomeMonth) {
        return ((SomeMonth == 1) && ((SomeYear % 400 === 0) || ((SomeYear % 4 === 0) && (SomeYear % 100 !== 0)))) ? 29 : monthDays[SomeMonth];
    };
};


var DateTime = new DateTimeClass();