/******************************************************* request.js *******************************************/

function sendUiMessage(form){

	var roomVar = form.room.value;
	var dayVar = form.day.value;
	var monthVar = form.month.value;
	var yearVar = form.year.value;
	var nightsVar = form.nights.value;
	var mytableVar = form.mytable.value;
	var borderVar = form.border.value;
	var barVar = form.bar.value;
	var titleVar = form.title.value;
	var backVar = form.back1.value;
	var textVar = form.text1.value;
	var fontVar = form.font.value;
	var communityVar = form.communitylink.value;
	var selflocation = self.location;

 	var selflocation = String(selflocation);
 	var selflocation = selflocation.replace("http://", "");

	var codenumVar = form.codenumVar.value;


//	if(roomVar == "all"){document.getElementById("pipeFrame").style.height = "320px";}
//	if(roomVar != "all"){document.getElementById("pipeFrame").style.height = "320px";}

	var iwin;
		if(navigator.userAgent.indexOf("Safari") != -1){
				iwin = frames[codenumVar];
		}else{
				iwin = document.getElementById(codenumVar).contentWindow;
		}
		iwin.location = "http://www.bedbreakfastavailability.co.uk/remote/v8/availability.php?" + "room=" + roomVar + "&day=" + dayVar + "&month=" + monthVar + "&year=" + yearVar + "&nights=" + nightsVar + "&mytable=" + mytableVar + "&border=" + borderVar + "&bar=" + barVar + "&title=" + titleVar + "&back=" + backVar + "&text=" + textVar + "&font=" + fontVar + "&communitylink=" + communityVar + "&selflocation=" + selflocation;
}





/****************************************************** dropdown.js ******************************************************/

var dayno=['','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31'];
var monthtext=['','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sept','Oct','Nov','Dec'];
var monthno=['','01','02','03','04','05','06','07','08','09','10','11','12'];

function populatedropdown(dayfield, monthfield, yearfield){
	var today=new Date()
	var dayfield=document.getElementById(dayfield)
	var monthfield=document.getElementById(monthfield)
	var yearfield=document.getElementById(yearfield)
	for (var i=0; i<32; i++)
	dayfield.options[i]=new Option(dayno[i], dayno[i])
	dayfield.options[today.getDate()]=new Option(dayno[today.getDate()], dayno[today.getDate()], true, true) //select today's day
	for (var m=0; m<13; m++)
	monthfield.options[m]=new Option(monthtext[m], monthno[m])
	monthfield.options[today.getMonth()+1]=new Option(monthtext[today.getMonth()+1], monthno[today.getMonth()+1], true, true) //select today's month
	var thisyear=today.getFullYear()
	
	yearfield.options[0]=new Option(monthtext[0], monthtext[0])
	yearfield.options[1]=new Option(today.getFullYear(), today.getFullYear(), true, true) //select today's year
	yearfield.options[2]=new Option(thisyear+1, thisyear+1)
}


/**************************************************************************** yahoo.js ***********************************/

if (typeof YAHOO == "undefined") {
    var YAHOO = {};
}


YAHOO.namespace = function() {
    var a=arguments, o=null, i, j, d;
    for (i=0; i<a.length; ++i) {
        d=a[i].split(".");
        o=YAHOO;

        // YAHOO is implied, so it is ignored if it is included
        for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; ++j) {
            o[d[j]]=o[d[j]] || {};
            o=o[d[j]];
        }
    }

    return o;
};

YAHOO.log = function(msg, cat, src) {
    var l=YAHOO.widget.Logger;
    if(l && l.log) {
        return l.log(msg, cat, src);
    } else {
        return false;
    }
};

YAHOO.extend = function(subc, superc, overrides) {
    var F = function() {};
    F.prototype=superc.prototype;
    subc.prototype=new F();
    subc.prototype.constructor=subc;
    subc.superclass=superc.prototype;
    if (superc.prototype.constructor == Object.prototype.constructor) {
        superc.prototype.constructor=superc;
    }

    if (overrides) {
        for (var i in overrides) {
            subc.prototype[i]=overrides[i];
        }
    }
};

YAHOO.augment = function(r, s) {
    var rp=r.prototype, sp=s.prototype, a=arguments, i, p;
    if (a[2]) {
        for (i=2; i<a.length; ++i) {
            rp[a[i]] = sp[a[i]];
        }
    } else {
        for (p in sp) { 
            if (!rp[p]) {
                rp[p] = sp[p];
            }
        }
    }
};

YAHOO.namespace("util", "widget", "example");



/************************************************************* event.js ********************************************************************/

YAHOO.util.CustomEvent = function(type, oScope, silent, signature) {

    this.type = type;

    this.scope = oScope || window;

    this.silent = silent;

    this.signature = signature || YAHOO.util.CustomEvent.LIST;

    this.subscribers = [];

    if (!this.silent) {
    }

    var onsubscribeType = "_YUICEOnSubscribe";

    if (type !== onsubscribeType) {

        this.subscribeEvent = 
                new YAHOO.util.CustomEvent(onsubscribeType, this, true);

    } 
};

YAHOO.util.CustomEvent.LIST = 0;

YAHOO.util.CustomEvent.FLAT = 1;

YAHOO.util.CustomEvent.prototype = {

    subscribe: function(fn, obj, override) {
        if (this.subscribeEvent) {
            this.subscribeEvent.fire(fn, obj, override);
        }

        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, override) );
    },

    unsubscribe: function(fn, obj) {
        var found = false;
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            var s = this.subscribers[i];
            if (s && s.contains(fn, obj)) {
                this._delete(i);
                found = true;
            }
        }

        return found;
    },

    fire: function() {
        var len=this.subscribers.length;
        if (!len && this.silent) {
            return true;
        }

        var args=[], ret=true, i;

        for (i=0; i<arguments.length; ++i) {
            args.push(arguments[i]);
        }

        var argslength = args.length;

        if (!this.silent) {
        }

        for (i=0; i<len; ++i) {
            var s = this.subscribers[i];
            if (s) {
                if (!this.silent) {
                }

                var scope = s.getScope(this.scope);

                if (this.signature == YAHOO.util.CustomEvent.FLAT) {
                    var param = null;
                    if (args.length > 0) {
                        param = args[0];
                    }
                    ret = s.fn.call(scope, param, s.obj);
                } else {
                    ret = s.fn.call(scope, this.type, args, s.obj);
                }
                if (false === ret) {
                    if (!this.silent) {
                    }

                    //break;
                    return false;
                }
            }
        }

        return true;
    },

    unsubscribeAll: function() {
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            this._delete(len - 1 - i);
        }
    },

    _delete: function(index) {
        var s = this.subscribers[index];
        if (s) {
            delete s.fn;
            delete s.obj;
        }

        // delete this.subscribers[index];
        this.subscribers.splice(index, 1);
    },

    toString: function() {
         return "CustomEvent: " + "'" + this.type  + "', " + 
             "scope: " + this.scope;

    }
};

YAHOO.util.Subscriber = function(fn, obj, override) {

    this.fn = fn;

    this.obj = obj || null;

    this.override = override;

};

YAHOO.util.Subscriber.prototype.getScope = function(defaultScope) {
    if (this.override) {
        if (this.override === true) {
            return this.obj;
        } else {
            return this.override;
        }
    }
    return defaultScope;
};

YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
    if (obj) {
        return (this.fn == fn && this.obj == obj);
    } else {
        return (this.fn == fn);
    }
};

YAHOO.util.Subscriber.prototype.toString = function() {
    return "Subscriber { obj: " + (this.obj || "")  + 
           ", override: " +  (this.override || "no") + " }";
};

if (!YAHOO.util.Event) {

    YAHOO.util.Event = function() {

        var loadComplete =  false;

        var listeners = [];

        var unloadListeners = [];

        var legacyEvents = [];

        var legacyHandlers = [];

        var retryCount = 0;

        var onAvailStack = [];

        var legacyMap = [];

        var counter = 0;

        return { // PREPROCESS

            POLL_RETRYS: 200,

            POLL_INTERVAL: 20,

            EL: 0,

            TYPE: 1,

            FN: 2,

            WFN: 3,

            OBJ: 3,

            ADJ_SCOPE: 4,

            isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),

            isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) && 
                    navigator.userAgent.match(/msie/gi)),

            _interval: null,

            startInterval: function() {
                if (!this._interval) {
                    var self = this;
                    var callback = function() { self._tryPreloadAttach(); };
                    this._interval = setInterval(callback, this.POLL_INTERVAL);
                    // this.timeout = setTimeout(callback, i);
                }
            },

            onAvailable: function(p_id, p_fn, p_obj, p_override) {
                onAvailStack.push( { id:         p_id, 
                                     fn:         p_fn, 
                                     obj:        p_obj, 
                                     override:   p_override, 
                                     checkReady: false    } );

                retryCount = this.POLL_RETRYS;
                this.startInterval();
            },

            onContentReady: function(p_id, p_fn, p_obj, p_override) {
                onAvailStack.push( { id:         p_id, 
                                     fn:         p_fn, 
                                     obj:        p_obj, 
                                     override:   p_override,
                                     checkReady: true      } );

                retryCount = this.POLL_RETRYS;
                this.startInterval();
            },

            addListener: function(el, sType, fn, obj, override) {

                if (!fn || !fn.call) {
                    return false;
                }

                // The el argument can be an array of elements or element ids.
                if ( this._isValidCollection(el)) {
                    var ok = true;
                    for (var i=0,len=el.length; i<len; ++i) {
                        ok = this.on(el[i], 
                                       sType, 
                                       fn, 
                                       obj, 
                                       override) && ok;
                    }
                    return ok;

                } else if (typeof el == "string") {
                    var oEl = this.getEl(el);

                    if (oEl) {
                        el = oEl;
                    } else {
                        // defer adding the event until the element is available
                        this.onAvailable(el, function() {
                           YAHOO.util.Event.on(el, sType, fn, obj, override);
                        });

                        return true;
                    }
                }


                if (!el) {
                    return false;
                }


                if ("unload" == sType && obj !== this) {
                    unloadListeners[unloadListeners.length] =
                            [el, sType, fn, obj, override];
                    return true;
                }


                var scope = el;
                if (override) {
                    if (override === true) {
                        scope = obj;
                    } else {
                        scope = override;
                    }
                }


                var wrappedFn = function(e) {
                        return fn.call(scope, YAHOO.util.Event.getEvent(e), 
                                obj);
                    };

                var li = [el, sType, fn, wrappedFn, scope];
                var index = listeners.length;

                listeners[index] = li;

                if (this.useLegacyEvent(el, sType)) {
                    var legacyIndex = this.getLegacyIndex(el, sType);

                    if ( legacyIndex == -1 || 
                                el != legacyEvents[legacyIndex][0] ) {

                        legacyIndex = legacyEvents.length;
                        legacyMap[el.id + sType] = legacyIndex;

                        legacyEvents[legacyIndex] = 
                            [el, sType, el["on" + sType]];
                        legacyHandlers[legacyIndex] = [];

                        el["on" + sType] = 
                            function(e) {
                                YAHOO.util.Event.fireLegacyEvent(
                                    YAHOO.util.Event.getEvent(e), legacyIndex);
                            };
                    }


                    legacyHandlers[legacyIndex].push(li);

                } else {
                    this._simpleAdd(el, sType, wrappedFn, false);
                }

                return true;
                
            },


            fireLegacyEvent: function(e, legacyIndex) {
                var ok = true;

                var le = legacyHandlers[legacyIndex];
                for (var i=0,len=le.length; i<len; ++i) {
                    var li = le[i];
                    if ( li && li[this.WFN] ) {
                        var scope = li[this.ADJ_SCOPE];
                        var ret = li[this.WFN].call(scope, e);
                        ok = (ok && ret);
                    }
                }

                return ok;
            },

            getLegacyIndex: function(el, sType) {
                var key = this.generateId(el) + sType;
                if (typeof legacyMap[key] == "undefined") { 
                    return -1;
                } else {
                    return legacyMap[key];
                }
            },

            useLegacyEvent: function(el, sType) {
                if (!el.addEventListener && !el.attachEvent) {
                    return true;
                } else if (this.isSafari) {
                    if ("click" == sType || "dblclick" == sType) {
                        return true;
                    }
                }
                return false;
            },
                    
            removeListener: function(el, sType, fn) {
                var i, len;

                // The el argument can be a string
                if (typeof el == "string") {
                    el = this.getEl(el);
                // The el argument can be an array of elements or element ids.
                } else if ( this._isValidCollection(el)) {
                    var ok = true;
                    for (i=0,len=el.length; i<len; ++i) {
                        ok = ( this.removeListener(el[i], sType, fn) && ok );
                    }
                    return ok;
                }

                if (!fn || !fn.call) {
                    //return false;
                    return this.purgeElement(el, false, sType);
                }

                if ("unload" == sType) {

                    for (i=0, len=unloadListeners.length; i<len; i++) {
                        var li = unloadListeners[i];
                        if (li && 
                            li[0] == el && 
                            li[1] == sType && 
                            li[2] == fn) {
                                unloadListeners.splice(i, 1);
                                return true;
                        }
                    }

                    return false;
                }

                var cacheItem = null;

                var index = arguments[3];
  
                if ("undefined" == typeof index) {
                    index = this._getCacheIndex(el, sType, fn);
                }

                if (index >= 0) {
                    cacheItem = listeners[index];
                }

                if (!el || !cacheItem) {
                    return false;
                }

                if (this.useLegacyEvent(el, sType)) {
                    var legacyIndex = this.getLegacyIndex(el, sType);
                    var llist = legacyHandlers[legacyIndex];
                    if (llist) {
                        for (i=0, len=llist.length; i<len; ++i) {
                            li = llist[i];
                            if (li && 
                                li[this.EL] == el && 
                                li[this.TYPE] == sType && 
                                li[this.FN] == fn) {
                                    llist.splice(i, 1);
                                    break;
                            }
                        }
                    }

                } else {
                    this._simpleRemove(el, sType, cacheItem[this.WFN], false);
                }

                // removed the wrapped handler
                delete listeners[index][this.WFN];
                delete listeners[index][this.FN];
                listeners.splice(index, 1);

                return true;

            },


            getTarget: function(ev, resolveTextNode) {
                var t = ev.target || ev.srcElement;
                return this.resolveTextNode(t);
            },


            resolveTextNode: function(node) {
                // if (node && node.nodeName && 
                        // "#TEXT" == node.nodeName.toUpperCase()) {
                if (node && 3 == node.nodeType) {
                    return node.parentNode;
                } else {
                    return node;
                }
            },


            getPageX: function(ev) {
                var x = ev.pageX;
                if (!x && 0 !== x) {
                    x = ev.clientX || 0;

                    if ( this.isIE ) {
                        x += this._getScrollLeft();
                    }
                }

                return x;
            },


            getPageY: function(ev) {
                var y = ev.pageY;
                if (!y && 0 !== y) {
                    y = ev.clientY || 0;

                    if ( this.isIE ) {
                        y += this._getScrollTop();
                    }
                }

                return y;
            },


            getXY: function(ev) {
                return [this.getPageX(ev), this.getPageY(ev)];
            },


            getRelatedTarget: function(ev) {
                var t = ev.relatedTarget;
                if (!t) {
                    if (ev.type == "mouseout") {
                        t = ev.toElement;
                    } else if (ev.type == "mouseover") {
                        t = ev.fromElement;
                    }
                }

                return this.resolveTextNode(t);
            },


            getTime: function(ev) {
                if (!ev.time) {
                    var t = new Date().getTime();
                    try {
                        ev.time = t;
                    } catch(e) { 
                        return t;
                    }
                }

                return ev.time;
            },


            stopEvent: function(ev) {
                this.stopPropagation(ev);
                this.preventDefault(ev);
            },


            stopPropagation: function(ev) {
                if (ev.stopPropagation) {
                    ev.stopPropagation();
                } else {
                    ev.cancelBubble = true;
                }
            },


            preventDefault: function(ev) {
                if (ev.preventDefault) {
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
            },
             

            getEvent: function(e) {
                var ev = e || window.event;

                if (!ev) {
                    var c = this.getEvent.caller;
                    while (c) {
                        ev = c.arguments[0];
                        if (ev && Event == ev.constructor) {
                            break;
                        }
                        c = c.caller;
                    }
                }

                return ev;
            },


            getCharCode: function(ev) {
                return ev.charCode || ev.keyCode || 0;
            },


            _getCacheIndex: function(el, sType, fn) {
                for (var i=0,len=listeners.length; i<len; ++i) {
                    var li = listeners[i];
                    if ( li                 && 
                         li[this.FN] == fn  && 
                         li[this.EL] == el  && 
                         li[this.TYPE] == sType ) {
                        return i;
                    }
                }

                return -1;
            },


            generateId: function(el) {
                var id = el.id;

                if (!id) {
                    id = "yuievtautoid-" + counter;
                    ++counter;
                    el.id = id;
                }

                return id;
            },


            _isValidCollection: function(o) {


                return ( o                    && // o is something
                         o.length             && // o is indexed
                         typeof o != "string" && // o is not a string
                         !o.tagName           && // o is not an HTML element
                         !o.alert             && // o is not a window
                         typeof o[0] != "undefined" );

            },


            elCache: {},


            getEl: function(id) {
                return document.getElementById(id);
            },


            clearCache: function() { },


            _load: function(e) {
                loadComplete = true;
                var EU = YAHOO.util.Event;
                // Remove the listener to assist with the IE memory issue, but not
                // for other browsers because FF 1.0x does not like it.
                if (this.isIE) {
                    EU._simpleRemove(window, "load", EU._load);
                }
            },


            _tryPreloadAttach: function() {

                if (this.locked) {
                    return false;
                }

                this.locked = true;


                var tryAgain = !loadComplete;
                if (!tryAgain) {
                    tryAgain = (retryCount > 0);
                }


                var notAvail = [];
                for (var i=0,len=onAvailStack.length; i<len ; ++i) {
                    var item = onAvailStack[i];
                    if (item) {
                        var el = this.getEl(item.id);

                        if (el) {
                            // The element is available, but not necessarily ready

                            if ( !item.checkReady || 
                                    loadComplete || 
                                    el.nextSibling ||
                                    (document && document.body) ) {

                                var scope = el;
                                if (item.override) {
                                    if (item.override === true) {
                                        scope = item.obj;
                                    } else {
                                        scope = item.override;
                                    }
                                }
                                item.fn.call(scope, item.obj);
                                delete onAvailStack[i];
                            }
                        } else {
                            notAvail.push(item);
                        }
                    }
                }

                retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;

                if (tryAgain) {
                    this.startInterval();
                } else {
                    clearInterval(this._interval);
                    this._interval = null;
                }

                this.locked = false;

                return true;

            },


            purgeElement: function(el, recurse, sType) {
                var elListeners = this.getListeners(el, sType);
                if (elListeners) {
                    for (var i=0,len=elListeners.length; i<len ; ++i) {
                        var l = elListeners[i];

                        this.removeListener(el, l.type, l.fn);
                    }
                }

                if (recurse && el && el.childNodes) {
                    for (i=0,len=el.childNodes.length; i<len ; ++i) {
                        this.purgeElement(el.childNodes[i], recurse, sType);
                    }
                }
            },

        
            getListeners: function(el, sType) {
                var elListeners = [];
                if (listeners && listeners.length > 0) {
                    for (var i=0,len=listeners.length; i<len ; ++i) {
                        var l = listeners[i];
                        if ( l  && l[this.EL] === el && 
                                (!sType || sType === l[this.TYPE]) ) {
                            elListeners.push({
                                type:   l[this.TYPE],
                                fn:     l[this.FN],
                                obj:    l[this.OBJ],
                                adjust: l[this.ADJ_SCOPE],
                                index:  i
                            });
                        }
                    }
                }

                return (elListeners.length) ? elListeners : null;
            },


            _unload: function(e) {

                var EU = YAHOO.util.Event, i, j, l, len, index;

                for (i=0,len=unloadListeners.length; i<len; ++i) {
                    l = unloadListeners[i];
                    if (l) {
                        var scope = window;
                        if (l[EU.ADJ_SCOPE]) {
                            if (l[EU.ADJ_SCOPE] === true) {
                                scope = l[EU.OBJ];
                            } else {
                                scope = l[EU.ADJ_SCOPE];
                            }
                        }
                        l[EU.FN].call(scope, EU.getEvent(e), l[EU.OBJ] );
                        delete unloadListeners[i];
                        l=null;
                        scope=null;
                    }
                }

                if (listeners && listeners.length > 0) {
                    j = listeners.length;
                    while (j) {
                        index = j-1;
                        l = listeners[index];
                        if (l) {
                            EU.removeListener(l[EU.EL], l[EU.TYPE], 
                                    l[EU.FN], index);
                        } 
                        j = j - 1;
                    }
                    l=null;

                    EU.clearCache();
                }

                for (i=0,len=legacyEvents.length; i<len; ++i) {
                    // dereference the element
                    delete legacyEvents[i][0];
                    // delete the array item
                    delete legacyEvents[i];
                }

                EU._simpleRemove(window, "unload", EU._unload);

            },


            _getScrollLeft: function() {
                return this._getScroll()[1];
            },


            _getScrollTop: function() {
                return this._getScroll()[0];
            },


            _getScroll: function() {
                var dd = document.documentElement, db = document.body;
                if (dd && (dd.scrollTop || dd.scrollLeft)) {
                    return [dd.scrollTop, dd.scrollLeft];
                } else if (db) {
                    return [db.scrollTop, db.scrollLeft];
                } else {
                    return [0, 0];
                }
            },


            _simpleAdd: function () {
                if (window.addEventListener) {
                    return function(el, sType, fn, capture) {
                        el.addEventListener(sType, fn, (capture));
                    };
                } else if (window.attachEvent) {
                    return function(el, sType, fn, capture) {
                        el.attachEvent("on" + sType, fn);
                    };
                } else {
                    return function(){};
                }
            }(),


            _simpleRemove: function() {
                if (window.removeEventListener) {
                    return function (el, sType, fn, capture) {
                        el.removeEventListener(sType, fn, (capture));
                    };
                } else if (window.detachEvent) {
                    return function (el, sType, fn) {
                        el.detachEvent("on" + sType, fn);
                    };
                } else {
                    return function(){};
                }
            }()
        };

    }();

    (function() {
        var EU = YAHOO.util.Event;


        EU.on = EU.addListener;



        if (document && document.body) {
            EU._load();
        } else {
            // EU._simpleAdd(document, "DOMContentLoaded", EU._load);
            EU._simpleAdd(window, "load", EU._load);
        }
        EU._simpleAdd(window, "unload", EU._unload);
        EU._tryPreloadAttach();
    })();
}


YAHOO.util.EventProvider = function() { };

YAHOO.util.EventProvider.prototype = {

    /**
     * Private storage of custom events
     * @property __yui_events
     * @type Object[]
     * @private
     */
    __yui_events: null,


    __yui_subscribers: null,
    

    subscribe: function(p_type, p_fn, p_obj, p_override) {

        this.__yui_events = this.__yui_events || {};
        var ce = this.__yui_events[p_type];

        if (ce) {
            ce.subscribe(p_fn, p_obj, p_override);
        } else {
            this.__yui_subscribers = this.__yui_subscribers || {};
            var subs = this.__yui_subscribers;
            if (!subs[p_type]) {
                subs[p_type] = [];
            }
            subs[p_type].push(
                { fn: p_fn, obj: p_obj, override: p_override } );
        }
    },


    unsubscribe: function(p_type, p_fn, p_obj) {
        this.__yui_events = this.__yui_events || {};
        var ce = this.__yui_events[p_type];
        if (ce) {
            return ce.unsubscribe(p_fn, p_obj);
        } else {
            return false;
        }
    },


    createEvent: function(p_type, p_config) {

        this.__yui_events = this.__yui_events || {};
        var opts = p_config || {};
        var events = this.__yui_events;

        if (events[p_type]) {
        } else {

            var scope  = opts.scope  || this;
            var silent = opts.silent || null;

            var ce = new YAHOO.util.CustomEvent(p_type, scope, silent,
                    YAHOO.util.CustomEvent.FLAT);
            events[p_type] = ce;

            if (opts.onSubscribeCallback) {
                ce.subscribeEvent.subscribe(opts.onSubscribeCallback);
            }

            this.__yui_subscribers = this.__yui_subscribers || {};
            var qs = this.__yui_subscribers[p_type];

            if (qs) {
                for (var i=0; i<qs.length; ++i) {
                    ce.subscribe(qs[i].fn, qs[i].obj, qs[i].override);
                }
            }
        }

        return events[p_type];
    },


    fireEvent: function(p_type, arg1, arg2, etc) {

        this.__yui_events = this.__yui_events || {};
        var ce = this.__yui_events[p_type];

        if (ce) {
            var args = [];
            for (var i=1; i<arguments.length; ++i) {
                args.push(arguments[i]);
            }
            return ce.fire.apply(ce, args);
        } else {
            return null;
        }
    },


    hasEvent: function(type) {
        if (this.__yui_events) {
            if (this.__yui_events[type]) {
                return true;
            }
        }
        return false;
    }

};



/*************************************************** dom.js ***********************************************************/

(function() {
    var Y = YAHOO.util,     
        getStyle,           
        setStyle,           
        id_counter = 0,     
        propertyCache = {}; 


    var ua = navigator.userAgent.toLowerCase(),
        isOpera = (ua.indexOf('opera') > -1),
        isSafari = (ua.indexOf('safari') > -1),
        isGecko = (!isOpera && !isSafari && ua.indexOf('gecko') > -1),
        isIE = (!isOpera && ua.indexOf('msie') > -1);


    var patterns = {
        HYPHEN: /(-[a-z])/i
    };


    var toCamel = function(property) {
        if ( !patterns.HYPHEN.test(property) ) {
            return property; 
        }

        if (propertyCache[property]) { 
            return propertyCache[property];
        }

        while( patterns.HYPHEN.exec(property) ) {
            property = property.replace(RegExp.$1,
                    RegExp.$1.substr(1).toUpperCase());
        }

        propertyCache[property] = property;
        return property;

    };


    if (document.defaultView && document.defaultView.getComputedStyle) { 
        getStyle = function(el, property) {
            var value = null;

            var computed = document.defaultView.getComputedStyle(el, '');
            if (computed) { 
                value = computed[toCamel(property)];
            }

            return el.style[property] || value;
        };
    } else if (document.documentElement.currentStyle && isIE) { // IE method
        getStyle = function(el, property) {
            switch( toCamel(property) ) {
                case 'opacity' :// IE opacity uses filter
                    var val = 100;
                    try { // will error if no DXImageTransform
                        val = el.filters['DXImageTransform.Microsoft.Alpha'].opacity;

                    } catch(e) {
                        try { // make sure its in the document
                            val = el.filters('alpha').opacity;
                        } catch(e) {
                        }
                    }
                    return val / 100;
                    break;
                default:
                    // test currentStyle before touching
                    var value = el.currentStyle ? el.currentStyle[property] : null;
                    return ( el.style[property] || value );
            }
        };
    } else { // default to inline only
        getStyle = function(el, property) { return el.style[property]; };
    }

    if (isIE) {
        setStyle = function(el, property, val) {
            switch (property) {
                case 'opacity':
                    if ( typeof el.style.filter == 'string' ) { // in case not appended
                        el.style.filter = 'alpha(opacity=' + val * 100 + ')';

                        if (!el.currentStyle || !el.currentStyle.hasLayout) {
                            el.style.zoom = 1; // when no layout or cant tell
                        }
                    }
                    break;
                default:
                el.style[property] = val;
            }
        };
    } else {
        setStyle = function(el, property, val) {
            el.style[property] = val;
        };
    }


    YAHOO.util.Dom = {

        get: function(el) {
            if (!el) { return null; } 

            if (typeof el != 'string' && !(el instanceof Array) ) { 
                return el;
            }

            if (typeof el == 'string') { // ID
                return document.getElementById(el);
            }
            else { // array of ID's and/or elements
                var collection = [];
                for (var i = 0, len = el.length; i < len; ++i) {
                    collection[collection.length] = Y.Dom.get(el[i]);
                }

                return collection;
            }

            return null; 
        },


        getStyle: function(el, property) {
            property = toCamel(property);

            var f = function(element) {
                return getStyle(element, property);
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        setStyle: function(el, property, val) {
            property = toCamel(property);

            var f = function(element) {
                setStyle(element, property, val);

            };

            Y.Dom.batch(el, f, Y.Dom, true);
        },


        getXY: function(el) {
            var f = function(el) {

            // has to be part of document to have pageXY
                if (el.parentNode === null || el.offsetParent === null ||
                        this.getStyle(el, 'display') == 'none') {
                    return false;
                }

                var parentNode = null;
                var pos = [];
                var box;

                if (el.getBoundingClientRect) { // IE
                    box = el.getBoundingClientRect();
                    var doc = document;
                    if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
                        doc = parent.document;

                        if ( !this.isAncestor(doc.documentElement, el) ) {
                            return false;
                        }

                    }

                    var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
                    var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);

                    return [box.left + scrollLeft, box.top + scrollTop];
                }
                else { // safari, opera, & gecko
                    pos = [el.offsetLeft, el.offsetTop];
                    parentNode = el.offsetParent;
                    if (parentNode != el) {
                        while (parentNode) {
                            pos[0] += parentNode.offsetLeft;
                            pos[1] += parentNode.offsetTop;
                            parentNode = parentNode.offsetParent;
                        }
                    }
                    if (isSafari && this.getStyle(el, 'position') == 'absolute' ) { // safari doubles in some cases
                        pos[0] -= document.body.offsetLeft;
                        pos[1] -= document.body.offsetTop;
                    }
                }

                if (el.parentNode) { parentNode = el.parentNode; }
                else { parentNode = null; }

                while (parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML')
                { // account for any scrolled ancestors
                    if (Y.Dom.getStyle(parentNode, 'display') != 'inline') { // work around opera inline scrollLeft/Top bug
                        pos[0] -= parentNode.scrollLeft;
                        pos[1] -= parentNode.scrollTop;
                    }

                    if (parentNode.parentNode) {
                        parentNode = parentNode.parentNode;
                    } else { parentNode = null; }
                }


                return pos;
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        getX: function(el) {
            var f = function(el) {
                return Y.Dom.getXY(el)[0];
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        getY: function(el) {
            var f = function(el) {
                return Y.Dom.getXY(el)[1];
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        setXY: function(el, pos, noRetry) {
            var f = function(el) {
                var style_pos = this.getStyle(el, 'position');
                if (style_pos == 'static') { // default to relative
                    this.setStyle(el, 'position', 'relative');
                    style_pos = 'relative';
                }

                var pageXY = this.getXY(el);
                if (pageXY === false) { // has to be part of doc to have pageXY
                    return false;
                }

                var delta = [ // assuming pixels; if not we will have to retry
                    parseInt( this.getStyle(el, 'left'), 10 ),
                    parseInt( this.getStyle(el, 'top'), 10 )
                ];

                if ( isNaN(delta[0]) ) {// in case of 'auto'
                    delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
                }
                if ( isNaN(delta[1]) ) { // in case of 'auto'
                    delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop;
                }

                if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
                if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }

                var newXY = this.getXY(el);

                // if retry is true, try one more time if we miss
                if (!noRetry && (newXY[0] != pos[0] || newXY[1] != pos[1]) ) {
                    this.setXY(el, pos, true);
                }

            };

            Y.Dom.batch(el, f, Y.Dom, true);
        },


        setX: function(el, x) {
            Y.Dom.setXY(el, [x, null]);
        },


        setY: function(el, y) {
            Y.Dom.setXY(el, [null, y]);
        },


        getRegion: function(el) {
            var f = function(el) {
                var region = new Y.Region.getRegion(el);
                return region;
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        getClientWidth: function() {
            return Y.Dom.getViewportWidth();
        },


        getClientHeight: function() {
            return Y.Dom.getViewportHeight();
        },


        getElementsByClassName: function(className, tag, root) {
            var method = function(el) { return Y.Dom.hasClass(el, className); };
            return Y.Dom.getElementsBy(method, tag, root);
        },


        hasClass: function(el, className) {
            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');

            var f = function(el) {
                return re.test(el['className']);
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        addClass: function(el, className) {
            var f = function(el) {
                if (this.hasClass(el, className)) { return; } // already present


                el['className'] = [el['className'], className].join(' ');
            };

            Y.Dom.batch(el, f, Y.Dom, true);
        },


        removeClass: function(el, className) {
            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');

            var f = function(el) {
                if (!this.hasClass(el, className)) { return; } // not present


                var c = el['className'];
                el['className'] = c.replace(re, ' ');
                if ( this.hasClass(el, className) ) { // in case of multiple adjacent
                    this.removeClass(el, className);
                }

            };

            Y.Dom.batch(el, f, Y.Dom, true);
        },


        replaceClass: function(el, oldClassName, newClassName) {
            if (oldClassName === newClassName) { // avoid infinite loop
                return false;
            }

            var re = new RegExp('(?:^|\\s+)' + oldClassName + '(?:\\s+|$)', 'g');

            var f = function(el) {

                if ( !this.hasClass(el, oldClassName) ) {
                    this.addClass(el, newClassName); // just add it if nothing to replace
                    return; // note return
                }

                el['className'] = el['className'].replace(re, ' ' + newClassName + ' ');

                if ( this.hasClass(el, oldClassName) ) { // in case of multiple adjacent
                    this.replaceClass(el, oldClassName, newClassName);
                }
            };

            Y.Dom.batch(el, f, Y.Dom, true);
        },


        generateId: function(el, prefix) {
            prefix = prefix || 'yui-gen';
            el = el || {};

            var f = function(el) {
                if (el) {
                    el = Y.Dom.get(el);
                } else {
                    el = {}; // just generating ID in this case
                }

                if (!el.id) {
                    el.id = prefix + id_counter++;
                } // dont override existing


                return el.id;
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },


        isAncestor: function(haystack, needle) {
            haystack = Y.Dom.get(haystack);
            if (!haystack || !needle) { return false; }

            var f = function(needle) {
                if (haystack.contains && !isSafari) { // safari "contains" is broken
                    return haystack.contains(needle);
                }
                else if ( haystack.compareDocumentPosition ) {
                    return !!(haystack.compareDocumentPosition(needle) & 16);
                }
                else { // loop up and test each parent
                    var parent = needle.parentNode;

                    while (parent) {
                        if (parent == haystack) {
                            return true;
                        }
                        else if (!parent.tagName || parent.tagName.toUpperCase() == 'HTML') {
                            return false;
                        }

                        parent = parent.parentNode;
                    }
                    return false;
                }
            };

            return Y.Dom.batch(needle, f, Y.Dom, true);
        },


        inDocument: function(el) {
            var f = function(el) {
                return this.isAncestor(document.documentElement, el);
            };

            return Y.Dom.batch(el, f, Y.Dom, true);
        },

        getElementsBy: function(method, tag, root) {
            tag = tag || '*';
            root = Y.Dom.get(root) || document;

            var nodes = [];
            var elements = root.getElementsByTagName(tag);

            if ( !elements.length && (tag == '*' && root.all) ) {
                elements = root.all; // IE < 6
            }

            for (var i = 0, len = elements.length; i < len; ++i) {
                if ( method(elements[i]) ) { nodes[nodes.length] = elements[i]; }
            }


            return nodes;
        },

        batch: function(el, method, o, override) {
            var id = el;
            el = Y.Dom.get(el);

            var scope = (override) ? o : window;

            if (!el || el.tagName || !el.length) { 
                if (!el) {
                    return false;
                }
                return method.call(scope, el, o);
            }

            var collection = [];

            for (var i = 0, len = el.length; i < len; ++i) {
                if (!el[i]) {
                    id = el[i];
                }
                collection[collection.length] = method.call(scope, el[i], o);
            }

            return collection;
        },


        getDocumentHeight: function() {
            var scrollHeight = (document.compatMode != 'CSS1Compat') ? document.body.scrollHeight : document.documentElement.scrollHeight;

            var h = Math.max(scrollHeight, Y.Dom.getViewportHeight());
            return h;
        },


        getDocumentWidth: function() {
            var scrollWidth = (document.compatMode != 'CSS1Compat') ? document.body.scrollWidth : document.documentElement.scrollWidth;
            var w = Math.max(scrollWidth, Y.Dom.getViewportWidth());
            return w;
        },


        getViewportHeight: function() {
            var height = self.innerHeight; // Safari, Opera
            var mode = document.compatMode;

            if ( (mode || isIE) && !isOpera ) { // IE, Gecko
                height = (mode == 'CSS1Compat') ?
                        document.documentElement.clientHeight : // Standards
                        document.body.clientHeight; // Quirks
            }

            return height;
        },


        getViewportWidth: function() {
            var width = self.innerWidth;  // Safari
            var mode = document.compatMode;

            if (mode || isIE) { // IE, Gecko, Opera
                width = (mode == 'CSS1Compat') ?
                        document.documentElement.clientWidth : // Standards
                        document.body.clientWidth; // Quirks
            }
            return width;
        }
    };
})();

YAHOO.util.Region = function(t, r, b, l) {


    this.top = t;


    this[1] = t;


    this.right = r;


    this.bottom = b;


    this.left = l;


    this[0] = l;
};


YAHOO.util.Region.prototype.contains = function(region) {
    return ( region.left   >= this.left   &&
             region.right  <= this.right  &&
             region.top    >= this.top    &&
             region.bottom <= this.bottom    );

};


YAHOO.util.Region.prototype.getArea = function() {
    return ( (this.bottom - this.top) * (this.right - this.left) );
};


YAHOO.util.Region.prototype.intersect = function(region) {
    var t = Math.max( this.top,    region.top    );
    var r = Math.min( this.right,  region.right  );
    var b = Math.min( this.bottom, region.bottom );
    var l = Math.max( this.left,   region.left   );

    if (b >= t && r >= l) {
        return new YAHOO.util.Region(t, r, b, l);
    } else {
        return null;
    }
};


YAHOO.util.Region.prototype.union = function(region) {
    var t = Math.min( this.top,    region.top    );
    var r = Math.max( this.right,  region.right  );
    var b = Math.max( this.bottom, region.bottom );
    var l = Math.min( this.left,   region.left   );

    return new YAHOO.util.Region(t, r, b, l);
};


YAHOO.util.Region.prototype.toString = function() {
    return ( "Region {"    +
             "top: "       + this.top    +
             ", right: "   + this.right  +
             ", bottom: "  + this.bottom +
             ", left: "    + this.left   +
             "}" );
};


YAHOO.util.Region.getRegion = function(el) {
    var p = YAHOO.util.Dom.getXY(el);

    var t = p[1];
    var r = p[0] + el.offsetWidth;
    var b = p[1] + el.offsetHeight;
    var l = p[0];

    return new YAHOO.util.Region(t, r, b, l);
};


YAHOO.util.Point = function(x, y) {
   if (x instanceof Array) { // accept output from Dom.getXY
      y = x[1];
      x = x[0];
   }



    this.x = this.right = this.left = this[0] = x;


    this.y = this.top = this.bottom = this[1] = y;
};

YAHOO.util.Point.prototype = new YAHOO.util.Region();



/************************************************************ calendar.js ****************************************************************/

YAHOO.util.Config = function(owner) {
	if (owner) {
		this.init(owner);
	}
};

YAHOO.util.Config.prototype = {


	owner : null,


	queueInProgress : false,



	checkBoolean: function(val) {
		if (typeof val == 'boolean') {
			return true;
		} else {
			return false;
		}
	},


	checkNumber: function(val) {
		if (isNaN(val)) {
			return false;
		} else {
			return true;
		}
	}
};



YAHOO.util.Config.prototype.init = function(owner) {

	this.owner = owner;


	this.configChangedEvent = new YAHOO.util.CustomEvent("configChanged");

	this.queueInProgress = false;


	var config = {};


	var initialConfig = {};


	var eventQueue = [];


	var fireEvent = function( key, value ) {
		key = key.toLowerCase();

		var property = config[key];

		if (typeof property != 'undefined' && property.event) {
			property.event.fire(value);
		}
	};

	this.addProperty = function( key, propertyObject ) {
		key = key.toLowerCase();

		config[key] = propertyObject;

		propertyObject.event = new YAHOO.util.CustomEvent(key);
		propertyObject.key = key;

		if (propertyObject.handler) {
			propertyObject.event.subscribe(propertyObject.handler, this.owner, true);
		}

		this.setProperty(key, propertyObject.value, true);

		if (! propertyObject.suppressEvent) {
			this.queueProperty(key, propertyObject.value);
		}
	};


	this.getConfig = function() {
		var cfg = {};

		for (var prop in config) {
			var property = config[prop];
			if (typeof property != 'undefined' && property.event) {
				cfg[prop] = property.value;
			}
		}

		return cfg;
	};


	this.getProperty = function(key) {
		key = key.toLowerCase();

		var property = config[key];
		if (typeof property != 'undefined' && property.event) {
			return property.value;
		} else {
			return undefined;
		}
	};


	this.resetProperty = function(key) {
		key = key.toLowerCase();

		var property = config[key];
		if (typeof property != 'undefined' && property.event) {
			if (initialConfig[key] && initialConfig[key] != 'undefined')	{
				this.setProperty(key, initialConfig[key]);
			}
			return true;
		} else {
			return false;
		}
	};


	this.setProperty = function(key, value, silent) {
		key = key.toLowerCase();

		if (this.queueInProgress && ! silent) {
			this.queueProperty(key,value); // Currently running through a queue...
			return true;
		} else {
			var property = config[key];
			if (typeof property != 'undefined' && property.event) {
				if (property.validator && ! property.validator(value)) { // validator
					return false;
				} else {
					property.value = value;
					if (! silent) {
						fireEvent(key, value);
						this.configChangedEvent.fire([key, value]);
					}
					return true;
				}
			} else {
				return false;
			}
		}
	};


	this.queueProperty = function(key, value) {
		key = key.toLowerCase();

		var property = config[key];

		if (typeof property != 'undefined' && property.event) {
			if (typeof value != 'undefined' && property.validator && ! property.validator(value)) { // validator
				return false;
			} else {

				if (typeof value != 'undefined') {
					property.value = value;
				} else {
					value = property.value;
				}

				var foundDuplicate = false;

				for (var i=0;i<eventQueue.length;i++) {
					var queueItem = eventQueue[i];

					if (queueItem) {
						var queueItemKey = queueItem[0];
						var queueItemValue = queueItem[1];

						if (queueItemKey.toLowerCase() == key) {
							// found a dupe... push to end of queue, null current item, and break
							eventQueue[i] = null;
							eventQueue.push([key, (typeof value != 'undefined' ? value : queueItemValue)]);
							foundDuplicate = true;
							break;
						}
					}
				}

				if (! foundDuplicate && typeof value != 'undefined') { // this is a refire, or a new property in the queue
					eventQueue.push([key, value]);
				}
			}

			if (property.supercedes) {
				for (var s=0;s<property.supercedes.length;s++) {
					var supercedesCheck = property.supercedes[s];

					for (var q=0;q<eventQueue.length;q++) {
						var queueItemCheck = eventQueue[q];

						if (queueItemCheck) {
							var queueItemCheckKey = queueItemCheck[0];
							var queueItemCheckValue = queueItemCheck[1];

							if ( queueItemCheckKey.toLowerCase() == supercedesCheck.toLowerCase() ) {
								eventQueue.push([queueItemCheckKey, queueItemCheckValue]);
								eventQueue[q] = null;
								break;
							}
						}
					}
				}
			}

			return true;
		} else {
			return false;
		}
	};


	this.refireEvent = function(key) {
		key = key.toLowerCase();

		var property = config[key];
		if (typeof property != 'undefined' && property.event && typeof property.value != 'undefined') {
			if (this.queueInProgress) {
				this.queueProperty(key);
			} else {
				fireEvent(key, property.value);
			}
		}
	};


	this.applyConfig = function(userConfig, init) {
		if (init) {
			initialConfig = userConfig;
		}
		for (var prop in userConfig) {
			this.queueProperty(prop, userConfig[prop]);
		}
	};


	this.refresh = function() {
		for (var prop in config) {
			this.refireEvent(prop);
		}
	};


	this.fireQueue = function() {
		this.queueInProgress = true;
		for (var i=0;i<eventQueue.length;i++) {
			var queueItem = eventQueue[i];
			if (queueItem) {
				var key = queueItem[0];
				var value = queueItem[1];

				var property = config[key];
				property.value = value;

				fireEvent(key,value);
			}
		}

		this.queueInProgress = false;
		eventQueue = [];
	};


	this.subscribeToConfigEvent = function(key, handler, obj, override) {
		key = key.toLowerCase();

		var property = config[key];
		if (typeof property != 'undefined' && property.event) {
			if (! YAHOO.util.Config.alreadySubscribed(property.event, handler, obj)) {
				property.event.subscribe(handler, obj, override);
			}
			return true;
		} else {
			return false;
		}
	};


	this.unsubscribeFromConfigEvent = function(key, handler, obj) {
		key = key.toLowerCase();

		var property = config[key];
		if (typeof property != 'undefined' && property.event) {
			return property.event.unsubscribe(handler, obj);
		} else {
			return false;
		}
	};


	this.toString = function() {
		var output = "Config";
		if (this.owner) {
			output += " [" + this.owner.toString() + "]";
		}
		return output;
	};


	this.outputEventQueue = function() {
		var output = "";
		for (var q=0;q<eventQueue.length;q++) {
			var queueItem = eventQueue[q];
			if (queueItem) {
				output += queueItem[0] + "=" + queueItem[1] + ", ";
			}
		}
		return output;
	};
};


YAHOO.util.Config.alreadySubscribed = function(evt, fn, obj) {
	for (var e=0;e<evt.subscribers.length;e++) {
		var subsc = evt.subscribers[e];
		if (subsc && subsc.obj == obj && subsc.fn == fn) {
			return true;
		}
	}
	return false;
};


YAHOO.widget.DateMath = {

	DAY : "D",


	WEEK : "W",


	YEAR : "Y",


	MONTH : "M",


	ONE_DAY_MS : 1000*60*60*24,

	add : function(date, field, amount) {
		var d = new Date(date.getTime());
		switch (field) {
			case this.MONTH:
				var newMonth = date.getMonth() + amount;
				var years = 0;


				if (newMonth < 0) {
					while (newMonth < 0) {
						newMonth += 12;
						years -= 1;
					}
				} else if (newMonth > 11) {
					while (newMonth > 11) {
						newMonth -= 12;
						years += 1;
					}
				}

				d.setMonth(newMonth);
				d.setFullYear(date.getFullYear() + years);
				break;
			case this.DAY:
				d.setDate(date.getDate() + amount);
				break;
			case this.YEAR:
				d.setFullYear(date.getFullYear() + amount);
				break;
			case this.WEEK:
				d.setDate(date.getDate() + (amount * 7));
				break;
		}
		return d;
	},


	subtract : function(date, field, amount) {
		return this.add(date, field, (amount*-1));
	},


	before : function(date, compareTo) {
		var ms = compareTo.getTime();
		if (date.getTime() < ms) {
			return true;
		} else {
			return false;
		}
	},


	after : function(date, compareTo) {
		var ms = compareTo.getTime();
		if (date.getTime() > ms) {
			return true;
		} else {
			return false;
		}
	},


	between : function(date, dateBegin, dateEnd) {
		if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
			return true;
		} else {
			return false;
		}
	},


	getJan1 : function(calendarYear) {
		return new Date(calendarYear,0,1);
	},


	getDayOffset : function(date, calendarYear) {
		var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.

		// Find the number of days the passed in date is away from the calendar year start
		var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
		return dayOffset;
	},


	getWeekNumber : function(date, calendarYear) {
		date = this.clearTime(date);
		var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));

		var jan1 = new Date(nearestThurs.getFullYear(),0,1);
		var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;

		var weekNum = Math.ceil((dayOfYear)/ 7);
		return weekNum;
	},


	isYearOverlapWeek : function(weekBeginDate) {
		var overlaps = false;
		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
		if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
			overlaps = true;
		}
		return overlaps;
	},


	isMonthOverlapWeek : function(weekBeginDate) {
		var overlaps = false;
		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
		if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
			overlaps = true;
		}
		return overlaps;
	},


	findMonthStart : function(date) {
		var start = new Date(date.getFullYear(), date.getMonth(), 1);
		return start;
	},


	findMonthEnd : function(date) {
		var start = this.findMonthStart(date);
		var nextMonth = this.add(start, this.MONTH, 1);
		var end = this.subtract(nextMonth, this.DAY, 1);
		return end;
	},


	clearTime : function(date) {
		date.setHours(12,0,0,0);
		return date;
	}
};


YAHOO.widget.Calendar = function(id, containerId, config) {
	this.init(id, containerId, config);
};


YAHOO.widget.Calendar.IMG_ROOT = (window.location.href.toLowerCase().indexOf("https") === 0 ? "https://a248.e.akamai.net/sec.yimg.com/i/" : "http://us.i1.yimg.com/us.yimg.com/i/");


YAHOO.widget.Calendar.DATE = "D";


YAHOO.widget.Calendar.MONTH_DAY = "MD";


YAHOO.widget.Calendar.WEEKDAY = "WD";


YAHOO.widget.Calendar.RANGE = "R";


YAHOO.widget.Calendar.MONTH = "M";


YAHOO.widget.Calendar.DISPLAY_DAYS = 42;


YAHOO.widget.Calendar.STOP_RENDER = "S";

YAHOO.widget.Calendar.prototype = {


	Config : null,


	parent : null,


	index : -1,


	cells : null,


	cellDates : null,


	id : null,


	oDomContainer : null,


	today : null,


	renderStack : null,


	_renderStack : null,


	_pageDate : null,


	_selectedDates : null,


	domEventMap : null
};




YAHOO.widget.Calendar.prototype.init = function(id, containerId, config) {
	this.initEvents();
	this.today = new Date();
	YAHOO.widget.DateMath.clearTime(this.today);

	this.id = id;
	this.oDomContainer = document.getElementById(containerId);


	this.cfg = new YAHOO.util.Config(this);


	this.Options = {};


	this.Locale = {};

	this.initStyles();

	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
	YAHOO.util.Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);

	this.cellDates = [];
	this.cells = [];
	this.renderStack = [];
	this._renderStack = [];

	this.setupConfig();

	if (config) {
		this.cfg.applyConfig(config, true);
	}

	this.cfg.fireQueue();
};


YAHOO.widget.Calendar.prototype.configIframe = function(type, args, obj) {
	var useIframe = args[0];

	if (YAHOO.util.Dom.inDocument(this.oDomContainer)) {
		if (useIframe) {
			var pos = YAHOO.util.Dom.getStyle(this.oDomContainer, "position");

			if (this.browser == "ie" && (pos == "absolute" || pos == "relative")) {
				if (! YAHOO.util.Dom.inDocument(this.iframe)) {
					this.iframe = document.createElement("iframe");
					this.iframe.src = "javascript:false;";
					YAHOO.util.Dom.setStyle(this.iframe, "opacity", "0");
					this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
				}
			}
		} else {
			if (this.iframe) {
				if (this.iframe.parentNode) {
					this.iframe.parentNode.removeChild(this.iframe);
				}
				this.iframe = null;
			}
		}
	}
};


YAHOO.widget.Calendar.prototype.configTitle = function(type, args, obj) {
	var title = args[0];
	var close = this.cfg.getProperty("close");

	var titleDiv;

	if (title && title !== "") {
		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
		titleDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
		titleDiv.innerHTML = title;
		this.oDomContainer.insertBefore(titleDiv, this.oDomContainer.firstChild);
		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
	} else {
		titleDiv = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;

		if (titleDiv) {
			YAHOO.util.Event.purgeElement(titleDiv);
			this.oDomContainer.removeChild(titleDiv);
		}
		if (! close) {
			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
		}
	}
};


YAHOO.widget.Calendar.prototype.configClose = function(type, args, obj) {
	var close = args[0];
	var title = this.cfg.getProperty("title");

	var linkClose;

	if (close === true) {
		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || document.createElement("a");
		linkClose.href = "javascript:void(null);";
		linkClose.className = "link-close";
		YAHOO.util.Event.addListener(linkClose, "click", this.hide, this, true);
		var imgClose = document.createElement("img");
		imgClose.src = YAHOO.widget.Calendar.IMG_ROOT + "us/my/bn/x_d.gif";
		imgClose.className = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE;
		linkClose.appendChild(imgClose);
		this.oDomContainer.appendChild(linkClose);
		YAHOO.util.Dom.addClass(this.oDomContainer, "withtitle");
	} else {
		linkClose = YAHOO.util.Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;

		if (linkClose) {
			YAHOO.util.Event.purgeElement(linkClose);
			this.oDomContainer.removeChild(linkClose);
		}
		if (! title || title === "") {
			YAHOO.util.Dom.removeClass(this.oDomContainer, "withtitle");
		}
	}
};


YAHOO.widget.Calendar.prototype.initEvents = function() {


	this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");


	this.selectEvent = new YAHOO.util.CustomEvent("select");


	this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");


	this.deselectEvent = new YAHOO.util.CustomEvent("deselect");


	this.changePageEvent = new YAHOO.util.CustomEvent("changePage");


	this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");


	this.renderEvent = new YAHOO.util.CustomEvent("render");


	this.resetEvent = new YAHOO.util.CustomEvent("reset");


	this.clearEvent = new YAHOO.util.CustomEvent("clear");

	this.beforeSelectEvent.subscribe(this.onBeforeSelect, this, true);
	this.selectEvent.subscribe(this.onSelect, this, true);
	this.beforeDeselectEvent.subscribe(this.onBeforeDeselect, this, true);
	this.deselectEvent.subscribe(this.onDeselect, this, true);
	this.changePageEvent.subscribe(this.onChangePage, this, true);
	this.renderEvent.subscribe(this.onRender, this, true);
	this.resetEvent.subscribe(this.onReset, this, true);
	this.clearEvent.subscribe(this.onClear, this, true);
};


YAHOO.widget.Calendar.prototype.doSelectCell = function(e, cal) {
	var target = YAHOO.util.Event.getTarget(e);

	var cell,index,d,date;

	while (target.tagName.toLowerCase() != "td" && ! YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
		target = target.parentNode;
		if (target.tagName.toLowerCase() == "html") {
			return;
		}
	}

	cell = target;

	if (YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
		index = cell.id.split("cell")[1];
		d = cal.cellDates[index];
		date = new Date(d[0],d[1]-1,d[2]);

		var link;

		if (cal.Options.MULTI_SELECT) {
			link = cell.getElementsByTagName("a")[0];
			if (link) {
				link.blur();
			}

			var cellDate = cal.cellDates[index];
			var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);

			if (cellDateIndex > -1) {
				cal.deselectCell(index);
			} else {
				cal.selectCell(index);
			}

		} else {
			link = cell.getElementsByTagName("a")[0];
			if (link) {
				link.blur();
			}
			cal.selectCell(index);
		}
	}
};


YAHOO.widget.Calendar.prototype.doCellMouseOver = function(e, cal) {
	var target;
	if (e) {
		target = YAHOO.util.Event.getTarget(e);
	} else {
		target = this;
	}

	while (target.tagName.toLowerCase() != "td") {
		target = target.parentNode;
		if (target.tagName.toLowerCase() == "html") {
			return;
		}
	}

	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
		YAHOO.util.Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
	}
};


YAHOO.widget.Calendar.prototype.doCellMouseOut = function(e, cal) {
	var target;
	if (e) {
		target = YAHOO.util.Event.getTarget(e);
	} else {
		target = this;
	}

	while (target.tagName.toLowerCase() != "td") {
		target = target.parentNode;
		if (target.tagName.toLowerCase() == "html") {
			return;
		}
	}

	if (YAHOO.util.Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
		YAHOO.util.Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
	}
};

YAHOO.widget.Calendar.prototype.setupConfig = function() {


	this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );


	this.cfg.addProperty("selected", { value:[], handler:this.configSelected } );


	this.cfg.addProperty("title", { value:"", handler:this.configTitle } );


	this.cfg.addProperty("close", { value:false, handler:this.configClose } );


	this.cfg.addProperty("iframe", { value:true, handler:this.configIframe, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("mindate", { value:null, handler:this.configMinDate } );


	this.cfg.addProperty("maxdate", { value:null, handler:this.configMaxDate } );



	this.cfg.addProperty("MULTI_SELECT",	{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("START_WEEKDAY",	{ value:0, handler:this.configOptions, validator:this.cfg.checkNumber  } );


	this.cfg.addProperty("SHOW_WEEKDAYS",	{ value:true, handler:this.configOptions, validator:this.cfg.checkBoolean  } );


	this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.configOptions, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("NAV_ARROW_LEFT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.configOptions } );


	this.cfg.addProperty("NAV_ARROW_RIGHT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.configOptions } );


	this.cfg.addProperty("MONTHS_SHORT",	{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.configLocale } );


	this.cfg.addProperty("MONTHS_LONG",		{ value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.configLocale } );


	this.cfg.addProperty("WEEKDAYS_1CHAR",	{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.configLocale } );


	this.cfg.addProperty("WEEKDAYS_SHORT",	{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.configLocale } );


	this.cfg.addProperty("WEEKDAYS_MEDIUM",	{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.configLocale } );


	this.cfg.addProperty("WEEKDAYS_LONG",	{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.configLocale } );


	var refreshLocale = function() {
		this.cfg.refireEvent("LOCALE_MONTHS");
		this.cfg.refireEvent("LOCALE_WEEKDAYS");
	};

	this.cfg.subscribeToConfigEvent("START_WEEKDAY", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("MONTHS_SHORT", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("MONTHS_LONG", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("WEEKDAYS_1CHAR", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("WEEKDAYS_SHORT", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("WEEKDAYS_MEDIUM", refreshLocale, this, true);
	this.cfg.subscribeToConfigEvent("WEEKDAYS_LONG", refreshLocale, this, true);


	this.cfg.addProperty("LOCALE_MONTHS",	{ value:"long", handler:this.configLocaleValues } );


	this.cfg.addProperty("LOCALE_WEEKDAYS",	{ value:"short", handler:this.configLocaleValues } );


	this.cfg.addProperty("DATE_DELIMITER",		{ value:",", handler:this.configLocale } );


	this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.configLocale } );


	this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.configLocale } );


	this.cfg.addProperty("MY_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MY_YEAR_POSITION",	{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MD_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MD_DAY_POSITION",		{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_MONTH_POSITION",	{ value:1, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_DAY_POSITION",	{ value:2, handler:this.configLocale, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_YEAR_POSITION",	{ value:3, handler:this.configLocale, validator:this.cfg.checkNumber } );
};


YAHOO.widget.Calendar.prototype.configPageDate = function(type, args, obj) {
	var val = args[0];
	var month, year, aMonthYear;

	if (val) {
		if (val instanceof Date) {
			val = YAHOO.widget.DateMath.findMonthStart(val);
			this.cfg.setProperty("pagedate", val, true);
			if (! this._pageDate) {
				this._pageDate = this.cfg.getProperty("pagedate");
			}
			return;
		} else {
			aMonthYear = val.split(this.cfg.getProperty("DATE_FIELD_DELIMITER"));
			month = parseInt(aMonthYear[this.cfg.getProperty("MY_MONTH_POSITION")-1], 10)-1;
			year = parseInt(aMonthYear[this.cfg.getProperty("MY_YEAR_POSITION")-1], 10);
		}
	} else {
		month = this.today.getMonth();
		year = this.today.getFullYear();
	}

	this.cfg.setProperty("pagedate", new Date(year, month, 1), true);
	if (! this._pageDate) {
		this._pageDate = this.cfg.getProperty("pagedate");
	}
};


YAHOO.widget.Calendar.prototype.configMinDate = function(type, args, obj) {
	var val = args[0];
	if (typeof val == 'string') {
		val = this._parseDate(val);
		this.cfg.setProperty("mindate", new Date(val[0],(val[1]-1),val[2]));
	}
};


YAHOO.widget.Calendar.prototype.configMaxDate = function(type, args, obj) {
	var val = args[0];
	if (typeof val == 'string') {
		val = this._parseDate(val);
		this.cfg.setProperty("maxdate", new Date(val[0],(val[1]-1),val[2]));
	}
};


YAHOO.widget.Calendar.prototype.configSelected = function(type, args, obj) {
	var selected = args[0];

	if (selected) {
		if (typeof selected == 'string') {
			this.cfg.setProperty("selected", this._parseDates(selected), true);
		}
	}
	if (! this._selectedDates) {
		this._selectedDates = this.cfg.getProperty("selected");
	}
};


YAHOO.widget.Calendar.prototype.configOptions = function(type, args, obj) {
	type = type.toUpperCase();
	var val = args[0];
	this.Options[type] = val;
};


YAHOO.widget.Calendar.prototype.configLocale = function(type, args, obj) {
	type = type.toUpperCase();
	var val = args[0];
	this.Locale[type] = val;

	this.cfg.refireEvent("LOCALE_MONTHS");
	this.cfg.refireEvent("LOCALE_WEEKDAYS");

};


YAHOO.widget.Calendar.prototype.configLocaleValues = function(type, args, obj) {
	type = type.toUpperCase();
	var val = args[0];

	switch (type) {
		case "LOCALE_MONTHS":
			switch (val) {
				case "short":
					this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_SHORT").concat();
					break;
				case "long":
					this.Locale.LOCALE_MONTHS = this.cfg.getProperty("MONTHS_LONG").concat();
					break;
			}
			break;
		case "LOCALE_WEEKDAYS":
			switch (val) {
				case "1char":
					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_1CHAR").concat();
					break;
				case "short":
					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_SHORT").concat();
					break;
				case "medium":
					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_MEDIUM").concat();
					break;
				case "long":
					this.Locale.LOCALE_WEEKDAYS = this.cfg.getProperty("WEEKDAYS_LONG").concat();
					break;
			}

			var START_WEEKDAY = this.cfg.getProperty("START_WEEKDAY");

			if (START_WEEKDAY > 0) {
				for (var w=0;w<START_WEEKDAY;++w) {
					this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());
				}
			}
			break;
	}
};


YAHOO.widget.Calendar.prototype.initStyles = function() {


	this.Style = {

		CSS_ROW_HEADER: "calrowhead",

		CSS_ROW_FOOTER: "calrowfoot",

		CSS_CELL : "calcell",

		CSS_CELL_SELECTED : "selected",

		CSS_CELL_SELECTABLE : "selectable",

		CSS_CELL_RESTRICTED : "restricted",

		CSS_CELL_TODAY : "today",

		CSS_CELL_OOM : "oom",

		CSS_CELL_OOB : "previous",

		CSS_HEADER : "calheader",

		CSS_HEADER_TEXT : "calhead",

		CSS_WEEKDAY_CELL : "calweekdaycell",

		CSS_WEEKDAY_ROW : "calweekdayrow",

		CSS_FOOTER : "calfoot",

		CSS_CALENDAR : "yui-calendar",

		CSS_SINGLE : "single",

		CSS_CONTAINER : "yui-calcontainer",

		CSS_NAV_LEFT : "calnavleft",

		CSS_NAV_RIGHT : "calnavright",

		CSS_CELL_TOP : "calcelltop",

		CSS_CELL_LEFT : "calcellleft",

		CSS_CELL_RIGHT : "calcellright",

		CSS_CELL_BOTTOM : "calcellbottom",

		CSS_CELL_HOVER : "calcellhover",

		CSS_CELL_HIGHLIGHT1 : "highlight1",

		CSS_CELL_HIGHLIGHT2 : "highlight2",

		CSS_CELL_HIGHLIGHT3 : "highlight3",

		CSS_CELL_HIGHLIGHT4 : "highlight4"
	};
};


YAHOO.widget.Calendar.prototype.buildMonthLabel = function() {
	var text = this.Locale.LOCALE_MONTHS[this.cfg.getProperty("pagedate").getMonth()] + " " + this.cfg.getProperty("pagedate").getFullYear();
	return text;
};


YAHOO.widget.Calendar.prototype.buildDayLabel = function(workingDate) {
	var day = workingDate.getDate();
	return day;
};


YAHOO.widget.Calendar.prototype.renderHeader = function(html) {
	var colSpan = 7;

	if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
		colSpan += 1;
	}

	if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
		colSpan += 1;
	}

	html[html.length] = "<thead>";
	html[html.length] =		"<tr>";
	html[html.length] =			'<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
	html[html.length] =				'<div class="' + this.Style.CSS_HEADER + '">';

		var renderLeft, renderRight = false;

		if (this.parent) {
			if (this.index === 0) {
				renderLeft = true;
			}
			if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
				renderRight = true;
			}
		} else {
			renderLeft = true;
			renderRight = true;
		}

		var cal = this.parent || this;

		if (renderLeft) {
			html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_LEFT") + ')">&#160;</a>';
		}

		html[html.length] = this.buildMonthLabel();

		if (renderRight) {
			html[html.length] = '<a class="' + this.Style.CSS_NAV_RIGHT + '" style="background-image:url(' + this.cfg.getProperty("NAV_ARROW_RIGHT") + ')">&#160;</a>';
		}


	html[html.length] =				'</div>';
	html[html.length] =			'</th>';
	html[html.length] =		'</tr>';

	if (this.cfg.getProperty("SHOW_WEEKDAYS")) {
		html = this.buildWeekdays(html);
	}

	html[html.length] = '</thead>';

	return html;
};


YAHOO.widget.Calendar.prototype.buildWeekdays = function(html) {

	html[html.length] = '<tr class="' + this.Style.CSS_WEEKDAY_ROW + '">';

	if (this.cfg.getProperty("SHOW_WEEK_HEADER")) {
		html[html.length] = '<th>&#160;</th>';
	}

	for(var i=0;i<this.Locale.LOCALE_WEEKDAYS.length;++i) {
		html[html.length] = '<th class="calweekdaycell">' + this.Locale.LOCALE_WEEKDAYS[i] + '</th>';
	}

	if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) {
		html[html.length] = '<th>&#160;</th>';
	}

	html[html.length] = '</tr>';

	return html;
};


YAHOO.widget.Calendar.prototype.renderBody = function(workingDate, html) {

	var startDay = this.cfg.getProperty("START_WEEKDAY");

	this.preMonthDays = workingDate.getDay();
	if (startDay > 0) {
		this.preMonthDays -= startDay;
	}
	if (this.preMonthDays < 0) {
		this.preMonthDays += 7;
	}

	this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
	this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;

	workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);

	var useDate,weekNum,weekClass;
	useDate = this.cfg.getProperty("pagedate");

	html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + '">';

	var i = 0;

	var tempDiv = document.createElement("div");
	var cell = document.createElement("td");
	tempDiv.appendChild(cell);

	var jan1 = new Date(useDate.getFullYear(),0,1);

	var cal = this.parent || this;

	for (var r=0;r<6;r++) {

		weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);

		weekClass = "w" + weekNum;

		if (r !== 0 && this.isDateOOM(workingDate) && this.cfg.getProperty("HIDE_BLANK_WEEKS") === true) {
			break;
		} else {

			html[html.length] = '<tr class="' + weekClass + '">';

			if (this.cfg.getProperty("SHOW_WEEK_HEADER")) { html = this.renderRowHeader(weekNum, html); }

			for (var d=0;d<7;d++){ // Render actual days

				var cellRenderers = [];

				this.clearElement(cell);

				YAHOO.util.Dom.addClass(cell, "calcell");

				cell.id = this.id + "_cell" + i;

				cell.innerHTML = i;

				var renderer = null;

				if (workingDate.getFullYear()	== this.today.getFullYear() &&
					workingDate.getMonth()		== this.today.getMonth() &&
					workingDate.getDate()		== this.today.getDate()) {
					cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
				}

				this.cellDates[this.cellDates.length]=[workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]; // Add this date to cellDates

				if (this.isDateOOM(workingDate)) {
					cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
				} else {

					YAHOO.util.Dom.addClass(cell, "wd" + workingDate.getDay());
					YAHOO.util.Dom.addClass(cell, "d" + workingDate.getDate());

					for (var s=0;s<this.renderStack.length;++s) {

						var rArray = this.renderStack[s];
						var type = rArray[0];

						var month;
						var day;
						var year;

						switch (type) {
							case YAHOO.widget.Calendar.DATE:
								month = rArray[1][1];
								day = rArray[1][2];
								year = rArray[1][0];

								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
									renderer = rArray[2];
									this.renderStack.splice(s,1);
								}
								break;
							case YAHOO.widget.Calendar.MONTH_DAY:
								month = rArray[1][0];
								day = rArray[1][1];

								if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
									renderer = rArray[2];
									this.renderStack.splice(s,1);
								}
								break;
							case YAHOO.widget.Calendar.RANGE:
								var date1 = rArray[1][0];
								var date2 = rArray[1][1];

								var d1month = date1[1];
								var d1day = date1[2];
								var d1year = date1[0];

								var d1 = new Date(d1year, d1month-1, d1day);

								var d2month = date2[1];
								var d2day = date2[2];
								var d2year = date2[0];

								var d2 = new Date(d2year, d2month-1, d2day);

								if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
									renderer = rArray[2];

									if (workingDate.getTime()==d2.getTime()) {
										this.renderStack.splice(s,1);
									}
								}
								break;
							case YAHOO.widget.Calendar.WEEKDAY:

								var weekday = rArray[1][0];
								if (workingDate.getDay()+1 == weekday) {
									renderer = rArray[2];
								}
								break;
							case YAHOO.widget.Calendar.MONTH:

								month = rArray[1][0];
								if (workingDate.getMonth()+1 == month) {
									renderer = rArray[2];
								}
								break;
						}

						if (renderer) {
							cellRenderers[cellRenderers.length]=renderer;
						}
					}

				}

				if (this._indexOfSelectedFieldArray([workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()]) > -1) {
					cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected;
				}

				var mindate = this.cfg.getProperty("mindate");
				var maxdate = this.cfg.getProperty("maxdate");

				if (mindate) {
					mindate = YAHOO.widget.DateMath.clearTime(mindate);
				}
				if (maxdate) {
					maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
				}

				if (
					(mindate && (workingDate.getTime() < mindate.getTime())) ||
					(maxdate && (workingDate.getTime() > maxdate.getTime()))
				) {
					cellRenderers[cellRenderers.length]=cal.renderOutOfBoundsDate;
				} else {
					cellRenderers[cellRenderers.length]=cal.styleCellDefault;
					cellRenderers[cellRenderers.length]=cal.renderCellDefault;
				}



				for (var x=0;x<cellRenderers.length;++x) {
					var ren = cellRenderers[x];
					if (ren.call((this.parent || this),workingDate,cell) == YAHOO.widget.Calendar.STOP_RENDER) {
						break;
					}
				}

				workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);

				if (i >= 0 && i <= 6) {
					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
				}
				if ((i % 7) === 0) {
					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
				}
				if (((i+1) % 7) === 0) {
					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
				}

				var postDays = this.postMonthDays;
				if (postDays >= 7 && this.cfg.getProperty("HIDE_BLANK_WEEKS")) {
					var blankWeeks = Math.floor(postDays/7);
					for (var p=0;p<blankWeeks;++p) {
						postDays -= 7;
					}
				}

				if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
					YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
				}

				html[html.length] = tempDiv.innerHTML;

				i++;
			}

			if (this.cfg.getProperty("SHOW_WEEK_FOOTER")) { html = this.renderRowFooter(weekNum, html); }

			html[html.length] = '</tr>';
		}
	}

	html[html.length] = '</tbody>';

	return html;
};


YAHOO.widget.Calendar.prototype.renderFooter = function(html) { return html; };


YAHOO.widget.Calendar.prototype.render = function() {
	this.beforeRenderEvent.fire();

	// Find starting day of the current month
	var workingDate = YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty("pagedate"));

	this.resetRenderers();
	this.cellDates.length = 0;

	YAHOO.util.Event.purgeElement(this.oDomContainer, true);

	var html = [];

	html[html.length] = '<table cellSpacing="0" class="' + this.Style.CSS_CALENDAR + ' y' + workingDate.getFullYear() + '" id="' + this.id + '">';
	html = this.renderHeader(html);
	html = this.renderBody(workingDate, html);
	html = this.renderFooter(html);
	html[html.length] = '</table>';

	this.oDomContainer.innerHTML = html.join("\n");

	this.applyListeners();
	this.cells = this.oDomContainer.getElementsByTagName("td");

	this.cfg.refireEvent("title");
	this.cfg.refireEvent("close");
	this.cfg.refireEvent("iframe");

	this.renderEvent.fire();
};


YAHOO.widget.Calendar.prototype.applyListeners = function() {

	var root = this.oDomContainer;
	var cal = this.parent || this;

	var linkLeft, linkRight;

	linkLeft = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT, "a", root);
	linkRight = YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT, "a", root);

	if (linkLeft) {
		this.linkLeft = linkLeft[0];
		YAHOO.util.Event.addListener(this.linkLeft, "mousedown", cal.previousMonth, cal, true);
	}

	if (linkRight) {
		this.linkRight = linkRight[0];
		YAHOO.util.Event.addListener(this.linkRight, "mousedown", cal.nextMonth, cal, true);
	}

	if (this.domEventMap) {
		var el,elements;
		for (var cls in this.domEventMap) {
			if (this.domEventMap.hasOwnProperty(cls)) {
				var items = this.domEventMap[cls];

				if (! (items instanceof Array)) {
					items = [items];
				}

				for (var i=0;i<items.length;i++)	{
					var item = items[i];
					elements = YAHOO.util.Dom.getElementsByClassName(cls, item.tag, this.oDomContainer);

					for (var c=0;c<elements.length;c++) {
						el = elements[c];
						 YAHOO.util.Event.addListener(el, item.event, item.handler, item.scope, item.correct );
					}
				}
			}
		}
	}

	YAHOO.util.Event.addListener(this.oDomContainer, "click", this.doSelectCell, this);
	YAHOO.util.Event.addListener(this.oDomContainer, "mouseover", this.doCellMouseOver, this);
	YAHOO.util.Event.addListener(this.oDomContainer, "mouseout", this.doCellMouseOut, this);
};


YAHOO.widget.Calendar.prototype.getDateByCellId = function(id) {
	var date = this.getDateFieldsByCellId(id);
	return new Date(date[0],date[1]-1,date[2]);
};


YAHOO.widget.Calendar.prototype.getDateFieldsByCellId = function(id) {
	id = id.toLowerCase().split("_cell")[1];
	id = parseInt(id, 10);
	return this.cellDates[id];
};


YAHOO.widget.Calendar.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
	cell.innerHTML = workingDate.getDate();
	return YAHOO.widget.Calendar.STOP_RENDER;
};


YAHOO.widget.Calendar.prototype.renderRowHeader = function(weekNum, html) {
	html[html.length] = '<th class="calrowhead">' + weekNum + '</th>';
	return html;
};


YAHOO.widget.Calendar.prototype.renderRowFooter = function(weekNum, html) {
	html[html.length] = '<th class="calrowfoot">' + weekNum + '</th>';
	return html;
};


YAHOO.widget.Calendar.prototype.renderCellDefault = function(workingDate, cell) {
	cell.innerHTML = '<a href="javascript:void(null);" >' + this.buildDayLabel(workingDate) + "</a>";
};


YAHOO.widget.Calendar.prototype.styleCellDefault = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTABLE);
};



YAHOO.widget.Calendar.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
};


YAHOO.widget.Calendar.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
};


YAHOO.widget.Calendar.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
};


YAHOO.widget.Calendar.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
};


YAHOO.widget.Calendar.prototype.renderCellStyleToday = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
};


YAHOO.widget.Calendar.prototype.renderCellStyleSelected = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
};


YAHOO.widget.Calendar.prototype.renderCellNotThisMonth = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
	cell.innerHTML=workingDate.getDate();
	return YAHOO.widget.Calendar.STOP_RENDER;
};


YAHOO.widget.Calendar.prototype.renderBodyCellRestricted = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RESTRICTED);
	cell.innerHTML=workingDate.getDate();
	return YAHOO.widget.Calendar.STOP_RENDER;
};


YAHOO.widget.Calendar.prototype.addMonths = function(count) {
	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
	this.resetRenderers();
	this.changePageEvent.fire();
};


YAHOO.widget.Calendar.prototype.subtractMonths = function(count) {
	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.MONTH, count));
	this.resetRenderers();
	this.changePageEvent.fire();
};


YAHOO.widget.Calendar.prototype.addYears = function(count) {
	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.add(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
	this.resetRenderers();
	this.changePageEvent.fire();
};


YAHOO.widget.Calendar.prototype.subtractYears = function(count) {
	this.cfg.setProperty("pagedate", YAHOO.widget.DateMath.subtract(this.cfg.getProperty("pagedate"), YAHOO.widget.DateMath.YEAR, count));
	this.resetRenderers();
	this.changePageEvent.fire();
};


YAHOO.widget.Calendar.prototype.nextMonth = function() {
	this.addMonths(1);
};


YAHOO.widget.Calendar.prototype.previousMonth = function() {
	this.subtractMonths(1);
};


YAHOO.widget.Calendar.prototype.nextYear = function() {
	this.addYears(1);
};


YAHOO.widget.Calendar.prototype.previousYear = function() {
	this.subtractYears(1);
};


YAHOO.widget.Calendar.prototype.reset = function() {
	this.cfg.resetProperty("selected");
	this.cfg.resetProperty("pagedate");
	this.resetEvent.fire();
};


YAHOO.widget.Calendar.prototype.clear = function() {
	this.cfg.setProperty("selected", []);
	this.cfg.setProperty("pagedate", new Date(this.today.getTime()));
	this.clearEvent.fire();
};


YAHOO.widget.Calendar.prototype.select = function(date) {
	this.beforeSelectEvent.fire();

	var selected = this.cfg.getProperty("selected");
	var aToBeSelected = this._toFieldArray(date);

	for (var a=0;a<aToBeSelected.length;++a) {
		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
		if (this._indexOfSelectedFieldArray(toSelect) == -1) { // not already selected?
			selected[selected.length]=toSelect;
		}
	}

	if (this.parent) {
		this.parent.cfg.setProperty("selected", selected);
	} else {
		this.cfg.setProperty("selected", selected);
	}

	this.selectEvent.fire(aToBeSelected);

	return this.getSelectedDates();
};


YAHOO.widget.Calendar.prototype.selectCell = function(cellIndex) {
	this.beforeSelectEvent.fire();

	var selected = this.cfg.getProperty("selected");

	var cell = this.cells[cellIndex];
	var cellDate = this.cellDates[cellIndex];

	var dCellDate = this._toDate(cellDate);

	var selectDate = cellDate.concat();

	selected[selected.length] = selectDate;

	if (this.parent) {
		this.parent.cfg.setProperty("selected", selected);
	} else {
		this.cfg.setProperty("selected", selected);
	}

	this.renderCellStyleSelected(dCellDate,cell);

	this.selectEvent.fire([selectDate]);

	this.doCellMouseOut.call(cell, null, this);

	return this.getSelectedDates();
};


YAHOO.widget.Calendar.prototype.deselect = function(date) {
	this.beforeDeselectEvent.fire();

	var selected = this.cfg.getProperty("selected");

	var aToBeSelected = this._toFieldArray(date);

	for (var a=0;a<aToBeSelected.length;++a) {
		var toSelect = aToBeSelected[a]; // For each date item in the list of dates we're trying to select
		var index = this._indexOfSelectedFieldArray(toSelect);

		if (index != -1) {
			selected.splice(index,1);
		}
	}

	if (this.parent) {
		this.parent.cfg.setProperty("selected", selected);
	} else {
		this.cfg.setProperty("selected", selected);
	}

	this.deselectEvent.fire(aToBeSelected);

	return this.getSelectedDates();
};


YAHOO.widget.Calendar.prototype.deselectCell = function(i) {
	this.beforeDeselectEvent.fire();

	var selected = this.cfg.getProperty("selected");

	var cell = this.cells[i];
	var cellDate = this.cellDates[i];
	var cellDateIndex = this._indexOfSelectedFieldArray(cellDate);

	var dCellDate = this._toDate(cellDate);

	var selectDate = cellDate.concat();

	if (cellDateIndex > -1) {
		if (this.cfg.getProperty("pagedate").getMonth() == dCellDate.getMonth() &&
			this.cfg.getProperty("pagedate").getFullYear() == dCellDate.getFullYear()) {
			YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
		}

		selected.splice(cellDateIndex, 1);
	}


	if (this.parent) {
		this.parent.cfg.setProperty("selected", selected);
	} else {
		this.cfg.setProperty("selected", selected);
	}

	this.deselectEvent.fire(selectDate);
	return this.getSelectedDates();
};


YAHOO.widget.Calendar.prototype.deselectAll = function() {
	this.beforeDeselectEvent.fire();

	var selected = this.cfg.getProperty("selected");
	var count = selected.length;
	var sel = selected.concat();

	if (this.parent) {
		this.parent.cfg.setProperty("selected", []);
	} else {
		this.cfg.setProperty("selected", []);
	}

	if (count > 0) {
		this.deselectEvent.fire(sel);
	}

	return this.getSelectedDates();
};


YAHOO.widget.Calendar.prototype._toFieldArray = function(date) {
	var returnDate = [];

	if (date instanceof Date) {
		returnDate = [[date.getFullYear(), date.getMonth()+1, date.getDate()]];
	} else if (typeof date == 'string') {
		returnDate = this._parseDates(date);
	} else if (date instanceof Array) {
		for (var i=0;i<date.length;++i) {
			var d = date[i];
			returnDate[returnDate.length] = [d.getFullYear(),d.getMonth()+1,d.getDate()];
		}
	}

	return returnDate;
};


YAHOO.widget.Calendar.prototype._toDate = function(dateFieldArray) {
	if (dateFieldArray instanceof Date) {
		return dateFieldArray;
	} else {
		return new Date(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]);
	}
};


YAHOO.widget.Calendar.prototype._fieldArraysAreEqual = function(array1, array2) {
	var match = false;

	if (array1[0]==array2[0]&&array1[1]==array2[1]&&array1[2]==array2[2]) {
		match=true;
	}

	return match;
};


YAHOO.widget.Calendar.prototype._indexOfSelectedFieldArray = function(find) {
	var selected = -1;
	var seldates = this.cfg.getProperty("selected");

	for (var s=0;s<seldates.length;++s) {
		var sArray = seldates[s];
		if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
			selected = s;
			break;
		}
	}

	return selected;
};


YAHOO.widget.Calendar.prototype.isDateOOM = function(date) {
	var isOOM = false;
	if (date.getMonth() != this.cfg.getProperty("pagedate").getMonth()) {
		isOOM = true;
	}
	return isOOM;
};


YAHOO.widget.Calendar.prototype.onBeforeSelect = function() {
	if (this.cfg.getProperty("MULTI_SELECT") === false) {
		if (this.parent) {
			this.parent.callChildFunction("clearAllBodyCellStyles", this.Style.CSS_CELL_SELECTED);
			this.parent.deselectAll();
		} else {
			this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
			this.deselectAll();
		}
	}
};


YAHOO.widget.Calendar.prototype.onSelect = function(selected) { };


YAHOO.widget.Calendar.prototype.onBeforeDeselect = function() { };


YAHOO.widget.Calendar.prototype.onDeselect = function(deselected) { };


YAHOO.widget.Calendar.prototype.onChangePage = function() {
	this.render();
};


YAHOO.widget.Calendar.prototype.onRender = function() { };


YAHOO.widget.Calendar.prototype.onReset = function() { this.render(); };


YAHOO.widget.Calendar.prototype.onClear = function() { this.render(); };


YAHOO.widget.Calendar.prototype.validate = function() { return true; };


YAHOO.widget.Calendar.prototype._parseDate = function(sDate) {
	var aDate = sDate.split(this.Locale.DATE_FIELD_DELIMITER);
	var rArray;

	if (aDate.length == 2) {
		rArray = [aDate[this.Locale.MD_MONTH_POSITION-1],aDate[this.Locale.MD_DAY_POSITION-1]];
		rArray.type = YAHOO.widget.Calendar.MONTH_DAY;
	} else {
		rArray = [aDate[this.Locale.MDY_YEAR_POSITION-1],aDate[this.Locale.MDY_MONTH_POSITION-1],aDate[this.Locale.MDY_DAY_POSITION-1]];
		rArray.type = YAHOO.widget.Calendar.DATE;
	}

	for (var i=0;i<rArray.length;i++) {
		rArray[i] = parseInt(rArray[i], 10);
	}

	return rArray;
};


YAHOO.widget.Calendar.prototype._parseDates = function(sDates) {
	var aReturn = [];

	var aDates = sDates.split(this.Locale.DATE_DELIMITER);

	for (var d=0;d<aDates.length;++d) {
		var sDate = aDates[d];

		if (sDate.indexOf(this.Locale.DATE_RANGE_DELIMITER) != -1) {
			// This is a range
			var aRange = sDate.split(this.Locale.DATE_RANGE_DELIMITER);

			var dateStart = this._parseDate(aRange[0]);
			var dateEnd = this._parseDate(aRange[1]);

			var fullRange = this._parseRange(dateStart, dateEnd);
			aReturn = aReturn.concat(fullRange);
		} else {
			// This is not a range
			var aDate = this._parseDate(sDate);
			aReturn.push(aDate);
		}
	}
	return aReturn;
};


YAHOO.widget.Calendar.prototype._parseRange = function(startDate, endDate) {
	var dStart   = new Date(startDate[0],startDate[1]-1,startDate[2]);
	var dCurrent = YAHOO.widget.DateMath.add(new Date(startDate[0],startDate[1]-1,startDate[2]),YAHOO.widget.DateMath.DAY,1);
	var dEnd     = new Date(endDate[0],  endDate[1]-1,  endDate[2]);

	var results = [];
	results.push(startDate);
	while (dCurrent.getTime() <= dEnd.getTime()) {
		results.push([dCurrent.getFullYear(),dCurrent.getMonth()+1,dCurrent.getDate()]);
		dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
	}
	return results;
};


YAHOO.widget.Calendar.prototype.resetRenderers = function() {
	this.renderStack = this._renderStack.concat();
};


YAHOO.widget.Calendar.prototype.clearElement = function(cell) {
	cell.innerHTML = "&#160;";
	cell.className="";
};


YAHOO.widget.Calendar.prototype.addRenderer = function(sDates, fnRender) {
	var aDates = this._parseDates(sDates);
	for (var i=0;i<aDates.length;++i) {
		var aDate = aDates[i];

		if (aDate.length == 2) { // this is either a range or a month/day combo
			if (aDate[0] instanceof Array) { // this is a range
				this._addRenderer(YAHOO.widget.Calendar.RANGE,aDate,fnRender);
			} else { // this is a month/day combo
				this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,aDate,fnRender);
			}
		} else if (aDate.length == 3) {
			this._addRenderer(YAHOO.widget.Calendar.DATE,aDate,fnRender);
		}
	}
};


YAHOO.widget.Calendar.prototype._addRenderer = function(type, aDates, fnRender) {
	var add = [type,aDates,fnRender];
	this.renderStack.unshift(add);
	this._renderStack = this.renderStack.concat();
};


YAHOO.widget.Calendar.prototype.addMonthRenderer = function(month, fnRender) {
	this._addRenderer(YAHOO.widget.Calendar.MONTH,[month],fnRender);
};


YAHOO.widget.Calendar.prototype.addWeekdayRenderer = function(weekday, fnRender) {
	this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
};


YAHOO.widget.Calendar.prototype.clearAllBodyCellStyles = function(style) {
	for (var c=0;c<this.cells.length;++c) {
		YAHOO.util.Dom.removeClass(this.cells[c],style);
	}
};


YAHOO.widget.Calendar.prototype.setMonth = function(month) {
	var current = this.cfg.getProperty("pagedate");
	current.setMonth(month);
	this.cfg.setProperty("pagedate", current);
};


YAHOO.widget.Calendar.prototype.setYear = function(year) {
	var current = this.cfg.getProperty("pagedate");
	current.setFullYear(year);
	this.cfg.setProperty("pagedate", current);
};


YAHOO.widget.Calendar.prototype.getSelectedDates = function() {
	var returnDates = [];
	var selected = this.cfg.getProperty("selected");

	for (var d=0;d<selected.length;++d) {
		var dateArray = selected[d];

		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
		returnDates.push(date);
	}

	returnDates.sort( function(a,b) { return a-b; } );
	return returnDates;
};


YAHOO.widget.Calendar.prototype.hide = function() {
	this.oDomContainer.style.display = "none";
};


YAHOO.widget.Calendar.prototype.show = function() {
	this.oDomContainer.style.display = "block";
};


YAHOO.widget.Calendar.prototype.browser = function() {
			var ua = navigator.userAgent.toLowerCase();
				  if (ua.indexOf('opera')!=-1) { // Opera (check first in case of spoof)
					 return 'opera';
				  } else if (ua.indexOf('msie 7')!=-1) { // IE7
					 return 'ie7';
				  } else if (ua.indexOf('msie') !=-1) { // IE
					 return 'ie';
				  } else if (ua.indexOf('safari')!=-1) { // Safari (check before Gecko because it includes "like Gecko")
					 return 'safari';
				  } else if (ua.indexOf('gecko') != -1) { // Gecko
					 return 'gecko';
				  } else {
					 return false;
				  }
			}();

YAHOO.widget.Calendar.prototype.toString = function() {
	return "Calendar " + this.id;
};


YAHOO.widget.Calendar_Core = YAHOO.widget.Calendar;

YAHOO.widget.Cal_Core = YAHOO.widget.Calendar;


YAHOO.widget.CalendarGroup = function(id, containerId, config) {
	if (arguments.length > 0) {
		this.init(id, containerId, config);
	}
};


YAHOO.widget.CalendarGroup.prototype.init = function(id, containerId, config) {
	this.initEvents();
	this.initStyles();


	this.pages = [];


	this.id = id;


	this.containerId = containerId;


	this.oDomContainer = document.getElementById(containerId);

	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_CONTAINER);
	YAHOO.util.Dom.addClass(this.oDomContainer, YAHOO.widget.CalendarGroup.CSS_MULTI_UP);


	this.cfg = new YAHOO.util.Config(this);


	this.Options = {};


	this.Locale = {};

	this.setupConfig();

	if (config) {
		this.cfg.applyConfig(config, true);
	}

	this.cfg.fireQueue();

	// OPERA HACK FOR MISWRAPPED FLOATS
	if (this.browser == "opera"){
		var fixWidth = function() {
			var startW = this.oDomContainer.offsetWidth;
			var w = 0;
			for (var p=0;p<this.pages.length;++p) {
				var cal = this.pages[p];
				w += cal.oDomContainer.offsetWidth;
			}
			if (w > 0) {
				this.oDomContainer.style.width = w + "px";
			}
		};
		this.renderEvent.subscribe(fixWidth,this,true);
	}
};


YAHOO.widget.CalendarGroup.prototype.setupConfig = function() {

	this.cfg.addProperty("pages", { value:2, validator:this.cfg.checkNumber, handler:this.configPages } );


	this.cfg.addProperty("pagedate", { value:new Date(), handler:this.configPageDate } );


	this.cfg.addProperty("selected", { value:[], handler:this.delegateConfig } );


	this.cfg.addProperty("title", { value:"", handler:this.configTitle } );


	this.cfg.addProperty("close", { value:false, handler:this.configClose } );


	this.cfg.addProperty("iframe", { value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("mindate", { value:null, handler:this.delegateConfig } );


	this.cfg.addProperty("maxdate", { value:null, handler:this.delegateConfig  } );


	this.cfg.addProperty("MULTI_SELECT",	{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("START_WEEKDAY",	{ value:0, handler:this.delegateConfig, validator:this.cfg.checkNumber  } );


	this.cfg.addProperty("SHOW_WEEKDAYS",	{ value:true, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("SHOW_WEEK_HEADER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("SHOW_WEEK_FOOTER",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("HIDE_BLANK_WEEKS",{ value:false, handler:this.delegateConfig, validator:this.cfg.checkBoolean } );


	this.cfg.addProperty("NAV_ARROW_LEFT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/callt.gif", handler:this.delegateConfig } );


	this.cfg.addProperty("NAV_ARROW_RIGHT",	{ value:YAHOO.widget.Calendar.IMG_ROOT + "us/tr/calrt.gif", handler:this.delegateConfig } );


	this.cfg.addProperty("MONTHS_SHORT",	{ value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], handler:this.delegateConfig } );


	this.cfg.addProperty("MONTHS_LONG",		{ value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], handler:this.delegateConfig } );


	this.cfg.addProperty("WEEKDAYS_1CHAR",	{ value:["S", "M", "T", "W", "T", "F", "S"], handler:this.delegateConfig } );


	this.cfg.addProperty("WEEKDAYS_SHORT",	{ value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], handler:this.delegateConfig } );


	this.cfg.addProperty("WEEKDAYS_MEDIUM",	{ value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], handler:this.delegateConfig } );


	this.cfg.addProperty("WEEKDAYS_LONG",	{ value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], handler:this.delegateConfig } );


	this.cfg.addProperty("LOCALE_MONTHS",	{ value:"long", handler:this.delegateConfig } );


	this.cfg.addProperty("LOCALE_WEEKDAYS",	{ value:"short", handler:this.delegateConfig } );


	this.cfg.addProperty("DATE_DELIMITER",		{ value:",", handler:this.delegateConfig } );


	this.cfg.addProperty("DATE_FIELD_DELIMITER",{ value:"/", handler:this.delegateConfig } );


	this.cfg.addProperty("DATE_RANGE_DELIMITER",{ value:"-", handler:this.delegateConfig } );


	this.cfg.addProperty("MY_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MY_YEAR_POSITION",	{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MD_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MD_DAY_POSITION",		{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_MONTH_POSITION",	{ value:1, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_DAY_POSITION",	{ value:2, handler:this.delegateConfig, validator:this.cfg.checkNumber } );


	this.cfg.addProperty("MDY_YEAR_POSITION",	{ value:3, handler:this.delegateConfig, validator:this.cfg.checkNumber } );

};


YAHOO.widget.CalendarGroup.prototype.initEvents = function() {
	var me = this;


	var sub = function(fn, obj, bOverride) {
		for (var p=0;p<me.pages.length;++p) {
			var cal = me.pages[p];
			cal[this.type + "Event"].subscribe(fn, obj, bOverride);
		}
	};


	var unsub = function(fn, obj) {
		for (var p=0;p<me.pages.length;++p) {
			var cal = me.pages[p];
			cal[this.type + "Event"].unsubscribe(fn, obj);
		}
	};


	this.beforeSelectEvent = new YAHOO.util.CustomEvent("beforeSelect");
	this.beforeSelectEvent.subscribe = sub; this.beforeSelectEvent.unsubscribe = unsub;


	this.selectEvent = new YAHOO.util.CustomEvent("select");
	this.selectEvent.subscribe = sub; this.selectEvent.unsubscribe = unsub;


	this.beforeDeselectEvent = new YAHOO.util.CustomEvent("beforeDeselect");
	this.beforeDeselectEvent.subscribe = sub; this.beforeDeselectEvent.unsubscribe = unsub;


	this.deselectEvent = new YAHOO.util.CustomEvent("deselect");
	this.deselectEvent.subscribe = sub; this.deselectEvent.unsubscribe = unsub;


	this.changePageEvent = new YAHOO.util.CustomEvent("changePage");
	this.changePageEvent.subscribe = sub; this.changePageEvent.unsubscribe = unsub;


	this.beforeRenderEvent = new YAHOO.util.CustomEvent("beforeRender");
	this.beforeRenderEvent.subscribe = sub; this.beforeRenderEvent.unsubscribe = unsub;


	this.renderEvent = new YAHOO.util.CustomEvent("render");
	this.renderEvent.subscribe = sub; this.renderEvent.unsubscribe = unsub;


	this.resetEvent = new YAHOO.util.CustomEvent("reset");
	this.resetEvent.subscribe = sub; this.resetEvent.unsubscribe = unsub;


	this.clearEvent = new YAHOO.util.CustomEvent("clear");
	this.clearEvent.subscribe = sub; this.clearEvent.unsubscribe = unsub;

};


YAHOO.widget.CalendarGroup.prototype.configPages = function(type, args, obj) {
	var pageCount = args[0];

	for (var p=0;p<pageCount;++p) {
		var calId = this.id + "_" + p;
		var calContainerId = this.containerId + "_" + p;

		var childConfig = this.cfg.getConfig();
		childConfig.close = false;
		childConfig.title = false;

		var cal = this.constructChild(calId, calContainerId, childConfig);
		var caldate = cal.cfg.getProperty("pagedate");
		caldate.setMonth(caldate.getMonth()+p);
		cal.cfg.setProperty("pagedate", caldate);

		YAHOO.util.Dom.removeClass(cal.oDomContainer, this.Style.CSS_SINGLE);
		YAHOO.util.Dom.addClass(cal.oDomContainer, "groupcal");

		if (p===0) {
			YAHOO.util.Dom.addClass(cal.oDomContainer, "first");
		}

		if (p==(pageCount-1)) {
			YAHOO.util.Dom.addClass(cal.oDomContainer, "last");
		}

		cal.parent = this;
		cal.index = p;

		this.pages[this.pages.length] = cal;
	}
};


YAHOO.widget.CalendarGroup.prototype.configPageDate = function(type, args, obj) {
	var val = args[0];

	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.cfg.setProperty("pagedate", val);
		var calDate = cal.cfg.getProperty("pagedate");
		calDate.setMonth(calDate.getMonth()+p);
	}
};


YAHOO.widget.CalendarGroup.prototype.delegateConfig = function(type, args, obj) {
	var val = args[0];
	var cal;

	for (var p=0;p<this.pages.length;p++) {
		cal = this.pages[p];
		cal.cfg.setProperty(type, val);
	}
};



YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
	var pageCount = this.cfg.getProperty("pages");

	for (var p=0;p<pageCount;++p) {
		this.pages[p][fnName] = fn;
	}
};


YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {
	var pageCount = this.cfg.getProperty("pages");

	for (var p=0;p<pageCount;++p) {
		var page = this.pages[p];
		if (page[fnName]) {
			var fn = page[fnName];
			fn.call(page, args);
		}
	}
};


YAHOO.widget.CalendarGroup.prototype.constructChild = function(id,containerId,config) {
	var container = document.getElementById(containerId);
	if (! container) {
		container = document.createElement("div");
		container.id = containerId;
		this.oDomContainer.appendChild(container);
	}
	return new YAHOO.widget.Calendar(id,containerId,config);
};



YAHOO.widget.CalendarGroup.prototype.setMonth = function(month) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.setMonth(month+p);
	}
};


YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		var pageDate = cal.cfg.getProperty("pageDate");

		if ((pageDate.getMonth()+1) == 1 && p>0) {
			year+=1;
		}
		cal.setYear(year);
	}
};

YAHOO.widget.CalendarGroup.prototype.render = function() {
	this.renderHeader();
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.render();
	}
	this.renderFooter();
};


YAHOO.widget.CalendarGroup.prototype.select = function(date) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.select(date);
	}
	return this.getSelectedDates();
};


YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.selectCell(cellIndex);
	}
	return this.getSelectedDates();
};


YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.deselect(date);
	}
	return this.getSelectedDates();
};


YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.deselectAll();
	}
	return this.getSelectedDates();
};


YAHOO.widget.CalendarGroup.prototype.deselectCell = function(cellIndex) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.deselectCell(cellIndex);
	}
	return this.getSelectedDates();
};


YAHOO.widget.CalendarGroup.prototype.reset = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.reset();
	}
};


YAHOO.widget.CalendarGroup.prototype.clear = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.clear();
	}
};


YAHOO.widget.CalendarGroup.prototype.nextMonth = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.nextMonth();
	}
};


YAHOO.widget.CalendarGroup.prototype.previousMonth = function() {
	for (var p=this.pages.length-1;p>=0;--p) {
		var cal = this.pages[p];
		cal.previousMonth();
	}
};


YAHOO.widget.CalendarGroup.prototype.nextYear = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.nextYear();
	}
};


YAHOO.widget.CalendarGroup.prototype.previousYear = function() {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.previousYear();
	}
};



YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() {
	var returnDates = [];
	var selected = this.cfg.getProperty("selected");

	for (var d=0;d<selected.length;++d) {
		var dateArray = selected[d];

		var date = new Date(dateArray[0],dateArray[1]-1,dateArray[2]);
		returnDates.push(date);
	}

	returnDates.sort( function(a,b) { return a-b; } );
	return returnDates;
};


YAHOO.widget.CalendarGroup.prototype.addRenderer = function(sDates, fnRender) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.addRenderer(sDates, fnRender);
	}
};


YAHOO.widget.CalendarGroup.prototype.addMonthRenderer = function(month, fnRender) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.addMonthRenderer(month, fnRender);
	}
};


YAHOO.widget.CalendarGroup.prototype.addWeekdayRenderer = function(weekday, fnRender) {
	for (var p=0;p<this.pages.length;++p) {
		var cal = this.pages[p];
		cal.addWeekdayRenderer(weekday, fnRender);
	}
};


YAHOO.widget.CalendarGroup.prototype.renderHeader = function() {};


YAHOO.widget.CalendarGroup.prototype.renderFooter = function() {};


YAHOO.widget.CalendarGroup.prototype.addMonths = function(count) {
	this.callChildFunction("addMonths", count);
};



YAHOO.widget.CalendarGroup.prototype.subtractMonths = function(count) {
	this.callChildFunction("subtractMonths", count);
};


YAHOO.widget.CalendarGroup.prototype.addYears = function(count) {
	this.callChildFunction("addYears", count);
};


YAHOO.widget.CalendarGroup.prototype.subtractYears = function(count) {
	this.callChildFunction("subtractYears", count);
};


YAHOO.widget.CalendarGroup.CSS_CONTAINER = "yui-calcontainer";


YAHOO.widget.CalendarGroup.CSS_MULTI_UP = "multi";


YAHOO.widget.CalendarGroup.CSS_2UPTITLE = "title";


YAHOO.widget.CalendarGroup.CSS_2UPCLOSE = "close-icon";

YAHOO.augment(YAHOO.widget.CalendarGroup, YAHOO.widget.Calendar, "buildDayLabel",
																 "buildMonthLabel",
																 "renderOutOfBoundsDate",
																 "renderRowHeader",
																 "renderRowFooter",
																 "renderCellDefault",
																 "styleCellDefault",
																 "renderCellStyleHighlight1",
																 "renderCellStyleHighlight2",
																 "renderCellStyleHighlight3",
																 "renderCellStyleHighlight4",
																 "renderCellStyleToday",
																 "renderCellStyleSelected",
																 "renderCellNotThisMonth",
																 "renderBodyCellRestricted",
																 "initStyles",
																 "configTitle",
																 "configClose",
																 "hide",
																 "show",
																 "browser");


YAHOO.widget.CalendarGroup.prototype.toString = function() {
	return "CalendarGroup " + this.id;
};

YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;


YAHOO.widget.Calendar2up = function(id, containerId, config) {
	this.init(id, containerId, config);
};

YAHOO.extend(YAHOO.widget.Calendar2up, YAHOO.widget.CalendarGroup);


YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;

/*************************************************************************** initial.js *************************************************/

YAHOO.namespace("example.calendar");

function handleSelect(type,args,obj) {
	var dates = args[0]; 
	var date = dates[0];
	var year = date[0], month = date[1], day = date[2];

	var selMonth = document.getElementById(update_month);
	var selDay = document.getElementById(update_day);
	var selYear = document.getElementById(update_year);
	
	selMonth.selectedIndex = month;
	selDay.selectedIndex = day;

	for (var y=0;y<selYear.options.length;y++) {
		if (selYear.options[y].text == year) {
			selYear.selectedIndex = y;
			break;
		}
	}
	YAHOO.example.calendar.cal1.hide();
}


function popupCal(xyz_day, xyz_month, xyz_year, xyz_container) {
	update_day = xyz_day;
	update_month = xyz_month;
	update_year = xyz_year;
YAHOO.example.calendar.cal1 = new YAHOO.widget.CalendarGroup("cal1", xyz_container, { pages:2, title:"Please make a selection:", close:true } );
YAHOO.example.calendar.cal1.render();
	YAHOO.example.calendar.cal1.show();
	YAHOO.example.calendar.cal1.selectEvent.subscribe(handleSelect, YAHOO.example.calendar.cal1, true);
	YAHOO.example.calendar.cal1.render();
}

function init() {
//	YAHOO.example.calendar.cal1 = new YAHOO.widget.CalendarGroup("cal1","cal1Container", { pages:2, title:"Please make a selection:", close:true } );
	//YAHOO.example.calendar.cal1.render();

	// Listener to show the 3-up Calendar when the button is clicked
	//YAHOO.util.Event.addListener("show3up", "click", YAHOO.example.calendar.cal1.show, YAHOO.example.calendar.cal1, true);




	//YAHOO.util.Event.addListener(["selMonth","selDay","selYear"], "change", updateCal);
}

YAHOO.util.Event.addListener(window, "load", init);
