Array.prototype.contains = function(obj) {
  for (var i=0; i<this.length; i++) {
    if (this[i].toString() == obj.toString()) return i;
  }
  return "undefined";
}


/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version 0.11.3
*/

var YAHOO = window.YAHOO || {};


YAHOO.namespace = function( sNameSpace ) {

    if (!sNameSpace || !sNameSpace.length) {
        return null;
    }

    var levels = sNameSpace.split(".");

    var currentNS = YAHOO;

    // YAHOO is implied, so it is ignored if it is included
    for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) {
        currentNS[levels[i]] = currentNS[levels[i]] || {};
        currentNS = currentNS[levels[i]];
    }

    return currentNS;
};

/**
 * Global log method.
 */
YAHOO.log = function(sMsg,sCategory) {
    if(YAHOO.widget.Logger) {
        YAHOO.widget.Logger.log(null, sMsg, sCategory);
    } else {
        return false;
    }
};

YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");


YAHOO.util.CustomEvent = function(type, oScope) {
    /**
     * The type of event, returned to subscribers when the event fires
     * @type string
     */
    this.type = type;

    /**
     * The scope the the event will fire from by default.  Defaults to the window 
     * obj
     * @type object
     */
    this.scope = oScope || window;

    /**
     * The subscribers to this event
     * @type Subscriber[]
     */
    this.subscribers = [];

    // Register with the event utility for automatic cleanup.  Made optional
    // so that CustomEvent can be used independently of pe.event
    if (YAHOO.util.Event) { 
        YAHOO.util.Event.regCE(this);
    }
};

YAHOO.util.CustomEvent.prototype = {
    subscribe: function(fn, obj, bOverride) {
        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, bOverride) );
    },

    /**
     * Unsubscribes the caller from this event
     * @param {Function} fn  The function to execute
     * @param {Object}   obj An object to be passed along when the event fires
     * @return {boolean} True if the subscriber was found and detached.
     */
    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;
    },

    /**
     * Notifies the subscribers.  The callback functions will be executed
     * from the scope specified when the event was created, and with the following
     * parameters:
     *   <pre>
     *   - The type of event
     *   - All of the arguments fire() was executed with as an array
     *   - The custom object (if any) that was passed into the subscribe() method
     *   </pre>
     *   
     * @param {Array} an arbitrary set of parameters to pass to the handler
     */
    fire: function() {
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            var s = this.subscribers[i];
            if (s) {
                var scope = (s.override) ? s.obj : this.scope;
                s.fn.call(scope, this.type, arguments, s.obj);
            }
        }
    },

    /**
     * Removes all listeners
     */
    unsubscribeAll: function() {
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            this._delete(i);
        }
    },

    /**
     * @private
     */
    _delete: function(index) {
        var s = this.subscribers[index];
        if (s) {
            delete s.fn;
            delete s.obj;
        }

        delete this.subscribers[index];
    }
};

/////////////////////////////////////////////////////////////////////

/**
 * @class Stores the subscriber information to be used when the event fires.
 * @param {Function} fn       The function to execute
 * @param {Object}   obj      An object to be passed along when the event fires
 * @param {boolean}  bOverride If true, the obj passed in becomes the execution
 *                            scope of the listener
 * @constructor
 */
YAHOO.util.Subscriber = function(fn, obj, bOverride) {
    /**
     * The callback that will be execute when the event fires
     * @type function
     */
    this.fn = fn;

    /**
     * An optional custom object that will passed to the callback when
     * the event fires
     * @type object
     */
    this.obj = obj || null;

    /**
     * The default execution scope for the event listener is defined when the
     * event is created (usually the object which contains the event).
     * By setting override to true, the execution scope becomes the custom
     * object passed in by the subscriber
     * @type boolean
     */
    this.override = (bOverride);
};

/**
 * Returns true if the fn and obj match this objects properties.
 * Used by the unsubscribe method to match the right subscriber.
 *
 * @param {Function} fn the function to execute
 * @param {Object} obj an object to be passed along when the event fires
 * @return {boolean} true if the supplied arguments match this 
 *                   subscriber's signature.
 */
YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
    return (this.fn == fn && this.obj == obj);
};



// Only load this library once.  If it is loaded a second time, existing
// events cannot be detached.
if (!YAHOO.util.Event) {

/**
 * @class
 * The event utility provides functions to add and remove event listeners,
 * event cleansing.  It also tries to automatically remove listeners it
 * registers during the unload event.
 * @constructor
 */
    YAHOO.util.Event = function() {

        /**
         * True after the onload event has fired
         * @type boolean
         * @private
         */
        var loadComplete =  false;

        /**
         * Cache of wrapped listeners
         * @type array
         * @private
         */
        var listeners = [];

        /**
         * Listeners that will be attached during the onload event
         * @type array
         * @private
         */
        var delayedListeners = [];

        /**
         * User-defined unload function that will be fired before all events
         * are detached
         * @type array
         * @private
         */
        var unloadListeners = [];

        /**
         * Cache of the custom events that have been defined.  Used for
         * automatic cleanup
         * @type array
         * @private
         */
        var customEvents = [];

        /**
         * Cache of DOM0 event handlers to work around issues with DOM2 events
         * in Safari
         * @private
         */
        var legacyEvents = [];

        /**
         * Listener stack for DOM0 events
         * @private
         */
        var legacyHandlers = [];

        /**
         * The number of times to poll after window.onload.  This number is
         * increased if additional late-bound handlers are requested after
         * the page load.
         * @private
         */
        var retryCount = 0;

        /**
         * onAvailable listeners
         * @private
         */
        var onAvailStack = [];

        /**
         * Lookup table for legacy events
         * @private
         */
        var legacyMap = [];

        /**
         * Counter for auto id generation
         * @private
         */
        var counter = 0;

        return { // PREPROCESS

            /**
             * The number of times we should look for elements that are not
             * in the DOM at the time the event is requested after the document
             * has been loaded.  The default is 200@50 ms, so it will poll
             * for 10 seconds or until all outstanding handlers are bound
             * (whichever comes first).
             * @type int
             */
            POLL_RETRYS: 200,

            /**
             * The poll interval in milliseconds
             * @type int
             */
            POLL_INTERVAL: 50,

            /**
             * Element to bind, int constant
             * @type int
             */
            EL: 0,

            /**
             * Type of event, int constant
             * @type int
             */
            TYPE: 1,

            /**
             * Function to execute, int constant
             * @type int
             */
            FN: 2,

            /**
             * Function wrapped for scope correction and cleanup, int constant
             * @type int
             */
            WFN: 3,

            /**
             * Object passed in by the user that will be returned as a 
             * parameter to the callback, int constant
             * @type int
             */
            SCOPE: 3,

            /**
             * Adjusted scope, either the element we are registering the event
             * on or the custom object passed in by the listener, int constant
             * @type int
             */
            ADJ_SCOPE: 4,

            /**
             * Safari detection is necessary to work around the preventDefault
             * bug that makes it so you can't cancel a href click from the 
             * handler.  There is not a capabilities check we can use here.
             * @private
             */
            isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),

            /**
             * IE detection needed to properly calculate pageX and pageY.  
             * capabilities checking didn't seem to work because another 
             * browser that does not provide the properties have the values 
             * calculated in a different manner than IE.
             * @private
             */
            isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) && 
                    navigator.userAgent.match(/msie/gi)),

            /**
             * @private
             */
            addDelayedListener: function(el, sType, fn, oScope, bOverride) {
                delayedListeners[delayedListeners.length] =
                    [el, sType, fn, oScope, bOverride];

                // If this happens after the inital page load, we need to
                // reset the poll counter so that we continue to search for
                // the element for a fixed period of time.
                if (loadComplete) {
                    retryCount = this.POLL_RETRYS;
                    this.startTimeout(0);
                    // this._tryPreloadAttach();
                }
            },

            /**
             * @private
             */
            startTimeout: function(interval) {
                var i = (interval || interval === 0) ? interval : this.POLL_INTERVAL;
                var self = this;
                var callback = function() { self._tryPreloadAttach(); };
                this.timeout = setTimeout(callback, i);
            },

            /**
             * Executes the supplied callback when the item with the supplied
             * id is found.  This is meant to be used to execute behavior as
             * soon as possible as the page loads.  If you use this after the
             * initial page load it will poll for a fixed time for the element.
             * The number of times it will poll and the frequency are
             * configurable.  By default it will poll for 10 seconds.
             * @param {string} p_id the id of the element to look for.
             * @param {function} p_fn what to execute when the element is found.
             * @param {object} p_obj an optional object to be passed back as
             * a parameter to p_fn.
             * @param {boolean} p_override If set to true, p_fn will execute
             * in the scope of p_obj
             *
             */
            onAvailable: function(p_id, p_fn, p_obj, p_override) {
                onAvailStack.push( { id:       p_id, 
                                     fn:       p_fn, 
                                     obj:      p_obj, 
                                     override: p_override } );

                retryCount = this.POLL_RETRYS;
                this.startTimeout(0);
                // this._tryPreloadAttach();
            },

            /**
             * Appends an event handler
             *
             * @param {Object}   el        The html element to assign the 
             *                             event to
             * @param {String}   sType     The type of event to append
             * @param {Function} fn        The method the event invokes
             * @param {Object}   oScope    An arbitrary object that will be 
             *                             passed as a parameter to the handler
             * @param {boolean}  bOverride If true, the obj passed in becomes
             *                             the execution scope of the listener
             * @return {boolean} True if the action was successful or defered,
             *                        false if one or more of the elements 
             *                        could not have the event bound to it.
             */
            addListener: function(el, sType, fn, oScope, bOverride) {

                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, 
                                       oScope, 
                                       bOverride) && ok );
                    }
                    return ok;

                } else if (typeof el == "string") {
                    var oEl = this.getEl(el);
                    // If the el argument is a string, we assume it is 
                    // actually the id of the element.  If the page is loaded
                    // we convert el to the actual element, otherwise we 
                    // defer attaching the event until onload event fires

                    // check to see if we need to delay hooking up the event 
                    // until after the page loads.
                    if (loadComplete && oEl) {
                        el = oEl;
                    } else {
                        // defer adding the event until onload fires
                        this.addDelayedListener(el, 
                                                sType, 
                                                fn, 
                                                oScope, 
                                                bOverride);

                        return true;
                    }
                }

                // Element should be an html element or an array if we get 
                // here.
                if (!el) {
                    return false;
                }

                // we need to make sure we fire registered unload events 
                // prior to automatically unhooking them.  So we hang on to 
                // these instead of attaching them to the window and fire the
                // handles explicitly during our one unload event.
                if ("unload" == sType && oScope !== this) {
                    unloadListeners[unloadListeners.length] =
                            [el, sType, fn, oScope, bOverride];
                    return true;
                }


                // if the user chooses to override the scope, we use the custom
                // object passed in, otherwise the executing scope will be the
                // HTML element that the event is registered on
                var scope = (bOverride) ? oScope : el;

                // wrap the function so we can return the oScope object when
                // the event fires;
                var wrappedFn = function(e) {
                        return fn.call(scope, YAHOO.util.Event.getEvent(e), 
                                oScope);
                    };

                var li = [el, sType, fn, wrappedFn, scope];
                var index = listeners.length;
                // cache the listener so we can try to automatically unload
                listeners[index] = li;

                if (this.useLegacyEvent(el, sType)) {
                    var legacyIndex = this.getLegacyIndex(el, sType);
                    if (legacyIndex == -1) {

                        legacyIndex = legacyEvents.length;
                        legacyMap[el.id + sType] = legacyIndex;

                        // cache the signature for the DOM0 event, and 
                        // include the existing handler for the event, if any
                        legacyEvents[legacyIndex] = 
                            [el, sType, el["on" + sType]];
                        legacyHandlers[legacyIndex] = [];

                        el["on" + sType] = 
                            function(e) {
                                YAHOO.util.Event.fireLegacyEvent(
                                    YAHOO.util.Event.getEvent(e), legacyIndex);
                            };
                    }

                    // add a reference to the wrapped listener to our custom
                    // stack of events
                    legacyHandlers[legacyIndex].push(index);

                // DOM2 Event model
                } else if (el.addEventListener) {
                    el.addEventListener(sType, wrappedFn, false);
                // Internet Explorer abstraction
                } else if (el.attachEvent) {
                    el.attachEvent("on" + sType, wrappedFn);
                }

                return true;
                
            },

            /**
             * Shorthand for YAHOO.util.Event.addListener
             * @type function
             */
            // on: this.addListener,

            /**
             * When using legacy events, the handler is routed to this object
             * so we can fire our custom listener stack.
             * @private
             */
            fireLegacyEvent: function(e, legacyIndex) {
                var ok = true;

                var le = legacyHandlers[legacyIndex];
                for (var i=0,len=le.length; i<len; ++i) {
                    var index = le[i];
                    if (index) {
                        var li = listeners[index];
                        if ( li && li[this.WFN] ) {
                            var scope = li[this.ADJ_SCOPE];
                            var ret = li[this.WFN].call(scope, e);
                            ok = (ok && ret);
                        } else {
                            // This listener was removed, so delete it from
                            // the array
                            delete le[i];
                        }
                    }
                }

                return ok;
            },

            /**
             * Returns the legacy event index that matches the supplied 
             * signature
             * @private
             */
            getLegacyIndex: function(el, sType) {
                /*
                for (var i=0,len=legacyEvents.length; i<len; ++i) {
                    var le = legacyEvents[i];
                    if (le && le[0] === el && le[1] === sType) {
                        return i;
                    }
                }
                return -1;
                */

                var key = this.generateId(el) + sType;
                if (typeof legacyMap[key] == "undefined") { 
                    return -1;
                } else {
                    return legacyMap[key];
                }

            },

            /**
             * Logic that determines when we should automatically use legacy
             * events instead of DOM2 events.
             * @private
             */
            useLegacyEvent: function(el, sType) {

                if (!el.addEventListener && !el.attachEvent) {
                    return true;
                } else if (this.isSafari) {
                    if ("click" == sType || "dblclick" == sType) {
                        return true;
                    }
                }

                return false;
            },
                    
            /**
             * Removes an event handler
             *
             * @param {Object} el the html element or the id of the element to 
             * assign the event to.
             * @param {String} sType the type of event to remove
             * @param {Function} fn the method the event invokes
             * @return {boolean} true if the unbind was successful, false 
             * otherwise
             */
            removeListener: function(el, sType, fn, index) {

                if (!fn || !fn.call) {
                    return false;
                }

                // 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 (var i=0,len=el.length; i<len; ++i) {
                        ok = ( this.removeListener(el[i], sType, fn) && ok );
                    }
                    return ok;
                }

                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) {
                                delete unloadListeners[i];
                                return true;
                        }
                    }

                    return false;
                }

                var cacheItem = null;
  
                if ("undefined" == typeof index) {
                    index = this._getCacheIndex(el, sType, fn);
                }

                if (index >= 0) {
                    cacheItem = listeners[index];
                }

                if (!el || !cacheItem) {
                    return false;
                }


                if (el.removeEventListener) {
                    el.removeEventListener(sType, cacheItem[this.WFN], false);
                } else if (el.detachEvent) {
                    el.detachEvent("on" + sType, cacheItem[this.WFN]);
                }

                // removed the wrapped handler
                delete listeners[index][this.WFN];
                delete listeners[index][this.FN];
                delete listeners[index];

                return true;

            },

            /**
             * Returns the event's target element
             * @param {Event} ev the event
             * @param {boolean} resolveTextNode when set to true the target's
             *                  parent will be returned if the target is a 
             *                  text node
             * @return {HTMLElement} the event's target
             */
            getTarget: function(ev, resolveTextNode) {
                var t = ev.target || ev.srcElement;

                if (resolveTextNode && t && "#text" == t.nodeName) {
                    return t.parentNode;
                } else {
                    return t;
                }
            },

            /**
             * Returns the event's pageX
             * @param {Event} ev the event
             * @return {int} the event's pageX
             */
            getPageX: function(ev) {
                var x = ev.pageX;
                if (!x && 0 !== x) {
                    x = ev.clientX || 0;

                    if ( this.isIE ) {
                        x += this._getScrollLeft();
                    }
                }

                return x;
            },

            /**
             * Returns the event's pageY
             * @param {Event} ev the event
             * @return {int} the event's pageY
             */
            getPageY: function(ev) {
                var y = ev.pageY;
                if (!y && 0 !== y) {
                    y = ev.clientY || 0;

                    if ( this.isIE ) {
                        y += this._getScrollTop();
                    }
                }

                return y;
            },

            /**
             * Returns the pageX and pageY properties as an indexed array.
             * @type int[]
             */
            getXY: function(ev) {
                return [this.getPageX(ev), this.getPageY(ev)];
            },

            /**
             * Returns the event's related target 
             * @param {Event} ev the event
             * @return {HTMLElement} the event's relatedTarget
             */
            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 t;
            },

            /**
             * Returns the time of the event.  If the time is not included, the
             * event is modified using the current time.
             * @param {Event} ev the event
             * @return {Date} the time of the event
             */
            getUTCTime: function(ev) {
                if (!ev.time) {
                    var t = new Date().getUTCTime();
                    try {
                        ev.time = t;
                    } catch(e) { 
                        // can't set the time property  
                        return t;
                    }
                }

                return ev.time;
            },

            /**
             * Convenience method for stopPropagation + preventDefault
             * @param {Event} ev the event
             */
            stopEvent: function(ev) {
                this.stopPropagation(ev);
                this.preventDefault(ev);
            },

            /**
             * Stops event propagation
             * @param {Event} ev the event
             */
            stopPropagation: function(ev) {
                if (ev.stopPropagation) {
                    ev.stopPropagation();
                } else {
                    ev.cancelBubble = true;
                }
            },

            /**
             * Prevents the default behavior of the event
             * @param {Event} ev the event
             */
            preventDefault: function(ev) {
                if (ev.preventDefault) {
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
            },
             
            /**
             * Finds the event in the window object, the caller's arguments, or
             * in the arguments of another method in the callstack.  This is
             * executed automatically for events registered through the event
             * manager, so the implementer should not normally need to execute
             * this function at all.
             * @param {Event} the event parameter from the handler
             * @return {Event} the event 
             */
            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;
            },

            /**
             * Returns the charcode for an event
             * @param {Event} ev the event
             * @return {int} the event's charCode
             */
            getCharCode: function(ev) {
                return ev.charCode || ((ev.type == "keypress") ? ev.keyCode : 0);
            },

            /**
             * @private
             * Locating the saved event handler data by function ref
             */
            _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;
            },

            /**
             * Generates an unique ID for the element if it does not already 
             * have one.
             * @param el the element
             * @return {string} the id of the element
             */
            generateId: function(el) {
                var id = el.id;

                if (!id) {
                    id = "yuievtautoid-" + (counter++);
                    el.id = id;
                }

                return id;
            },

            /**
             * We want to be able to use getElementsByTagName as a collection
             * to attach a group of events to.  Unfortunately, different 
             * browsers return different types of collections.  This function
             * tests to determine if the object is array-like.  It will also 
             * fail if the object is an array, but is empty.
             * @param o the object to test
             * @return {boolean} true if the object is array-like and populated
             * @private
             */
            _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" );

            },

            /**
             * @private
             * DOM element cache
             */
            elCache: {},

            /**
             * We cache elements bound by id because when the unload event 
             * fires, we can no longer use document.getElementById
             * @private
             */
            getEl: function(id) {
                return document.getElementById(id);
            },

            /**
             * Clears the element cache
             * @deprecated
             * @private
             */
            clearCache: function() { },

            /**
             * Called by CustomEvent instances to provide a handle to the 
             * event * that can be removed later on.  Should be package 
             * protected.
             * @private
             */
            regCE: function(ce) {
                customEvents.push(ce);
            },

            /**
             * @private
             * hook up any deferred listeners
             */
            _load: function(e) {
                loadComplete = true;
            },

            /**
             * Polling function that runs before the onload event fires, 
             * attempting * to attach to DOM Nodes as soon as they are 
             * available
             * @private
             */
            _tryPreloadAttach: function() {

                if (this.locked) {
                    return false;
                }

                this.locked = true;


                // keep trying until after the page is loaded.  We need to 
                // check the page load state prior to trying to bind the 
                // elements so that we can be certain all elements have been 
                // tested appropriately
                var tryAgain = !loadComplete;
                if (!tryAgain) {
                    tryAgain = (retryCount > 0);
                }

                // Delayed listeners
                var stillDelayed = [];

                for (var i=0,len=delayedListeners.length; i<len; ++i) {
                    var d = delayedListeners[i];
                    // There may be a race condition here, so we need to 
                    // verify the array element is usable.
                    if (d) {

                        // el will be null if document.getElementById did not
                        // work
                        var el = this.getEl(d[this.EL]);

                        if (el) {
                            this.on(el, d[this.TYPE], d[this.FN], 
                                    d[this.SCOPE], d[this.ADJ_SCOPE]);
                            delete delayedListeners[i];
                        } else {
                            stillDelayed.push(d);
                        }
                    }
                }

                delayedListeners = stillDelayed;

                // onAvailable
                notAvail = [];
                for (i=0,len=onAvailStack.length; i<len ; ++i) {
                    var item = onAvailStack[i];
                    if (item) {
                        el = this.getEl(item.id);

                        if (el) {
                            var scope = (item.override) ? item.obj : el;
                            item.fn.call(scope, item.obj);
                            delete onAvailStack[i];
                        } else {
                            notAvail.push(item);
                        }
                    }
                }

                retryCount = (stillDelayed.length === 0 && 
                                    notAvail.length === 0) ? 0 : retryCount - 1;

                if (tryAgain) {
                    this.startTimeout();
                }

                this.locked = false;

            },

            /**
             * Removes all listeners registered by pe.event.  Called 
             * automatically during the unload event.
             * @private
             */
            _unload: function(e, me) {
                for (var i=0,len=unloadListeners.length; i<len; ++i) {
                    var l = unloadListeners[i];
                    if (l) {
                        var scope = (l[this.ADJ_SCOPE]) ? l[this.SCOPE]: window;
                        l[this.FN].call(scope, this.getEvent(e), l[this.SCOPE] );
                    }
                }

                if (listeners && listeners.length > 0) {
                    for (i=0,len=listeners.length; i<len ; ++i) {
                        l = listeners[i];
                        if (l) {
                            this.removeListener(l[this.EL], l[this.TYPE], 
                                    l[this.FN], i);
                        }
                    }

                    this.clearCache();
                }

                for (i=0,len=customEvents.length; i<len; ++i) {
                    customEvents[i].unsubscribeAll();
                    delete customEvents[i];
                }

                for (i=0,len=legacyEvents.length; i<len; ++i) {
                    // dereference the element
                    delete legacyEvents[i][0];
                    // delete the array item
                    delete legacyEvents[i];
                }
            },

            /**
             * Returns scrollLeft
             * @private
             */
            _getScrollLeft: function() {
                return this._getScroll()[1];
            },

            /**
             * Returns scrollTop
             * @private
             */
            _getScrollTop: function() {
                return this._getScroll()[0];
            },

            /**
             * Returns the scrollTop and scrollLeft.  Used to calculate the 
             * pageX and pageY in Internet Explorer
             * @private
             */
            _getScroll: function() {
                var dd = document.documentElement; db = document.body;
                if (dd && dd.scrollTop) {
                    return [dd.scrollTop, dd.scrollLeft];
                } else if (db) {
                    return [db.scrollTop, db.scrollLeft];
                } else {
                    return [0, 0];
                }
            }
        };
    } ();

    /**
     * @private
     */
    YAHOO.util.Event.on = YAHOO.util.Event.addListener;

    if (document && document.body) {
        YAHOO.util.Event._load();
    } else {
        YAHOO.util.Event.on(window, "load", YAHOO.util.Event._load, 
                YAHOO.util.Event, true);
    }

    YAHOO.util.Event.on(window, "unload", YAHOO.util.Event._unload, 
                YAHOO.util.Event, true);

    YAHOO.util.Event._tryPreloadAttach();

}


YAHOO.util.Dom = function() {
   var ua = navigator.userAgent.toLowerCase();
   var isOpera = (ua.indexOf('opera') != -1);
   var isIE = (ua.indexOf('msie') != -1 && !isOpera); // not opera spoof
   var id_counter = 0;
   
   return {
      get: function(el) {
         if (typeof el != 'string' && !(el instanceof Array) )
         { // assuming HTMLElement or HTMLCollection, so pass back as is
            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] = this.get(el[i]);
            }
            
            return collection;
         }

         return null; // safety, should never happen
      },
   
      getStyle: function(el, property) {
         var f = function(el) {
            var value = null;
            var dv = document.defaultView;
            
            if (property == 'opacity' && el.filters) 
            {// IE opacity
               value = 1;
               try {
                  value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
               } catch(e) {
                  try {
                     value = el.filters.item('alpha').opacity / 100;
                  } catch(e) {}
               }
            }
            else if (el.style[property]) 
            {
               value = el.style[property];
            }
            else if (el.currentStyle && el.currentStyle[property]) {
               value = el.currentStyle[property];
            }
            else if ( dv && dv.getComputedStyle )
            {  // convert camelCase to hyphen-case
               
               var converted = '';
               for(var i = 0, len = property.length;i < len; ++i) {
                  if (property.charAt(i) == property.charAt(i).toUpperCase()) 
                  {
                     converted = converted + '-' + property.charAt(i).toLowerCase();
                  } else {
                     converted = converted + property.charAt(i);
                  }
               }
               
               if (dv.getComputedStyle(el, '') && dv.getComputedStyle(el, '').getPropertyValue(converted)) {
                  value = dv.getComputedStyle(el, '').getPropertyValue(converted);
               }
            }
      
            return value;
         };
         
         return this.batch(el, f, this, true);
      },
   
      setStyle: function(el, property, val) {
         var f = function(el) {
            switch(property) {
               case 'opacity' :
                  if (isIE && 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
                     }
                  } else {
                     el.style.opacity = val;
                     el.style['-moz-opacity'] = val;
                     el.style['-khtml-opacity'] = val;
                  }

                  break;
               default :
                  el.style[property] = val;
            }
            
         };
         
         this.batch(el, f, this, true);
      },
      
      /**
       * Gets the current position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       @ return {Array} The XY position of the element(s)
       */
      getXY: function(el) {
         var f = function(el) {
   
         // has to be part of document to have pageXY
            if (el.parentNode === null || this.getStyle(el, 'display') == 'none') {
               return false;
            }
            
            var parent = null;
            var pos = [];
            var box;
            
            if (el.getBoundingClientRect) { // IE
               box = el.getBoundingClientRect();
               var scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
               var scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
               
               return [box.left + scrollLeft, box.top + scrollTop];
            }
            else if (document.getBoxObjectFor) { // gecko
               box = document.getBoxObjectFor(el);
               
               var borderLeft = parseInt(this.getStyle(el, 'borderLeftWidth'));
               var borderTop = parseInt(this.getStyle(el, 'borderTopWidth'));
               
               pos = [box.x - borderLeft, box.y - borderTop];
            }
            else { // safari & opera
               pos = [el.offsetLeft, el.offsetTop];
               parent = el.offsetParent;
               if (parent != el) {
                  while (parent) {
                     pos[0] += parent.offsetLeft;
                     pos[1] += parent.offsetTop;
                     parent = parent.offsetParent;
                  }
               }
               if (
                  ua.indexOf('opera') != -1 
                  || ( ua.indexOf('safari') != -1 && this.getStyle(el, 'position') == 'absolute' ) 
               ) {
                  pos[0] -= document.body.offsetLeft;
                  pos[1] -= document.body.offsetTop;
               } 
            }
            
            if (el.parentNode) { parent = el.parentNode; }
            else { parent = null; }
      
            while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML') 
            { // account for any scrolled ancestors
               pos[0] -= parent.scrollLeft;
               pos[1] -= parent.scrollTop;
      
               if (parent.parentNode) { parent = parent.parentNode; } 
               else { parent = null; }
            }
      
            return pos;
         };
         
         return this.batch(el, f, this, true);
      },
      
      getX: function(el) {
         return this.getXY(el)[0];
      },
      
      getY: function(el) {
         return this.getXY(el)[1];
      },
      
      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 = YAHOO.util.Dom.getXY(el);
            if (pageXY === false) { return false; } // has to be part of doc to have pageXY
            
            var delta = [
               parseInt( YAHOO.util.Dom.getStyle(el, 'left'), 10 ),
               parseInt( YAHOO.util.Dom.getStyle(el, 'top'), 10 )
            ];
         
            if ( isNaN(delta[0]) ) // defaults to 'auto'
            { 
               delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
            } 
            if ( isNaN(delta[1]) ) // defaults to '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]) ) {
               var retry = function() { YAHOO.util.Dom.setXY(el, pos, true); };
               setTimeout(retry, 0); // "delay" for IE resize timing issue
            }
         };
         
         this.batch(el, f, this, true);
      },
      
      setX: function(el, x) {
         this.setXY(el, [x, null]);
      },
      
      setY: function(el, y) {
         this.setXY(el, [null, y]);
      },
      
      getRegion: function(el) {
         var f = function(el) {
            return new YAHOO.util.Region.getRegion(el);
         };
         
         return this.batch(el, f, this, true);
      },
      
      getClientWidth: function() {
         return this.getViewportWidth();
      },
      
      getClientHeight: function() {
         return this.getViewportHeight();
      },

      getElementsByClassName: function(className, tag, root) {
         var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
         
         var method = function(el) { return re.test(el['className']); };
         
         return this.getElementsBy(method, tag, root);
      },

      hasClass: function(el, className) {
         var f = function(el) {
            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
            return re.test(el['className']);
         };
         
         return this.batch(el, f, this, true);
      },
   
      addClass: function(el, className) {
         var f = function(el) {
            if (this.hasClass(el, className)) { return; } // already present
            
            el['className'] = [el['className'], className].join(' ');
         };
         
         this.batch(el, f, this, true);
      },
   
      removeClass: function(el, className) {
         var f = function(el) {
            if (!this.hasClass(el, className)) { return; } // not present
            
            var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');
            var c = el['className'];
            
            el['className'] = c.replace( re, ' ');
         };
         
         this.batch(el, f, this, true);
      },
      
      replaceClass: function(el, oldClassName, newClassName) {
         var f = function(el) {
            this.removeClass(el, oldClassName);
            this.addClass(el, newClassName);
         };
         
         this.batch(el, f, this, true);
      },
      
      generateId: function(el, prefix) {
         prefix = prefix || 'yui-gen';
         
         var f = function(el) {
            el = el || {}; // just generating ID in this case
            
            if (!el.id) { el.id = prefix + id_counter++; } // dont override existing
            
            return el.id;
         };
         
         return this.batch(el, f, this, true);
      },
      
      isAncestor: function(haystack, needle) {
         haystack = this.get(haystack);
         if (!haystack || !needle) { return false; }
         
         var f = function(needle) {
            if (haystack.contains && ua.indexOf('safari') < 0) 
            { // 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 == 'HTML') {
                     return false;
                  }
                  
                  parent = parent.parentNode;
               }
               
               return false;
            }    
         };
         
         return this.batch(needle, f, this, true);     
      },
      
      inDocument: function(el) {
         var f = function(el) {
            return this.isAncestor(document.documentElement, el);
         };
         
         return this.batch(el, f, this, true);
      },
      
      getElementsBy: function(method, tag, root) {
         tag = tag || '*';
         root = this.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) {
         el = this.get(el);
         var scope = (override) ? o : window;
         
         if (!el || el.tagName || !el.length) 
         { // is null or not a collection (tagName for SELECT and others that can be both an element and a collection)
            return method.call(scope, el, o);
         } 
         
         var collection = [];
         
         for (var i = 0, len = el.length; i < len; ++i)
         {
            collection[collection.length] = method.call(scope, el[i], o);
         }
         
         return collection;
      },
      
      getDocumentHeight: function() {
         var scrollHeight=-1,windowHeight=-1,bodyHeight=-1;
         var marginTop = parseInt(this.getStyle(document.body, 'marginTop'), 10);
         var marginBottom = parseInt(this.getStyle(document.body, 'marginBottom'), 10);
         
         var mode = document.compatMode;
         
         if ( (mode || isIE) && !isOpera ) { // (IE, Gecko)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  scrollHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  windowHeight = [document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a, b){return(a-b);})[1];
                  bodyHeight = document.body.offsetHeight + marginTop + marginBottom;
                  break;
               
               default: // Quirks
                  scrollHeight = document.body.scrollHeight;
                  bodyHeight = document.body.clientHeight;
            }
         } else { // Safari & Opera
            scrollHeight = document.documentElement.scrollHeight;
            windowHeight = self.innerHeight;
            bodyHeight = document.documentElement.clientHeight;
         }
      
         var h = [scrollHeight,windowHeight,bodyHeight].sort(function(a, b){return(a-b);});
         return h[2];
      },
      
      /**
       * Returns the width of the document.
       * @return {Int} The width of the actual document (which includes the body and its margin).
       */
      getDocumentWidth: function() {
         var docWidth=-1,bodyWidth=-1,winWidth=-1;
         var marginRight = parseInt(this.getStyle(document.body, 'marginRight'), 10);
         var marginLeft = parseInt(this.getStyle(document.body, 'marginLeft'), 10);
         
         var mode = document.compatMode;
         
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  docWidth = document.documentElement.clientWidth;
                  bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
                  winWidth = self.innerWidth || -1;
                  break;
                  
               default: // Quirks
                  bodyWidth = document.body.clientWidth;
                  winWidth = document.body.scrollWidth;
                  break;
            }
         } else { // Safari
            docWidth = document.documentElement.clientWidth;
            bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
            winWidth = self.innerWidth;
         }
      
         var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
         return w[2];
      },

      getViewportHeight: function() {
         var height = -1;
         var mode = document.compatMode;
      
         if ( (mode || isIE) && !isOpera ) {
            switch (mode) { // (IE, Gecko)
               case 'CSS1Compat': // Standards mode
                  height = document.documentElement.clientHeight;
                  break;
      
               default: // Quirks
                  height = document.body.clientHeight;
            }
         } else { // Safari, Opera
            height = self.innerHeight;
         }
      
         return height;
      },
      
      getViewportWidth: function() {
         var width = -1;
         var mode = document.compatMode;
         
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
            case 'CSS1Compat': // Standards mode 
               width = document.documentElement.clientWidth;
               break;
               
            default: // Quirks
               width = document.body.clientWidth;
            }
         } else { // Safari
            width = self.innerWidth;
         }
         
         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    );

    // this.logger.debug("does " + this + " contain " + region + " ... " + ret);
};


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 {" +
             "t: "    + this.top    + 
             ", r: "    + this.right  + 
             ", b: "    + this.bottom + 
             ", l: "    + 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) {

    this.x      = x;


    this.y      = y;
    this.top    = y;
    this[1] = y;
    
    this.right  = x;
    this.bottom = y;
    this.left   = x;
    this[0] = x;
};

YAHOO.util.Point.prototype = new YAHOO.util.Region();


YAHOO.widget.DateMath = new function() {

	/**
	* Constant field representing Day
	* @type String
	*/
	this.DAY = "D";

	this.WEEK = "W";

	this.YEAR = "Y";

	this.MONTH = "M";

	this.ONE_DAY_MS = 1000*60*60*24;

	this.add = function(date, field, amount) {
            var d = new Date(date.toUTCString());
            //alert(d.getUTCMonth());
		switch (field) {
			case this.MONTH:
				var newMonth = date.getUTCMonth() + 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.setUTCMonth(newMonth);
				d.setUTCFullYear(date.getUTCFullYear() + years);
				break;
			case this.DAY:
				d.setUTCDate(date.getUTCDate() + amount);
				break;
			case this.YEAR:
				d.setUTCFullYear(date.getUTCFullYear() + amount);
				break;
			case this.WEEK:
				d.setUTCDate(date.getUTCDate() + (amount * 7));
				break;
		}
		return d;
	};

	this.subtract = function(date, field, amount) {
		return this.add(date, field, (amount*-1));
	};

	this.before = function(date, compareTo) {
                var ms = Date.UTC(compareTo);
		if (Date.UTC(date) < ms) {
			return true;
		} else {
			return false;
		}
	};

	this.after = function(date, compareTo) {
                var ms = Date.UTC(compareTo);
		if (Date.UTC(date) > ms) {
			return true;
		} else {
			return false;
		}
	};

	this.between = function(date, dateBegin, dateEnd) {
		if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
			return true;
		} else {
			return false;
		}
	};
	
	this.getJan1 = function(calendarYear) {
            return new Date(Date.UTC(calendarYear,0,1)); 
	};

	this.getUTCDayOffset = 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.getUTCTime()-beginYear.getUTCTime()) / this.ONE_DAY_MS);
		return dayOffset;
	};

	this.getWeekNumber = function(date, calendarYear, weekStartsOn) {
		date.setHours(12,0,0,0);

		if (! weekStartsOn) {
			weekStartsOn = 0;
		}
		if (! calendarYear) {
			calendarYear = date.getUTCFullYear();
		}
		
		var weekNum = -1;
		
		var jan1 = this.getJan1(calendarYear);

		var jan1Offset = jan1.getUTCDay() - weekStartsOn;
		var jan1DayOfWeek = (jan1Offset >= 0 ? jan1Offset : (7 + jan1Offset));

		var endOfWeek1 = this.add(jan1, this.DAY, (6 - jan1DayOfWeek));
		endOfWeek1.setHours(23,59,59,999);

		var month = date.getUTCMonth();
		var day = date.getUTCDate();
		var year = date.getUTCFullYear();
		
		var dayOffset = this.getUTCDayOffset(date, calendarYear); // Days since Jan 1, Calendar Year
			
		if (dayOffset < 0 || this.before(date, endOfWeek1)) {
			weekNum = 1;
		} else {
			weekNum = 2;
			var weekBegin = new Date(endOfWeek1.getUTCTime() + 1);
			var weekEnd = this.add(weekBegin, this.WEEK, 1);

			while (! this.between(date, weekBegin, weekEnd)) {
				weekBegin = this.add(weekBegin, this.WEEK, 1);
				weekEnd = this.add(weekEnd, this.WEEK, 1);
				weekNum += 1;
			}
		}
		
		return weekNum;
	};

	this.isYearOverlapWeek = function(weekBeginDate) {
		var overlaps = false;
		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
		if (nextWeek.getUTCFullYear() != weekBeginDate.getUTCFullYear()) {
			overlaps = true;
		}
		return overlaps;
	};

	this.isMonthOverlapWeek = function(weekBeginDate) {
		var overlaps = false;
		var nextWeek = this.add(weekBeginDate, this.DAY, 6);
		if (nextWeek.getUTCMonth() != weekBeginDate.getUTCMonth()) {
			overlaps = true;
		}
		return overlaps;
	};

	this.findMonthStart = function(date) {
			var start = new Date(date.toUTCString());
            start.setUTCDate(1);
		return start;
	};

	this.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;
	};

	this.clearTime = function(date) {
		date.setHours(0,0,0,0);
		return date;
	};
}
YAHOO.widget.Calendar_Core = function(id, containerId, monthyear, selected) {
	if (arguments.length > 0) {
		this.init(id, containerId, monthyear, selected);
	}
}

YAHOO.widget.Calendar_Core.IMG_ROOT =""; // for WCT use


YAHOO.widget.Calendar_Core.DATE = "D";

YAHOO.widget.Calendar_Core.MONTH_DAY = "MD";

YAHOO.widget.Calendar_Core.WEEKDAY = "WD";

YAHOO.widget.Calendar_Core.RANGE = "R";

YAHOO.widget.Calendar_Core.MONTH = "M";

YAHOO.widget.Calendar_Core.DISPLAY_DAYS = 42;

YAHOO.widget.Calendar_Core.STOP_RENDER = "S";

YAHOO.widget.Calendar_Core.prototype = {

	Config : null,

	parent : null,

	index : -1,

	cells : null,

	weekHeaderCells : null,

	weekFooterCells : null,
	
	cellDates : null,

	id : null,

	oDomContainer : null,

	today : null,

	renderStack : null,

	_renderStack : null,

	pageDate : null,

	_pageDate : null,
	
	minDate : null,

	maxDate : null,
	
	selectedDates : null,

	_selectedDates : null,

	shellRendered : false,

	table : null,

	headerCell : null
};



YAHOO.widget.Calendar_Core.prototype.init = function(id, containerId, monthyear, selected) {
	this.setupConfig();

	this.id = id;

	this.cellDates = new Array();
	
	this.cells = new Array();
	
	this.renderStack = new Array();
	this._renderStack = new Array();

	this.oDomContainer = document.getElementById(containerId);
	
	this.today = new Date();
	YAHOO.widget.DateMath.clearTime(this.today);

	var month;
	var year;

	if (monthyear) {
		var aMonthYear = monthyear.split(this.Locale.DATE_FIELD_DELIMITER);
		month = parseInt(aMonthYear[this.Locale.MY_MONTH_POSITION-1]);
		year = parseInt(aMonthYear[this.Locale.MY_YEAR_POSITION-1]);
	} else {
		month = this.today.getUTCMonth()+1;
		year = this.today.getUTCFullYear();
	}

	this.pageDate = new Date(Date.UTC(year, month-1, 1));
        //alert(this.pageDate.toUTCString());
	this._pageDate = new Date(this.pageDate.toUTCString());
                                  //this._pageDate.setUTCTime(this.pageDate.getTime());

	if (selected) {
		this.selectedDates = this._parseDates(selected);
		this._selectedDates = this.selectedDates.concat();
	} else {
		this.selectedDates = new Array();
		this._selectedDates = new Array();
	}

	this.wireDefaultEvents();
	this.wireCustomEvents();
};


YAHOO.widget.Calendar_Core.prototype.wireDefaultEvents = function() {
	
	this.doSelectCell = function(e, cal) {		
		var cell = this;
		var index = cell.index;
		var d = cal.cellDates[index];
		var date = new Date(Date.UTC(d[0],d[1]-1,d[2]));
		
		if (! cal.isDateOOM(date) && ! YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_RESTRICTED) && ! YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_OOB)) {
			if (cal.Options.MULTI_SELECT) {
				var link = cell.getElementsByTagName("A")[0];
				link.blur();
				
				var cellDate = cal.cellDates[index];
				var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
				
				if (cellDateIndex > -1) {	
					cal.deselectCell(index);
				} else {
					cal.selectCell(index);
				}	
				
			} else {
				var link = cell.getElementsByTagName("A")[0];
				link.blur()
				cal.selectCell(index);
			}
		}
	}

	this.doCellMouseOver = function(e, cal) {
		var cell = this;
		var index = cell.index;
		var d = cal.cellDates[index];
		var date = new Date(Date.UTC(d[0],d[1]-1,d[2]));

		if (! cal.isDateOOM(date) && ! YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_RESTRICTED) && ! YAHOO.util.Dom.hasClass(cell, cal.Style.CSS_CELL_OOB)) {
			YAHOO.util.Dom.addClass(cell, cal.Style.CSS_CELL_HOVER);
		}
	}

	this.doCellMouseOut = function(e, cal) {
		YAHOO.util.Dom.removeClass(this, cal.Style.CSS_CELL_HOVER);
	}
	
	this.doNextMonth = function(e, cal) {
		cal.nextMonth();
	}

	this.doPreviousMonth = function(e, cal) {
		cal.previousMonth();
	}
}

YAHOO.widget.Calendar_Core.prototype.wireCustomEvents = function() { }

YAHOO.widget.Calendar_Core.prototype.setupConfig = function() {
	/**
	* Container for the CSS style configuration variables.
	*/
	this.Config = new Object();
	
	this.Config.Style = {

		CSS_ROW_HEADER: "calrowhead",
		CSS_ROW_FOOTER: "calrowfoot",
		CSS_CELL : "calcell",
		CSS_CELL_SELECTED : "selected",
		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 : "calendar",
		CSS_BORDER : "calbordered",
		CSS_CONTAINER : "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"
	};

	this.Style = this.Config.Style;

	this.Config.Locale = {
		// Locale definition
		MONTHS_SHORT : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
		MONTHS_LONG : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
		WEEKDAYS_1CHAR : ["S", "M", "T", "W", "T", "F", "S"],
		WEEKDAYS_SHORT : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
		WEEKDAYS_MEDIUM : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
		WEEKDAYS_LONG : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
		DATE_DELIMITER : ",",
		DATE_FIELD_DELIMITER : "/",
		DATE_RANGE_DELIMITER : "-",
		MY_MONTH_POSITION : 1,
		MY_YEAR_POSITION : 2,
		MD_MONTH_POSITION : 1,
		MD_DAY_POSITION : 2,
		MDY_MONTH_POSITION : 1,
		MDY_DAY_POSITION : 2,
		MDY_YEAR_POSITION : 3
	};

	this.Locale = this.Config.Locale;

	this.Config.Options = {
		// Configuration variables
		MULTI_SELECT : false,
		SHOW_WEEKDAYS : true,
		START_WEEKDAY : 0,
		SHOW_WEEK_HEADER : false,
		SHOW_WEEK_FOOTER : false,
		HIDE_BLANK_WEEKS : false,
		NAV_ARROW_LEFT : YAHOO.widget.Calendar_Core.IMG_ROOT + "us/tr/callt.gif",
		NAV_ARROW_RIGHT : YAHOO.widget.Calendar_Core.IMG_ROOT + "us/tr/calrt.gif"
	};

	this.Options = this.Config.Options;

	this.customConfig();

	if (! this.Options.LOCALE_MONTHS) {
		this.Options.LOCALE_MONTHS=this.Locale.MONTHS_LONG;
	}
	if (! this.Options.LOCALE_WEEKDAYS) {
		this.Options.LOCALE_WEEKDAYS=this.Locale.WEEKDAYS_SHORT;
	}

	// If true, reconfigure weekday arrays to place Mondays first
	if (this.Options.START_WEEKDAY > 0) {
		for (var w=0;w<this.Options.START_WEEKDAY;++w) {
			this.Locale.WEEKDAYS_SHORT.push(this.Locale.WEEKDAYS_SHORT.shift());
			this.Locale.WEEKDAYS_MEDIUM.push(this.Locale.WEEKDAYS_MEDIUM.shift());
			this.Locale.WEEKDAYS_LONG.push(this.Locale.WEEKDAYS_LONG.shift());		
		}
	}
};

YAHOO.widget.Calendar_Core.prototype.customConfig = function() { };

YAHOO.widget.Calendar_Core.prototype.buildMonthLabel = function() {
	var text = this.Options.LOCALE_MONTHS[this.pageDate.getUTCMonth()] + " " + this.pageDate.getUTCFullYear();
	return text;
};

YAHOO.widget.Calendar_Core.prototype.buildDayLabel = function(workingDate) {
	var day = workingDate.getUTCDate();
	return day;
};



YAHOO.widget.Calendar_Core.prototype.buildShell = function() {
	
	this.table = document.createElement("TABLE");
	this.table.cellSpacing = 0;	
	YAHOO.widget.Calendar_Core.setCssClasses(this.table, [this.Style.CSS_CALENDAR]);

	this.table.id = this.id;
	
	this.buildShellHeader();
	this.buildShellBody();
	this.buildShellFooter();
	
	YAHOO.util.Event.addListener(window, "unload", this._unload, this);
};

/**
* Builds the calendar shell header by inserting a THEAD into the local calendar table.
*/
YAHOO.widget.Calendar_Core.prototype.buildShellHeader = function() {
	var head = document.createElement("THEAD");
	var headRow = document.createElement("TR");

	var headerCell = document.createElement("TH");
	
	var colSpan = 7;
	if (this.Config.Options.SHOW_WEEK_HEADER) {
		this.weekHeaderCells = new Array();
		colSpan += 1;
	}
	if (this.Config.Options.SHOW_WEEK_FOOTER) {
		this.weekFooterCells = new Array();
		colSpan += 1;
	}	
	
	headerCell.colSpan = colSpan;
	
	YAHOO.widget.Calendar_Core.setCssClasses(headerCell,[this.Style.CSS_HEADER_TEXT]);

	this.headerCell = headerCell;

	headRow.appendChild(headerCell);
	head.appendChild(headRow);

	// Append day labels, if needed
	if (this.Options.SHOW_WEEKDAYS) {
		var row = document.createElement("TR");
		var fillerCell;

		YAHOO.widget.Calendar_Core.setCssClasses(row,[this.Style.CSS_WEEKDAY_ROW]);
		
		if (this.Config.Options.SHOW_WEEK_HEADER) {
			fillerCell = document.createElement("TH");
			YAHOO.widget.Calendar_Core.setCssClasses(fillerCell,[this.Style.CSS_WEEKDAY_CELL]);
			row.appendChild(fillerCell);
		}
		
		for(var i=0;i<this.Options.LOCALE_WEEKDAYS.length;++i) {
			var cell = document.createElement("TH");
			YAHOO.widget.Calendar_Core.setCssClasses(cell,[this.Style.CSS_WEEKDAY_CELL]);
			cell.innerHTML=this.Options.LOCALE_WEEKDAYS[i];
			row.appendChild(cell);
		}

		if (this.Config.Options.SHOW_WEEK_FOOTER) {
			fillerCell = document.createElement("TH");
			YAHOO.widget.Calendar_Core.setCssClasses(fillerCell,[this.Style.CSS_WEEKDAY_CELL]);
			row.appendChild(fillerCell);
		}
				
		head.appendChild(row);
	}

	this.table.appendChild(head);
};

/**
* Builds the calendar shell body (6 weeks by 7 days)
*/
YAHOO.widget.Calendar_Core.prototype.buildShellBody = function() {
	// This should only get executed once
	this.tbody = document.createElement("TBODY");

	for (var r=0;r<6;++r) {
		var row = document.createElement("TR");
		
		for (var c=0;c<this.headerCell.colSpan;++c) {
			var cell;
			if (this.Config.Options.SHOW_WEEK_HEADER && c===0) { // Row header
				cell = document.createElement("TH");
				this.weekHeaderCells[this.weekHeaderCells.length] = cell;
			} else if (this.Config.Options.SHOW_WEEK_FOOTER && c==(this.headerCell.colSpan-1)){ // Row footer
				cell = document.createElement("TH");
				this.weekFooterCells[this.weekFooterCells.length] = cell;
			} else {
				cell = document.createElement("TD");
				this.cells[this.cells.length] = cell;
				YAHOO.widget.Calendar_Core.setCssClasses(cell, [this.Style.CSS_CELL]);
				YAHOO.util.Event.addListener(cell, "click", this.doSelectCell, this);

				YAHOO.util.Event.addListener(cell, "mouseover", this.doCellMouseOver, this);
				YAHOO.util.Event.addListener(cell, "mouseout", this.doCellMouseOut, this);
			}
			row.appendChild(cell);
		}
		this.tbody.appendChild(row);
	}
	
	this.table.appendChild(this.tbody);
};

YAHOO.widget.Calendar_Core.prototype.buildShellFooter = function() { };

YAHOO.widget.Calendar_Core.prototype.renderShell = function() {
	this.oDomContainer.appendChild(this.table);
	this.shellRendered = true;
};

YAHOO.widget.Calendar_Core.prototype.render = function() {
	if (! this.shellRendered) {
		this.buildShell();
		this.renderShell();
	}

	this.resetRenderers();

	this.cellDates.length = 0;

	// Find starting day of the current month
	var workingDate = YAHOO.widget.DateMath.findMonthStart(this.pageDate);

	this.renderHeader();
	this.renderBody(workingDate);
	this.renderFooter();

	this.onRender();
};



/**
* Appends the header contents into the widget header.
*/
YAHOO.widget.Calendar_Core.prototype.renderHeader = function() {
	this.headerCell.innerHTML = "";
	
	var headerContainer = document.createElement("DIV");
	headerContainer.className = this.Style.CSS_HEADER;
	
	headerContainer.appendChild(document.createTextNode(this.buildMonthLabel()));
	
	this.headerCell.appendChild(headerContainer);
};

YAHOO.widget.Calendar_Core.prototype.renderBody = function(workingDate) {

	this.preMonthDays = workingDate.getUTCDay();
	if (this.Options.START_WEEKDAY > 0) {
		this.preMonthDays -= this.Options.START_WEEKDAY;
	}
	if (this.preMonthDays < 0) {
		this.preMonthDays += 7;
	}
	
	this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getUTCDate();
	this.postMonthDays = YAHOO.widget.Calendar_Core.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
	
	workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
	
	var weekRowIndex = 0;
	
	for (var c=0;c<this.cells.length;++c) {
		var cellRenderers = new Array();
		
		var cell = this.cells[c];
		this.clearElement(cell);

		cell.index = c;
		cell.id = this.id + "_cell" + c;
		
		this.cellDates[this.cellDates.length]=[workingDate.getUTCFullYear(),workingDate.getUTCMonth()+1,workingDate.getUTCDate()]; // Add this date to cellDates

		if (workingDate.getUTCDay() == this.Options.START_WEEKDAY) {
			var rowHeaderCell = null;
			var rowFooterCell = null;
			
			if (this.Options.SHOW_WEEK_HEADER) {
				rowHeaderCell = this.weekHeaderCells[weekRowIndex];
				this.clearElement(rowHeaderCell);
			}
			
			if (this.Options.SHOW_WEEK_FOOTER) {
				rowFooterCell = this.weekFooterCells[weekRowIndex];
				this.clearElement(rowFooterCell);
			}			
			
			if (this.Options.HIDE_BLANK_WEEKS && this.isDateOOM(workingDate) && ! YAHOO.widget.DateMath.isMonthOverlapWeek(workingDate)) {
				// The first day of the week is not in this month, and it's not an overlap week
				continue;
			} else {
				if (rowHeaderCell) {
					this.renderRowHeader(workingDate, rowHeaderCell);
				}
				if (rowFooterCell) {
					this.renderRowFooter(workingDate, rowFooterCell);
				}	
			}
		}

		

		var renderer = null;
		
		if (workingDate.getUTCFullYear()	== this.today.getUTCFullYear() &&
			workingDate.getUTCMonth()		== this.today.getUTCMonth() &&
			workingDate.getUTCDate()		== this.today.getUTCDate()) {
			cellRenderers[cellRenderers.length]=this.renderCellStyleToday;
		}
		
		if (this.isDateOOM(workingDate)) {
			cellRenderers[cellRenderers.length]=this.renderCellNotThisMonth;
		} else {
			for (var r=0;r<this.renderStack.length;++r) {
				var rArray = this.renderStack[r];
				var type = rArray[0];
				
				var month;
				var day;
				var year;

				switch (type) {
					case YAHOO.widget.Calendar_Core.DATE:
						month = rArray[1][1];
						day = rArray[1][2];
						year = rArray[1][0];

						if (workingDate.getUTCMonth()+1 == month && workingDate.getUTCDate() == day && workingDate.getUTCFullYear() == year) {
							renderer = rArray[2];
							this.renderStack.splice(r,1);
						}
						break;
					case YAHOO.widget.Calendar_Core.MONTH_DAY:
						month = rArray[1][0];
						day = rArray[1][1];
						
						if (workingDate.getUTCMonth()+1 == month && workingDate.getUTCDate() == day) {
							renderer = rArray[2];
							this.renderStack.splice(r,1);
						}
						break;
					case YAHOO.widget.Calendar_Core.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(Date.UTC(d1year, d1month-1, d1day));

						var d2month = date2[1];
						var d2day = date2[2];
						var d2year = date2[0];

						var d2 = new Date(Date.UTC(d2year, d2month-1, d2day));

						if (Date.UTC(workingDate) >= Date.UTC(d1) && Date.UTC(workingDate) <= Date.UTC(d2)) {
							renderer = rArray[2];

							if (Date.UTC(workingDate)==Date.UTC(d2)) { 
								this.renderStack.splice(r,1);
							}
						}
						break;
					case YAHOO.widget.Calendar_Core.WEEKDAY:
						
						var weekday = rArray[1][0];
						if (workingDate.getUTCDay()+1 == weekday) {
							renderer = rArray[2];
						}
						break;
					case YAHOO.widget.Calendar_Core.MONTH:
						
						month = rArray[1][0];
						if (workingDate.getUTCMonth()+1 == month) {
							renderer = rArray[2];
						}
						break;
				}
				
				if (renderer) {
					cellRenderers[cellRenderers.length]=renderer;
				}
			}

		}

		if (this._indexOfSelectedFieldArray([workingDate.getUTCFullYear(),workingDate.getUTCMonth()+1,workingDate.getUTCDate()]) > -1) {
			cellRenderers[cellRenderers.length]=this.renderCellStyleSelected; 
		}

		if (this.minDate) {
			this.minDate = YAHOO.widget.DateMath.clearTime(this.minDate);
		}
		if (this.maxDate) {
			this.maxDate = YAHOO.widget.DateMath.clearTime(this.maxDate);
		}

		if (
			(this.minDate && (workingDate.getTime() < this.minDate.getTime())) ||
			(this.maxDate && (workingDate.getTime() > this.maxDate.getTime()))
		) {
			cellRenderers[cellRenderers.length]=this.renderOutOfBoundsDate;
		} else {
			cellRenderers[cellRenderers.length]=this.renderCellDefault;	
		}
		
		for (var x=0;x<cellRenderers.length;++x) {
			var ren = cellRenderers[x];
			if (ren.call(this,workingDate,cell) == YAHOO.widget.Calendar_Core.STOP_RENDER) {
				break;
			}
		}
		
		workingDate = YAHOO.widget.DateMath.add(workingDate, YAHOO.widget.DateMath.DAY, 1); // Go to the next day
		if (workingDate.getUTCDay() == this.Options.START_WEEKDAY) {
			weekRowIndex += 1;
		}

		YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL);

		if (c >= 0 && c <= 6) {
			YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
		}
		if ((c % 7) == 0) {
			YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
		}
		if (((c+1) % 7) == 0) {
			YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
		}
		
		var postDays = this.postMonthDays; 
		if (postDays >= 7 && this.Options.HIDE_BLANK_WEEKS) {
			var blankWeeks = Math.floor(postDays/7);
			for (var p=0;p<blankWeeks;++p) {
				postDays -= 7;
			}
		}
		
		if (c >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
			YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
		}
	}
		
};

YAHOO.widget.Calendar_Core.prototype.renderFooter = function() { };
YAHOO.widget.Calendar_Core.prototype._unload = function(e, cal) {
	for (var c in cal.cells) {
		c = null;
	}
	
	cal.cells = null;
	
	cal.tbody = null;
	cal.oDomContainer = null;
	cal.table = null;
	cal.headerCell = null;
	
	cal = null;
};
												  
												  

YAHOO.widget.Calendar_Core.prototype.renderOutOfBoundsDate = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOB);
	cell.innerHTML = workingDate.getUTCDate();
	return YAHOO.widget.Calendar_Core.STOP_RENDER;
}

YAHOO.widget.Calendar_Core.prototype.renderRowHeader = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_ROW_HEADER);
	
	var useYear = this.pageDate.getUTCFullYear();
	
	if (! YAHOO.widget.DateMath.isYearOverlapWeek(workingDate)) {
		useYear = workingDate.getUTCFullYear();
	}
	
	var weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useYear, this.Options.START_WEEKDAY);
	cell.innerHTML = weekNum;
	
	if (this.isDateOOM(workingDate) && ! YAHOO.widget.DateMath.isMonthOverlapWeek(workingDate)) {
		YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);	
	}
};

YAHOO.widget.Calendar_Core.prototype.renderRowFooter = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_ROW_FOOTER);
	
	if (this.isDateOOM(workingDate) && ! YAHOO.widget.DateMath.isMonthOverlapWeek(workingDate)) {
		YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);	
	}
};

YAHOO.widget.Calendar_Core.prototype.renderCellDefault = function(workingDate, cell) {
	cell.innerHTML = "";
	var link = document.createElement("a");

	link.href="javascript:void(null);";
	link.name=this.id+"__"+workingDate.getUTCFullYear()+"_"+(workingDate.getUTCMonth()+1)+"_"+workingDate.getUTCDate();

	link.appendChild(document.createTextNode(this.buildDayLabel(workingDate)));
	cell.appendChild(link);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleHighlight1 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT1);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleHighlight2 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT2);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleHighlight3 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT3);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleHighlight4 = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_HIGHLIGHT4);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleToday = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TODAY);
};

YAHOO.widget.Calendar_Core.prototype.renderCellStyleSelected = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_SELECTED);
};

YAHOO.widget.Calendar_Core.prototype.renderCellNotThisMonth = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_OOM);
	cell.innerHTML=workingDate.getUTCDate();
	return YAHOO.widget.Calendar_Core.STOP_RENDER;
};

YAHOO.widget.Calendar_Core.prototype.renderBodyCellRestricted = function(workingDate, cell) {
	YAHOO.widget.Calendar_Core.setCssClasses(cell, [this.Style.CSS_CELL,this.Style.CSS_CELL_RESTRICTED]);
	cell.innerHTML=workingDate.getUTCDate();
	return YAHOO.widget.Calendar_Core.STOP_RENDER;
};
YAHOO.widget.Calendar_Core.prototype.addMonths = function(count) {
	this.pageDate = YAHOO.widget.DateMath.add(this.pageDate, YAHOO.widget.DateMath.MONTH, count);
	this.resetRenderers();
	this.onChangePage();
};

YAHOO.widget.Calendar_Core.prototype.subtractMonths = function(count) {
	this.pageDate = YAHOO.widget.DateMath.subtract(this.pageDate, YAHOO.widget.DateMath.MONTH, count);
	this.resetRenderers();
	this.onChangePage();
};

YAHOO.widget.Calendar_Core.prototype.addYears = function(count) {
	this.pageDate = YAHOO.widget.DateMath.add(this.pageDate, YAHOO.widget.DateMath.YEAR, count);
	this.resetRenderers();
	this.onChangePage();
};

YAHOO.widget.Calendar_Core.prototype.subtractYears = function(count) {
	this.pageDate = YAHOO.widget.DateMath.subtract(this.pageDate, YAHOO.widget.DateMath.YEAR, count);
	this.resetRenderers();
	this.onChangePage();
};

YAHOO.widget.Calendar_Core.prototype.nextMonth = function() {
	this.addMonths(1);
};

YAHOO.widget.Calendar_Core.prototype.previousMonth = function() {
	this.subtractMonths(1);
};

YAHOO.widget.Calendar_Core.prototype.nextYear = function() {
	this.addYears(1);
};

YAHOO.widget.Calendar_Core.prototype.previousYear = function() {
	this.subtractYears(1);
};

YAHOO.widget.Calendar_Core.prototype.reset = function() {
	this.selectedDates.length = 0;
	this.selectedDates = this._selectedDates.concat();

	this.pageDate = new Date(this._pageDate.toUTCString());
	this.onReset();
};

YAHOO.widget.Calendar_Core.prototype.clear = function() {
	this.selectedDates.length = 0;
	this.pageDate = new Date(this.today.toUTCString());
	this.onClear();
};

YAHOO.widget.Calendar_Core.prototype.select = function(date) {
	this.onBeforeSelect();

	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?
			this.selectedDates[this.selectedDates.length]=toSelect;
		}
	}
	
	if (this.parent) {
		this.parent.sync(this);
	}

	this.onSelect(aToBeSelected);

	return this.getSelectedDates();
};

YAHOO.widget.Calendar_Core.prototype.selectCell = function(cellIndex) {
	this.onBeforeSelect();

	this.cells = this.tbody.getElementsByTagName("TD");

	var cell = this.cells[cellIndex];
	var cellDate = this.cellDates[cellIndex];

	var dCellDate = this._toDate(cellDate);

	var selectDate = cellDate.concat();

	this.selectedDates.push(selectDate);
	
	if (this.parent) {
		this.parent.sync(this);
	}

	this.renderCellStyleSelected(dCellDate,cell);

	this.onSelect([selectDate]);
	this.doCellMouseOut.call(cell, null, this);

	return this.getSelectedDates();
};

YAHOO.widget.Calendar_Core.prototype.deselect = function(date) {
	this.onBeforeDeselect();

	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) {	
			this.selectedDates.splice(index,1);
		}
	}

	if (this.parent) {
		this.parent.sync(this);
	} 

	this.onDeselect(aToBeSelected);
	return this.getSelectedDates();
};

YAHOO.widget.Calendar_Core.prototype.deselectCell = function(i) {
	this.onBeforeDeselect();
	this.cells = this.tbody.getElementsByTagName("TD");

	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.pageDate.getUTCMonth() == dCellDate.getUTCMonth() &&
			this.pageDate.getUTCFullYear() == dCellDate.getUTCFullYear()) {
			YAHOO.util.Dom.removeClass(cell, this.Style.CSS_CELL_SELECTED);
		}

		this.selectedDates.splice(cellDateIndex, 1);
	}


	if (this.parent) {
		this.parent.sync(this);
	}

	this.onDeselect(selectDate);
	return this.getSelectedDates();
};

YAHOO.widget.Calendar_Core.prototype.deselectAll = function() {
	this.onBeforeDeselect();
	var count = this.selectedDates.length;
	var sel = this.selectedDates.concat();
	this.selectedDates.length = 0;

	if (this.parent) {
		this.parent.sync(this);
	}
	
	if (count > 0) {
		this.onDeselect(sel);
	}

	return this.getSelectedDates();
};
YAHOO.widget.Calendar_Core.prototype._toFieldArray = function(date) {
	var returnDate = new Array();

	if (date instanceof Date) {
		returnDate = [[date.getUTCFullYear(), date.getUTCMonth()+1, date.getUTCDate()]];
	} 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.getUTCFullYear(),d.getUTCMonth()+1,d.getUTCDate()];
		}
	}
	
	return returnDate;
};

YAHOO.widget.Calendar_Core.prototype._toDate = function(dateFieldArray) {
	if (dateFieldArray instanceof Date) {
		return dateFieldArray;
	} else {
		return new Date(Date.UTC(dateFieldArray[0],dateFieldArray[1]-1,dateFieldArray[2]));
	}
};
YAHOO.widget.Calendar_Core.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_Core.prototype._indexOfSelectedFieldArray = function(find) {
	var selected = -1;

	for (var s=0;s<this.selectedDates.length;++s) {
		var sArray = this.selectedDates[s];
		if (find[0]==sArray[0]&&find[1]==sArray[1]&&find[2]==sArray[2]) {
			selected = s;
			break;
		}
	}

	return selected;
};

YAHOO.widget.Calendar_Core.prototype.isDateOOM = function(date) {
	var isOOM = false;
	if (date.getUTCMonth() != this.pageDate.getUTCMonth()) {
		isOOM = true;
	}
	return isOOM;
};


YAHOO.widget.Calendar_Core.prototype.onBeforeSelect = function() {
	if (! this.Options.MULTI_SELECT) {
		this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);
		this.deselectAll();
	}
};

YAHOO.widget.Calendar_Core.prototype.onSelect = function(selected) { };

YAHOO.widget.Calendar_Core.prototype.onBeforeDeselect = function() { };

YAHOO.widget.Calendar_Core.prototype.onDeselect = function(deselected) { };

YAHOO.widget.Calendar_Core.prototype.onChangePage = function() {
		var me = this;

		this.renderHeader();
		if (this.renderProcId) {
			clearTimeout(this.renderProcId);
		}
		this.renderProcId = setTimeout(function() {
											me.render();
											me.renderProcId = null;
										}, 1);
};

YAHOO.widget.Calendar_Core.prototype.onRender = function() { };

YAHOO.widget.Calendar_Core.prototype.onReset = function() { this.render(); };

YAHOO.widget.Calendar_Core.prototype.onClear = function() { this.render(); };

YAHOO.widget.Calendar_Core.prototype.validate = function() { return true; };

YAHOO.widget.Calendar_Core.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_Core.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_Core.DATE;
	}
	return rArray;
};

YAHOO.widget.Calendar_Core.prototype._parseDates = function(sDates) {
	var aReturn = new Array();
	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_Core.prototype._parseRange = function(startDate, endDate) {
    var dStart   = new Date(Date.UTC(startDate[0],startDate[1]-1,startDate[2]));
    var dCurrent = YAHOO.widget.DateMath.add(new Date(Date.UTC(startDate[0],startDate[1]-1,startDate[2])),YAHOO.widget.DateMath.DAY,1);
    var dEnd     = new Date(Date.UTC(endDate[0],  endDate[1]-1,  endDate[2]));
   
	var results = new Array();
	results.push(startDate);
        while (Date.UTC(dCurrent) <= Date.UTC(dEnd)) {
		results.push([dCurrent.getUTCFullYear(),dCurrent.getUTCMonth()+1,dCurrent.getUTCDate()]);
		dCurrent = YAHOO.widget.DateMath.add(dCurrent,YAHOO.widget.DateMath.DAY,1);
	}
	return results;
};

YAHOO.widget.Calendar_Core.prototype.resetRenderers = function() {
	this.renderStack = this._renderStack.concat();
};

YAHOO.widget.Calendar_Core.prototype.clearElement = function(cell) {
	cell.innerHTML = "&nbsp;";
	cell.className="";
};

YAHOO.widget.Calendar_Core.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_Core.RANGE,aDate,fnRender);
			} else { // this is a month/day combo
				this._addRenderer(YAHOO.widget.Calendar_Core.MONTH_DAY,aDate,fnRender);
			}
		} else if (aDate.length == 3) {
			this._addRenderer(YAHOO.widget.Calendar_Core.DATE,aDate,fnRender);
		}
	}
};

YAHOO.widget.Calendar_Core.prototype._addRenderer = function(type, aDates, fnRender) {
	var add = [type,aDates,fnRender];	
	this.renderStack.unshift(add);	
	
	this._renderStack = this.renderStack.concat();
};

YAHOO.widget.Calendar_Core.prototype.addMonthRenderer = function(month, fnRender) {
	this._addRenderer(YAHOO.widget.Calendar_Core.MONTH,[month],fnRender);
};

YAHOO.widget.Calendar_Core.prototype.addWeekdayRenderer = function(weekday, fnRender) {
	this._addRenderer(YAHOO.widget.Calendar_Core.WEEKDAY,[weekday],fnRender);
};
YAHOO.widget.Calendar_Core.setCssClasses = function(element, aStyles) {
	element.className = "";
	var className = aStyles.join(" ");
	element.className = className;
};

YAHOO.widget.Calendar_Core.prototype.clearAllBodyCellStyles = function(style) {
	for (var c=0;c<this.cells.length;++c) {
		YAHOO.util.Dom.removeClass(this.cells[c],style);
	}
};

YAHOO.widget.Calendar_Core.prototype.setUTCMonth = function(month) {
	this.pageDate.setUTCMonth(month);
};

YAHOO.widget.Calendar_Core.prototype.setYear = function(year) {
	this.pageDate.setUTCFullYear(year);
};

YAHOO.widget.Calendar_Core.prototype.getSelectedDates = function() {
	var returnDates = new Array();

	for (var d=0;d<this.selectedDates.length;++d) {
		var dateArray = this.selectedDates[d];

		var date = new Date(Date.UTC(dateArray[0],dateArray[1]-1,dateArray[2]));
		returnDates.push(date);
	}

	returnDates.sort();
	return returnDates;
};
YAHOO.widget.Calendar_Core._getBrowser = 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')!=-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_Core.prototype.toString = function() {
	return "Calendar_Core " + this.id;
}

YAHOO.widget.Cal_Core = YAHOO.widget.Calendar_Core;
YAHOO.widget.Calendar = function(id, containerId, monthyear, selected) {
	if (arguments.length > 0) {
		this.init(id, containerId, monthyear, selected);
	}
}

YAHOO.widget.Calendar.prototype = new YAHOO.widget.Calendar_Core();

YAHOO.widget.Calendar.prototype.buildShell = function() {
	this.border = document.createElement("DIV");
	this.border.className =  this.Style.CSS_CONTAINER;
	
	this.table = document.createElement("TABLE");
	this.table.cellSpacing = 0;	
	
	YAHOO.widget.Calendar_Core.setCssClasses(this.table, [this.Style.CSS_CALENDAR]);

	this.border.id = this.id;
	
	this.buildShellHeader();
	this.buildShellBody();
	this.buildShellFooter();
};

YAHOO.widget.Calendar.prototype.renderShell = function() {
	this.border.appendChild(this.table);
	this.oDomContainer.appendChild(this.border);
	this.shellRendered = true;
};

YAHOO.widget.Calendar.prototype.renderHeader = function() {
	this.headerCell.innerHTML = "";
	
	var headerContainer = document.createElement("DIV");
	headerContainer.className = this.Style.CSS_HEADER;
	
	if (this.linkLeft) {
		YAHOO.util.Event.removeListener(this.linkLeft, "mousedown", this.previousMonth);
	}
	this.linkLeft = document.createElement("A");
	this.linkLeft.innerHTML = "&nbsp;";
	YAHOO.util.Event.addListener(this.linkLeft, "mousedown", this.previousMonth, this, true);
	//this.linkLeft.style.backgroundImage =  "url(" + this.Options.NAV_ARROW_LEFT + ")";
	this.linkLeft.className = this.Style.CSS_NAV_LEFT;
	
	if (this.linkRight) {
		YAHOO.util.Event.removeListener(this.linkRight, "mousedown", this.nextMonth);
	}
	this.linkRight = document.createElement("A");
	this.linkRight.innerHTML = "&nbsp;";
	YAHOO.util.Event.addListener(this.linkRight, "mousedown", this.nextMonth, this, true);
//	this.linkRight.style.backgroundImage = "url(" + this.Options.NAV_ARROW_RIGHT + ")";  /* remove for wct use */
	this.linkRight.className = this.Style.CSS_NAV_RIGHT;
	
	headerContainer.appendChild(this.linkLeft);
	headerContainer.appendChild(document.createTextNode(this.buildMonthLabel()));
	headerContainer.appendChild(this.linkRight);
	
	this.headerCell.appendChild(headerContainer);
};

YAHOO.widget.Cal = YAHOO.widget.Calendar;
YAHOO.widget.CalendarGroup = function(pageCount, id, containerId, monthyear, selected) {
	if (arguments.length > 0) {
		this.init(pageCount, id, containerId, monthyear, selected);
	}
}

YAHOO.widget.CalendarGroup.prototype.init = function(pageCount, id, containerId, monthyear, selected) {
	this.id = id;
	this.selectedDates = new Array();
	this.containerId = containerId;
	
	this.pageCount = pageCount;

	this.pages = new Array();

	for (var p=0;p<pageCount;++p) {
		var cal = this.constructChild(id + "_" + p, this.containerId + "_" + p , monthyear, selected);
				
		cal.parent = this;
		
		cal.index = p;

		cal.pageDate.setUTCMonth(cal.pageDate.getUTCMonth()+p);
		cal._pageDate = new Date(Date.UTC(cal.pageDate.getUTCFullYear(),cal.pageDate.getUTCMonth(),cal.pageDate.getUTCDate()));
		this.pages.push(cal);
	}
	
	this.sync();

	this.doNextMonth = function(e, calGroup) {
		calGroup.nextMonth();
	};
	
	this.doPreviousMonth = function(e, calGroup) {
		calGroup.previousMonth();
	};
};

YAHOO.widget.CalendarGroup.prototype.setChildFunction = function(fnName, fn) {
	for (var p=0;p<this.pageCount;++p) {
		this.pages[p][fnName] = fn;
	}
}

YAHOO.widget.CalendarGroup.prototype.callChildFunction = function(fnName, args) {	
	for (var p=0;p<this.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,monthyear,selected) {
	return new YAHOO.widget.Calendar_Core(id,containerId,monthyear,selected);
};


YAHOO.widget.CalendarGroup.prototype.setUTCMonth = function(month) {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal.setUTCMonth(month+p);
	}
};

YAHOO.widget.CalendarGroup.prototype.minDate = function(date) {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal.minDate=date;
	}
};


YAHOO.widget.CalendarGroup.prototype.setYear = function(year) {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		if ((cal.pageDate.getUTCMonth()+1) == 1 && p>0)
		{
			year+=1;
		}
		cal.setYear(year);
	}
};

YAHOO.widget.CalendarGroup.prototype.render = function() {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal.render();
	}
};

YAHOO.widget.CalendarGroup.prototype.select = function(date) {
	var ret;
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		ret = cal.select(date);
	}
	return ret;
};

YAHOO.widget.CalendarGroup.prototype.selectCell = function(cellIndex) {
	var ret;
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		ret = cal.selectCell(cellIndex);
	}
	return ret;
};

YAHOO.widget.CalendarGroup.prototype.deselect = function(date) {
	var ret;
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		ret = cal.deselect(date);
	}
	return ret;
};

YAHOO.widget.CalendarGroup.prototype.deselectAll = function() {
	var ret;
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		ret = cal.deselectAll();
	}
	return ret;
};

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.sync = function(caller) {
	var calendar;

	if (caller)
	{
		this.selectedDates = caller.selectedDates.concat();
	} else {
		var hash = new Object();
		var combinedDates = new Array();

		for (var p=0;p<this.pages.length;++p)
		{
			calendar = this.pages[p];

			var values = calendar.selectedDates;

			for (var v=0;v<values.length;++v)
			{
				var valueArray = values[v];
				hash[valueArray.toString()] = valueArray;
			}
		}

		for (var val in hash)
		{
			combinedDates[combinedDates.length]=hash[val];
		}
		
		this.selectedDates = combinedDates.concat();
	}

	// Set all the values into the children
	for (p=0;p<this.pages.length;++p)
	{
		calendar = this.pages[p];
		if (! calendar.Options.MULTI_SELECT) {
			calendar.clearAllBodyCellStyles(calendar.Config.Style.CSS_CELL_SELECTED);
		}
		calendar.selectedDates = this.selectedDates.concat();
		
	}
	
	return this.getSelectedDates();
};

YAHOO.widget.CalendarGroup.prototype.getSelectedDates = function() { 
	var returnDates = new Array();

	for (var d=0;d<this.selectedDates.length;++d)
	{
		var dateArray = this.selectedDates[d];

		var date = new Date(Date.UTC(dateArray[0],dateArray[1]-1,dateArray[2]));
		returnDates.push(date);
	}

	returnDates.sort();
	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.wireEvent = function(eventName, fn) {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal[eventName] = fn;
	}
};

YAHOO.widget.CalendarGroup.prototype.toString = function() {
	return "CalendarGroup " + this.id;
}

YAHOO.widget.CalGrp = YAHOO.widget.CalendarGroup;
YAHOO.widget.Calendar2up_Cal = function(id, containerId, monthyear, selected) {
	if (arguments.length > 0)
	{
		this.init(id, containerId, monthyear, selected);
	}
}

YAHOO.widget.Calendar2up_Cal.prototype = new YAHOO.widget.Calendar_Core();

YAHOO.widget.Calendar2up_Cal.prototype.renderHeader = function() {
	this.headerCell.innerHTML = "";
	
	var headerContainer = document.createElement("DIV");
	headerContainer.className = this.Style.CSS_HEADER;
	
	if (this.index == 0) {

		if (this.linkLeft) {
			YAHOO.util.Event.removeListener(this.linkLeft, "mousedown", this.parent.doPreviousMonth);
		}
		this.linkLeft = document.createElement("A");
		this.linkLeft.innerHTML = "&nbsp;";
		// this.linkLeft.style.backgroundImage =  "url(" + this.Options.NAV_ARROW_LEFT + ")"; /* remove for wct use */
		this.linkLeft.className = this.Style.CSS_NAV_LEFT;
		
		YAHOO.util.Event.addListener(this.linkLeft, "mousedown", this.parent.doPreviousMonth, this.parent);
		headerContainer.appendChild(this.linkLeft);
	}
	
	headerContainer.appendChild(document.createTextNode(this.buildMonthLabel()));
	
	if (this.index == 1) {

		if (this.linkRight) {
			YAHOO.util.Event.removeListener(this.linkRight, "mousedown", this.parent.doNextMonth);
		}
		this.linkRight = document.createElement("A");
		this.linkRight.innerHTML = "&nbsp;";
		// this.linkRight.style.backgroundImage = "url(" + this.Options.NAV_ARROW_RIGHT + ")"; /* remove for WCT use */
		this.linkRight.className = this.Style.CSS_NAV_RIGHT;

		YAHOO.util.Event.addListener(this.linkRight, "mousedown", this.parent.doNextMonth, this.parent);
		headerContainer.appendChild(this.linkRight);
	}
	
	this.headerCell.appendChild(headerContainer);
};


YAHOO.widget.Calendar2up = function(id, containerId, monthyear, selected) {
	if (arguments.length > 0)
	{	
		this.buildWrapper(containerId);
		this.init(2, id, containerId, monthyear, selected);
	}
}

YAHOO.widget.Calendar2up.prototype = new YAHOO.widget.CalendarGroup();

YAHOO.widget.Calendar2up.CSS_2UPWRAPPER = "cal2upwrapper";

YAHOO.widget.Calendar2up.CSS_CONTAINER = "calcontainer";

YAHOO.widget.Calendar2up.CSS_2UPCONTAINER = "cal2up";

YAHOO.widget.Calendar2up.CSS_2UPTITLE = "title";

YAHOO.widget.Calendar2up.CSS_2UPCLOSE = "close-icon";

YAHOO.widget.Calendar2up.prototype.constructChild = function(id,containerId,monthyear,selected) {
	var cal = new YAHOO.widget.Calendar2up_Cal(id,containerId,monthyear,selected);
	return cal;
};

YAHOO.widget.Calendar2up.prototype.buildWrapper = function(containerId) {
	var outerContainer = document.getElementById(containerId);
	
	outerContainer.className = YAHOO.widget.Calendar2up.CSS_2UPWRAPPER;
	
	var innerContainer = document.createElement("DIV");
	innerContainer.className = YAHOO.widget.Calendar2up.CSS_CONTAINER;
	innerContainer.id = containerId + "_inner";
	
	var cal1Container = document.createElement("DIV");
	cal1Container.id = containerId + "_0";
	cal1Container.className = YAHOO.widget.Calendar2up.CSS_2UPCONTAINER;
	cal1Container.style.marginRight = "10px";
	
	var cal2Container = document.createElement("DIV");
	cal2Container.id = containerId + "_1"; 
	cal2Container.className = YAHOO.widget.Calendar2up.CSS_2UPCONTAINER;
	
	outerContainer.appendChild(innerContainer);
	innerContainer.appendChild(cal1Container);
	innerContainer.appendChild(cal2Container);
	
	this.innerContainer = innerContainer;
	this.outerContainer = outerContainer;
}

YAHOO.widget.Calendar2up.prototype.render = function() {
	this.renderHeader();
	YAHOO.widget.CalendarGroup.prototype.render.call(this);
	this.renderFooter();
};

YAHOO.widget.Calendar2up.prototype.renderHeader = function() {
	if (! this.title) {
		this.title = "";
	}
	if (! this.titleDiv)
	{
		this.titleDiv = document.createElement("DIV");
		if (this.title == "")
		{
			this.titleDiv.style.display="none";
		}
	}

	this.titleDiv.className = YAHOO.widget.Calendar2up.CSS_2UPTITLE;
	this.titleDiv.innerHTML = this.title;

	if (this.outerContainer.style.position == "absolute")
	{
		var linkClose = document.createElement("A");
		linkClose.href = "javascript:void(null)";
		YAHOO.util.Event.addListener(linkClose, "click", this.hide, this);

		var imgClose = document.createElement("IMG");
		imgClose.src = YAHOO.widget.Calendar_Core.IMG_ROOT + "/cal/2/images/x_d.gif";
		imgClose.className = YAHOO.widget.Calendar2up.CSS_2UPCLOSE;

		linkClose.appendChild(imgClose);

		this.linkClose = linkClose;

		this.titleDiv.appendChild(linkClose);
	}

	if (this.titleDiv != this.innerContainer.firstChild) {
		this.innerContainer.insertBefore(this.titleDiv, this.innerContainer.firstChild);
	}
}

YAHOO.widget.Calendar2up.prototype.hide = function(e, cal) {
	if (! cal)
	{
		cal = this;
	}
	cal.outerContainer.style.display = "none";
}

YAHOO.widget.Calendar2up.prototype.renderFooter = function() {}

YAHOO.widget.Cal2up = YAHOO.widget.Calendar2up;

/***************************** WCT custom function **************************/

YAHOO.widget.Calendar2up.prototype.setParent = function(p)
{
	this.parentMain = p;  // stores wct calendar reference
}

YAHOO.widget.Calendar.prototype.setParent = function(p)
{
	this.parentMain = p;  // stores wct calendar reference
}



YAHOO.widget.Calendar_Core.prototype.removeRenderer = 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._removeRenderer(YAHOO.widget.Calendar_Core.RANGE,aDate,fnRender);
			} else { // this is a month/day combo
				this._removeRenderer(YAHOO.widget.Calendar_Core.MONTH_DAY,aDate,fnRender);
			}
		} else if (aDate.length == 3) {
			this._removeRenderer(YAHOO.widget.Calendar_Core.DATE,aDate,fnRender);
		}
	}
};

YAHOO.widget.Calendar_Core.prototype._removeRenderer = function(type, aDates, fnRender) {
	var remove = [type,aDates,fnRender];
	var searchIndex = this.renderStack.contains(remove);
	if(searchIndex != "undefined")
	{
		this.renderStack.splice(searchIndex,1);	
		this._renderStack = this.renderStack.concat();
	}
};

YAHOO.widget.CalendarGroup.prototype.removeRenderer = function(sDates, fnRender) {
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal.removeRenderer(sDates, fnRender);
	}
};


YAHOO.widget.Calendar_Core.prototype.clearRenderer = function(){
	delete this.renderStack;
	delete this._renderStack;
	
	this.renderStack = new Array();
	this._renderStack = new Array();	
}

YAHOO.widget.CalendarGroup.prototype.clearRenderer = function(){
	for (var p=0;p<this.pages.length;++p)
	{
		var cal = this.pages[p];
		cal.clearRenderer();
	}		
}

YAHOO.widget.Calendar_Core.prototype.isMaxDateReached = function(){
	return (this.pageDate.getUTCTime() == this.maxDate.getUTCTime());
}

YAHOO.widget.CalendarGroup.prototype.isMaxDateReached = function(){
		var cal = this.pages[1];
		return cal.isMaxDateReached();
}


		YAHOO.widget.Calendar_Itnl_Cal = function(id, containerId, monthyear, selected) {
			if (arguments.length > 0)
			{
				this.init(id, containerId, monthyear, selected);
			}
		}

		YAHOO.widget.Calendar_Itnl_Cal.prototype = new YAHOO.widget.Calendar();


var WCT = {};
returnDate= "undefined";
var over_cal = false;  // variable to determine if mouse is over calendar container

WCT.calendar = function (id,container,parentContainerId,dateInput,type) 
{
	if (arguments.length > 0)
	{
		var defaultSelectedDate = null;
		
		if(type){
			var calType = type.toLowerCase();
			if(calType == "doa" || calType == "dod")
			{
				this.calType = calType;
			}
		}
		
		if (parentContainerId)
		{
			if (typeof (parentContainerId) != "object")
			{
				this.parentContainerId = document.getElementById(parentContainerId);
			}
			else
			{			
				this.parentContainerId = parentContainerId;
			}
		}

		if (dateInput)
		{			
			if (typeof (dateInput) != "object")
			{
				this.dateInput = document.getElementById(dateInput);
			}
			else
			{			
				this.dateInput = dateInput;
			}	
		}
	
		this.today = new Date();


		YAHOO.widget.Calendar2up_CU_Cal = function(id, containerId, monthyear, selected) {
			if (arguments.length > 0)
			{
				this.init(id, containerId, monthyear, selected);
			}
		}

		YAHOO.widget.Calendar2up_CU_Cal.prototype = new YAHOO.widget.Calendar2up_Cal();


		YAHOO.widget.Calendar2up_Itnl_Custom = function(id, containerId, monthyear, selected) {
			if (arguments.length > 0)
			{	
				this.buildWrapper(containerId);
				this.init(2, id, containerId, monthyear, selected);
			}
		}

		YAHOO.widget.Calendar2up_Itnl_Custom.prototype = new YAHOO.widget.Calendar2up();

		YAHOO.widget.Calendar2up_Itnl_Custom.prototype.constructChild = function(id,containerId,monthyear,selected) {
			var cal = new YAHOO.widget.Calendar2up_CU_Cal(id,containerId,monthyear,selected);
			return cal;
		};

		this.wctinit(id,container);
	}
}

WCT.calendar.prototype.wctinit = function(id, container, monthyear, selected)
{
	if(arguments.length >0)
	{
		var maxDate = YAHOO.widget.DateMath.add(new Date(), YAHOO.widget.DateMath.DAY, 330);
		this.cal = new YAHOO.widget.Calendar_Itnl_Cal("WCT.calendar."+id,container);		
		this.calClass = this.cal.toString();
		if(this.calClass.match("Calendar_Core"))
		{
			this.cal.minDate=new Date();
			this.cal.maxDate=maxDate;			
			this.cal.onSelect = this.selectedDate;
		}
		else{			
			this.minDate(new Date());
			this.maxDate(maxDate);
			this.cal.setChildFunction("onSelect",this.selectedDate);
		}
		
		this.cal.setParent(this);
		this.cal.render();	
		this.prevRenderer = new Array();
		this.dateFormat = "US";
	}
}


WCT.calendar.prototype.showCalendar = function (hideCalendar,el){
	
	// hideCalendar can be type of Array, single calendar object, or string.  This is the calendar that you want to hide.
	// displayCalendar is a single calendar object to display. 	
	if (typeof(hideCalendar.length) == "number")
	{	
		var index = 0;
		for (index=0; index <hideCalendar.length; index++)
		{
			var calObj;
			if (typeof(hideCalendar[index]) == "object")
			{
				calObj = hideCalendar[index];
			}
			else if (typeof(hideCalendar[index]) == "string")
			{
				calObj = document.getElementById(hideCalendar[index]);
			}
			try
			{
				calObj.hideCal();
			}
			catch(e){};
		}
	}
	else if (typeof(hideCalendar) == "object")
	{
		hideCalendar.hideCal();
	}	
	
	if(el)
	{
		
		var pos = YAHOO.util.Dom.getXY(el);
		returnDate=this.dateInput;
		
		//pre-select the calendar if there is a date in the input field
                if(this.dateInput.value.toLowerCase() != "mm/dd/aaaa" && this.dateInput.value.toLowerCase() != "mm/dd/yyyy" && (this.dateInput.value.toLowerCase() != "dd.mm.yyyy" && this.dateInput.value.toLowerCase() != "dd/mm/yyyy"))
		{	
			if(!this.cal.getSelectedDates()[0])
			{
				var inputDateArray = this.dateInput.value.split('/');
				var typedDate = new Date();
				if(inputDateArray.length == 3)
				{				
					if (isNaN(parseInt(inputDateArray[0])) || isNaN(parseInt(inputDateArray[1])) || isNaN(parseInt(inputDateArray[2])))
					{
						this.dateInput.value="Invalid Date";
						this.dateInput.style.background = "#fff url(http://images.wctravel.com/images-general/warningBG.gif) 100% 50% no-repeat";
						this.cal.render();
						return false;		
					}
					else{
						this.dateInput.style.background = "";
						if (this.dateFormat.toUpperCase() == "EU")
						{
							typedDate.setUTCFullYear(inputDateArray[2],inputDateArray[1]-1,inputDateArray[0]);
							this.cal.setUTCMonth(inputDateArray[1]-1);	
						}
						else
						{					
							typedDate.setUTCFullYear(inputDateArray[2],inputDateArray[0]-1,inputDateArray[1]);
							this.cal.setUTCMonth(inputDateArray[0]-1);	
						}
						this.cal.select(typedDate);		
						this.cal.setYear(inputDateArray[2]);
					}
					this.cal.render();
				}
			}
		}
		
		this.highlightCell();

		var ie=document.all
		var ieNOTopera=document.all&&navigator.userAgent.indexOf("Opera")==-1
		//getting current view port size
		var dsoctop=ie? document.body.scrollTop : pageYOffset  // amt of pixel from top of document to top of window.
		var window_height=ieNOTopera? document.body.clientHeight : window.innerHeight  // window height.

		if (this.parentContainerId)
		{
			this.parentContainerId.style.display='block';
			if(this.calendarPosition == 'relative')
			{
				var calendarHeight = this.parentContainerId.offsetHeight;
				if(eval(parseInt(pos[1])+parseInt(el.offsetHeight+1)+calendarHeight) < eval(parseInt(dsoctop)+parseInt(window_height)))				
					YAHOO.util.Dom.setXY(this.parentContainerId, [pos[0],pos[1]+el.offsetHeight+1]);
				else
				{	
					YAHOO.util.Dom.setXY(this.parentContainerId, [pos[0],eval(pos[1]-calendarHeight-1)]);
				}
			}
		}
		else
		{
			this.outerContainer.style.display='block';					
			if(this.calendarPosition == 'relative')
			{				
				var calendarHeight = this.parentContainerId.offsetHeight;
				if(eval(parseInt(pos[1])+parseInt(el.offsetHeight+1)+calendarHeight) < eval(parseInt(dsoctop)+parseInt(window_height)))				
					YAHOO.util.Dom.setXY(this.outerContainer, [pos[0],pos[1]+el.offsetHeight+1]);		
				else
				{
					YAHOO.util.Dom.setXY(this.outerContainer, [pos[0],eval(pos[1]-calendarHeight-1)]);		
				}
			}
		}			
	
		// hide select box from appearing on top of calendar
		if (YAHOO.util.Event.isIE) // boolean set if we're on IE
		{
			this.hiddenSelects = new Array();

			// Get the rectangle occupied by this calendar.
			if (this.parentContainerId)
			{
				var r = YAHOO.util.Dom.getRegion(this.parentContainerId);
			}
			else
			{
				var r = YAHOO.util.Dom.getRegion(this.outerContainer);
			}
			
			// Hide any selects which intersect
			var selects = document.getElementsByTagName("select");
			for (var i = 0; i < selects.length; i++)
			{
				if (r.intersect(YAHOO.util.Dom.getRegion(selects[i])))
				{
					selects[i].style.visibility = "hidden";
					this.hiddenSelects.push(selects[i]);
				}
			}
		}		
		
		// auto hide calendar if click out side of current date field
		YAHOO.util.Event.addListener(el, 'blur', onUnfocus,this)
	    YAHOO.util.Event.addListener(this.parentContainerId, 'mouseover', overCal);
	    YAHOO.util.Event.addListener(this.parentContainerId, 'mouseout', outCal);
		// attach onChange event to automatically update the calendar if user type in date
		YAHOO.util.Event.addListener(this.dateInput, 'change', this.updateCalendar,this);
	}
}

WCT.calendar.prototype.highlightCell = function()
{
	if (this.linkedCal)
	{
		var linkC = this.linkedCal.getInternalCal();
		var extSelectedDate = linkC.getSelectedDates()[0];
		var selectedDate = this.cal.getSelectedDates()[0];		
		var adjustInvalidDate = 0;
		if (extSelectedDate)
		{
			var month = extSelectedDate.getUTCMonth() +1;
			var date  = extSelectedDate.getUTCDate();
			var year  = extSelectedDate.getUTCFullYear();
			var extdateString = month+"/"+ date+"/"+year;
			
			if(extSelectedDate > this.cal.getSelectedDates()[0] && this.calType == "dod")
			{  // if external calendar date is greater than this date, default this to external calendar date +1
				var newDate = YAHOO.widget.DateMath.add(extSelectedDate, YAHOO.widget.DateMath.DAY, 1);
				this.cal.select(newDate);
				selectedDate = this.cal.getSelectedDates()[0];
				adjustInvalidDate = 1;
			}
			
			// clear previous calendar style			
			if(this.prevRenderer.length > 0)
			{
				this.cal.clearRenderer();
			}

			if(this.calType == "dod")
			{
				this.cal.setUTCMonth(month-1);			
				this.cal.setYear(year);				
				if(this.calClass.match("Calendar_Core"))
				{
					this.cal.minDate=extSelectedDate;
				}
				else
				{			
					this.minDate(new Date());
				}				
			}

			/* Highlight a date range */
			var dateStringRange;	//valid format:	12/1/2004-1/1/2005
			if(selectedDate && adjustInvalidDate != 1)
			{			
				var newHighlightDate;
				var newHighlightDateExt;
				
				// calculating date range 
				// ie:  currectDate - futureDate.  The range will be (currectDate +1) - (futureDate-1)
				
				if (this.calType == "doa" && selectedDate < extSelectedDate)
				{	// this.selected date - external cal selected date
					newHighlightDate = YAHOO.widget.DateMath.add(selectedDate, YAHOO.widget.DateMath.DAY, 1);
					newHighlightDateExt = YAHOO.widget.DateMath.subtract(extSelectedDate, YAHOO.widget.DateMath.DAY, 1);
				}
				else if (this.calType == "dod")
				{
					newHighlightDate = YAHOO.widget.DateMath.add(extSelectedDate, YAHOO.widget.DateMath.DAY, 1);					
					newHighlightDateExt = YAHOO.widget.DateMath.subtract(selectedDate, YAHOO.widget.DateMath.DAY, 1);

				}

				if (newHighlightDate && newHighlightDateExt)
				{
					var highlightMonth = newHighlightDate.getUTCMonth()+1;
					var highlightDate  = newHighlightDate.getUTCDate();
					var highlightYear  = newHighlightDate.getUTCFullYear();
					var highLightDateStart = highlightMonth+"/"+highlightDate+"/"+highlightYear;
					var highlightDateExtMonth = newHighlightDateExt.getUTCMonth()+1;
					var highlightDateExtDate = newHighlightDateExt.getUTCDate();
					var highlightDateExtYear = newHighlightDateExt.getUTCFullYear();
					var highlightDateEnd = highlightDateExtMonth+"/"+highlightDateExtDate+"/"+highlightDateExtYear;
					var dateStringRange = highLightDateStart+"-"+highlightDateEnd;
		
					this.cal.addRenderer(dateStringRange,this.renderHighlight);
					this.prevRenderer.push([dateStringRange,this.renderHighlight]);
				}			
			}			/* end Highlight a date range */			
			this.cal.addRenderer(extdateString, this.renderSelected);
			this.prevRenderer.push([extdateString,this.renderSelected]);					
			if(selectedDate)
			{
				// default calendar view to the selected month
				var currSelectedMonth = selectedDate.getUTCMonth();
				var currSelectedYear  = selectedDate.getUTCFullYear();
				this.cal.setUTCMonth(currSelectedMonth);			
				this.cal.setYear(currSelectedYear);
			}

			this.cal.render();		
		}
	}		
}

WCT.calendar.prototype.getInternalCal = function()
{
	return this.cal;	
}


WCT.calendar.prototype.returnDateFormat = function(dformat)
{	
	if (arguments.length > 0)
	{
		if(dformat.toUpperCase() == "US" || dformat.toUpperCase() == "EU")
		{
			this.dateFormat = dformat.toUpperCase();
		}
	}
	else{
		return  this.dateFormat
	}
}
											 
WCT.calendar.prototype.selectedDate = function(selected)
{
	var cal = this.parent;
	var selectedCalDate=null;
	if (cal)
	{
		selectedCalDate = cal.getSelectedDates()[0];
	}
	else
	{
		selectedCalDate = this.getSelectedDates()[0];
	}
	var month = selectedCalDate.getUTCMonth() +1;
	var date  = selectedCalDate.getUTCDate();
	var year  = selectedCalDate.getUTCFullYear();

	if(month.toString().length < 2)
	  {
	  month = "0" + month + "";
	  }

	if(date.toString().length < 2)
	  {
	  date = "0" + date + "";
	  }
	
	if (cal) 
	{
		if (cal.parentMain.dateFormat.toUpperCase() == "EU")
		{
			returnDate.value = date +"."+ month+"."+ year;		
		}
		else
		{
			returnDate.value = month+"/"+ date +"/"+ year;		
		}
		cal.parentMain.dateInput.style.background = "";
		cal.parentMain.hideCal();
	}
	else
	{
		if (this.parentMain.dateFormat.toUpperCase() == "EU")
		{
			returnDate.value = date +"."+ month+"."+ year;		
		}
		else
		{
			returnDate.value = month+"/"+ date +"/"+ year;		
		}
		this.parentMain.dateInput.style.background = "";			
		this.parentMain.hideCal();
	}
	
}

WCT.calendar.prototype.hideCal = function() 
{
	if(this.hiddenSelects)
	{
		if (YAHOO.util.Event.isIE)
		{
			for (var i = 0; i < this.hiddenSelects.length; i++)
				this.hiddenSelects[i].style.visibility = "";
		}
	}
	
	
	if (this.parentContainerId)
	{
		this.parentContainerId.style.display = "none";
	}
	else 
	{
		this.cal.hide();
	}
}

WCT.calendar.prototype.addLinkedCal = function(linkedCal)
{
	this.linkedCal = linkedCal;	
}

WCT.calendar.prototype.renderSelected = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, "selected");
}

WCT.calendar.prototype.renderHighlight = function(workingDate, cell) {
	YAHOO.util.Dom.addClass(cell, "highlight");
}


WCT.calendar.prototype.previousMonth = function(){
	this.cal.previousMonth()
}

WCT.calendar.prototype.nextMonth = function(){
	this.cal.nextMonth()
}

WCT.calendar.prototype.getSelectedDates = function()
{
	this.cal.getSelectedDates();
}

WCT.calendar.prototype.updateCalendar = function(e,obj)
{
	var dstring = obj.dateInput.value;	

	if (dstring.length <1)
	{
		return false;
	}
	obj.cal.deselectAll();	
	var splitstring = '/';
	if (obj.dateFormat.toUpperCase() == "EU")
		{
		splitstring = '.';
		}
	var inputDateArray = dstring.split(splitstring);
	var typedDate = new Date();
	var currentDate = new Date();
	if (inputDateArray.length == 2) inputDateArray[2]=""; // missing year
	try{
		if(inputDateArray[2].toString().length < 4)
		{
		  inputDateArray[2] = currentDate.getUTCFullYear();
		}
	}
	catch(e){}

	if (isNaN(parseInt(inputDateArray[0])) || isNaN(parseInt(inputDateArray[1])) || isNaN(parseInt(inputDateArray[2])))
	{
		obj.dateInput.value = "Invalid Date";
		obj.dateInput.style.background = "#fff url(http://images.wctravel.com/images-general/warningBG.gif) 100% 50% no-repeat";
		return false;		
	}
	else
	{
		obj.dateInput.style.background = "";
	}
	if (obj.dateFormat.toUpperCase() == "EU")
	{
		if(inputDateArray.length == 3)
		{
			typedDate.setUTCFullYear(inputDateArray[2],inputDateArray[1]-1,inputDateArray[0]);
		}
	}
	else
	{
		if(inputDateArray.length == 3)
		{
			typedDate.setUTCFullYear(inputDateArray[2],inputDateArray[0]-1,inputDateArray[1]);
		}

	}		
	obj.cal.select(typedDate);
	obj.cal.render();
}

WCT.calendar.prototype.minDate = function(date) {
	if(typeof(this.cal.pages) != "undefined")
	{
		// Multiple calendar pages (2up)
		for (var p=0;p<this.cal.pages.length;++p)
		{
			var cal = this.cal.pages[p];
			cal.minDate=date;
		}
	}
	else
	{
		this.cal.minDate=date;
	}
};


WCT.calendar.prototype.maxDate = function(date) {
	if(typeof(this.cal.pages) != "undefined")
	{
		// 2 calendar side by side
		for (var p=0;p<this.cal.pages.length;++p)
		{
			var cal = this.cal.pages[p];
			cal.maxDate=date;
		}
	}
	else
	{
		this.cal.maxDate=date;
	}
};

WCT.calendar.prototype.position = function(pos)
{
	this.calendarPosition = pos.toLowerCase();
}


WCT.calendar.prototype.returnSelectedDate = function(year,month,day)
{
	if (arguments.length > 0)
	{		
		var searchForm = this.dateInput.form;
		if (typeof(year) !="object")
		{
			year = searchForm.elements[year];		
		}
		if (typeof(month) !="object")
		{
			month = searchForm.elements[month];
		}

		if (typeof(day) !="object")
		{
			day = searchForm.elements[day];
		}

                if(this.dateInput.value.toLowerCase() != "mm/dd/aaaa" && this.dateInput.value.toLowerCase() != "mm/dd/yyyy" && (this.dateInput.value.toLowerCase() != "dd.mm.yyyy" && this.dateInput.value.toLowerCase() != "dd/mm/yyyy") )
		{	
			var splitstring = '/';
			if (this.dateFormat.toUpperCase() == "EU")
				{
				splitstring = '.';
				}
			var inputDateArray = this.dateInput.value.split(splitstring);
			if(inputDateArray.length == 3)
			{
				if (isNaN(parseInt(inputDateArray[0])) || isNaN(parseInt(inputDateArray[1])) || isNaN(parseInt(inputDateArray[2])))
				{
					this.dateInput.value="Invalid Date";
					this.dateInput.style.background = "#fff url(http://images.wctravel.com/images-general/warningBG.gif) 100% 50% no-repeat";
					return false;		
				}
				else
				{
					this.dateInput.style.background = "";
					if (this.dateFormat.toUpperCase() == "EU")
					{
						(year) ? year.value = inputDateArray[2]:"";
						month.value = inputDateArray[1];
						day.value = inputDateArray[0];
					}
					else
					{					
						(year) ? year.value = inputDateArray[2]: "";
						month.value = inputDateArray[0];
						day.value = inputDateArray[1];
					}
					//alert(month.value+"/"+day.value);
					return true;
				}
			}
		}
		else
		{
			this.dateInput.value="Enter Date";
			this.dateInput.style.background = "#fff url(http://images.wctravel.com/images-general/warningBG.gif) 100% 50% no-repeat";
			return false;					
		}
	}
	return false;
}

WCT.calendar.prototype.clear = function()
{
	this.cal.minDate=new Date();
	this.cal.clearRenderer();
	this.cal.reset();	
}

WCT.calendar.prototype.toString = function()
{
	return this.cal.id;
}

onUnfocus = function (el,obj)
{
	if (!over_cal) 
	{
		obj.hideCal();
	}
}

function overCal() 
{
    over_cal = true;
}

function outCal() 
{
    over_cal = false;
}

