

function Calendar( leftCalendar, rightCalendar) {
    //alert("in the calendar 1");
    var logger = LogFactory.getLog("Calendar.js");

    var self = this;

    var months = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun",
                           "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
     //alert("in the calendar 2");
    // HTML ID values for the left and right calendar elements
    this.leftCal = leftCalendar;
    this.rightCal = rightCalendar;
    //alert("in the calendar 3");
    // The javascript reservation object
    var reservation;
    //alert("in the calendar 4");
    this.setReservation = function(r) {
        reservation = r;
        //alert("in the calendar 2");
    }
    //alert("in the calendar 4");
    var calendarDateRegex = new RegExp("^\\d{6}$");
    var calTableRegex     = new RegExp("^\\d{4}$");

    var tempMessage = "<div class='calTempMessage'>Loading availability ....</div>";
    //var MAX_DAYS_BETWEEN_START_END = 20;
    //alert("in the calendar 5");
    var calIdLoaded = new Array();
    calIdLoaded[this.leftCal] = false;
    calIdLoaded[this.rightCal] = false;

    var calIdDate = new Array();
    var today = new Date();

    
    var calLeft;
    var calRight;
     //alert("in the calendar 6");
    this.init = function() {
        //alert("in the calendar 7");
        var clearDates = document.getElementById("clearDates");
        clearDates.onclick = function() {
            reservation.clearDates();
            //reservation.setStartDate("");
            self.updateCalendars();
            //alert("in the calendar 8");
            return false;
        }

        
        calLeft     = document.getElementById( "calLeft" );
        calRight     = document.getElementById( "calRight" );

        // Set mouseovers
        

    }

    this.loadCalendars = function() {
//       try{

        if( arguments[0] && !( calIdLoaded[self.leftCal] && calIdLoaded[self.rightCal] ) ) {
            // Skip this if there is an argument and both cals aren't loaded
            return;
        }

        if( calIdLoaded[self.leftCal] ) {
            // load with the existing date on the left
            var cal1      = document.getElementById( self.leftCal );
            var tableId;
            var tNodes = cal1.getElementsByTagName("table");
            for( var i=0; i<tNodes.length; i++ ) {
                tableId = tNodes[i].id;
            }

            if( !tableId.substr ){
               return;
               }

            var leftDate = tableId.substr( 8, 4 );
            if( ! calTableRegex.test( leftDate ) ) {
                return;
            }

            self.loadCalsFromString( leftDate );

        } else if( res.getStartDate().length == 0 ) {
            // Today's month goes on the left
            var firstCal = "" + today.getFullYear() + getMonthAsString(today);
            firstCal = firstCal.substr(2, 6);
            var lastCal = getNextMonthString( today );
            self.getCalendar( this.leftCal,  firstCal );
            self.getCalendar( this.rightCal, lastCal );

        } else {
            self.loadCalsFromString( res.getStartDate().substr(0, 4) );

        }
//       }catch( e ){
//          return;
//       }

    }

    this.loadCalsFromString = function( dateStr ) {

        var startMonth = dateStr.substr(2, 2) -1;
        firstCal = dateStr;
        var check = startMonth - today.getMonth();
        if(  check != -2 && check != 10 ) {
            if( startMonth == 11 ) {
                var rightDate = dateStr.substring(0, 2);
                rightDate *= 1;
                rightDate++;
                rightDate = "" + rightDate;
                if( rightDate.length == 1 ) rightDate = "0" + rightDate;
                lastCal = rightDate + "01";
            } else {
                lastCal = dateStr.substring(0, 2) + 
                    (((startMonth+2) < 10) ? "0" : "") + (startMonth+2 );
            }
                          
        } else {
            lastCal = firstCal;
            if( startMonth == 0 ) {
                firstCal = (dateStr.substring(0, 2)-1) + "12";
				if (firstCal.length == 3)
					firstCal = "0" + firstCal;
            } else {
                firstCal = dateStr.substring(0, 2) + 
                    (((startMonth) < 10) ? "0" : "") + (startMonth);
            }

        }

        self.getCalendar( self.leftCal,  firstCal );
        self.getCalendar( self.rightCal, lastCal );

    }

    function getMonthAsString( date ) {
        var mon = date.getMonth() + 1;
        return (( mon < 10 ) ?  "0" + mon : mon );
    }

    // onclick handler to load calendars based on a date
    var loadCalendarsForDate = function(e) {
        //alert("claendar 10");
        var elem = getEventSource(e);
        //alert("claendar 111");
        if( elem.id.length > 0 && elem.id.indexOf("jmpto") == 0 ) {
            self.loadCalsFromString( elem.id.substr(5, 4) );
            //alert("claendar 12");
        }
        return false;
    }

    this.getCalendar = function( calId, date ) {
        logger.debug("Enter getCalendar(), calId=", calId, ", date=", date);
        //alert("claendar 12");
        if( !calTableRegex.test( date ) ){
           return;
           }

        disableLeftRight();
        var calElem     = document.getElementById( calId );
        calElem.innerHTML = tempMessage; // is this necessary?
        calIdLoaded[calId] = false;
        //alert("claendar 13");
        var year = "20" + date.substr(0, 2);
        var month = date.substr(2, 4);

        var http = getHTTPObject(); 
        var cursorHelper = new CursorHelper();
        cursorHelper.setNewCursor("wait");
        // Should this be a POST?
        //alert("claendar 14");
        var uri = "/reservation/GetCalendar.do?" +
                  reservation.getFormPostData() + 
                  "&calDate=" + date;
        //alert("claendar 15 "+uri);          
        http.open("GET", uri );
        //alert("claendar 16");
        http.onreadystatechange = 
            function() {
                if (http.readyState == 4 ) {
                    if( http.status == 200 ) {
                        logger.debug("in handleHttpResponse() - setting innerHTML");
                        //alert("claendar 17");
                        calElem.innerHTML = http.responseText;
                        //alert("claendar 18 "+http.responseText);
                        calIdLoaded[calId] = true;
                        calElem.onclick = selectDate; // do this here?
                        self.updateCalendar( calId );
                        calIdDate[calId] = new Date( year, month - 1, 1 );
                        enableLeftRight();
                    } else {
                        //alert("Problem with response, code = ", http.status, "\n",
                                           //http.responseText);
                    }
                    cursorHelper.removeCursor();
                }
            }

        http.send( null );


        logger.debug("Exit getCalendar()");
    }

    this.updateCalendar = function( calId ) {
        logger.debug("Enter updateCalendar(), calId=", calId);

        var calElem     = document.getElementById( calId );
        calElem.onclick = selectDate;

        var nodes = calElem.getElementsByTagName("A");
        for( var i=0; i<nodes.length; i++ ) {

            var nodei = nodes[i];
            var subNode = nodei.lastChild;
            if( subNode.nodeType == 1 ) {
                nodei.removeChild( subNode );
            }

            if( reservation.getStartDate().length == 0 ||
                reservation.getStartDate() > nodei.id ) {

                removeSelClass( nodei );

            } else if( reservation.getStartDate() == nodei.id ) {

                if( reservation.isValid() ) {
                    addAmount( nodei, reservation.getAmount(nodei.id) );
                    addSelClass( nodei );
                } else {
                    addSelClass( nodei );
                }

            } else if( reservation.getEndDate().length == 0 ||
                       reservation.getEndDate() < nodei.id ) {

                removeSelClass( nodei );

            } else {

                if( reservation.isValid() ) {
                    addAmount( nodei, reservation.getAmount(nodei.id) );
                    addSelClass( nodei );
                } else {
                    addSelClass( nodei );
                }

            }
            
        }

        logger.debug("Exit updateCalendar(), calId=", calId);
    }

    function removeSelClass( node ) {
        var className = node.className;
        if( className.indexOf(" sel") > 0 ) {
            node.className = className.substring( 0, className.indexOf(" sel") );
        }
    }

    function addSelClass( node ) {
        if( node.className.indexOf(" sel") < 0 ) {
            node.className = node.className + " sel";
        }
    }

    var tmpNode = document.createElement("SPAN");
    function addAmount( node, amount ) {
        var newNode = tmpNode.cloneNode(false);
        var newTxt  = document.createTextNode(amount);
        newNode.appendChild( newTxt );
        node.appendChild( newNode );
    }

    var selectDate = function(e) {
        logger.debug("Enter selectDate()");

        var elem = getEventSource(e);
       logger.debug("ID: ", elem.id, 
                  "\nStart Date: ", reservation.getStartDate(), 
                   "\nEnd Date: ", reservation.getEndDate() );

        if( elem.id == null || elem.id == "" ||
            ! calendarDateRegex.test( elem.id ) ) {
            // The user clicked on something other than a selectable date
            return false;
        }

        if( reservation.getStartDate() == elem.id ) {
            
            reservation.setStartDate( "" );
            reservation.setEndDate( "" );

        } else if( reservation.getStartDate().length == 0 || 
            reservation.getEndDate().length > 0         ) {

            reservation.setStartDate( elem.id );
            reservation.setEndDate( "" );

        } else if( reservation.getEndDate().length == 0 ) {

            var tmpDate = reservation.getStartDate();
            var numDays = daysBetweenDateStrings( tmpDate, elem.id );
            if( reservation.getStartDate() > elem.id ) {
                       reservation.setStartDate( elem.id );
                reservation.setEndDate( tmpDate );
            } else {
                reservation.setEndDate( elem.id );
            }

        } else {
//            alert("Should not get here!");
        }

        self.updateCalendars();

        logger.debug("Exit selectDate()");
        return false;
    }

    this.updateCalendars = function() {
        logger.debug("Enter updateCalendars()");
        this.updateCalendar( self.leftCal );
        this.updateCalendar( self.rightCal );
        logger.debug("Exit updateCalendars()");
    }

    var ONE_DAY = 1000 * 60 * 60 * 24
    function daysBetweenDateStrings( dateStr1, dateStr2 ) {
        logger.debug("Enter daysBetweenDateStrings()");
        date1 = getDateFromIdString( dateStr1 );
        date2 = getDateFromIdString( dateStr2 );
        // The number of milliseconds in one day

        // Convert both dates to milliseconds
        var date1_ms = date1.getTime()
        var date2_ms = date2.getTime()

        // Calculate the difference in milliseconds
        var difference_ms = Math.abs(date1_ms - date2_ms)
        
        // Convert back to days and return
        logger.debug("Exit daysBetweenDateStrings()");
        return Math.round(difference_ms/ONE_DAY)
    }
        
    function getDateFromIdString( dateStr ) {
        var year  = "20" + dateStr.substr(0, 2);
        var month = dateStr.substr(2, 2);
        var day   = dateStr.substr(4, 2);
        var date = new Date( year, month - 1, day );
        return date;
    }

    var disableLeftRight = function() {
        logger.debug("Enter disableLeftRight()");

        
        calLeft.onclick = null;
        calLeft.style.display = "none";
        calRight.onclick = null;
        calRight.style.display = "none";


        logger.debug("Exit disableLeftRight()");
    }

    var enableLeftRight = function() {
        logger.debug("Enter enableLeftRight()");

        var loaded = true;
        for( var i in calIdLoaded ) {
           logger.debug("CalId: ", i, " loaded? ", calIdLoaded[i]);
            loaded = loaded && calIdLoaded[i];
        }

        if( loaded ) {
            logger.debug("LOADED!");
            var leftMonth = calIdDate[self.leftCal].getMonth();
            var rightMonth = calIdDate[self.rightCal].getMonth();
            var todayMonth = today.getMonth();
            if( leftMonth != todayMonth ) {
                calLeft.onclick  = calendarLeft;
                var lm = leftMonth - 1;
                lm = (lm<0) ? 11 : lm;
                calLeft.innerHTML = months[lm];
                calLeft.style.display = "block";
            }
            var check = rightMonth - todayMonth
            if(  check != -2 && check != 10 ) {
                calRight.onclick = calendarRight;
                calRight.innerHTML = months[ (rightMonth+1)%12 ];
                calRight.style.display = "block";
            }

            

        }

        logger.debug("Exit enableLeftRight()");
    }

    var calendarRight = function() {
        logger.debug("Enter calendarRight()");

        disableLeftRight();
        var cal1      = document.getElementById( self.leftCal );
        var cal2     = document.getElementById( self.rightCal );
        cal1.innerHTML = cal2.innerHTML;
        calIdDate[self.leftCal] = calIdDate[self.rightCal];
        var tDate = getNextMonthString( calIdDate[self.rightCal] );
        self.getCalendar(self.rightCal, tDate);
        
        logger.debug("Exit calendarRight()");
        return false;
    }

    function getNextMonthString( date ) {
        logger.debug("Enter getNextMonthString()");

        var year = date.getFullYear();
        var month = date.getMonth();
        if( month == 11 ) {
            month = 1;
            year += 1;
        } else {
            month += 2;
        }
        if( month < 10 ) {
            month = "0" + month;
        }
        tYear = "" + year;
        tDate = "" + tYear.substring(2,4) + month;

        logger.debug("Exit getNextMonthString()");
        return tDate;
    }

    var calendarLeft = function() {
        logger.debug("Enter calendarLeft()");
        disableLeftRight();
        var cal1      = document.getElementById( self.leftCal );
        var cal2     = document.getElementById( self.rightCal );
        cal2.innerHTML = cal1.innerHTML;
        calIdDate[self.rightCal] = calIdDate[self.leftCal];
        var year = calIdDate[self.leftCal].getFullYear();
        var month = calIdDate[self.leftCal].getMonth();
        if( month == 0 ) {
            month = 12;
            year -= 1;
        }
        if( month < 10 ) {
            month = "0" + month;
        }
        tYear = "" + year;
        tDate = "" + tYear.substring(2,4) + month;
        self.getCalendar(self.leftCal, tDate);
        
        logger.debug("Exit calendarLeft()");
        return false;
    }

}

