﻿/**================================================ 
 * DateFormat version 1.1 (Prototype Version)
 * Created: 08 September 2008
 * Modified: 01 December 2008
 * Created by: Zaenal - http://www.lokamaya.net
 * ================================================
 *
 * Copyright (c) 2008 Zaenal - http://www.lokamaya.net 
 * Release under LGPL - GNU Lesser General Public License
 *
 * ================================================
 * Demo: http://code.lokamaya.net/dateformat/
 * Blog: http://blog.lokamaya.net
 * ================================================
 *
 * Requirement: prototype.js (version 1.6.0) 
 * 
 * PHP#strftime FORMAT CONVERSION Support:
 * %a, %A, %b or %h, %B, %C, %d, %e, %H, %I, %j, %m, %M, %n, %p, %r, %S, %u, %w, %y, %Y or %G, %Z or %z
 * and I add:
 * %F for calculating the week of month (not supported in PHP#strftime)
**/

/* LANGUAGE HANDLER */
/* You can edit or populate as many language as needed */
var DateFormatLang = new Array();
DateFormatLang.Populate = function(lang, defaultFormat, arrayMonths, arrayMonthsAbbr, arrayDays, arrayDaysAbbr) {
    DateFormatLang[lang] = DateFormatLang.Populate.arguments;
};
//Populate Danish language
DateFormatLang.Populate('da', 
    '%d-%m-%Y',
    ['January','February','March','April','May','June','July','August','September','October','November','December'],
    ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
    ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
    ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']);
//Populate English language
DateFormatLang.Populate('en', 
    '%m/%d/%Y',
    ['January','February','March','April','May','June','July','August','September','October','November','December'],
    ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
    ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
    ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']);
//Populate Indonesia language
DateFormatLang.Populate('id', 
    '%d/%m/%Y',
    ['Januari','Februari','Maret','April','Mei','Juni','Juli','Agustus','September','Oktober','Nopember','Desember'],
    ['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Agu','Sep','Okt','Nov','Des'],
    ['Minggu','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'],
    ['Ming','Sen','Sel','Rab','Kam','Jum','Sab']);

/**================================================
Do not edit anything below this line, 
except you know what you are doing
***================================================*/

/* EXTEND DEFAULT DATE OBJECT */
Date.prototype.getDayOfYear = function() {
    var firstyear = new Date(this.getFullYear(),0,1);
    return Math.ceil((this - firstyear) / 86400000);
}
Date.prototype.getWeekOfYear = function() {
    var firstyear = new Date(this.getFullYear(),0,1);
    return Math.ceil((((this - firstyear) / 86400000) + firstyear.getDay())/7);
}
Date.prototype.getWeekOfMonth = function() {
    return Math.ceil((this.getDate() + (6 - this.getDay())) /7);
}

/* DATEFORMAT CLASS */
var DateFormat = Class.create({
        defaultLang: 'en',
        defaultFormat: '%m/%d/%Y',
        property: {
            lang: 'en',
            utc: false,
            format: '%m/%d/%Y',
            months: [],
            monthsAbbr: [],
            days: [],
            daysAbbr: []
        },
        initialize: function(property) {
            property = $H(property);
            var lang = property.get('lang') || this.defaultLang;
            if (typeof DateFormatLang[lang] == 'undefined') {
                alert('Can not find language "'+lang+'" configuration for DateFormat.'+"\n"+'Using default language:"'+this.defaultLang+'"');
                lang = this.defaultLang;
            }
            this.oDate = null;
            this.hDate = null;
            this.property.lang = lang;
            this.property.utc = property.get('utc') || false;
            //this.defaultFormat = DateFormatLang[lang][1];
            this.property.format = property.get('format') || DateFormatLang[lang][1];
            this.property.months = DateFormatLang[lang][2];
            this.property.monthsAbbr = DateFormatLang[lang][3];
            this.property.days = DateFormatLang[lang][4];
            this.property.daysAbbr = DateFormatLang[lang][5];
        },
        valid: function(val, format) {
            return;
        },
        compare: function(options1,options2) {
            return;
        },
        toFormat: function(format) {
            format = format ? format : this.property.format;   
            var rep = '', place = '', that=this;
            var str = format;
            format.scan(/%[a-zA-Z%]/, function(match){
                    rep = that.formatCallback(match[0]);
                    place = new RegExp(match[0]);
                    str = str.replace(place, rep);
            });
            return str;
        },
        getDate: function(options, format) {
            this.setDate(options);
            return this.toFormat(format);
        },
        setUTC: function(utc) {
            return this.property.utc = ((utc===false || utc==0) ? false : true);
        },
        setDate: function(options, retval) {
            if (!options && this.hDate) return;
            var op = $H(options);
            if (op.get('hour')) op.set('hours', op.get('hour'));
            if (op.get('minute')) op.set('minutes', op.get('minute'));
            if (op.get('second')) op.set('seconds', op.get('second'));
            
            var oD = new Date();
            var oT = false;
            if (op.get('format')) {
                this.property.format = op.get('format');
            }
            if (op.get('time') && op.get('time') > 0) {
                oD.setTime(op.get('time'));
                oT = true;
            } else {
                op.set('time', oD.getTime());
            }
            if (op.get('year') && op.get('year') > 0) {
                oD.setFullYear(op.get('year'));
            } else {
                op.set('year', oD.getFullYear());
            }
            if (op.get('month') && op.get('month') > 0) {
                oD.setMonth(this.unTZ(op.get('month')) -1);
            }
            op.set('month', oD.getMonth());
            
            if (op.get('date') && op.get('date') > 0) {
                oD.setDate(op.get('date'));
            } else {
                op.set('date', oD.getDate());
            }
            if (op.get('hours') && op.get('hours') > 0) {
                oD.setHours(this.unTZ(op.get('hours')));
            } else {
                op.set('hours', oD.getHours());
            }
            if (op.get('minutes') && op.get('minutes') > 0) {
                oD.setMinutes(this.unTZ(op.get('minutes')));
            } else {
                op.set('minutes', oD.getMinutes());
            }
            if (op.get('seconds') && op.get('seconds') > 0) {
                oD.setSeconds(this.unTZ(op.get('seconds')));
            } else {
                op.set('seconds', oD.getSeconds());
            }
            if (op.get('milliseconds') && op.get('milliseconds') > 0) {
                oD.setMilliseconds(this.unTZ(op.get('milliseconds')));
            } else {
                op.set('milliseconds', oD.getMilliseconds());
            }
            op.set('dayofweek', oD.getDay());
            this.oDate = oD;
            this.hDate = op;

            if (retval=='hash') return op;
            else if (retval=='object') return oD;
            else return;
        },
        toLocaleDateString: function(options) {
            this.setDate(options);
            //default javascript Date.toLocaleDateString
            return this.oDate.toLocaleDateString();
        },
        toString: function(options) {
            this.setDate(options);
            //default javascript Date.toString
            return this.oDate.toString();
        },
        toJSON: function(options) {
            this.setDate(options);
            //required prototype 1.6.0.2 or higher
            return this.oDate.toJSON();
        },
        toObject: function(options) {
            this.setDate(options);
            return this.oDate;
        },
        toDate: function(val,format) {
            return
        },
        formatCallback: function(x) {
            var oD = this.oDate;
            var tP = this.property;
            var utc = tP.utc && tP.utc===true ? true : false;
            if (!oD) return x;
            
            switch(x) {
                case '%a' :
                    return (utc ? tP.daysAbbr[oD.getUTCDay()] : tP.daysAbbr[oD.getDay()]);
                case '%A' :
                    return (utc ? tP.days[oD.getUTCDay()] : tP.days[oD.getDay()]);
                case '%b' : case '%h' :
                    return (utc ? tP.monthsAbbr[oD.getUTCMonth()] : tP.monthsAbbr[oD.getMonth()]);
                case '%B' :
                    return (utc ? tP.months[oD.getUTCMonth()] : tP.months[oD.getMonth()]);
                case '%d' :
                    return this.TZ(utc ? oD.getUTCDate() : oD.getDate());
                case '%e' :
                    return (utc ? oD.getUTCDate() : oD.getDate());
                case '%F' :
                    return oD.getWeekOfMonth();
                case '%H' :
                    return this.TZ(utc ? oD.getUTCHours() : oD.getHours());
                case '%I' : case '%p' :
                    var h = (utc ? oD.getUTCHours() : oD.getHours());
                    if (x=='%p') return (h >= 12 ? 'PM' : 'AM');
                    var hMod = this.TZ(h % 12);
                    if (hMod == '00') hMod = 12;
                    return hMod;
                case '%j' :
                    return oD.getDayOfYear();
                case '%m' :
                    return this.TZ(utc ? oD.getUTCMonth() + 1 : oD.getMonth() + 1);
                case '%M' :
                    return this.TZ(utc ? oD.getUTCMinutes() : oD.getMinutes());
                case '%n' :
                    return '<br />';
                case '%S' :
                    return this.TZ(utc ? oD.getUTCSeconds() : oD.getSeconds());
                case '%u' : case '%w' :
                    var d = (utc ? oD.getUTCDay() : oD.getDay());
                    if (x=='%u' && d==0) d=7;
                    return d;
                case '%U' : case '%W' :
                    return oD.getWeekOfYear();
                case '%y' : case '%Y' : case '%G' : case '%C' : case '%g' :
                    var y = (utc ? oD.getUTCFullYear() : oD.getFullYear()) + "";
                    if (x==='%y' || x==='%g') return y.substr(2,2);
                    if (x=='%C') return this.TZ(Math.ceil(y/100) + "");
                    return y;
                case '%Z' :
                    var s = (oD.toString()).split(':');
                    var s = (oD.toString().split(':'));
                    if (s[2]) {
                        s = s[2].split(' ');
                        s = s[1] ? s[1] : false; 
                    } else {
                        s = false;
                    }
                    return (s ? s : 'TZ:' + oD.getTimezoneOffset());
                case '%z' :
                    return oD.getTimezoneOffset();
                case '%%' :
                    return '&#37;';
                default :
                    return x;
            }
        },
        populate: function(property) {
            return DateFormatLang.Populate(property.get('lang'), 
                (property.get('format') || DateFormatLang[this.defaultLang][1]), 
                (property.get('months') || DateFormatLang[this.defaultLang][2]), 
                (property.get('monthsAbbr') || DateFormatLang[this.defaultLang][3]), 
                (property.get('days') || DateFormatLang[this.defaultLang][4]), 
                (property.get('daysAbbr') || DateFormatLang[this.defaultLang][5]));
        },
        TZ: function(x) {
            return(x<0||x>9?"":"0")+x;
        },
        unTZ: function(x) {
            return parseInt(x);
        }
});
