﻿/* Javascript by Daniel Cohen Gindi (c) danielgindi@gmail.com 054-5655765 */
/* Version: 2009-06-01 */

function datePicker() {
    var thisObj = this;
    this._FInputOnBlur = function(e) { thisObj.input_onBlur(e || event); };
    return this;
}
datePicker.prototype = {
    language: 'en',
    // 'dd/mm/yyyy', 'mm.dd.yyyy', 'yyyy-mm-dd' etc...
    dateFormat: 'dd/mm/yyyy',
    mainObj: null,
    txtCloseBtn: null,
    txtTodayBtn: null,
    closeOnBlur: false,
    zIndex: 100,
    datePickerLanguages: {
        en: {
            dayArrayShort: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
            dayArrayLong: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
            monthArrayShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
            monthArrayLong: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
            close: 'close',
            today: 'today'
        },
        he: {
            dayArrayShort: ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש'],
            dayArrayLong: ['ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'],
            monthArrayShort: ['ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוג', 'נוב', 'דצמ'],
            monthArrayLong: ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
            close: 'סגור',
            today: 'היום'
        }
    },

    hide: function() {
        if (this.mainObj) this.mainObj.style.display = 'none';
        if (this._RegisteredOnBlurO) {
            this.unregisterEvent(this._RegisteredOnBlurO, 'blur', this._FInputOnBlur);
        }
    },

    show: function(dateFieldId, displayBelowThisObject, dtFormat, alignRight, params) {
        this.hide();

        this.targetDateField = null;
        if (dateFieldId) {
            this.targetDateField = document.getElementById(dateFieldId);
            if (this.targetDateField == null) {
                this.targetDateField = document.getElementsByName(dateFieldId).item(0);
            }
        }
        if (this.targetDateField == null) return false;

        if (params.closeOnBlur) this.closeOnBlur = true;
        if (params.zIndex) this.zIndex = params.zIndex;

        if (!displayBelowThisObject) displayBelowThisObject = this.targetDateField;

        if (dtFormat) this.dateFormat = dtFormat;

        var x = displayBelowThisObject.offsetLeft;
        var y = displayBelowThisObject.offsetTop + displayBelowThisObject.offsetHeight;
        if (alignRight) x -= displayBelowThisObject.offsetWidth;

        var parent = displayBelowThisObject;
        while (parent.offsetParent) {
            parent = parent.offsetParent;
            x += parent.offsetLeft;
            y += parent.offsetTop;
        }

        var ret = this.drawDatePicker(x, y);

        if (this.targetDateField) this.targetDateField.focus();

        return ret;
    },

    drawDatePicker: function(x, y) {
        var dt = this.getFieldDate(this.targetDateField.value);

        if (this.mainObj == null) {

            this.mainObj = document.createElement('div');
            this.mainObj.className = 'datePicker_Div';
            this.mainObj.style.display = 'none';
            this.mainObj.setAttribute('tabindex', '0');
            document.body.appendChild(this.mainObj);
        }

        this.mainObj.style.position = 'absolute';
        this.mainObj.style.left = x + 'px';
        this.mainObj.style.top = y + 'px';
        this.mainObj.style.display = '';
        this.mainObj.style.zIndex = this.zIndex;

        this.refreshDatePicker(dt.getFullYear(), dt.getMonth(), dt.getDate());
    },

    refreshDatePicker: function(year, month, day) {
        this.suppressOnBlur = true;

        var thisDay = new Date();

        if ((month >= 0) && (year > 0)) {
            thisDay = new Date(year, month, 1);
        } else {
            day = thisDay.getDate();
            thisDay.setDate(1);
        }

        var lang = this.datePickerLanguages[this.language];
        var thisObj = this;
        if (!this._FDayClick) {
            this._FDayClick = function(e) {
                var evt = e || event;
                var target = evt.relatedTarget || evt.srcElement || evt.target;
                if (target) thisObj.updateDateField(target.day);
            };
        }
        var htmlTb, htmlBdy, htmlTr, htmlTd, htmlBtn, htmlDiv;

        htmlBdy = document.createElement('tbody');

        htmlTr = document.createElement('tr');
        htmlTr.className = 'datePicker_TitleTR';

        htmlTd = document.createElement('td');
        htmlTd.className = 'datePicker_ButtonTD';
        htmlBtn = document.createElement('button');
        htmlBtn.className = 'datePicker_Button';
        htmlBtn.innerHTML = '&lt;';
        this.setButtonEvent(htmlBtn, thisDay, -1);
        htmlTd.appendChild(htmlBtn);
        htmlTr.appendChild(htmlTd);

        htmlTd = document.createElement('td');
        htmlTd.className = 'datePicker_TitleTD';
        htmlTd.colSpan = 5;
        htmlDiv = document.createElement('div');
        htmlDiv.className = 'datePicker_TitleText';
        htmlDiv.innerHTML = lang.monthArrayLong[thisDay.getMonth()] + " " + thisDay.getFullYear();
        htmlTd.appendChild(htmlDiv);
        htmlTr.appendChild(htmlTd);

        htmlTd = document.createElement('td');
        htmlTd.className = 'datePicker_ButtonTD';
        htmlBtn = document.createElement('button');
        htmlBtn.className = 'datePicker_Button';
        htmlBtn.innerHTML = '&gt;';
        this.setButtonEvent(htmlBtn, thisDay, 1);
        htmlTd.appendChild(htmlBtn);
        htmlTr.appendChild(htmlTd);

        htmlBdy.appendChild(htmlTr);

        htmlTr = document.createElement('tr');
        htmlTr.className = 'datePicker_DayTR';
        for (var i = 0; i < lang.dayArrayShort.length; i++) {
            htmlTd = document.createElement('td');
            htmlTd.className = 'datePicker_DayTD';
            htmlTd.innerHTML = lang.dayArrayShort[i];
            htmlTr.appendChild(htmlTd);
        }
        htmlBdy.appendChild(htmlTr);

        htmlTr = document.createElement('tr');
        htmlTr.className = 'datePicker_TR';

        // blank days
        for (var i = 0; i < thisDay.getDay(); i++) {
            htmlTd = document.createElement('td');
            htmlTd.className = 'datePicker_TD';
            htmlTr.appendChild(htmlTd);
        }

        do {
            var dayNum = thisDay.getDate();

            htmlTd = document.createElement('td');

            if (dayNum == day) {
                htmlTd.className = 'datePicker_DayHighlightTD';
                htmlTd.day = thisObj.getDateString(thisDay);
                this.registerEvent(htmlTd, 'click', this._FDayClick);
                htmlTd.innerHTML = dayNum;
            }
            else {
                htmlTd.className = 'datePicker_TD';
                htmlTd.day = thisObj.getDateString(thisDay);
                this.registerEvent(htmlTd, 'click', this._FDayClick);
                htmlTd.innerHTML = dayNum;
            }

            htmlTr.appendChild(htmlTd);

            if (thisDay.getDay() == 6) {
                htmlBdy.appendChild(htmlTr);
                htmlTr = document.createElement('tr');
            }

            thisDay.setDate(thisDay.getDate() + 1);
        } while (thisDay.getDate() > 1)

        // blank days
        if (thisDay.getDay() > 0) {
            for (i = 7; i > thisDay.getDay(); i--) {
                htmlTd = document.createElement('td');
                htmlTd.className = 'datePicker_TD';
                htmlTr.appendChild(htmlTd);
            }
        }

        htmlBdy.appendChild(htmlTr);

        var today = new Date();
        htmlTr = document.createElement('tr');
        htmlTr.className = 'datePicker_TodayButtonTR';
        htmlTd = document.createElement('td');
        htmlTd.className = 'datePicker_TodayButtonTD';
        htmlTd.colSpan = 7;
        htmlBtn = document.createElement('button');
        htmlBtn.className = 'datePicker_TodayButton';
        htmlBtn.innerHTML = (this.txtTodayBtn != null) ? this.txtTodayBtn : lang.today;
        this.registerEvent(htmlBtn, 'click', function() { thisObj.refreshDatePicker(); })
        htmlTd.appendChild(htmlBtn);
        htmlBtn = document.createElement('button');
        htmlBtn.className = 'datePicker_TodayButton';
        htmlBtn.innerHTML = (this.txtCloseBtn != null) ? this.txtCloseBtn : lang.close;
        this.registerEvent(htmlBtn, 'click', function() { thisObj.updateDateField(); })
        htmlTd.appendChild(htmlBtn);
        htmlTr.appendChild(htmlTd);
        htmlBdy.appendChild(htmlTr);

        htmlTb = document.createElement('table');
        htmlTb.className = 'datePicker_Table';
        htmlTb.cols = 7;
        htmlTb.appendChild(htmlBdy);

        while (this.mainObj.childNodes.length > 0)
            this.mainObj.removeChild(this.mainObj.firstChild);
        this.mainObj.appendChild(htmlTb);

        if (this.closeOnBlur && this.targetDateField) {
            if (this._RegisteredOnBlurO) {
                this.unregisterEvent(this._RegisteredOnBlurO, 'blur', thisObj._FInputOnBlur);
            }
            this.registerEvent(this.targetDateField, 'blur', thisObj._FInputOnBlur);
            this._RegisteredOnBlurO = this.targetDateField;
        }

        this.suppressOnBlur = false;
    },
    input_onBlur: function(evt) {
        if (!window.ie) return;
        var target = evt.explicitOriginalTarget || document.activeElement;
        this.targetDateField.focus();
        if (this.mainObj.hasFocus) return;
        while (target) {
            if (target == this.mainObj) {
                return;
            }
            target = target.parentNode;
        }
        this.hide();
    },
    setButtonEvent: function(button, dateVal, adjust) {
        var newMonth = (dateVal.getMonth() + adjust) % 12;
        var newYear = dateVal.getFullYear() + parseInt((dateVal.getMonth() + adjust) / 12, 10);
        if (newMonth < 0) {
            newMonth += 12;
            newYear += -1;
        }

        var thisObj = this;
        this.registerEvent(button, 'click', function() { thisObj.refreshDatePicker(newYear, newMonth); });
    },
    getDateString: function(dateVal) {
        var dayString = "00" + dateVal.getDate();
        var monthString = "00" + (dateVal.getMonth() + 1);
        dayString = dayString.substring(dayString.length - 2);
        monthString = monthString.substring(monthString.length - 2);

        var strRet = this.dateFormat;
        strRet = strRet.replace('yyyy', dateVal.getFullYear());
        strRet = strRet.replace('mm', monthString);
        strRet = strRet.replace('dd', dayString);
        return strRet;
    },
    getFieldDate: function(dateString) {
        var dateVal;
        var dArray;
        var d, m, y;

        try {
            var pos_yyyy = this.dateFormat.indexOf('yyyy');
            if (pos_yyyy > -1) y = parseInt(dateString.substr(pos_yyyy, 4), 10);
            else y = new Date().getYear();
            var pos_mm = this.dateFormat.indexOf('mm');
            if (pos_mm > -1) m = parseInt(dateString.substr(pos_mm, 2), 10);
            else {
                if (pos_yyyy > -1) m = 1;
                else new Date().getMonth() + 1;
            }
            var pos_dd = this.dateFormat.indexOf('dd');
            if (pos_dd > -1) d = parseInt(dateString.substr(pos_dd, 2), 10);
            else {
                if (pos_yyyy > -1 || pos_mm > -1) d = 1;
                else new Date().getDate();
            }

            if (y == null) {
                var pos_yy = this.dateFormat.indexOf('yy');
                if (pos_yy > -1) y = dateString.substr(pos_yy, 2);
                var curYYYY = new Date().getFullYear();
                var min = parseInt(((curYYYY - 49) + '').substr(2, 2), 10);
                var min_p = parseInt(((curYYYY - 49) + '').substr(0, 2), 10);
                var max = parseInt(((curYYYY) + '').substr(2, 2), 10);
                var max_p = parseInt(((curYYYY) + '').substr(0, 2), 10);
                if ((y >= min && y <= max) || (y >= min && min > max)) {
                    y = min_p * 100 + y;
                }
                else {
                    y = max_p * 100 + y;
                }
            }
            if (y && m && d) {
                dateVal = new Date(y, m - 1, d);
            } else if (dateString) {
                dateVal = new Date(dateString);
            } else {
                dateVal = new Date();
            }
        } catch (e) {
            dateVal = new Date();
        }

        return dateVal;
    },
    updateDateField: function(dateString) {
        if (dateString) this.targetDateField.value = dateString;

        this.hide();

        this.targetDateField.focus();

        if ((dateString) && (typeof (this.eventPicked) == "function")) {
            this.eventPicked(targetDateField);
        }
    },

    registerEvent: function(element, event, ev_func, capture) {
        if (element == null) return;
        if (element.addEventListener) element.addEventListener(event, ev_func, capture ? true : false);
        else if (element.attachEvent) element.attachEvent('on' + event, ev_func);
        return ev_func;
    },
    unregisterEvent: function(element, event, ev_func, capture) {
        if (element == null) return;
        if (element.removeEventListener) element.removeEventListener(event, ev_func, capture ? true : false);
        else if (element.detachEvent) element.detachEvent('on' + event, ev_func);
    }
};
