
    var _ng_date_object = {
        language:{
            days:{'char':["S", "M", "T", "W", "T", "F", "S"], 'short':["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], mid:["Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat"], 'long':["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
            months:{'short':["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], 'long':["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
            am_pm:{lowerCase:["am", "pm"], upperCase:["AM", "PM"]}
            },
        daysInMonth:function () {var a = new Date(this.getFullYear(), this.getMonth(), 28);var i = 28;for (i = 28; i <= 32; i++) {a.setDate(i);if (a.getMonth() != this.getMonth()) {return i - 1;}}},
        isLeapYear:function () {var a = new Date(this.getFullYear(), 1, 29);return a.getMonth() == 1;},
        fromString:function (a) {var b = Date.parse(a.replace(/[-|\\]/g, "/"));if (isNaN(b)) {a = a.toLowerCase();a = a.replace(/(\s)*([\+|-])(\s)*/g, "$2");var y = this.getFullYear();var m = this.getMonth();var d = this.getDate();if (a == "yesterday") {d = this.getDate() - 1;} else if (a == "tomorrow") {d = this.getDate() + 1;} else if (a.indexOf("today+") >= 0) {d = this.getDate() + a.replace("today+", "").toInt();} else if (a.indexOf("today-") >= 0) {d = this.getDate() - a.replace("today-", "").toInt();} else if (a == "last month") {m = this.getMonth() - 1;} else if (a == "next month") {m = this.getMonth() + 1;} else if (a.indexOf("month+") >= 0) {m = this.getMonth() + a.replace("month+", "").toInt();} else if (a.indexOf("month-") >= 0) {m = this.getMonth() - a.replace("month-", "").toInt();} else if (a == "last year") {y = this.getFullYear() - 1;} else if (a == "next year") {y = this.getFullYear() + 1;} else if (a.indexOf("year+") >= 0) {y = this.getFullYear() + a.replace("year+", "").toInt();} else if (a.indexOf("year-") >= 0) {y = this.getFullYear() - a.replace("year-", "").toInt();}var c = new Date(y, m, d, this.getHours(), this.getMinutes(), this.getSeconds(), this.getMilliseconds());} else {var c = new Date(b);}return c;},
        fromObject:function (a) {var b = {};var p;for (p in a) {b[p] = a[p];}if (!$defined(b.date)) {b.date = this.getDate();}if (!$defined(b.month)) {b.month = this.getMonth();}if (!$defined(b.year)) {b.year = this.getFullYear();}if (!$defined(b.hour)) {b.hour = this.getHours();}if (!$defined(b.minute)) {b.minute = this.getMinutes();}if (!$defined(b.second)) {b.second = this.getSeconds();}if (!$defined(b.millisecond)) {b.millisecond = this.getMilliseconds();}if ($type(b.date) != "string") {return new Date(b.year, b.month, b.date, b.hour, b.minute, b.second, b.millisecond);}b.date = b.date.toLowerCase();var d = new Date(b.year, b.month, 1);var e;if (b.date.indexOf("sunday") != -1) {e = 0;} else if (b.date.indexOf("monday") != -1) {e = 1;} else if (b.date.indexOf("tuesday") != -1) {e = 2;} else if (b.date.indexOf("wednesday") != -1) {e = 3;} else if (b.date.indexOf("thursday") != -1) {e = 4;} else if (b.date.indexOf("friday") != -1) {e = 5;} else if (b.date.indexOf("saturday") != -1) {e = 6;}if (d.getDay() > e) {var f = d.getDate() + e + 1;} else if (d.getDay() < e) {var f = e - d.getDay() + 1;} else {var f = 1;}var g = ["1st", "2nd", "3rd", "4th", "5th"];var c = 5;var h = d.daysInMonth();while (b.date.indexOf("last") != -1) {if (f + c * 7 <= h) {b.date = b.date.replace("last", g[c]);}c--;if (c < 0) {b.date = b.date.replace("last", "1st");}}var i;if (b.date.indexOf("1st") != -1) {i = 0;} else if (b.date.indexOf("2nd") != -1) {i = 1;} else if (b.date.indexOf("3rd") != -1) {i = 2;} else if (b.date.indexOf("4th") != -1) {i = 3;} else if (b.date.indexOf("5th") != -1) {i = 4;}return new Date(b.year, b.month, f + i * 7);},
        print:function (a, b) {if (!$defined(b)) {b = this.language;} else {if ($defined(b.days)) {if (!$defined(b.days['char'])) {b.day['char'] = this.language.days['char'];}if (!$defined(b.days['short'])) {b.day['short'] = this.language.days['short'];}if (!$defined(b.days.mid)) {b.day.mid = this.language.days.mid;}if (!$defined(b.days['long'])) {b.day['long'] = this.language.days['long'];}} else {b.days = this.language.days;}if ($defined(b.months)) {if (!$defined(b.months['short'])) {b.months['short'] = this.language.months['short'];}if (!$defined(b.months['long'])) {b.months['long'] = this.language.months['long'];}} else {b.months = this.language.months;}if ($defined(b.am_pm)) {if (!$defined(b.am_pm.lowerCase)) {b.am_pm.lowerCase = this.language.am_pm.lowerCase;}if (!$defined(b.am_pm.upperCase)) {b.am_pm.upperCase = this.language.am_pm.upperCase;}} else {b.am_pm = this.language.am_pm;}}var i = 0;var c = "";var d = "";for (i = 0; i < a.length; i++) {d = a.charAt(i);if (d == "d") {if (this.getDate() < 10) {c += "0";}c += this.getDate();} else if (d == "D") {c += b.days.mid[this.getDay()];} else if (d == "j") {c += day;} else if (d == "l") {c += b.days['long'][this.getDay()];} else if (d == "N") {var e = this.getDay();if (e == 0) {e = 7;}c += e;} else if (d == "S") {if (this.getDate() == "1" || this.getDate() == "21" || this.getDate() == "31") {c += "st";} else if (this.getDate() == "2" || this.getDate() == "22") {c += "nd";} else if (this.getDate() == "3" || this.getDate() == "23") {c += "rd";} else {c += "th";}} else if (d == "w") {c += this.getDay();} else if (d == "z") {c += this.getDayInYear();} else if (d == "F") {c += b.months['long'][this.getMonth()];} else if (d == "M") {c += b.months['short'][this.getMonth()];} else if (d == "m") {if (this.getMonth()+1 < 10) {c += 0;}c += this.getMonth()+1;} else if (d == "n") {c += this.getMonth();} else if (d == "t") {c += this.daysInMonth();} else if (d == "L") {if (this.isLeapYear()) {c += 1;} else {c += 0;}} else if (d == "Y" || d == "o") {c += this.getFullYear();} else if (d == "y") {c += this.getFullYear().toString().substr(2, 2);} else if (d == "a") {if (this.getHours() < 12) {c += b.am_pm.lowerCase[0];} else {c += b.am_pm.lowerCase[1];}} else if (d == "A") {if (this.getHours() < 12) {c += b.am_pm.upperCase[0];} else {c += b.am_pm.upperCase[1];}} else if (d == "B") {c += this.toSwatchInternetTime();} else if (d == "g") {var f = this.getHours() % 12;if (f == 0) {f = 12;}c += f;} else if (d == "G") {c += this.getHours();} else if (d == "h") {var f = this.getHours() % 12;if (f == 0) {f = 12;}if (h < 10) {r += 0;}c += f;} else if (d == "H") {if (this.getHours() < 10) {c += 0;}c += this.getHours();} else if (d == "i") {if (this.getMinutes() < 10) {c += 0;}c += this.getMinutes();} else if (d == "s") {if (this.getSeconds() < 10) {c += 0;}c += this.getSeconds();} else if (d == "u") {c += this.getMilliseconds();} else if (d == "O" || d == "P") {var f = this.getTimezoneOffset() / 60;var g = f - Math.floor(f);g = g * 60;f = Math.floor(f);g = Math.floor(g);if (f == 0) {f = "00";} else if (f > -10 && f < 0) {f = "-0" + Math.abs(f);} else if (f < 10 && f > 0) {f = "0" + f;} else {f = f.toString();}if (f > 0) {c += "+";}if (g < 10) {g = "0" + g;} else {g = g.toString();}if (d == "P") {var j = ":";} else {var j = "";}c += f + j + g;} else if (d == "Z") {c += this.getTimezoneOffset();} else if (d == "c") {a = a.substr(0, i - 0) + "Y-m-dTH:i:sP" + a.substr(0, i);i--;} else if (d == "r") {a = a.substr(0, i - 0) + "D, d M Y H:i:s O" + a.substr(0, i);i--;} else if (d == "U") {c += Math.floor(this.timeDifference(new Date(1970, 0, 1)) / 1000);} else {c += d;}}return c;},
        getWeekInYear:function () {return Math.floor(this.getDayInYear() / 7);},
        getDayInYear:function () {return Math.floor(this.getHourInYear() / 24);},
        getHourInYear:function () {return Math.floor(this.getMinuteInYear() / 60);},
        getMinuteInYear:function () {return Math.floor(this.getSecondInYear() / 60);},
        getSecondInYear:function () {return Math.floor(this.getMillisecondInYear() / 1000);},
        getMillisecondInYear:function () {return this.timeDifference(new Date(this.getFullYear(), 0, 1));},
        getWeekSince:function (a) {return Math.floor(this.getDaySince(a) / 7);},
        getDaySince:function (a) {return Math.floor(this.getHourSince(a) / 24);},
        getHourSince:function (a) {return Math.floor(this.getMinuteSince(a) / 60);},
        getMinuteSince:function (a) {return Math.floor(this.getSecondSince(a) / 60);},
        getSecondSince:function (a) {return Math.floor(this.getMillisecondSince(a) / 1000);},
        getMillisecondSince:function (a) {return this.timeDifference(a);},
        timeDifference:function (a) {return this.getTime() - a.getTime();},
        toSwatchInternetTime:function () {var a = this.getHours() * 3600 + this.getMinutes() * 60 + this.getSeconds() + (this.getTimezoneOffset() + 60) * 60;var b = Math.floor(a / 86.4);return "@" + b;},
        fromSwatchInternetTime:function (a) {if ($type(a) == "string") {a = a.replace("@", "").toInt();}var b = Math.floor(a * 86.4) - (this.getTimezoneOffset() + 60) * 60;var c = new Date(this.getFullYear(), this.getMonth(), this.getDate());c.setTime(c.getTime() + b * 1000);return c;}
};
    if ($defined($native)) {
        $native(Date);
        Date.extend(_ng_date_object);
    } else {
        Native.implement([Date], _ng_date_object);
    }
    var Calendar = new Class(
    {options:{visible:false, offset:{x:0, y:0}, dateFormat:"D, d M Y", numMonths:1, classPrefix:"ng-", idPrefix:"ng-", startDay:0, startDate:"today", endDate:"year+10", inputType:"text", inputField:null, allowSelection:true, multiSelection:false, maxSelection:0, selectedDate:null, datesOff:[], allowDatesOffSelection:false, daysOff:[], allowDaysOffSelection:false, weekend:[0, 6], allowWeekendSelection:false, forceSelections:[], onSelect:function () {return;}, onUnSelect:function () {return;}, onCalendarLoad:function () {return;}, onOpen:function () {return;}, onClose:function () {return;}, onClear:function () {return;}, formmater:function (a) {return a.getDate();}, outOfRangeFormmater:function (a) {return a.getDate();}, weekendFormmater:function (a) {return a.getDate();}, daysOffFormmater:function (a) {return a.getDate();}, datesOffFormmater:function (a) {return a.getDate();}, selectedDateFormmater:function (a) {return a.getDate();}, language:null, daysText:"mid", monthsText:"long", preTdHTML:"&laquo;", preTdHTMLOff:"&nbsp;", nexTdHTML:"&raquo;", nexTdHTMLOff:"&nbsp;", closeLinkHTML:"Close", clearLinkHTML:"Clear", calEvents:{mouseenter:function (a) {if (!a.hasClass(this.options.classPrefix + "selected-day")) {a.addClass(this.options.classPrefix + "mouse-over");}}, mouseleave:function (a) {a.removeClass(this.options.classPrefix + "mouse-over");}}, tdEvents:[], dateOnAvailable:[], speedFireFox:false, closeOpenCalendars:true},
    initialize:function (b, c, d) {
        //alert('initializing...');
        this.element = $(b);
        if ($defined(c)) {
            this.toggler = $(c);
        } else {
            this.toggler = null;
        }
        this.visibleMonth = [];
        this.manageTDs = [];
        this.selectedDates = [];
        this.setOptions(d);
        this.options.inputType = this.options.inputType.toLowerCase();
        this.date = new Date;
        this.date = new Date(this.date.getFullYear(), this.date.getMonth(), this.date.getDate());
        if ($defined(this.options.language)) {
            this.date.language = this.options.language;
        }
        this.options.startDate = this.processDates(this.options.startDate);
        this.options.endDate = this.processDates(this.options.endDate);
        if (!$defined(this.options.startDate)) {
            this.options.startDate = this.date.fromObject({date:"year-10"});
        }
        if (!$defined(this.options.endDate)) {
            this.options.endDate = this.date.fromObject({date:"year+10"});
        }
        this.options.selectedDate = this.processDates(this.options.selectedDate);
        if (!this.isSelectable(this.options.selectedDate)) {
            this.options.selectedDate = null;
        }
        this.options.selectedDate2 = this.processDates(this.options.selectedDate2);
        if (!this.isSelectable(this.options.selectedDate2)) {
            this.options.selectedDate2 = null;
        }
        if (!this.options.visible) {
            if (window.ie && !window.ie7) {
                this.iframe = new Element("iframe", {src:"about:Blank", styles:{position:"absolute", 'z-index':20000, opacity:0, 'background-color':"#ffffff"}, frameborder:0});
                    document.body.appendChild(this.iframe);
            }

            //console.log(this);

            this.element.setStyles({position:"absolute", 'z-index':25000, opacity:0});
            if ($defined(this.toggler)) {
                this.toggler.addEvent("click", (
                    function (e) {
                        var e = new Event(e);
                        if (this.element.getStyle("opacity") == 0) {
                            this.openCalendar();
                        } else {
                            this.closeCalendar();
                        }
                        e.stop();
                    }).bind(this));
            }
        }
        if (this.options.numMonths > 1) {
            this.loading_div = new Element("div", {styles:{position:"absolute", 'z-index':26000, opacity:0, background:"#FFFFFF"}});
                this.element.appendChild(this.loading_div);
        }
        var f = new Element("table", {'class':this.options.classPrefix + "cal-header-table"});
        var g = new Element("tbody");f.appendChild(g);
        var h = new Element("tr");
        this.preTD = new Element("td", {'class':this.options.classPrefix + "cal-previous-td"});
        this.preTD.addEvent("click", (function () {var i = this.options.numMonths;var a;while (i > 0) {a = this.date.fromString("month-" + i);if (!this.isOutOfRange(a)) {a.fromString("month-1");break;}i--;}if (i > 0) {this.updateCalendar(a);}}).bind(this));
        h.appendChild(this.preTD);
        this.headerTD = new Element("td", {'class':this.options.classPrefix + "cal-header-td"});
        h.appendChild(this.headerTD);
        this.nexTD = new Element("td", {'class':this.options.classPrefix + "cal-next-td"});
        this.nexTD.addEvent("click", (function () {var i = this.options.numMonths;var a;while (i > 0) {a = this.date.fromString("month+" + i);a.fromString("month-1");if (!this.isOutOfRange(a)) {break;}i--;}if (i > 0) {this.updateCalendar(a);}}).bind(this));
        h.appendChild(this.nexTD);
        this.updateHeader();
        g.appendChild(h);
        this.element.appendChild(f);
        this.calendarHolder = new Element("div");
        this.element.appendChild(this.calendarHolder);
        var j = new Element("div", {styles:{clear:"both"}});
        this.element.appendChild(j);
        var k = new Element("div", {styles:{clear:"both", height:1, 'font-size':"1px"}});
        k.setHTML("&nbsp;");
        this.element.appendChild(k);
        if (!this.options.visible) {
            var l = new Element("a", {'class':this.options.classPrefix + "close-link", href:"#"});
            l.addEvent("click", (function (e) {var e = new Event(e);e.preventDefault();this.closeCalendar();}).bind(this));
            l.setHTML(this.options.closeLinkHTML);
            j.appendChild(l);
        }
        if (this.options.multiSelection) {
            var m = new Element("a", {'class':this.options.classPrefix + "clear-link", href:"#"});
            m.addEvent("click", (function (e) {var e = new Event(e);e.preventDefault();this.unselectAll();}).bind(this));
            m.setHTML(this.options.clearLinkHTML);
            j.appendChild(m);
        }
        this.populateCalender();
        if (this.options.allowSelection) {
            if (this.options.inputType == "select") {
                this.options.inputField.year = $(this.options.inputField.year);
                this.options.inputField.month = $(this.options.inputField.month);
                this.options.inputField.date = $(this.options.inputField.date);
                this.options.inputField.year.addEvent("change", (function () {if (this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value != "") {if ($defined(this.options.selectedDate)) {var a = new Date(this.options.selectedDate.getTime());} else {var a = new Date(this.date.getTime());}a.setYear(this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value);if (!this.options.multiSelection) {this.selectDate(a);}this.updateCalendar(a);this.populateMonthSelect();}}).bind(this));
                this.options.inputField.month.addEvent("change", (function () {if (this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value != "") {if ($defined(this.options.selectedDate)) {var a = new Date(this.options.selectedDate.getTime());} else {var a = new Date(this.date.getTime());}a.setMonth(this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value.toInt() - 1);if (!this.options.multiSelection) {this.selectDate(a);}if (!$defined(this.visibleMonth[a.getMonth() + "-" + a.getFullYear()])) {this.updateCalendar(a);}this.populateDateSelect(this.options.inputField);}}).bind(this));
                this.options.inputField.date.addEvent("change", (function () {if ($defined(this.options.selectedDate)) {var a = new Date(this.options.selectedDate.getTime());} else {var a = new Date(this.date.getTime());}a.setDate(this.options.inputField.date.options[this.options.inputField.date.selectedIndex].value);this.selectDate(a);}).bind(this));
                this.populateSelect();
            } else if (this.options.inputType == "text") {
                this.options.inputField = $(this.options.inputField);
                this.options.inputField.addEvent("focus", (function () {this.openCalendar();}).bind(this));
                this.options.inputField.addEvent("keydown", function (e) {var e = new Event(e);if (e.key.length == 1 || e.key == "space") {e.stop();}});
            }
        }

        if ($defined(this.options.selectedDate)) {
            this.selectDate(this.options.selectedDate);
        }
        _all_page_calendars.push(this);
        //alert('initialized...');
    },

    populateSelect:function () {
        if (this.options.inputType != "select") {
            return;
        }
        this.options.inputField.year.empty();
        var a = new Element("option");
        this.options.inputField.year.appendChild(a);
        var i = 0;
        for (i = this.options.startDate.getFullYear(); i <= this.options.endDate.getFullYear(); i++) {
            a = new Element("option", {value:i});
            a.setText(i);
            if ($defined(this.options.selectedDate) && this.options.selectedDate.getFullYear() == i) {
                a.selected = "selected";}
                this.options.inputField.year.appendChild(a);}
                this.populateMonthSelect();
    },

    populateMonthSelect:function () {
        if (this.options.inputType != "select") {
            return;
        }
        var a = 0;
        if (this.options.startDate.getFullYear() == this.date.getFullYear()) {
            a = this.options.startDate.getMonth();}
            var b = 11;
            if (this.options.endDate.getFullYear() == this.date.getFullYear()) {
                b = this.options.endDate.getMonth();}
                this.options.inputField.month.empty();
                opt = new Element("option");
                this.options.inputField.month.appendChild(opt);
                for (i = a; i <= b; i++) {
                    opt = new Element("option", {value:i + 1});
                    opt.setText(this.date.language.months[this.options.monthsText][i]);
                    if ($defined(this.options.selectedDate) && this.options.selectedDate.getMonth() == i) {
                        opt.selected = "selected";}
                        this.options.inputField.month.appendChild(opt);}
                        this.populateDateSelect();
    },
    populateDateSelect:function () {
        if (this.options.inputType != "select") {
            return;
        }
        if (this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value != "" && this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value != "") {
            var a = new Date(this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value, this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value - 1, 1);
        } else if ($defined(this.options.selectedDate)) {
            var a = this.options.selectedDate;
        } else {
            var a = this.date;
        }
        var b = a.daysInMonth();
        this.options.inputField.date.empty();
        opt = new Element("option");
        this.options.inputField.date.appendChild(opt);
        var c;for (i = 1; i <= b; i++) {
            opt = new Element("option", {value:i});
            opt.setText(i);
            if (!this.isSelectable(new Date(a.getFullYear(), a.getMonth(), i))) {
                opt.disabled = true;
                opt.setStyles({color:"#cccccc"});
            } else if ($defined(this.options.selectedDate) && this.options.selectedDate.getDate() == i && this.options.selectedDate.getMonth() == this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value - 1 && this.options.selectedDate.getFullYear() == this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value) {
                opt.selected = "selected";
            }
            this.options.inputField.date.appendChild(opt);
        }
    },
    populateCalender:function () {
        if ($defined(this.iframe)) {
            this.iframe.setStyles({width:this.element.getStyle("width"), height:this.element.getStyle("height")});
        }
        var c = function (a, b) {
            var i = 0;
            this.visibleMonth = [];
            this.calendarHolder.setHTML("");
            for (i = 0; i < this.options.numMonths; i++) {
                this.calendarHolder.innerHTML += this.createCalenderTable(a, b);
                this.visibleMonth[a + "-" + b] = true;
                a++;
                if (a > 11) {
                    a = 0;b++;
                }
            }
            if (this.options.numMonths > 1) {
                this.loading_div.setOpacity(0);
            }
            this.processTdEvents();
            this.fireEvent("onCalendarLoad");
        };
        if (this.options.numMonths > 1) {
            if (this.element.getStyle("opacity") > 0) {
                this.loading_div.setStyles({opacity:0.5, height:this.element.getStyle("height"), width:this.element.getStyle("width")});
            }
            c.delay(1, this, [this.date.getMonth(), this.date.getFullYear()]);
        } else {
            this.calendarHolder.innerHTML = this.createCalenderTable(this.date.getMonth(), this.date.getFullYear());
            this.visibleMonth[this.date.getMonth() + "-" + this.date.getFullYear()] = true;
            this.processTdEvents();
        }
    },
    createCalenderTable:function (a, b) {
        var t = new Array;
        t[t.length] = "<table class=\"" + this.options.classPrefix + "cal\" id=\"" + this.options.idPrefix + "month-" + (a + 1) + "-" + b + "-table" + "\"><tr>				<th class=\"" + this.options.classPrefix + "month-name-th" + "\" id=\"" + this.options.idPrefix + "month-name-" + (a + 1) + "-" + b + "-th" + "\" colspan=\"7\">" + this.date.language.months[this.options.monthsText][a] + " " + b + "</th></tr><tr>";
        var i = 0;
        var c = 0;
        for (i = 0; i < 7; i++) {
            c = (i + this.options.startDay) % 7;
            t[t.length] = "<td class=\"" + this.options.classPrefix + "days-name-td" + "\" id=\"" + this.options.idPrefix + "days-name-" + c + "-" + (a + 1) + "-" + b + "-td" + "\">" + this.date.language.days[this.options.daysText][c] + "</td>";
        }
        t[t.length] = "</tr>";
        var d = new Date(b, a, 1);
        d.setDate(d.getDate() - (d.getDay() - this.options.startDay));
        var i, j, className, title, html, id_str, selectable;
        var f = 7;
        for (i = 1; i < f; i++) {
            t[t.length] = "<tr>";
            for (j = 1; j <= 7; j++) {
                className = "";
                html = "";
                id_str = "";
                if (d.getMonth() != a) {
                    id_str = d.getMonth() + 1 + "-" + d.getDate() + "-" + d.getFullYear();
                    t[t.length] = "<td class=\"" + this.options.classPrefix + "date-" + id_str + " " + this.options.classPrefix + "outOfRange" + "\">" + this.options.outOfRangeFormmater(d) + "</td>";
                } else {
                    selectable = this.isSelectable(d, true);
                    if (selectable[1] == "outOfRange") {
                        className = this.options.classPrefix + "outOfRange";
                        html = this.options.outOfRangeFormmater(d);
                    } else if (selectable[1] == "weekend") {
                        className = this.options.classPrefix + "weekend";
                        html = this.options.weekendFormmater(d);
                    } else if (selectable[1] == "dayOff") {
                        className = this.options.classPrefix + "dayOff";
                        html = this.options.daysOffFormmater(d);
                    } else if (selectable[1] == "dateOff") {
                        className = this.options.classPrefix + "dateOff";
                        html = this.options.datesOffFormmater(d);
                    } else {
                        html = this.options.formmater(d);
                    }
                    if (selectable[0]) {
                        if (this.isSelected(d)) {
                            className += " " + this.options.classPrefix + "selected-day";
                            html = this.options.selectedDateFormmater(d);
                        }
                    }
                    id_str = d.getMonth() + 1 + "-" + d.getDate() + "-" + d.getFullYear();
                    this.manageTDs[id_str] = [];
                    t[t.length] = "<td class=\"" + this.options.classPrefix + "date-" + id_str + " " + className + "\" id=\"" + this.options.idPrefix + "date-" + id_str + "\">" + html + "</td>";
                    if (selectable[0]) {
                        this.manageTDs[id_str].click = true;
                    }
                    if ($defined(this.options.tdEvents[id_str])) {
                        if (!$defined(this.manageTDs[id_str].event)) {
                            this.manageTDs[id_str].event = [];
                        }
                        for (e in this.options.tdEvents[id_str]) {
                            this.manageTDs[id_str].event[e] = this.options.tdEvents[id_str][e];
                        }
                    }
                    if ($defined(this.options.dateOnAvailable[id_str])) {
                        if (!$defined(this.manageTDs[id_str].dateOnAvailable)) {
                            this.manageTDs[id_str].dateOnAvailable = [];
                        }
                        this.manageTDs[id_str].dateOnAvailable.push(this.options.dateOnAvailable[id_str]);
                    }
                }
                d.setDate(d.getDate() + 1);
            }
            t[t.length] = "</tr>";
            if (d.getMonth() > a && this.options.numMonths == 1) {
                f = 6;
            }
        }
        t[t.length] = "</table>";
        return t.join("");
    },


    processTdEvents:function () {
        var d, obj;
        for (p in this.manageTDs) {
            obj = this.manageTDs[p];
            d = $(this.options.idPrefix + "date-" + p);
            var f = p;
            if ($defined(obj.click)) {
                d.addEvent("click", (function (a, b) {
                    var c = (new Date).fromString(b);
                    if (this.isSelected(c)) {
                        this.unselectDate(c);
                    } else {
                        this.selectDate(c);
                    }
                }).bind(this, [d, f]));
                d.setStyle("cursor", "pointer");
                for (e in this.options.calEvents) {
                    d.addEvent(e, this.options.calEvents[e].bind(this, d));
                }
            }
            if ($defined(obj.event)) {
                for (ep in obj.event) {
                    d.addEvent(ep, obj.event[ep].bind(this, [d, f]));
                }
            }
            if ($defined(obj.dateOnAvailable)) {
                obj.dateOnAvailable.each(function (a) {a.attempt([d, f], this);}, this);
            }
        }
        this.manageTDs = [];
    },

    isWeekend:function (a) {return this.options.weekend.contains(a);
    },

    isDayOff:function (a) {
        if (this.options.speedFireFox && window.gecko) {
            return false;
        }
        return this.options.daysOff.contains(a);
    },
    isDateOff:function (a) {
        if (this.options.speedFireFox && window.gecko) {
            return false;
        }
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        var j = 0;
        var b = this.options.datesOff.length;
        for (j = 0; j < b; j++) {
            cur_date = this.processDates(this.options.datesOff[j], a);
            if ($defined(cur_date)) {
                if (a.getTime() == cur_date.getTime()) {
                    return true;
                }
            }
        }
        return false;
    },

    isOutOfRange:function (a) {
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        return a.getTime() < this.options.startDate.getTime() || a.getTime() > this.options.endDate.getTime();
    },

    isSelectable:function (a, b) {
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        if (!$defined(b) && !this.options.allowSelection) {
            return false;
        }
        var c = [true, a];
        if (this.isOutOfRange(a)) {
            c = [false, "outOfRange"];
        } else if (!this.options.allowDaysOffSelection && this.isDayOff(a.getDay())) {
            c = [false, "dayOff"];
        } else if (!this.options.allowWeekendSelection && this.isWeekend(a.getDay())) {
            c = [false, "weekend"];
        } else if (!this.options.allowDatesOffSelection && this.isDateOff(a)) {
            c = [false, "dateOff"];
        }
        if (!this.options.allowSelection && c[0]) {
            c = [false, "noSelection"];
        }
        if (!c[0]) {
            if (this.isForcedSelection(a)) {
                c = [true, a];
            }
        }
        if ($defined(b)) {
            return c;
        } else {
            return c[0];
        }
        return [false, a];
    },

    isForcedSelection:function (a) {
        if (this.options.speedFireFox && window.gecko) {
            return false;
        }
        var i = 0;
        var b = this.options.forceSelections.length;
        var c;
        for (i = 0; i < b; i++) {
            c = this.processDates(this.options.forceSelections[i], a);
            if (c.getTime() == a.getTime()) {
                return true;
            }
        }
        return false;
    },

    isSelected:function (a) {
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        return this.selectedDates.contains(a.getTime());
    },

    updateCalendar:function (a) {
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        if (this.isOutOfRange(a)) {
            this.date = this.options.startDate;
        } else {
            this.date = a;
        }
        this.populateCalender();
        this.updateHeader();
    },

    selectDate:function (a) {
        if (!this.options.allowSelection) {
            return false;
        }
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        if (this.options.maxSelection > 0 && this.selectedDates.length >= this.options.maxSelection) {
            return false;
        }
        if (this.isSelectable(a)) {
            if (this.options.inputType == "select") {
                var b = true;
                var c = true;
                if ($defined(this.options.selectedDate)) {
                    if (a.getFullYear() == this.options.selectedDate.getFullYear()) {
                        b = false;
                    } else if (a.getMonth() == this.options.selectedDate.getMonth()) {
                        c = false;
                    }
                }
            }
            if (!this.options.multiSelection) {
                this.unselectDate(this.options.selectedDate);
            }
            this.options.selectedDate = this.date = a;
            this.selectedDates.push(a.getTime());
            var d = this.options.idPrefix + "date-" + (a.getMonth() + 1) + "-" + a.getDate() + "-" + a.getFullYear();
            if ($defined($(d))) {
                $(d).removeClass(this.options.classPrefix + "mouse-over");
                $(d).addClass(this.options.classPrefix + "selected-day");
                $(d).setHTML(this.options.selectedDateFormmater(this.options.selectedDate));
            }
            if (this.options.inputType == "select") {
                if (b) {
                    this.populateMonthSelect();
                } else if (c) {
                    this.populateDateSelect();
                }
                this.selectSelectMenu();
            } else if (this.options.inputType == "text") {
                this.fillInputField();
            }
            this.fireEvent("onSelect");
            this.closeCalendar();
            return true;
        } else {
            if (this.options.inputType == "select") {
                this.options.inputField.date.selectedIndex = 0;
                return false;
            }
        }
        this.updateHeader();
    },

    unselectDate:function (a) {
        if (!this.options.allowSelection) {
            return false;
        }
        var a = this.processDates(a);
        if (!$defined(a)) {
            return false;
        }
        this.selectedDates.remove(a.getTime());
        var b = this.options.idPrefix + "date-" + (a.getMonth() + 1) + "-" + a.getDate() + "-" + a.getFullYear();
        if ($defined($(b))) {
            $(b).removeClass(this.options.classPrefix + "selected-day");
        }
        if ($defined(this.options.selectedDate) && this.options.multiSelection) {
            if (this.options.selectedDate.getTime() == a.getTime()) {
                if ($defined(this.selectedDates.getLast())) {
                    this.options.selectedDate = new Date(this.selectedDates.getLast());
                } else {
                    this.options.selectedDate = null;
                }
            }
        } else {
            this.options.selectedDate = null;
        }
        if (this.options.inputType == "select") {
            var c = true;
            var d = true;
            if ($defined(this.options.selectedDate)) {
                if (a.getFullYear() == this.options.selectedDate.getFullYear()) {
                    c = false;
                } else if (a.getMonth() == this.options.selectedDate.getMonth()) {
                    d = false;
                }
            }
            if (c) {
                this.populateMonthSelect();
            } else if (d) {
                this.populateDateSelect();
            }
            this.selectSelectMenu();
        } else if (this.options.inputType == "text") {
            this.options.inputField.value = this.options.inputField.value.replace(a.print(this.options.dateFormat, this.options.language), "");
        }
        this.fireEvent("onUnSelect");
    },

    unselectAll:function () {
        if (!this.options.allowSelection) {
            return false;
        }
        var b = this.selectedDates.copy();
        b.each(function (a) {this.unselectDate(new Date(a));}, this);
        this.fireEvent("onClear");
    },

    selectSelectMenu:function () {
        if (this.options.inputType != "select") {
            return;
        }
        if (!$defined(this.options.selectedDate)) {
            this.options.inputField.date.selectedIndex = 0;
            this.options.inputField.month.selectedIndex = 0;
            this.options.inputField.year.selectedIndex = 0;
            return;
        }
        this.options.inputField.date.selectedIndex = this.options.selectedDate.getDate();
        var a;
        var i = 0;
        var b = $ES("option", this.options.inputField.month);
        a = b.length;
        for (i = 0; i < a; i++) {
            if (b[i].value.toInt() - 1 == this.options.selectedDate.getMonth()) {
                this.options.inputField.month.selectedIndex = i;break;
            }
        }
        var b = $ES("option", this.options.inputField.year);
        a = b.length;
        for (i = 0; i < a; i++) {
            if (b[i].value.toInt() == this.options.selectedDate.getFullYear()) {
                this.options.inputField.year.selectedIndex = i;
                break;
            }
        }
    },

    fillInputField:function () {
        if (!this.options.multiSelection) {
            this.options.inputField.value = "";
        }
        this.options.inputField.value += this.options.selectedDate.print(this.options.dateFormat, this.options.language);
    },

    updateHeader:function () {
        this.headerTD.setHTML(this.date.language.months[this.options.monthsText][this.date.getMonth()] + " " + this.date.getFullYear());
        if (!this.isOutOfRange(this.date.fromString("last month"))) {
            this.preTD.setHTML(this.options.preTdHTML);
            this.preTD.setStyle("cursor", "pointer");
        } else {
            this.preTD.setHTML(this.options.preTdHTMLOff);
            this.preTD.setStyle("cursor", "");
        }
        if (!this.isOutOfRange(this.date.fromString("next month"))) {
            this.nexTD.setHTML(this.options.nexTdHTML);
            this.nexTD.setStyle("cursor", "pointer");
        } else {
            this.nexTD.setHTML(this.options.nexTdHTMLOff);this.nexTD.setStyle("cursor", "");
        }
    },

    processDates:function (a, b) {
        if (!$defined(b)) {
            b = this.date;
        }
        if ($type(a) == "object" && $defined(a.getFullYear)) {
            return a;
        } else if ($type(a) == "object") {
            return b.fromObject(a);
        } else if ($type(a) == "string") {
            return b.fromString(a);
        } else if ($type(a) == "number") {
            return new Date(a);
        } else {
            return null;
        }
    },

    openCalendar:function () {
        if (this.options.closeOpenCalendars) {
            $closeAllCalendars();
        }
        if (this.options.inputType == "select") {
            var a = this.options.inputField.date;
        } else {
            var a = this.options.inputField;
        }
        var b = a.getCoordinates();
        this.element.setStyles({top:b.top + b.height + this.options.offset.y, left:b.left + this.options.offset.x, opacity:1});
        if ($defined(this.iframe)) {
            this.iframe.setStyles({top:b.top + b.height, left:b.left, opacity:1});
        }
        this.fireEvent("onOpen");
    },

    closeCalendar:function () {
        if (this.options.visible) {
            return false;
        }
        this.element.setStyle("opacity", 0);
        if ($defined(this.iframe)) {
            this.iframe.setStyle("opacity", 0);
        }
        this.fireEvent("onClose");
    }

}
);


    Calendar.implement(new Events, new Options);
    var _all_page_calendars = [];
    var $closeAllCalendars = function () {_all_page_calendars.each(function (a) {a.closeCalendar();});};













