﻿
jQuery.jcalendar = function() {

    var one_day = 1000 * 60 * 60 * 24;
    //dynamic years array for autocomplete
    var years = new Array();

    //dutch month names array
    var months = messages.date_months_long.split(',');

    //dutch day names array
    var days = messages.date_days_long.split(',');

    var restaurantID;
    var limitedDays = '';
    var limitedDates = '';

    var type;

    //script options object
    //contains type and monthCount
    //if type:0 then the page is booking step 1
    //if type:1 then the page is special booking page
    //if type:2 then the page is booking overview page
    var options = {};
    //script dayClass object
    //contains  outOfBounds(out of start and end dates), 
    //          status0(day status 0),
    //          status1(day status 1), 
    //          status2(day status 2), 
    //          status3(day status 3),
    //          status4(day status 4) objects
    //each of these objects contains clickable and cssClass properties
    //clickable:boolean means the day clickable or not
    //cssClass:string refers the css class of the day (gray, empty, full ...)s
    var dayClass = {};

    //first day of the week
    var _firstDayOfWeek;

    //first date of the calender
    var _firstDate;

    //last date of the calender
    var _lastDate;

    //selected date of the calender
    var _todayDate;

    //server today date
    var _serverDate;

    //second selected day of the calender
    var _selectedDate;

    //boolean year can be changed or not value
    //if firstdate - lastdate interval has more than one year 
    //then year can be changed(input box) otherwise not(label only)
    var _yearChange = false;

    //it is used during user interaction
    //if user select another month in interaction then
    //load the day status array from the server
    var _monthChange = false;

    //it is used during user interaction
    //if user changes the day then
    //go to the month inbox then go another place in page
    //load the day availability hours for type:0(booking step 1) again
    var _dayChange = false;

    var _isNextPrev = false;

    //the months between firstdate and lastdate
    var _currentMonths;

    //day availability string
    //it is like 0010243...
    //char count is equal how many days there are in selected month
    var _dayavailability;

    var _editDate = '';

    //draw the calender
    //params    dateIn:selecteddate on the calender
    //          day: day input control
    //          month: month input control
    //          year: year input control
    //          datespan: label of the selected date 
    var _drawCalendar = function(dateIn, day, month, year, datespan) {
        var today = _todayDate;
        var d;
        if (dateIn == undefined) {
            // start from firstdate month
            d = new Date(_firstDate.getFullYear(), _firstDate.getMonth(), 1);
            datespan.html(day.val() + " " + month.val() + " " + year.val());
        }
        else {
            // start from the passed in date
            d = dateIn;
            d.setDate(1);
        }

        // check that date is within allowed limits
        if ((d.getMonth() < _firstDate.getMonth() && d.getFullYear() == _firstDate.getFullYear()) || d.getFullYear() < _firstDate.getFullYear()) {
            d = new Date(_firstDate.getFullYear(), _firstDate.getMonth(), 1);
        }
        else if ((d.getMonth() > _lastDate.getMonth() && d.getFullYear() == _lastDate.getFullYear()) || d.getFullYear() > _lastDate.getFullYear()) {
            d = new Date(_lastDate.getFullYear(), _lastDate.getMonth(), 1);
        }
        _dayChange = false;
        var firstMonth = true;
        var firstDate = _firstDate.getDate();
        if (options.type != 3) {
            // create prev month and next month links		
            if (!(d.getMonth() == _firstDate.getMonth() && d.getFullYear() == _firstDate.getFullYear())) {
                // not in first display month so show a previous link
                firstMonth = false;

                //if selected date month is first month(January) then the prev link will go to the previous year
                var lastMonthDate = d.getMonth() == 0 ? new Date(d.getFullYear() - 1, 11, 1) : new Date(d.getFullYear(), d.getMonth() - 1, 1);

                //lastMonth is for is selected day is in prev month days interval
                //exp:if day is 31 but prev month is February(28 or 29 days) so it doesn't allowed
                var lastMonth = d.getMonth() == 0 ? new Date(d.getFullYear() - 1, 11, 0) : new Date(d.getFullYear(), d.getMonth(), 0);
                var prevLink = jQuery('<a href="javascript:void(0);" class="link-prev"><img src="' + messages.path_prefix + '/images/calender/month_left.jpg" alt=""/></a>').click(function() {
                    //var prevLink = jQuery('<a href="javascript:;" class="link-prev"><<</a>').click(function() {
                    //unbind the click event for fast clicks
                    $(this).unbind('click');

                    _isNextPrev = true;

                    //control the dav val in interval
                    //if not set the day val to the last day of the month
                    if (day.val() > lastMonth.getDate())
                        day.val(lastMonth.getDate());

                    //month change true so load the days availability string for new month
                    _monthChange = true;

                    //set year and month values
                    year.val(lastMonthDate.getFullYear());
                    month.val(months[lastMonthDate.getMonth()]);

                    //call month change event
                    month.change();
                    return false;
                });
            } else {
                //display nothing
                var prevLink = jQuery('<a style="visibility:hidden;" href="javascript:void(0);" class="link-prev"><img src="' + messages.path_prefix + '/images/calender/month_left.jpg" alt=""/></a>');
                //var prevLink = jQuery('<a style="visibility:hidden;" href="javascript:;" class="link-prev"><<</a>');
            }

            var finalMonth = true;
            var lastDate = _lastDate.getDate();
            if (!(d.getMonth() == _lastDate.getMonth() && d.getFullYear() == _lastDate.getFullYear())) {
                // in the last month - no next link
                finalMonth = false;

                //if selected date month is last month(December) then the next link will go to the next year
                var nextMonthDate = new Date(d.getFullYear(), d.getMonth() + 1, 1);

                //nextMonth is for is selected day is in next month days interval
                //exp:if day is 31 but next month is February(28 or 29 days) so it doesn't allowed
                var nextMonth = new Date(d.getFullYear(), d.getMonth() + 2, 0);
                var nextLink = jQuery('<a href="javascript:void(0);" class="link-next"><img src="' + messages.path_prefix + '/images/calender/month_right.jpg" alt=""/></a>').click(function() {
                    //var nextLink = jQuery('<a href="javascript:;" class="link-next">>></a>').click(function() {
                    //unbind the click event for fast clicks
                    $(this).unbind('click');

                    _isNextPrev = true;

                    //control the dav val in interval
                    //if not set the day val to the last day of the month
                    if (day.val() > nextMonth.getDate())
                        day.val(nextMonth.getDate());

                    //month change true so load the days availability string for new month
                    _monthChange = true;

                    //set year and month values
                    year.val(nextMonthDate.getFullYear());
                    month.val(months[nextMonthDate.getMonth()]);

                    //call month change event
                    month.change();
                    return false;
                });
            }
        }
        //update the year, month input boxes, date span and selected month label
        year.val(d.getFullYear());
        month.val(months[d.getMonth()]);
        if (options.type != 3) {
            datespan.html(day.val() + " " + month.val() + " " + year.val());
            var selectedmonth = jQuery('<div>' + month.val().substring(0, 3) + " " + year.val() + '</div>');

            var headRow = jQuery("<tr></tr>");
            //create the days row with first two chars 
            for (var i = _firstDayOfWeek; i < _firstDayOfWeek + 7; i++) {
                var weekday = i % 7;
                var wordday = days[weekday].substring(0, 2);
                headRow.append('<th scope="col" abbr="' + wordday + '" title="' + days[weekday] + '" class="' + (weekday == 0 || weekday == 6 ? 'weekend' : 'weekday') + '">' + wordday + '</th>');
            }
            headRow = jQuery("<thead></thead>").append(headRow);

            var tBody = jQuery("<tbody></tbody>");
            var lastDay = (new Date(d.getFullYear(), d.getMonth() + 1, 0)).getDate();
            var curDay = _firstDayOfWeek - d.getDay();
            if (curDay > 0) curDay -= 7;

            if (options.type == 1 || options.type == 5) {
                var todayDate = today.getDate();
                var thisMonth = d.getMonth() == today.getMonth() && d.getFullYear() == today.getFullYear();
            } else {//otherwise today is firstdate
                var todayDate = _firstDate.getDate();
                var thisMonth = d.getMonth() == _firstDate.getMonth() && d.getFullYear() == _firstDate.getFullYear();
            }
            //entered day from input boxes may not be allowed(clickable) day 
            //so control it by isSelectedLink? variable
            var isSelectedLink = false;
            var selectedDay = 0;
            //--------------------------
            var j = 0; //counts rows of calender(for rounding bottom cells)
            var cols = 0; //
            var rows = 4; //determines if calender has 5 or 6 rows
            //--------------------------
            // render calendar
            do {
                var thisRow = jQuery("<tr></tr>");
                for (var i = 0; i < 7; i++) {
                    var weekday = (_firstDayOfWeek + i) % 7;
                    var atts = { 'class': (weekday == 0 || weekday == 6 ? 'weekend ' : 'weekday ') };

                    //-------------------------------------------------
                    if (i == 1 & j == 3) {//tries to find if this month's calender is composed of 5 or 6 rows(rounded cells will be determined)
                        if ((curDay + 7 + 6) < lastDay)
                            rows = 5; //6 ROWS
                        else
                            rows = 4; //5 ROWS
                    }
                    //-------------------------------------------------
                    if (curDay < 0 || curDay >= lastDay) {
                        //the day is not in the selected month
                        dayStr = ' ';
                        if (i == 6 & j == rows)
                            atts['class'] += dayClass.outOfBounds_r.cssClass;
                        else
                            atts['class'] += dayClass.outOfBounds.cssClass;
                    }
                    else if (firstMonth && curDay < firstDate - 1) {
                        //the day is before firstdate

                        //if clickable then look for the day status and assign css class
                        //if(dayClass.outOfBounds.clickable){
                        if (dayClass.status0.clickable) {
                            dayStr = _checkDayStatus(curDay, atts, dayStr, i, j, rows, d.getMonth(), d.getFullYear());
                        } else {
                            //if not clickable then put the day value only and assign the css class
                            dayStr = curDay + 1;
                            //atts['class'] += dayClass.outOfBounds.cssClass;
                            if (i == 0 & j == rows)
                                atts['class'] += dayClass.status0_l.cssClass; //no_day_schedule left rounded
                            else
                                atts['class'] += dayClass.status0.cssClass; //no_day_schedule
                        }

                    }
                    else if (finalMonth && curDay > lastDate - 1) {
                        //the day is after lastdate

                        //if clickable then look for the day status and assign css class
                        if (dayClass.outOfBounds.clickable) {
                            dayStr = _checkDayStatus(curDay, atts, dayStr, i, j, rows, d.getMonth(), d.getFullYear());
                        } else {
                            //if not clickable then put the day value only and assign the css class
                            dayStr = curDay + 1;
                            //-----------------------------------------------------
                            if (i == 0 & j == rows) {//makes the bottom left cell of calender rounded background image  
                                //atts['class'] += dayClass.outOfBounds_l.cssClass;
                                atts['class'] += dayClass.status0_l.cssClass;
                            }
                            else if (i == 6 & j == rows) {//makes the bottom right cell of calender rounded background image 
                                //atts['class'] += dayClass.outOfBounds_r.cssClass;
                                atts['class'] += dayClass.status0_r.cssClass;
                            }
                            else {//normal square cell background image
                                //-----------------------------------------------------
                                //atts['class'] += dayClass.outOfBounds.cssClass;
                                atts['class'] += dayClass.status0.cssClass;
                            }
                        }
                    }
                    else {
                        //the day is in interval
                        d.setDate(curDay + 1);
                        var editClass = ((d - _editDate == 0) ? "class='editval'" : '');
                        //attach a click handler to every day to select it if clicked
                        //we use the rel attribute to keep track of the day that is being clicked
                        dayStr = jQuery('<a href="" rel="' + d + '" id="link_' + curDay + '" ' + editClass + '>' + (curDay + 1) + '</a>').click(function(e) {
                            if (_selectedDate) {
                                $("span.selected").parent().html(_selectedDate.html());
                                _selectedDate.removeClass('selected');
                            }
                            _selectedDate = jQuery(this);
                            _selectedDate.addClass('selected');
                            var datet = new Date(_selectedDate.attr('rel'));
                            //update day input control with clicked day
                            day.val(datet.getDate());

                            //update datespan text
                            datespan.html(day.val() + " " + month.val() + " " + year.val());

                            if (options.type == 5) {
                                $('div.selected-date').removeClass('notchanged').addClass('changed');
                                type = "date";
                            }

                            //call dateChenged function
                            _dateChanged();
                            return false;
                        });
                        //highlight the current selected day
                        if (options.type == 0) {
                            if (day.val() == d.getDate()) {
                                _selectedDate = dayStr;
                                _selectedDate.addClass('selected');
                            }
                        } else if (options.type == 1 || options.type == 5) {
                            if (jQuery.jcalendar.getDateStr(d) == $('input.hdnSelectedDate').val()) {
                                _selectedDate = dayStr;
                                _selectedDate.addClass('selected');
                            }
                        }

                        //assign day clickable and css class properties with its status
                        dayStr = _checkDayStatus(curDay, atts, dayStr, i, j, rows, d.getMonth(), d.getFullYear());

                        if (day.val() == d.getDate() && jQuery(dayStr).is('a')) {
                            //the day is link
                            isSelectedLink = true;
                            if (options.type == 0 || options.type == 5)
                                _dateChanged();
                        } else if (day.val() == d.getDate() && !jQuery(dayStr).is('a') && (options.type == 0)) {
                            dayStr = "<span class='selected'>" + day.val() + "</span>";
                            // at restaurant detail page: even if there is not day availability
                            // , make this day (day from search page) selected. And call _dateChanged()
                            // *** at previous version we were changing selected day automatically
                            // to a day where we have day availability (a clickable day) ***
                            _dateChanged();
                        }
                    }
                    if (day.val() == d.getDate()) {
                        selectedDay = day.val();
                    }
                    thisRow.append(jQuery("<td></td>").attr(atts).append(dayStr));
                    curDay++;

                }
                //-------------------------
                j = j + 1;
                //-------------------------
                tBody.append(thisRow);
            } while (curDay < lastDay);

            //create the calender days html
            jQuery('div.jcalendar').html('<div class="jcalendar-links"></div><table cellspacing="0"></table>');
            jQuery('div.jcalendar > div.jcalendar-links').append(prevLink, selectedmonth, nextLink);
            jQuery('div.jcalendar table').append(headRow, tBody);
        }

        //type:2(booking overview page)
        if (options.type == 2) {
            //if monthChange is true
            if (_monthChange) {
                //look the selected date is clickable or not
                //if not then find clickable day around the selected day
                //then click it and load the page again
                newday = _checkSelectedStatus(Number(_selectedDate.html()));
                if (newday != Number(_selectedDate.html())) {
                    $('#link_' + newday).click();
                } else {
                    _dateChanged();
                }
            }
        } else if (options.type == 0) { // restaurant detail page
            // In here: if selected day (selected at search page) is not available,
            // we found a clickable day around and make it selected. We don't do this anymore. 
            // We do: Show this unavailable day as selected, but instead of displaying selectable times (already we don't have any)
            // we display sth like "NO AVAILABILITY"
            /* Commented on 10/20/2008
            //if selected day is not link then look the clickable day around the entered day
            if(!isSelectedLink){
            //_checkSelectedStatus(Number(selectedDay));
            newday = _checkSelectedStatus(Number(_selectedDate.html()));
            if($('#link_'+newday).is('a')){
            $('#link_'+newday).click();
            }else{
            _dateChanged();
            }
            }
            */
        } else if (options.type == 5) { // restaurant detail page
            //if selected day is not link then look the clickable day around the entered day
            if (!_monthChange) {
                if (!isSelectedLink) {
                    //_checkSelectedStatus(Number(selectedDay));
                    newday = _checkSelectedStatus(Number(_selectedDate.html()));
                    if ($('#link_' + newday).is('a')) {
                        $('#link_' + newday).click();
                    } else {
                        _dateChanged();
                    }
                }
            }
        } else {
            _selectedDate = jQuery('<a href="" rel="' + d + '" id="link_' + curDay + '"></a>');
        }
    };

    //check the day status
    //params    curDay:the day value
    //          atts: css attributes
    //          dayStr: day string, if it is not clickable only day value, if it is surround with <a>
    var _checkDayStatus = function(curDay, atts, dayStr, col, row, rowCount, selectedMonth, selectedYear) {
        /*
        SELECTS availability status of each day to fill in the calendar on reservation page.

	        It may not return a record for each day between @start_date and @end_date if there is no corresponding
        availability record. 

	        status
        ----------
        0 -> NO DAY SCHEDULE
        1 -> EMPTY
        2 -> PARTLY FULL
        3 -> FULL
        4 -> CLOSED
        */
        var today = new Date();
        //var index = curDay;
        //if(options.type == 1)
        //index = _daysElapsed( new Date(selectedYear, selectedMonth, curDay+1) , _firstDate);
        switch (_dayavailability.charAt(curDay)) {
            case '0':
                //--------fade colors-------------
                if (selectedMonth < today.getMonth() & selectedYear <= today.getFullYear())
                    atts['class'] += "opac";
                if (selectedMonth == today.getMonth() & selectedYear == today.getFullYear() & curDay + 1 < today.getDate())
                    atts['class'] += "opac";
                //--------------------------------
                if (!dayClass.status0.clickable) {
                    dayStr = curDay + 1;
                }
                if (col == 0 & row == rowCount) {//makes the bottom left cell of calender rounded background image  
                    atts['class'] += dayClass.status0_l.cssClass;
                }
                else if (col == 6 & row == rowCount) {//makes the bottom right cell of calender rounded background image 
                    atts['class'] += dayClass.status0_r.cssClass;
                }
                else {//normal square cell background image
                    atts['class'] += dayClass.status0.cssClass;
                }
                break;
            case '1':
                //--------fade colors-------------
                if (selectedMonth < today.getMonth() & selectedYear <= today.getFullYear())
                    atts['class'] += "opac";
                if (selectedMonth == today.getMonth() & selectedYear == today.getFullYear() & curDay + 1 < today.getDate())
                    atts['class'] += "opac";
                //--------------------------------
                if (!dayClass.status1.clickable) {
                    dayStr = curDay + 1;
                }
                if (col == 0 & row == rowCount) {//makes the bottom left cell of calender rounded background image 
                    atts['class'] += dayClass.status1_l.cssClass;
                }
                else if (col == 6 & row == rowCount) {//makes the bottom right cell of calender rounded background image 
                    atts['class'] += dayClass.status1_r.cssClass;
                }
                else {//normal square cell background image
                    atts['class'] += dayClass.status1.cssClass;
                }
                break;
            case '2':
                //--------fade colors-------------
                if (selectedMonth < today.getMonth() & selectedYear <= today.getFullYear())
                    atts['class'] += "opac";
                if (selectedMonth == today.getMonth() & selectedYear == today.getFullYear() & curDay + 1 < today.getDate())
                    atts['class'] += "opac";
                //--------------------------------
                if (!dayClass.status2.clickable) {
                    dayStr = curDay + 1;
                }
                if (col == 0 & row == rowCount) {//makes the bottom left cell of calender rounded background image 
                    atts['class'] += dayClass.status2_l.cssClass;
                }
                else if (col == 6 & row == rowCount) {//makes the bottom right cell of calender rounded background image 
                    atts['class'] += dayClass.status2_r.cssClass;
                }
                else {//normal square cell background image
                    atts['class'] += dayClass.status2.cssClass;
                }
                break;
            case '3':
                //--------fade colors-------------
                if (selectedMonth < today.getMonth() & selectedYear <= today.getFullYear())
                    atts['class'] += "opac";
                if (selectedMonth == today.getMonth() & selectedYear == today.getFullYear() & curDay + 1 < today.getDate())
                    atts['class'] += "opac";
                //--------------------------------
                if (!dayClass.status3.clickable) {
                    dayStr = curDay + 1;
                }
                if (col == 0 & row == rowCount) {//makes the bottom left cell of calender rounded background image 
                    atts['class'] += dayClass.status3_l.cssClass;
                }
                else if (col == 6 & row == rowCount) {//makes the bottom right cell of calender rounded background image 
                    atts['class'] += dayClass.status3_r.cssClass;
                }
                else {//normal square cell background image
                    atts['class'] += dayClass.status3.cssClass;
                }
                break;
            case '4':
                //--------fade colors-------------
                if (selectedMonth < today.getMonth() & selectedYear <= today.getFullYear())
                    atts['class'] += "opac";
                if (selectedMonth == today.getMonth() & selectedYear == today.getFullYear() & curDay + 1 < today.getDate())
                    atts['class'] += "opac";
                //--------------------------------
                if (!dayClass.status4.clickable) {
                    dayStr = curDay + 1;
                }
                if (col == 0 & row == rowCount) {//makes the bottom left cell of calender rounded background image 
                    atts['class'] += dayClass.status4_l.cssClass;
                }
                else if (col == 6 & row == rowCount) {//makes the bottom right cell of calender rounded background image 
                    atts['class'] += dayClass.status4_r.cssClass;
                }
                else {//normal square cell background image
                    atts['class'] += dayClass.status4.cssClass;
                }
                break;
        }
        return dayStr;
    };

    var _daysElapsed = function(date1, date2) {
        var difference =
            Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate(), 0, 0, 0)
          - Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate(), 0, 0, 0);
        return difference / 1000 / 60 / 60 / 24;
    };


    //check the selected day status for booking overview
    //params    index:index of the day
    //if the selected day is not clickable then
    //find clicakble day around the selected day and retrn new clicable day value
    var _checkSelectedStatus = function(index) {
        for (i = 0; i < 31; i++) {
            if ($('#link_' + (index - 1 + i)).is('a')) {
                return (index - 1 + i);
            } else if ($('#link_' + (index - 1 - i)).is('a')) {
                return (index - 1 - i);
            }
        }
        return index;
    };

    //dateChanged function
    //if type:0(restaurant detail) then load the day hours, and update imege clock
    //if type:1(lister page)
    var _dateChanged = function() {
        // detail page calendar
        if (options.type == 0) {
            var selectedDate = _getCurrentDate();

            var diff = Math.ceil((selectedDate.getTime() - _serverDate.getTime()) / (one_day));
            var linebreak = "<br />";
            $('#spanDate').html("");
            if (diff == 0) {
                $('#spanDate').html(messages.TODAY + ",<br />");
                linebreak = " ";
            } else if (diff == 1) {
                $('#spanDate').html(messages.TOMORROW + ",<br />");
                linebreak = " ";
            }

            //added break and changed to html
            $('#spanDate').append(selectedDate.getDate() + " " + (months[selectedDate.getMonth()]) + linebreak + selectedDate.getFullYear());

            if (!_isNextPrev)
                $('.divCal').hide("slow");

            _isNextPrev = false;

            if (integration) {
                if (options.timeType == 1)
                    jQuery.makeBooking.checkAvailability(jQuery.jcalendar.getDateStr(_getCurrentDate()), -1/*time*/, restaurantID, limitedDays, limitedDates);
                else
                    jQuery.makeBooking.checkAvailabilityIframe(jQuery.jcalendar.getDateStr(_getCurrentDate()), -1/*time*/, restaurantID, limitedDays, limitedDates);
            }
            else {
                jQuery.makeBooking.checkAvailability(jQuery.jcalendar.getDateStr(_getCurrentDate()), -1/*time*/, restaurantID, '', '');
            }
        }
        // search page calendar
        else if (options.type == 1) {
            $('input.hdnSelectedDate').val(jQuery.jcalendar.getDateStr(_getCurrentDate()));
            Search.changeDate(jQuery.jcalendar.getstringdate());
        }
        // home page calendar
        else if (options.type == 5) {
            if (!_isNextPrev)
                $('.divCal').hide("slow");

            _isNextPrev = false;
            $('input.hdnSelectedDate').val(jQuery.jcalendar.getDateStr(_getCurrentDate()));

            var selectedDate = _getCurrentDate();
            var diff = Math.ceil((selectedDate.getTime() - _serverDate.getTime()) / (one_day));
            var linebreak = "<br />";
            $('#spanDate').html("");
            if (diff == 0) {
                $('#spanDate').html(messages.TODAY + ",<br />");
                linebreak = " ";
            } else if (diff == 1) {
                $('#spanDate').html(messages.TOMORROW + ",<br />");
                linebreak = " ";
            }

            //added break and changed to html
            $('#spanDate').append(selectedDate.getDate() + " " + (months[selectedDate.getMonth()]) + linebreak + selectedDate.getFullYear());

            jQuery.makeBooking.changeHomePageSearchLink(type);
            type = "";
        }
    };

    //getMonthArray function
    //return the months array
    var _getMonthArray = function() {
        return months;
    };

    //getMonthLimitArray function
    //params    start: start index of the month array
    //          size: size of the limited array
    //return the months array with starting month and desired size
    var _getMonthLimitArray = function(start, size) {
        newmonths = [];
        _currentMonths = [];
        if (start + size > 11) {
            _yearChange = true;
        }
        for (var i = start; i < start + size; i++) {
            newmonths[i - start] = months[i % 12];
            _currentMonths[i - start] = (i % 12) + 1;
        }
        return newmonths;
    };

    //getDayArray function
    //return the days array
    var _getDayArray = function() {
        return days;
    };

    //getYearChange function
    //return the _yearChenge value
    var _getYearChange = function() {
        return _yearChange;
    };

    //getYearChange function
    //return the _yearChange value
    var _getDayChange = function() {
        return _dayChange;
    };

    //setDayChange function
    //set the _dayChange value
    var _setDayChange = function(val) {
        _dayChange = val;
    };

    //getCurrentDate function
    //return the current(selected) date
    var _getCurrentDate = function() {
        return new Date(_selectedDate.attr('rel'));
    };

    //getCurrentDateStr function
    //return the current(selected) date string exp: 1/2/2008
    var _getCurrentDateStr = function(d, a, day, month, year, datespan, startdate, enddate) {
        return jQuery.jcalendar.getDateStr(_getCurrentDate());
    };

    //getCurrentMonths function
    //return the alowed months array which is created on calender load
    var _getCurrentMonths = function() {
        return _currentMonths;
    };

    //loadDayAvailibility function
    //params    d:selecteddate on the calender
    //          day: day input control
    //          month: month input control
    //          year: year input control
    //          datespan: label of the selected date
    //          startdate: startday of the selected month
    //          enddate: last day of the selected month
    //it loads the _dayavailability string with the status of the days in selected month
    var _loadDayAvailibility = function(d, day, month, year, datespan, startdate, enddate, restaurantID, ldays, ldates) {
        $.ajax({
            type: "POST",
            url: messages.path_prefix + "/handlers/loadDayAvailability.ashx",
            data: "startdate=" + startdate + "&enddate=" + enddate + "&rid=" + restaurantID + "&days=" + ldays + "&dates=" + ldates,
            async: false,
            success: function(data) {
                _dayavailability = data;
                jQuery.jcalendar.changeMonth(d, day, month, year, datespan);
            },
            error: function(data) {
            }
        });
    };

    //getFirstDate function
    //return the first alowed date
    var _getFirstDate = function() {
        return _firstDate;
    };

    //indexOf function
    //params    array: array of anything
    //          val: search val in the array
    //return the index of the value on given array
    var _indexOf = function(array, val) {
        for (var i = 0; i < array.length; i++) {
            if (array[i] == val) return i;
        }
        return -1;
    };

    //global functions
    return {
        //show function
        //params    a: object which contains _today, _selectedDate, _startDate, _startDate, _endDate, _availability, 
        //          day: day input control
        //          month: month input control
        //          year: year input control
        //          datespan: label of the selected date
        //first load of the calender
        show: function(a, day, month, year, datespan) {
            _serverDate = a._today;
            _todayDate = a._selectedDate;
            _firstDate = a._startDate;
            _lastDate = a._endDate;
            _firstDayOfWeek = a._firstDayOfWeek;
            _dayavailability = a._availability;
            _editDate = a._editDate;
            if ((index = _indexOf(_getMonthArray(), month.val())) != -1) {
                month.val(index + 1);
            }
            // pass in the selected form date if one was set
            var selected;
            if (year.val() > 0 && month.val() > 0 && day.val() > 0) {
                selected = new Date(year.val(), month.val() - 1, day.val());
            }
            else {
                selected = null;
            }
            if (options.type == 0) {
                var start = new Date(year.val(), month.val() - 1, 1);
                var last = new Date(year.val(), month.val(), 0).getDate();
                var end = new Date(year.val(), month.val() - 1, last);
                jQuery.jcalendar.loadDayAvailibility(selected, day, month, year, datespan, jQuery.jcalendar.getDateStr(start), jQuery.jcalendar.getDateStr(end), restaurantID, limitedDays, limitedDates);
            } else if (options.type == 1 || options.type == 5) {
                jQuery.jcalendar.changeMonth(selected, day, month, year, datespan);
            }
        },

        //changeMonth function
        //params    d: selected date
        //          day: day input control
        //          month: month input control
        //          year: year input control
        //          datespan: label of the selected date
        //call the _drawCalendar function
        changeMonth: function(d, day, month, year, datespan) {
            _drawCalendar(d, day, month, year, datespan);
        },

        //setLanguageStrings function
        //params    aDays: days name string array
        //          aMonths:months name string array
        setLanguageStrings: function(aDays, aMonths) {
            days = aDays;
            months = aMonths;
        },

        //setDateWindow function
        //params    i: The id of the INPUT element this date window is for
        //          w: The date window - an object containing startDate and endDate properties
        //e.g. {startDate:'24-11-1981', endDate:'25-12-2012}
        //Used internally to set the start and end dates for a given date select
        setDateWindow: function(i, w, year) {
            if (w == undefined) w = {};
            if (w.startDate != undefined) {
                dateParts = w.startDate.split('-');
                i._startDate = new Date(dateParts[2], Number(dateParts[1]) - 1, Number(dateParts[0]));
            }
            if (w.endDate != undefined) {
                dateParts = w.endDate.split('-');
                i._endDate = new Date(dateParts[2], Number(dateParts[1]) - 1, Number(dateParts[0]));
            }
            if (w.selectedDate != undefined) {
                dateParts = w.selectedDate.split('-');
                i._selectedDate = new Date(dateParts[2], Number(dateParts[1]) - 1, Number(dateParts[0]));
            }

            if (w.today != undefined) {
                dateParts = w.today.split('-');
                i._today = new Date(dateParts[2], Number(dateParts[1]) - 1, Number(dateParts[0]));
            }
            if (w.editDate != undefined && w.editDate != '') {
                dateParts = w.editDate.split('-');
                i._editDate = new Date(dateParts[2], Number(dateParts[1]) - 1, Number(dateParts[0]));
            }

            if (w.availability == undefined) {
                i._availability = '1111111111111111111111111111111';
            }
            else {
                i._availability = w.availability;
            }

            i._firstDayOfWeek = w.firstDayOfWeek == undefined ? 1 : w.firstDayOfWeek;
        },

        //getMonthArray function
        //call _getMonthArray function
        getMonthArray: function() {
            return _getMonthArray();
        },

        //getMonthLimitArray function
        //call _getMonthLimitArray function
        getMonthLimitArray: function(start, size) {
            return _getMonthLimitArray(start, size);
        },

        //getDayArray function
        //call _getDayArray function
        getDayArray: function() {
            return _getDayArray();
        },

        //getYearChange function
        //call _getYearChange function
        getYearChange: function() {
            return _getYearChange();
        },

        //getDayChange function
        //call _getDayChange function
        getDayChange: function() {
            return _getDayChange();
        },

        //setDayChange function
        //call _setDayChange function
        setDayChange: function(val) {
            _setDayChange(val);
        },

        //setMonthChange function
        //set monthChange value
        setMonthChange: function(val) {
            _monthChange = true;
        },

        //getCurrentDate function
        //call _getCurrentDate function
        getCurrentDate: function() {
            return _getCurrentDate();
        },

        //getCurrentDateStr function
        //call _getCurrentDateStr function
        getCurrentDateStr: function() {
            return _getCurrentDateStr();
        },

        //getServerTodayDate function
        //return _serverDate value
        getServerTodayDate: function() {
            return _serverDate;
        },

        //getCurrentMonths function
        //call _getCurrentMonths function
        getCurrentMonths: function() {
            return _getCurrentMonths();
        },

        //loadDayAvailibility function
        //params    d:selecteddate on the calender
        //          day: day input control
        //          month: month input control
        //          year: year input control
        //          datespan: label of the selected date
        //          startdate: startday of the selected month
        //          enddate: last day of the selected month
        //call _loadDayAvailibility function
        loadDayAvailibility: function(d, day, month, year, datespan, startdate, enddate, restaurantID, ldays, ldates) {
            return _loadDayAvailibility(d, day, month, year, datespan, startdate, enddate, restaurantID, ldays, ldates);
        },

        //getDateStr function
        //params    date(javascript date object)
        //generates date string like 20080201
        getDateStr: function(date) {
            month = date.getMonth() + 1;
            if (month < 10) month = "0" + month;
            day = date.getDate();
            if (day < 10) day = "0" + day;
            datestr = date.getFullYear() + "" + month + "" + day;
            return datestr;
        },

        //getFirstDate function
        //call _getFirstDate function
        getFirstDate: function() {
            return _getFirstDate();
        },

        //dayFocus function
        //if day input focus then select all value in it
        dayFocus: function() {
            $('input#day').select();
        },

        //indexOf function
        //call _indexOf function
        indexOf: function(array, val) {
            return _indexOf(array, val);
        },

        //getYears function
        //return years array
        getYears: function() {
            return years;
        },

        //getstringdate function
        //return selected date string like 20080324
        getstringdate: function() {
            return $('input.jcalendar-select-year').val() +
               ((jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(), $('input.jcalendar-select-month').val()) + 1) < 10
               ? "0" + (jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(), $('input.jcalendar-select-month').val()) + 1)
               : (jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(), $('input.jcalendar-select-month').val()) + 1)) +
               ($('input.jcalendar-select-day').val() < 10 ? "0" + $('input.jcalendar-select-day').val() : $('input.jcalendar-select-day').val())
        },

        //resetCalender function
        //go to first date 
        resetCalender: function() {
            var firstdate = _getFirstDate();
            var date = new Date(firstdate.getFullYear(), firstdate.getMonth(), firstdate.getDate());
            $('input#year').val(date.getFullYear());
            $('input#month').val(jQuery.jcalendar.getMonthArray()[date.getMonth()]);
            $('input#day').val(date.getDate());
            $('input#month').change();
        },

        //setOptions functions
        //params    opt : object
        //          dayCla: object  
        setOptions: function(opt, dayCla) {
            options = opt;
            dayClass = dayCla;
        },

        setRestaurant: function(restaurant) {
            restaurantID = restaurant.rid;
        },

        setLimitedData: function(limitedData) {
            limitedDays = limitedData.days;
            limitedDates = limitedData.dates;
        },

        //setAutocompleteData function
        setAutocompleteData: function(month, year, startdate) {
            switch (options.type) {
                case 0:
                    month.autocomplete(_getMonthLimitArray(_firstDate.getMonth(), options.monthCount), { mustMatch: false, max: options.monthCount });
                    if (!_getYearChange()) {
                        $('span#yearspan').html(_firstDate.getFullYear());
                        year.hide();
                        $('span#yearspan').show();
                    } else {
                        $('span#yearspan').hide();
                        var i = 0;
                        for (i = 0; i < 2; i++) {
                            jQuery.jcalendar.getYears().push((Number(startdate.split('-')[2]) + i).toString());
                        }
                        year.autocomplete(jQuery.jcalendar.getYears(), { mustMatch: false });
                    }
                    break;
                case 1:
                    month.autocomplete(_getMonthLimitArray(0, options.monthCount), { mustMatch: false, max: options.monthCount });
                    var i = 0;
                    for (i = 0; i < 3; i++) {
                        jQuery.jcalendar.getYears().push((Number(startdate.split('-')[2]) + i).toString());
                    }
                    year.autocomplete(jQuery.jcalendar.getYears(), { mustMatch: false });
                    break;
                case 3:
                    month.autocomplete(_getMonthLimitArray(0, options.monthCount), { mustMatch: false, max: options.monthCount });
                    var i = 0;
                    if (jQuery.jcalendar.getYears().length == 0) {
                        for (i = 0; i < 3; i++) {
                            jQuery.jcalendar.getYears().push((Number(startdate.split('-')[2]) + i).toString());
                        }
                    }
                    year.autocomplete(jQuery.jcalendar.getYears(), { mustMatch: false });
                    break;
            }
        }
    };
} ();

jQuery.fn.jcalendar = function(a) {
	this.each(function() {
	    //get the controls
        var day = $(this).find('input.jcalendar-select-day');
        var month = $(this).find('input.jcalendar-select-month');
        var year = $(this).find('input.jcalendar-select-year');
        var datespan = $('span#jcalendar-select-date');
        
        var tomorrow = $(this).find('a#tomorrow');
        var nextfriday = $(this).find('a#nextfriday');
        var nextsaturday = $(this).find('a#nextsaturday');
        var nextweek = $(this).find('a#nextweek');
        $('div.jcalendar-selects').after('<div class="jcalendar"></div>');
        
        //set options
        jQuery.jcalendar.setOptions(a.options, a.dayClass);
        
        //set initial dates
		jQuery.jcalendar.setDateWindow(this, a.dates, year);
		
		if(a.options.type == 0){
		    // set restaurant info
		    jQuery.jcalendar.setRestaurant(a.restaurant);
		    
		    jQuery.jcalendar.setLimitedData(a.limitedData);
    		
		    //show the calender
		    jQuery.jcalendar.show(this, day, month, year, datespan);
    		
            //find the nextfriday and nextsaturday names
		    nextfriday.html(jQuery.jcalendar.getDayArray()[5]);
  		    nextsaturday.html(jQuery.jcalendar.getDayArray()[6]);
    		
		    day.change(function() {
		        // only if a valid day is selected
    		    
		        //get the current day
		        currentdate = jQuery.jcalendar.getCurrentDate();
    		    
		        //get the first date
		        firstdate = jQuery.jcalendar.getFirstDate();
    		    
		        //if date value is between 0 and 32 then
		        //set dayChange true
		        //else set day value currentdate day value
		        if ((this.value >  0) && this.value <= 31){
  	                if(this.value != currentdate.getDate())
  	                    jQuery.jcalendar.setDayChange(true);
  	            }else{
  	                this.value = currentdate.getDate();
  	            }
  	        });
      	    
  	        $("input#day").unbind('focus').bind("focus", {}, jQuery.jcalendar.dayFocus);
            
		    month.change(function() {
		        // only if a valid month is selected
    		    
		        //get the currentdate
		        currentDate = jQuery.jcalendar.getCurrentDate();
    		    
		        //find the month name index
	            index = jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(),month.val());
    	        
	            //if noy find, maybe entered month val is integer
	            if(index==-1){	            
	                index = parseInt(month.val())-1;
    	            
	                //if not supported value set day value currentdate day value
	                if(jQuery.jcalendar.indexOf(jQuery.jcalendar.getCurrentMonths(),this.value) == -1 || this.value == 0){
	                    day.val(currentDate.getDate());
	                    index = currentDate.getMonth();
	                }               
                }
                
                //look for the day val is inselected month days interval
                if (!(day.val() > 0 && day.val() <= new Date(currentDate.getFullYear(),index+1,0).getDate())) {
		            index = currentDate.getMonth();
  	                day.val(currentDate.getDate());
  	            }
      	        
  	            //look for the day val is inselected month days interval
                if(parseInt(day.val(),10) > parseInt(new Date(year.val(), index+1, 0).getDate(),10)){
                    index = currentDate.getMonth();
  	                day.val(currentDate.getDate());
                }
                
                //create month start and end dates
                var start = new Date(year.val(), index, 1);
                var last = new Date(year.val(), index+1, 0).getDate();
                var end = new Date(year.val(), index, last);
	            d = new Date(year.val(), index, day.val());
	            jQuery.jcalendar.loadDayAvailibility(d, day, month, year, datespan,jQuery.jcalendar.getDateStr(start),jQuery.jcalendar.getDateStr(end), a.restaurant.rid, a.limitedData.days, a.limitedData.dates);
	            jQuery.jcalendar.setDayChange(false);
		    });
    		
		    month.blur(function() {
		        //if day value changed but month value is not changed
		        if(jQuery.jcalendar.getDayChange()){
		            currentdate = jQuery.jcalendar.getCurrentDate();
		            firstdate = jQuery.jcalendar.getFirstDate();
		            bounddate = new Date(currentdate.getFullYear(), currentdate.getMonth()+1,0).getDate();
		            if (($('#day').val() > (currentdate.getMonth() == firstdate.getMonth() ? firstdate.getDate() : 0)) && $('#day').val() <= bounddate){//new Date(currentDate.getFullYear(),currentDate.getMonth()+1,0).getDate()) {
		                d = new Date(year.val(), jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(),month.val()), day.val());
		                jQuery.jcalendar.changeMonth(d, day, month, year, datespan);
  	                }else{
  	                    $('#day').val(currentdate.getDate());
  	                }
		        }
  	        });
            
		    year.change(function() {
		        // only if a valid year is selected		  		    		    
		        if (this.value > 0) {
		            //look for year is allowed years
		            var arr = jQuery.jcalendar.getYears();
		            var i = 0;
		            var control = false;
		            for(i = 0;i<arr.length;i++){
		                if(arr[i].indexOf(year.val()) != -1){
		                    year.val(arr[i]);
		                    control = true;
		                    break;
		                }
		            }
    		        
		            //if year is allowed then change the date
		            if(control){
  		                d = new Date(this.value, jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(),month.val()), day.val());
    	                month.change();
    	            }else{//otherwise set the year with the currentdate year   
    	                year.val(jQuery.jcalendar.getCurrentDate().getFullYear());
    	            }
    	        }
		    });
      	    
  	    }
  	    else if(a.options.type == 1 || a.options.type == 5){
  	        //show the calender
		    jQuery.jcalendar.show(this, day, month, year, datespan);
		    
		    month.change(function() {
		        
		        // only if a valid month is selected
    		    
		        //get the currentdate
		        currentDate = jQuery.jcalendar.getCurrentDate();
    		    
		        //find the month name index
	            index = jQuery.jcalendar.indexOf(jQuery.jcalendar.getMonthArray(),month.val());
    	        
	            //if not find, maybe entered month val is integer
	            if(index==-1){	            
	                index = parseInt(month.val())-1;
    	            
	                //if not supported value set day value currentdate day value
	                if(jQuery.jcalendar.indexOf(jQuery.jcalendar.getCurrentMonths(),this.value) == -1 || this.value == 0){
	                    day.val(currentDate.getDate());
	                    index = currentDate.getMonth();
	                }               
                }
                
                //look for the day val is inselected month days interval
                if (!(day.val() > 0 && day.val() <= new Date(currentDate.getFullYear(),index+1,0).getDate())) {
		            index = currentDate.getMonth();
  	                day.val(currentDate.getDate());
  	            }
      	        
  	            //look for the day val is inselected month days interval
                if(parseInt(day.val(),10) > parseInt(new Date(year.val(), index+1, 0).getDate(),10)){
                    index = currentDate.getMonth();
  	                day.val(currentDate.getDate());
                }
                
                //create month start and end dates
                var start = new Date(year.val(), index, 1);
                var last = new Date(year.val(), index+1, 0).getDate();
                var end = new Date(year.val(), index, last);
	            d = new Date(year.val(), index, day.val());
	            jQuery.jcalendar.changeMonth(d, day, month, year, datespan);
	            jQuery.jcalendar.setDayChange(false);
		    });
  	    }
        
	});
	return this;
};


