/* version 0.1: http://dren.ch/ */

Number.prototype.pad =
    function (n,p) {
        var s = '' + this;
        p = p || '0';
        while (s.length < n) s = p + s;
        return s;
    };

Date.prototype.months = [
        'January', 'February', 'March', 'April', 'May', 'June', 'July',
        'August', 'September', 'October', 'November', 'December'
    ];
Date.prototype.weekdays = [
        'Sunday', 'Monday', 'Tuesday', 'Wednesday',
        'Thursday', 'Friday', 'Saturday'
    ];
Date.prototype.dpm = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ];

Date.prototype.strftime_f = {
        A: function (d) { return d.weekdays[d.getDay()] },
        a: function (d) { return d.weekdays[d.getDay()].substring(0,3) },
        B: function (d) { return d.months[d.getMonth()] },
        b: function (d) { return d.months[d.getMonth()].substring(0,3) },
        C: function (d) { return Math.floor(d.getFullYear()/100); },
        c: function (d) { return d.toString() },
        D: function (d) {
                return d.strftime_f.m(d) + '/' +
                    d.strftime_f.d(d) + '/' + d.strftime_f.y(d);
            },
        d: function (d) { return d.getDate().pad(2,'0') },
        e: function (d) { return d.getDate().pad(2,' ') },
        F: function (d) {
                return d.strftime_f.Y(d) + '-' + d.strftime_f.m(d) + '-' +
                    d.strftime_f.d(d);
            },
        H: function (d) { return d.getHours().pad(2,'0') },
        I: function (d) { return ((d.getHours() % 12 || 12).pad(2)) },
        j: function (d) {
                var t = d.getDate();
                var m = d.getMonth() - 1;
                if (m > 1) {
                    var y = d.getYear();
                    if (((y % 100) == 0) && ((y % 400) == 0)) ++t;
                    else if ((y % 4) == 0) ++t;
                }
                while (m > -1) t += d.dpm[m--];
                return t.pad(3,'0');
            },
        k: function (d) { return d.getHours().pad(2,' ') },
        l: function (d) { return ((d.getHours() % 12 || 12).pad(2,' ')) },
        M: function (d) { return d.getMinutes().pad(2,'0') },
        m: function (d) { return (d.getMonth()+1).pad(2,'0') },
        n: function (d) { return "\n" },
        p: function (d) { return (d.getHours() > 11) ? 'PM' : 'AM' },
        R: function (d) { return d.strftime_f.H(d) + ':' + d.strftime_f.M(d) },
        r: function (d) {
                return d.strftime_f.I(d) + ':' + d.strftime_f.M(d) + ':' +
                    d.strftime_f.S(d) + ' ' + d.strftime_f.p(d);
            },
        S: function (d) { return d.getSeconds().pad(2,'0') },
        s: function (d) { return Math.floor(d.getTime()/1000) },
        T: function (d) {
                return d.strftime_f.H(d) + ':' + d.strftime_f.M(d) + ':' +
                    d.strftime_f.S(d);
            },
        t: function (d) { return "\t" },
/*      U: function (d) { return false }, */
        u: function (d) { return(d.getDay() || 7) },
/*      V: function (d) { return false }, */
        v: function (d) {
                return d.strftime_f.e(d) + '-' + d.strftime_f.b(d) + '-' +
                    d.strftime_f.Y(d);
            },
/*      W: function (d) { return false }, */
        w: function (d) { return d.getDay() },
        X: function (d) { return d.toTimeString() }, // wrong?
        x: function (d) { return d.toDateString() }, // wrong?
        Y: function (d) { return d.getFullYear() },
        y: function (d) { return (d.getYear() % 100).pad(2) },
//      Z: function (d) { return d.toString().match(/\((.+)\)$/)[1]; },
//      z: function (d) { return d.getTimezoneOffset() }, // wrong
//      z: function (d) { return d.toString().match(/\sGMT([+-]\d+)/)[1]; },
        '%': function (d) { return '%' },

        // DateTime::Locale support
        'day': function (d) { return d.getDate() },         
        'ce_year': function (d) { return d.getFullYear() }
    };

Date.prototype.strftime_f['+'] = Date.prototype.strftime_f.c;
Date.prototype.strftime_f.h = Date.prototype.strftime_f.b;

Date.prototype.strftime =
    function (fmt) {
        var r = '';
        var n = 0;
        while(n < fmt.length) {
            var c = fmt.substring(n, n+1);
            if (c == '%') {
                c = fmt.substring(++n, n+1);
                
                // this is a quick fix to support locale formats
                // returned by  DataTime::Locale.  DateTime::Locale
                // allows method names to be included as a format option
                // (i.e. %{day}, %{year}, etc -jkiser
                if (c == '{') {
                    c = fmt.substring(++n, n+1);
   
                    var method_name = '';
                    while (c != '}') {
                        method_name += c;
                        c = fmt.substring(++n, n+1); 
                    }

                    r += (this.strftime_f[method_name]) ? this.strftime_f[method_name](this) : alert(method_name);
                }
                else {
                    r += (this.strftime_f[c]) ? this.strftime_f[c](this) : c;
                }
            } 
            else {
                r += c;
            }
            ++n;
        }
        return r;
    };

