/* 
Script: nogray_calendar_vs1.js 
Calendar class (see below)
License: 
http://www.nogray.com/license.php
provided by the NoGray.com
by Wesam Saif
http://www.nogray.com
support: support@nogray.com
*/

var NGCalendar = Class.create({
    fireEvent: function (type) {
        this.options[type]();
    },
    setOptions: function (listOption) {
        for (var option in listOption) {
            this.options[option] = listOption[option];
        }
    },
    initialize: function (el, toggler, options) {
        this.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+5',
            inputType: 'none',
            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;
            },
            formatter: function (dt) {
                return dt.getDate();
            },
            outOfRangeFormatter: function (dt) {
                return dt.getDate();
            },
            weekendFormatter: function (dt) {
                return dt.getDate();
            },
            daysOffFormatter: function (dt) {
                return dt.getDate();
            },
            datesOffFormatter: function (dt) {
                return dt.getDate();
            },
            selectedDateFormatter: function (dt) {
                return dt.getDate();
            },
            language: null,
            daysText: 'mid',
            monthsText: 'long',
            //preTdHTML: "&laquo;",
			preTdHTML: "&lt;",
            preTdHTMLOff: "&nbsp;",
            //nexTdHTML: "&raquo;",
			nexTdHTML: "&gt;",
            nexTdHTMLOff: "&nbsp;",
            closeLinkHTML: "Close",
            clearLinkHTML: "Clear",
            calEvents: { mouseenter: function (td) {
                if (!td.hasClassName(this.options.classPrefix + "selected-day")) {
                    $(td).addClassName(this.options.classPrefix + "mouse-over");
                }
            },
                mouseleave: function (td) {
                    $(td).removeClassName(this.options.classPrefix + "mouse-over");
                }
            },
            tdEvents: [],
            dateOnAvailable: [],
            speedFireFox: false,
            closeOpenCalendars: true
        };
        this.element = $(el);
        if (this.element != null)
            this.element.innerHTML = "";
        if ($defined(toggler))
            this.toggler = $(toggler);
        else
            this.toggler = null;
        this.visibleMonth = [];
        this.manageTDs = [];
        this.selectedDates = [];
        this.setOptions(options);
        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" });
        else
            this.date = this.processDates(new Date(this.options.startDate.getTime()));
        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.numMonths > 1) {
        //            this.loading_div = new Element("div", { 'styles': {
        //                'position': 'absolute',
        //                'z-index': 26000,
        //                'opacity': 0,
        //                'background': '#FFFFFF'
        //            }
        //            });
        //            this.element.insert(this.loading_div);
        //        }
        var ch = new Element("table");
		ch.addClassName(this.options.classPrefix + 'cal-header-table');
        var tbody = new Element("tbody");
        ch.insert(tbody);
        var tr = new Element("tr");
        this.preTD = new Element("td");
		this.preTD.addClassName(this.options.classPrefix + 'cal-previous-td');
        this.preTD.onclick = function () {

            var i = this.options.numMonths;
            var new_dt;
            new_dt = this.date.fromString("month-1" );
                new_dt.setDate(new_dt.daysInMonth());
                new_dt.fromString("month-1");

			
            //if (i > 0) this.updateCalendar(new_dt);
			this.updateCalendar(new_dt);
        } .bind(this);
        tr.insert(this.preTD);
        this.headerTD = new Element("td");
		this.headerTD.addClassName(this.options.classPrefix + 'cal-header-td');
        tr.insert(this.headerTD);
        this.nexTD = new Element("td");
		this.nexTD.addClassName(this.options.classPrefix + 'cal-next-td');
        this.nexTD.observe('click', function () {
			
            var i = this.options.numMonths;
            var new_dt = this.date.fromString("month+" + i);
			new_dt.setDate(1);
			new_dt.fromString("month-1");
			this.updateCalendar(new_dt);
        } .bind(this));
        tr.insert(this.nexTD);
        this.updateHeader();
        tbody.insert(tr);
        if (this.element != null)
            this.element.insert(ch);
        this.calendarHolder = new Element("div");
        if (this.element != null)
            this.element.insert(this.calendarHolder);

        //        var clear_float = new Element("div", { 'styles': { 'clear': 'both',
        //            'height': 1,
        //            'font-size': '1px'
        //        }
        //        });
        //        clear_float.innerHTML = ("&nbsp;");
        //        if (this.element != null)
        //            this.element.insert(clear_float);

        if (!this.options.visible) {
            var close_link = new Element("a", { 'class': this.options.classPrefix + 'close-link',
                'href': '#'
            });
            close_link.onclick = function (e) {
                var e = new Event(e);
                e.preventDefault();
                this.closeCalendar();
            } .bind(this);
            close_link.innerHTML = (this.options.closeLinkHTML);
            footer.insert(close_link);
        }

        if (this.options.multiSelection) {
            var clear_link = new Element("a", { 'class': this.options.classPrefix + 'clear-link',
                'href': '#'
            });
            clear_link.onclick = function (e) {
                var e = new Event(e);
                e.preventDefault();
                this.unselectAll();
            } .bind(this);

            clear_link.innerHTML = (this.options.clearLinkHTML);
            footer.insert(clear_link);
        }

        //this.populateCalendar();

        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 use_dt = new Date(this.options.selectedDate.getTime());
                        else
                            var use_dt = new Date(this.date.getTime());
                        use_dt.setYear(this.options.inputField.year.options[this.options.inputField.year.selectedIndex].value);
                        if (!this.options.multiSelection)
                            this.selectDate(use_dt);
                        this.updateCalendar(use_dt);
                        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 use_dt = new Date(this.options.selectedDate.getTime());
                        else
                            var use_dt = new Date(this.date.getTime());
                        var temp_dt = use_dt.getDate();
                        use_dt.setDate(1);
                        use_dt.setMonth(this.options.inputField.month.options[this.options.inputField.month.selectedIndex].value.toInt() - 1);
                        if (use_dt.daysInMonth() > temp_dt) use_dt.setDate(temp_dt);
                        else use_dt.setDate(use_dt.daysInMonth());
                        if (!this.options.multiSelection)
                            this.selectDate(use_dt);
                        if (!$defined(this.visibleMonth[use_dt.getMonth() + "-" + use_dt.getFullYear()]))
                            this.updateCalendar(use_dt);
                        this.populateDateSelect(this.options.inputField);
                    }
                } .bind(this));
                this.options.inputField.date.addEvent("change", function () {
                    if ($defined(this.options.selectedDate))
                        var use_dt = new Date(this.options.selectedDate.getTime());
                    else
                        var use_dt = new Date(this.date.getTime());
                    use_dt.setDate(this.options.inputField.date.options[this.options.inputField.date.selectedIndex].value);
                    this.selectDate(use_dt);
                } .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)) {
            if ((window.ie6) && (this.options.inputType == "select")) {
                (function () {
                    this.selectDate(this.options.selectedDate);
                    this.updateCalendar(this.options.selectedDate);
                }).delay(100, this);
            }
            else {
                this.updateCalendar(this.options.selectedDate);
                var date = this.options.selectedDate;
                var id_str = (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();
                this.SetValuesSelectedDate(id_str);
            }
        }
    },

    /*
    Function:
    populateSelect
    fill in the select menu values	
    */
    populateSelect: function () {

        if (this.options.inputType != "select") return;



        this.options.inputField.year.empty();



        var opt = new Element("option");

        this.options.inputField.year.insert(opt);

        var i = 0;

        for (i = this.options.startDate.getFullYear(); i <= this.options.endDate.getFullYear(); i++) {

            opt = new Element("option", { 'value': i });

            opt.setText(i);

            if (($defined(this.options.selectedDate)) && (this.options.selectedDate.getFullYear() == i)) opt.selected = "selected";

            this.options.inputField.year.insert(opt);

        }

        this.populateMonthSelect();



    },

    /*

    Function:

    populateMonthSelect

    fill in the months select menu values

			

    */

    populateMonthSelect: function () {

        if (this.options.inputType != "select") return;



        var st_mn = 0;

        if (this.options.startDate.getFullYear() == this.date.getFullYear())

            st_mn = this.options.startDate.getMonth();



        var en_mn = 11;

        if (this.options.endDate.getFullYear() == this.date.getFullYear())

            en_mn = this.options.endDate.getMonth();



        this.options.inputField.month.empty();



        opt = new Element("option");

        this.options.inputField.month.insert(opt);



        for (i = st_mn; i <= en_mn; 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.insert(opt);

        }



        this.populateDateSelect();

    },



    /*

    Function:

    populateDateSelect

    fill in the date select menu values

			

    */

    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 use_dt = 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 use_dt = this.options.selectedDate;

        else

            var use_dt = this.date;



        var en_dy = use_dt.daysInMonth();



        this.options.inputField.date.empty();



        opt = new Element("option");

        this.options.inputField.date.insert(opt);

        var seletable;

        for (i = 1; i <= en_dy; i++) {

            opt = new Element("option", { 'value': i });

            opt.setText(i);

            if (!this.isSelectable(new Date(use_dt.getFullYear(), use_dt.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.insert(opt);

        }

    },



    /* backward compaitiblity typo */

    populateCalender: function () {

        return this.populateCalendar();

    },





    /*

    Function:

    populateCalendar

    populate the calendar table from the calendar date

			

    */



    populateCalendar: function () {

        var func = function (mn, yr) {

            var i = 0;

            this.visibleMonth = [];



            this.calendarHolder.innerHTML = ("");

            for (i = 0; i < this.options.numMonths; i++) {

                this.calendarHolder.innerHTML += this.createCalenderTable(mn, yr);

                this.visibleMonth[mn + "-" + yr] = true;

                mn++;

                if (mn > 11) {

                    mn = 0;

                    yr++;

                }

            }



            if (this.options.numMonths > 1) {

                this.loading_div.setOpacity(0);

            }



            this.processTdEvents();



            if ($defined(this.iframe)) {

                this.iframe.setStyles({

                    'width': this.element.getStyle('width'),

                    'height': this.element.getStyle('height')

                });

            }



            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')
                });

            }

            func.delay(1, this, [this.date.getMonth(), this.date.getFullYear()]);

        }

        else {

            this.visibleMonth = [];



            this.calendarHolder.innerHTML = this.createCalenderTable(this.date.getMonth(), this.date.getFullYear());

            this.visibleMonth[this.date.getMonth() + "-" + this.date.getFullYear()] = true;



            this.processTdEvents();



            if ($defined(this.iframe)) {

                this.iframe.width = this.element.getStyle('width');

                this.iframe.height = this.element.getStyle('height');

            }



            this.fireEvent("onCalendarLoad");

        }

    },





    /*

    Function:

    createCalenderTable

    create the month table for the given month and year

			

    Argumesnt:

    mn: month

    yr: year

			

    Returns:

    the table HTML

			

    */

    createCalenderTable: function (mn, yr) {

        var t = new Array();

        t[t.length] = '<table class="' + this.options.classPrefix + 'cal" id="' + this.options.idPrefix + 'month-' + (mn + 1) + '-' + yr + '-table' + '">' +
					  '<tr>';

        var i = 0;

        var wd = 0;

        for (i = 0; i < 7; i++) {

            wd = (i + this.options.startDay) % 7;

            t[t.length] = '<td class="' + this.options.classPrefix + 'days-name-td' + '" id="' + this.options.idPrefix + 'days-name-' + wd + '-' + (mn + 1) + '-' + yr + '-td' + '">' + this.date.language.days[this.options.daysText][wd] + '</td>';

        }



        t[t.length] = '</tr>';



        var date = new Date(yr, mn, 1);



        date.setDate(date.getDate() - (date.getDay() - this.options.startDay));



        if ((date.getDate() <= 7) && (date.getDate() != 1)) {

            date.setDate(date.getDate() - 7);

        }



        var i, j, className, title, html, id_str, selectable;



        var loop = 7;
        var spanPrice;

        for (i = 1; i < loop; i++) {

            t[t.length] = '<tr class="weekRow">';

            for (j = 1; j <= 7; j++) {

                className = "";

                html = "";

                id_str = "";

                if (date.getMonth() != mn) {

                    id_str = (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();
                    //muestra dias diferentes al mes actual
                    //t[t.length] = '<td class="' + this.options.classPrefix + 'date-' + id_str + ' ' + this.options.classPrefix + 'outOfRange' + '">' + this.options.outOfRangeFormatter(date) + '</td>';
                    t[t.length] = '<td class=""> </td>';
                }

                else {

                    selectable = this.isSelectable(date, true);



                  if (selectable[1] == "weekend") {

                        className = this.options.classPrefix + "weekend";

                        html = this.options.weekendFormatter(date);

                    }

                    else if (selectable[1] == "dayOff") {

                        className = this.options.classPrefix + "dayOff";

                        html = this.options.daysOffFormatter(date);

                    }

                    else if (selectable[1] == "dateOff") {

                        className = this.options.classPrefix + "dateOff";

                        html = this.options.datesOffFormatter(date);

                    }

                    else {

                        html = this.options.formatter(date);

                    }



                    if (selectable[0]) {

                        if (this.isSelected(date)) {

                            className += " " + this.options.classPrefix + "selected-day";

                            html = this.options.selectedDateFormatter(date);

                        }

                    }





                    id_str = (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();

                    this.manageTDs[id_str] = [];

                    if (selectable[0]) {

                        //var item = this.getProduct(date)
                        //class="' + getClassNameItemColor(item.Color) + '" abajo

                        t[t.length] = '<td class="ng-normalDay"  id="' + this.options.idPrefix + 'date-' + id_str + '" >' + html + '</td>';

                    } else {

                        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]);

                    }



                }



                date.setDate(date.getDate() + 1);

            }

            t[t.length] = '</tr>';
            if ((date.getMonth() > mn || (date.getMonth() == 0 && date.getFullYear() > yr)) && (this.options.numMonths == 1)) break;

        }



        t[t.length] = '</table>';



        return t.join("");

    },



    /*

    Function: 

    processTdEvents

    assign custom events to the table cells

    */

    processTdEvents: function () {

        var td, obj;

        for (p in this.manageTDs) {

            obj = this.manageTDs[p];

            td = $(this.options.idPrefix + 'date-' + p);

            var date_str = p;



            if ($defined(obj['click'])) {

                td.onclick = function (date_str) {

                    this.SetValuesSelectedDate(date_str[1]);

                } .bind(this, [td, date_str]);

                $(td).setStyle({ 'cursor': 'pointer' });


                for (e in this.options.calEvents) {
                    $(td).observe(e, this.options.calEvents[e].bind(this, td));
                }
            }



            if ($defined(obj['event'])) {

                for (ep in obj['event']) {

                    if ($type(obj['event'][ep]) == "function") {

                        td.addEvent(ep, obj['event'][ep].bind(this, [td, date_str]));

                    }

                }

            }



            if ($defined(obj['dateOnAvailable'])) {

                obj['dateOnAvailable'].each(function (func) {

                    func.attempt([td, date_str], this);

                }, this);

            }

        }



        this.manageTDs = [];

    },



    SetValuesSelectedDate: function (date_str) {

        var date = new Date().fromString(date_str);

        if (this.isSelected(date)) {

            this.unselectDate(date);

            //            panelsAddToCart["ExpressPass"] = false;

            //            enabledButtonsAddToCarts(true);

            //            spanPriceSelected.innerHTML = "&nbsp;";
            //            totalPriceExpressPass.innerHTML = "&nbsp;";
            //            dateSelectedExpressPass.innerHTML = "not selected";


        } else {

            this.selectDate(date);

            //            panelsAddToCart["ExpressPass"] = true;

            //            enabledButtonsAddToCarts(true);

            //            var item = this.getProduct(date);

            //            if (item == -1) {
            //                spanPriceSelected.innerHTML = "&nbsp;";
            //                totalPriceExpressPass.innerHTML = "&nbsp;";
            //            }
            //            else {
            //                spanPriceSelected.innerHTML = "$" + item.Price;
            //                totalPriceExpressPass.innerHTML = "$" + (item.Price * parseInt(txtGuestQtyEp)).toFixed(2);
            //            }
            //            dateSelectedExpressPass.innerHTML = date.format('MM/dd/yyyy');
        }
    },

    /*

    Function:

    isWeekend

    check if the day is a weekend in the calendar

			

    Arguments:

    weekDay: a number for the weekday. 0 for Sunday 6 for Saturday

			

    Returns:

    true or false

    */

    isWeekend: function (weekDay) {
        var valueQ = this.options.weekend.indexOf(weekDay);
        if (valueQ == -1)
            return false;
        else
            return true;
    },





    /*

    Function:

    isDayOff

    check if the day is a day off in the calendar

			

    Arguments:

    weekDay: a number for the weekday. 0 for Sunday 6 for Saturday

			

    Returns:

    true or false

    */

    isDayOff: function (weekDay) {

        if ((this.options.speedFireFox) && (window.gecko)) return false;

        var valueQ = this.options.daysOff.indexOf(weekDay);
        if (valueQ == -1)
            return false;
        else
            return true;
    },





    /*

    Function:

    isDateOff

    check if the date is a date off (holiday) in the calendar

			

    Arguments:

    date: date object (check above)

			

    Returns:

    true or false

    */

    isDateOff: function (date) {

        if ((this.options.speedFireFox) && (window.gecko)) return false;

        var date = this.processDates(date);

        if (!$defined(date)) return false;



        var j = 0;

        var loop = this.options.datesOff.length;

        for (j = 0; j < loop; j++) {

            cur_date = this.processDates(this.options.datesOff[j], date);

            if ($defined(cur_date))

                if (date.getTime() == cur_date.getTime())

                    return true;

        }

        return false;

    },



    /*

    Function:

    isOutOfRange

    check if the date is out of the selectable range in the calendar

			

    Arguments:

    date: date object (check above)

			

    Returns:

    true or false

    */

    isOutOfRange: function (date) {

        var date = this.processDates(date);

        if (!$defined(date)) return false;



        return ((date.getTime() < this.options.startDate.getTime())

				||

				(date.getTime() > this.options.endDate.getTime()));

    },



    /*

    Function:

    isSelectable

    check if the date is selectable

			

    Arguments:

    date: date object (check above)

    arr: returns true or false if null

    returns an array with the first element true or false

    the second element is either the reason for false or the date

    possible reasons

    outOfRange

    dayOff

    weekend

    dateOff

			

    Returns:

    check Arguments

    */

    isSelectable: function (date, arr) {

        var date = this.processDates(date);

        if (!$defined(date)) return false;



        if ((!$defined(arr)) && (!this.options.allowSelection)) return false;



        var re = [true, date];

        if (this.isDayOff(date.getDay()))

            re = [this.options.allowDaysOffSelection, 'dayOff'];

        else if (this.isWeekend(date.getDay())) {

            if (this.isDateOff(date)) {
                re = [false, 'weekend'];
            } else {
                re = [this.options.allowWeekendSelection, 'weekend'];
            }
        }

        else if (this.isDateOff(date))

            re = [this.options.allowDatesOffSelection, 'dateOff'];



        if ((!this.options.allowSelection) && (re[0])) re = [false, 'noSelection'];



        if (!re[0])

            if (this.isForcedSelection(date)) re = [true, date];

        if ($defined(arr))

            return re;

        else

            return re[0];





        return [false, date]



    },



    /*

    Function:

    isForcedSelection

    check if the date is forced to be selectable

			

    Arguments:

    date: date object (check above)

			

    Returns:

    true or false

    */



    isForcedSelection: function (date) {

        if ((this.options.speedFireFox) && (window.gecko)) return false;

        var i = 0;

        var loop = this.options.forceSelections.length;

        var dt;

        for (i = 0; i < loop; i++) {

            dt = this.processDates(this.options.forceSelections[i], date);

            if (dt.getTime() == date.getTime()) return true;

        }

        return false;

    },





    /*

    Function:

    isSelected

    check if the date is selected or not

			

    Arguments:

    date: date object (check above)

			

    Returns:

    true or false

    */

    isSelected: function (date) {

        var date = this.processDates(date);

        if (!$defined(date)) return false;

        var valueQ = this.selectedDates.indexOf(date.getTime());

        if (valueQ == -1)
            return false;
        else
            return true;

    },



    /*

    Function:

    updateCalendar

    update the calendar months from the given date

			

    Arguments:

    date: date object (check above)



    */



    updateCalendar: function (date) {

        var date = this.processDates(date);

        if (!$defined(date)) return false;



        //if (this.isOutOfRange(date))

           // this.date = this.options.startDate;

        //else

            this.date = date;





        this.populateCalendar();

        this.updateHeader();

    },



    /*

    Function:

    selectDate

    select the given date

			

    Arguments:

    date: date object (check above)

			

    Returns:

    true if selected

    false if not



    */



    selectDate: function (date) {

        var date = this.processDates(date);

        if (!$defined(date)) return false;

        if ((this.options.maxSelection > 0) && (this.selectedDates.length >= this.options.maxSelection)) return false;

        if (this.isSelectable(date)) {

            if (this.options.inputType == "select") {

                var update_year = true;

                var update_month = true;

                if ($defined(this.options.selectedDate)) {

                    if (date.getFullYear() == this.options.selectedDate.getFullYear())

                        update_year = false;

                    else if (date.getMonth() == this.options.selectedDate.getMonth())

                        update_month = false;

                }

            }



            if (!this.options.multiSelection)

                this.unselectDate(this.options.selectedDate);



            this.options.selectedDate = this.date = date;

            this.selectedDates.push(date.getTime());



            var id_str = this.options.idPrefix + 'date-' + (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();

            if ($defined($(id_str))) {

                $(id_str).removeClassName(this.options.classPrefix + "mouse-over");

                $(id_str).addClassName(this.options.classPrefix + "selected-day");

                $(id_str).innerHTML = (this.options.selectedDateFormatter(this.options.selectedDate));

            }



            if (this.options.inputType == "select") {

                if (update_year) this.populateMonthSelect();

                else if (update_month) this.populateDateSelect();

                this.selectSelectMenu();

            }

            else if (this.options.inputType == "text")

                this.fillInputField();

            this.fireEvent("onSelect");

            return true;

        }

        else {

            if (this.options.inputType == "select") {

                this.options.inputField.date.selectedIndex = 0;

                return false;

            }

        }

        this.updateHeader();

    },





    /*

    Function:

    unselectDate

    unselect the given date

			

    Arguments:

    date: date object (check above)



    */



    unselectDate: function (date) {

        if (!this.options.allowSelection) return false;



        var date = this.processDates(date);

        if (!$defined(date)) return false;

        if (this.selectedDates.length > 0) {
            this.selectedDates.length -= 1;
        }

        var id_str = this.options.idPrefix + 'date-' + (date.getMonth() + 1) + '-' + date.getDate() + '-' + date.getFullYear();



        if ($defined($(id_str)))

            $(id_str).removeClassName(this.options.classPrefix + "selected-day");


		

        if (($defined(this.options.selectedDate)) && (this.options.multiSelection)) {

            if (this.options.selectedDate.getTime() == date.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 update_year = true;

            var update_month = true;

            if ($defined(this.options.selectedDate)) {

                if (date.getFullYear() == this.options.selectedDate.getFullYear())

                    update_year = false;

                else if (date.getMonth() == this.options.selectedDate.getMonth())

                    update_month = false;

            }



            if (update_year) this.populateMonthSelect();

            else if (update_month) this.populateDateSelect();

            this.selectSelectMenu();

        }

        else if (this.options.inputType == "text")

            this.options.inputField.value = this.options.inputField.value.replace(date.print(this.options.dateFormat, this.options.language), "");

        this.fireEvent("onUnSelect", date);

    },



    /*

    Function:

    unselectAll

    unselect all the selected dates



    */

    unselectAll: function () {

        if (!this.options.allowSelection) return false;



        var arr = this.selectedDates.copy();

        arr.each(function (dt) {

            this.unselectDate(new Date(dt));

        }, this);



        this.fireEvent("onClear");

    },





    /*

    Function:

    selectSelectMenu

    select the drop down menu if the user click on the a selectable date in the calendar



    */

    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 loop;

        var i = 0;



        var opts = $(this.options.inputField.month).getElements("option");

        loop = opts.length;

        for (i = 0; i < loop; i++) {

            if (opts[i].value.toInt() - 1 == this.options.selectedDate.getMonth()) {

                this.options.inputField.month.selectedIndex = i;

                break;

            }

        }



        var opts = $(this.options.inputField.year).getElements("option");

        loop = opts.length;

        for (i = 0; i < loop; i++) {

            if (opts[i].value.toInt() == this.options.selectedDate.getFullYear()) {

                this.options.inputField.year.selectedIndex = i;

                break;

            }

        }

    },



    /*

    Function:

    fillInputField

    Fill the inpute field when the user select a date



    */

    fillInputField: function () {

        if (!this.options.multiSelection) this.options.inputField.value = "";

        this.options.inputField.value += this.options.selectedDate.print(this.options.dateFormat, this.options.language);

    },



    /*

    Function:

    updateHeader

    update the calendar headers (month and year and arrows)



    */

    updateHeader: function () {

        this.headerTD.innerHTML = (this.date.language.months[this.options.monthsText][this.date.getMonth()] + " " + this.date.getFullYear());

        //if (!this.isOutOfRange(new Date(this.date.getFullYear(), this.date.getMonth() - 1, this.options.startDate.getDate()))) {
        //    this.preTD.innerHTML = (this.options.preTdHTML);
        //    $(this.preTD).setStyle({ 'cursor': 'pointer' });
        //}
        //else {
        //    this.preTD.innerHTML = (this.options.preTdHTMLOff);
        //    $(this.preTD).setStyle({ 'cursor': '' });
        //}
		
		this.preTD.innerHTML = (this.options.preTdHTML);
		$(this.preTD).setStyle({ 'cursor': 'pointer' });

        //if (!this.isOutOfRange(new Date(this.date.getFullYear(), this.date.getMonth() + 1, this.options.endDate.getDate()))) {
        //    this.nexTD.innerHTML = (this.options.nexTdHTML);
        //    $(this.nexTD).setStyle({ 'cursor': 'pointer' });
        //}
        //else {
        //    this.nexTD.innerHTML = (this.options.nexTdHTMLOff);
        //    $(this.nexTD).setStyle({ 'cursor': '' });
        //}
		
		this.nexTD.innerHTML = (this.options.nexTdHTML);
		$(this.nexTD).setStyle({ 'cursor': 'pointer' });

    },



    /*

    Function:

    processDates

    return a JavaScript date from the date object

			

    Arguments:

    dt: a date object (see above)

    use_date: the default date to use

		

    Return:

    JavaScript Date



    */

    processDates: function (dt, use_date) {

        if (!$defined(use_date)) use_date = this.date;

        var rdt;

        if ((($type(dt) == "object") && ($defined(dt.getFullYear))) || ($type(dt) == "date")) rdt = dt;

        else if ($type(dt) == "object") rdt = use_date.fromObject(dt);

        else if ($type(dt) == "string") rdt = use_date.fromString(dt);

        else if ($type(dt) == "number") rdt = new Date(dt);

        else return null;

        if ($defined(this.options.language))

            rdt.language = this.options.language;



        rdt.setHours(0); rdt.setSeconds(0); rdt.setMinutes(0); rdt.setMilliseconds(0);

        return rdt;

    },





    /*

    Function:

    openCalendar

    opens the calendar



    */

    openCalendar: function () {

        if (this.options.closeOpenCalendars) $closeAllCalendars();

        if (this.options.inputType == "select")

            var inp_f = this.options.inputField.date;

        else

            var inp_f = this.options.inputField;



        var coord = inp_f.getCoordinates();



        this.element.setStyles({

            'top': coord.top + coord.height + this.options.offset.y,

            'left': coord.left + this.options.offset.x,

            'opacity': 1

        });

        if ($defined(this.iframe)) {

            this.iframe.setStyles({

                'top': coord.top + coord.height + this.options.offset.y,

                'left': coord.left + this.options.offset.x,

                'opacity': 1

            });

        }



        this.fireEvent("onOpen");

    },



    /*

    Function:

    closeCalendar

    closes the calendar



    */

    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");
    }
});



// array to hold all the calendar objects for the close all calendars

var _all_page_calendars = [];



// function to close all the open calendars

var $closeAllCalendars = function () {

    _all_page_calendars.each(function (obj) {

        obj.closeCalendar();

    });

};

function $defined(obj) {
    return (obj != undefined)
};
function $type(obj) {
    if (!$defined(obj)) return false;
    if (obj.htmlElement) return 'element';
    var type = typeof obj;
    if (type == 'object' && obj.nodeName) {
        switch (obj.nodeType) {
            case 1: return 'element';
            case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'
        }
    }
    if (type == 'object' || type == 'function') {
        switch (obj.constructor) {
            case Array: return 'array';
            case RegExp: return 'regexp';
            case Class: return 'class'
        }
        if (typeof obj.length == 'number') {
            if (obj.item) return 'collection';
            if (obj.callee) return 'arguments'
        }
    }
    return type
};

