mouseOverFunc = function () {
    addElementClass(this, "over");
};
mouseOutFunc = function () {
    removeElementClass(this, "over");
};

CalendarManager = function () {
    this.prevurl = null;
    this.nexturl = null;
    bindMethods(this);
};

update(CalendarManager.prototype, {
    "loadJSONFromURL": function (url) { //From the mochikit ajaxtables.js example
        log('loadJSONFromURL', url);
        var d;
        d = loadJSONDoc(url);
            this.deferred = d; // keep track of the current deferred, so that we can cancel it
            var self = this;
            // on success or error, remove the current deferred because it has completed, and pass through the result or error
            d.addBoth(function (res) {
                self.deferred = null; 
                log('loadFromURL success');
                return res;
            });
            // on success, tag the result with the format used so we can display it
            d.addCallback(function (res) {
                res.format = 'json';
                return res;
            });
            d.addCallback(this.repopulateCalendar); // call this.repopulateCalendar(data) once it's ready
            // if anything goes wrong, except for a simple cancellation, then log the error and show the logger
            d.addErrback(function (err) {
                if (err instanceof CancelledError) {
                    return;
                }
                logError(err);
                logger.debuggingBookmarklet();
            });
            return d;
        },
        "repopulateCalendar": function(data) {
            //Walk through the json structure applying the formatting to the referenced ids
            this.prevurl = data.prevmonth.url;
            this.nexturl = data.nextmonth.url;
            replaceChildNodes(this.thmonthname, A({'href': data.month.href}, data.month.monthname + " " + data.month.year ));
            days = data.days;
            while (days.length) {
                day = days.pop();
                td = getElement(day.htmlid);
                if (td) {
                    for (var i = 0; i < data.dayclasses.length; i++) {
                        removeElementClass(td, data.dayclasses[i]);
                    }
                    addElementClass(td, day.htmlclass);
                    if (day.href) {
                        replaceChildNodes(td, A({'href': day.href, "title": day.title}, day.daynumber));
                    } else {
                        if (day.date) {
                            replaceChildNodes(td, SPAN(day.daynumber));
                        } else {
                            replaceChildNodes(td, SPAN({'class':day.htmlclass},""));
                        }
                    }
                }
            }
        },
        "prevClickFunc" : function () {
            this.loadJSONFromURL(this.prevurl);
        },
        "nextClickFunc" : function () {
            this.loadJSONFromURL(this.nexturl);
        },
        "takeControl": function (table) {
            this.table = getElement(table);
            this.thmonthname = getElement("this-month");
            prev= getFirstElementByTagAndClassName("TH", "prev-month", parent=this.table);
            prev.onmouseover = null;
            prev.onmouseout = null;
            prev.onclick = null;
            replaceChildNodes(prev, SPAN("\u2190")); //should fish this out of the <a> text
            prev.onmouseover = mouseOverFunc;
            prev.onmouseout = mouseOutFunc;
            prev.onclick = this.prevClickFunc;
            next= getFirstElementByTagAndClassName("TH", "next-month", parent=this.table);
            next.onmouseover = null;
            next.onmouseout = null;
            next.onclick = null;
            replaceChildNodes(next, SPAN("\u2192"));
            next.onmouseover = mouseOverFunc;
            next.onmouseout = mouseOutFunc;
            next.onclick = this.nextClickFunc;
        }
});
