/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.6.0
*/
/**
 * The Carousel module provides a widget for browsing among a set of like
 * objects represented pictorially.
 *
 * @module carousel
 * @requires yahoo, dom, event, element
 * @optional animation
 * @namespace YAHOO.widget
 * @title Carousel Widget
 */
(function () {

    var WidgetName;             // forward declaration

    /**
     * The Carousel widget.
     *
     * @class Carousel
     * @extends YAHOO.util.Element
     * @constructor
     * @param el {HTMLElement | String} The HTML element that represents the
     * the container that houses the Carousel.
     * @param cfg {Object} (optional) The configuration values
     */
    YAHOO.widget.Carousel = function (el, cfg) {
        YAHOO.log("Component creation", WidgetName);

        this._navBtns = {};
        this._pages = {};

        YAHOO.widget.Carousel.superclass.constructor.call(this, el, cfg);
    };

    /*
     * Private variables of the Carousel component
     */

    /* Some abbreviations to avoid lengthy typing and lookups. */
    var Carousel    = YAHOO.widget.Carousel,
        Dom         = YAHOO.util.Dom,
        Event       = YAHOO.util.Event,
        JS          = YAHOO.lang;

    /**
     * The widget name.
     * @private
     * @static
     */
    WidgetName = "Carousel";

    /**
     * The internal table of Carousel instances.
     * @private
     * @static
     */
    var instances = {};

    /*
     * Custom events of the Carousel component
     */

    /**
     * @event afterScroll
     * @description Fires when the Carousel has scrolled to the previous or
     * next page.  Passes back the index of the first and last visible items in
     * the Carousel.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var afterScrollEvent = "afterScroll";

    /**
     * @event beforeHide
     * @description Fires before the Carousel is hidden.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var beforeHideEvent = "beforeHide";

    /**
     * @event beforePageChange
     * @description Fires when the Carousel is about to scroll to the previous
     * or next page.  Passes back the page number of the current page.  Note
     * that the first page number is zero.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var beforePageChangeEvent = "beforePageChange";

    /**
     * @event beforeScroll
     * @description Fires when the Carousel is about to scroll to the previous
     * or next page.  Passes back the index of the first and last visible items
     * in the Carousel and the direction (backward/forward) of the scroll.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var beforeScrollEvent = "beforeScroll";

    /**
     * @event beforeShow
     * @description Fires when the Carousel is about to be shown.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var beforeShowEvent = "beforeShow";

    /**
     * @event blur
     * @description Fires when the Carousel loses focus.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var blurEvent = "blur";

    /**
     * @event focus
     * @description Fires when the Carousel gains focus.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var focusEvent = "focus";

    /**
     * @event hide
     * @description Fires when the Carousel is hidden.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var hideEvent = "hide";

    /**
     * @event itemAdded
     * @description Fires when an item has been added to the Carousel.  Passes
     * back the content of the item that would be added, the index at which the
     * item would be added, and the event itself.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var itemAddedEvent = "itemAdded";

    /**
     * @event itemRemoved
     * @description Fires when an item has been removed from the Carousel.
     * Passes back the content of the item that would be removed, the index
     * from which the item would be removed, and the event itself.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var itemRemovedEvent = "itemRemoved";

    /**
     * @event itemSelected
     * @description Fires when an item has been selected in the Carousel.
     * Passes back the index of the selected item in the Carousel.  Note, that
     * the index begins from zero.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var itemSelectedEvent = "itemSelected";

    /**
     * @event loadItems
     * @description Fires when the Carousel needs more items to be loaded for
     * displaying them.  Passes back the first and last visible items in the
     * Carousel, and the number of items needed to be loaded.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var loadItemsEvent = "loadItems";

    /**
     * @event navigationStateChange
     * @description Fires when the state of either one of the navigation
     * buttons are changed from enabled to disabled or vice versa.  Passes back
     * the state (true/false) of the previous and next buttons.  The value true
     * signifies the button is enabled, false signifies disabled.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var navigationStateChangeEvent = "navigationStateChange";

    /**
     * @event pageChange
     * @description Fires after the Carousel has scrolled to the previous or
     * next page.  Passes back the page number of the current page.  Note
     * that the first page number is zero.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var pageChangeEvent = "pageChange";

    /**
     * @event render
     * @description Fires when the Carousel is rendered.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var renderEvent = "render";

    /**
     * @event show
     * @description Fires when the Carousel is shown.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var showEvent = "show";

    /**
     * @event startAutoPlay
     * @description Fires when the auto play has started in the Carousel.  See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var startAutoPlayEvent = "startAutoPlay";

    /**
     * @event stopAutoPlay
     * @description Fires when the auto play has been stopped in the Carousel.
     * See
     * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
     * for more information on listening for this event.
     * @type YAHOO.util.CustomEvent
     */
    var stopAutoPlayEvent = "stopAutoPlay";

    /*
     * Private helper functions used by the Carousel component
     */

    /**
     * Automatically scroll the contents of the Carousel.
     * @method autoScroll
     * @private
     */
    function autoScroll() {
        var currIndex = this._firstItem,
            index;

        if (currIndex >= this.get("numItems") - 1) {
            if (this.get("isCircular")) {
                index = 0;
            } else {
                this.stopAutoPlay();
            }
        } else {
            index = currIndex + this.get("numVisible");
        }
        this.scrollTo.call(this, index);
    }

    /**
     * Create an element, set its class name and optionally install the element
     * to its parent.
     * @method createElement
     * @param el {String} The element to be created
     * @param attrs {Object} Configuration of parent, class and id attributes.
     * If the content is specified, it is inserted after creation of the
     * element. The content can also be an HTML element in which case it would
     * be appended as a child node of the created element.
     * @private
     */
    function createElement(el, attrs) {
        var newEl = document.createElement(el);

        attrs = attrs || {};
        if (attrs.className) {
            Dom.addClass(newEl, attrs.className);
        }

        if (attrs.parent) {
            attrs.parent.appendChild(newEl);
        }

        if (attrs.id) {
            newEl.setAttribute("id", attrs.id);
        }

        if (attrs.content) {
            if (attrs.content.nodeName) {
                newEl.appendChild(attrs.content);
            } else {
                newEl.innerHTML = attrs.content;
            }
        }

        return newEl;
    }

    /**
     * Get the computed style of an element.
     *
     * @method getStyle
     * @param el {HTMLElement} The element for which the style needs to be
     * returned.
     * @param style {String} The style attribute
     * @param type {String} "int", "float", etc. (defaults to int)
     * @private
     */
    function getStyle(el, style, type) {
        var value;

        function getStyleIntVal(el, style) {
            var val;

            val = parseInt(Dom.getStyle(el, style), 10);
            return JS.isNumber(val) ? val : 0;
        }

        function getStyleFloatVal(el, style) {
            var val;

            val = parseFloat(Dom.getStyle(el, style));
            return JS.isNumber(val) ? val : 0;
        }

        if (typeof type == "undefined") {
            type = "int";
        }

        switch (style) {
        case "height":
            value = el.offsetHeight;
            if (value > 0) {
                value += getStyleIntVal(el, "marginTop")        +
                        getStyleIntVal(el, "marginBottom");
            } else {
                value = getStyleFloatVal(el, "height")          +
                        getStyleIntVal(el, "marginTop")         +
                        getStyleIntVal(el, "marginBottom")      +
                        getStyleIntVal(el, "borderTopWidth")    +
                        getStyleIntVal(el, "borderBottomWidth") +
                        getStyleIntVal(el, "paddingTop")        +
                        getStyleIntVal(el, "paddingBottom");
            }
            break;
        case "width":
            value = el.offsetWidth;
            if (value > 0) {
                value += getStyleIntVal(el, "marginLeft")       +
                        getStyleIntVal(el, "marginRight");
            } else {
                value = getStyleFloatVal(el, "width")           +
                        getStyleIntVal(el, "marginLeft")        +
                        getStyleIntVal(el, "marginRight")       +
                        getStyleIntVal(el, "borderLeftWidth")   +
                        getStyleIntVal(el, "borderRightWidth")  +
                        getStyleIntVal(el, "paddingLeft")       +
                        getStyleIntVal(el, "paddingRight");
            }
            break;
        default:
            if (type == "int") {
                value = getStyleIntVal(el, style);
                // XXX: Safari calculates incorrect marginRight for an element
                // which has its parent element style set to overflow: hidden
                // https://bugs.webkit.org/show_bug.cgi?id=13343
                // Let us assume marginLeft == marginRight
                if (style == "marginRight" && YAHOO.env.ua.webkit) {
                    value = getStyleIntVal(el, "marginLeft");
                }
            } else if (type == "float") {
                value = getStyleFloatVal(el, style);
            } else {
                value = Dom.getStyle(el, style);
            }
            break;
        }

        return value;
    }

    /**
     * Compute and return the height or width of a single Carousel item
     * depending upon the orientation.
     *
     * @method getCarouselItemSize
     * @param which {String} "height" or "width" to be returned.  If this is
     * passed explicitly, the calculated size is not cached.
     * @private
     */
    function getCarouselItemSize(which) {
        var child,
            size     = 0,
            vertical = false;

        if (this._itemsTable.numItems === 0) {
            return 0;
        }

        if (typeof which == "undefined") {
            if (this._itemsTable.size > 0) {
                return this._itemsTable.size;
            }
        }

        if (JS.isUndefined(this._itemsTable.items[0])) {
            return 0;
        }

        child = Dom.get(this._itemsTable.items[0].id);

        if (typeof which == "undefined") {
            vertical = this.get("isVertical");
        } else {
            vertical = which == "height";
        }

        if (vertical) {
            size = getStyle(child, "height");
        } else {
            size = getStyle(child, "width");
        }

        if (typeof which == "undefined") {
            this._itemsTable.size = size; // save the size for later
        }

        return size;
    }

    /**
     * Return the scrolling offset size given the number of elements to
     * scroll.
     *
     * @method getScrollOffset
     * @param delta {Number} The delta number of elements to scroll by.
     * @private
     */
    function getScrollOffset(delta) {
        var itemSize = 0,
            size     = 0;

        itemSize = getCarouselItemSize.call(this);
        size     = itemSize * delta;

        // XXX: really, when the orientation is vertical, the scrolling
        // is not exactly the number of elements into element size.
        if (this.get("isVertical")) {
            size -= delta;
        }

        return size;
    }

    /**
     * The load the required set of items that are needed for display.
     *
     * @method loadItems
     * @private
     */
    function loadItems() {
        var first      = this.get("firstVisible"),
            last       = 0,
            numItems   = this.get("numItems"),
            numVisible = this.get("numVisible"),
            reveal     = this.get("revealAmount");

        last = first + numVisible - 1 + (reveal ? 1 : 0);
        last = last > numItems - 1 ? numItems - 1 : last;

        if (!this.getItem(first) || !this.getItem(last)) {
            this.fireEvent(loadItemsEvent, {
                    ev: loadItemsEvent,
                    first: first, last: last,
                    num: last - first
            });
        }
    }

    /**
     * Scroll the Carousel by a page backward.
     *
     * @method scrollPageBackward
     * @param {Event} ev The event object
     * @param {Object} obj The context object
     * @private
     */
    function scrollPageBackward(ev, obj) {
        obj.scrollPageBackward();
        Event.preventDefault(ev);
    }

    /**
     * Scroll the Carousel by a page forward.
     *
     * @method scrollPageForward
     * @param {Event} ev The event object
     * @param {Object} obj The context object
     * @private
     */
    function scrollPageForward(ev, obj) {
        obj.scrollPageForward();
        Event.preventDefault(ev);
    }

    /**
     * Set the selected item.
     *
     * @method setItemSelection
     * @param {Number} newposition The index of the new position
     * @param {Number} oldposition The index of the previous position
     * @private
     */
     function setItemSelection(newposition, oldposition) {
        var backwards,
            cssClass   = this.CLASSES,
            el,
            firstItem  = this._firstItem,
            isCircular = this.get("isCircular"),
            numItems   = this.get("numItems"),
            numVisible = this.get("numVisible"),
            position   = oldposition,
            sentinel   = firstItem + numVisible - 1;

        backwards = numVisible > 1 && !isCircular && position > newposition;

        if (position >= 0 && position < numItems) {
            if (!JS.isUndefined(this._itemsTable.items[position])) {
                el = Dom.get(this._itemsTable.items[position].id);
                if (el) {
                    Dom.removeClass(el, cssClass.SELECTED_ITEM);
                }
            }
        }

        if (JS.isNumber(newposition)) {
            newposition = parseInt(newposition, 10);
            newposition = JS.isNumber(newposition) ? newposition : 0;
        } else {
            newposition = firstItem;
        }

        if (JS.isUndefined(this._itemsTable.items[newposition])) {
            this.scrollTo(newposition); // still loading the item
        }

        if (!JS.isUndefined(this._itemsTable.items[newposition])) {
            el = Dom.get(this._itemsTable.items[newposition].id);
            if (el) {
                Dom.addClass(el, cssClass.SELECTED_ITEM);
            }
        }

        if (newposition < firstItem || newposition > sentinel) {
            // out of focus
            if (backwards) {
                this.scrollTo(firstItem - numVisible, true);
            } else {
                this.scrollTo(newposition);
            }
        }
    }

    /**
     * Fire custom events for enabling/disabling navigation elements.
     *
     * @method syncNavigation
     * @private
     */
    function syncNavigation() {
        var attach   = false,
            cssClass = this.CLASSES,
            i,
            navigation,
            sentinel;

        navigation = this.get("navigation");
        sentinel   = this._firstItem + this.get("numVisible");

        if (navigation.prev) {
            if (this._firstItem === 0) {
                if (!this.get("isCircular")) {
                    Event.removeListener(navigation.prev, "click",
                            scrollPageBackward);
                    Dom.addClass(navigation.prev, cssClass.FIRST_NAV_DISABLED);
                    for (i = 0; i < this._navBtns.prev.length; i++) {
                        this._navBtns.prev[i].setAttribute("disabled", "true");
                    }
                    this._prevEnabled = false;
                } else {
                    attach = !this._prevEnabled;
                }
            } else {
                attach = !this._prevEnabled;
            }

            if (attach) {
                Event.on(navigation.prev, "click", scrollPageBackward, this);
                Dom.removeClass(navigation.prev, cssClass.FIRST_NAV_DISABLED);
                for (i = 0; i < this._navBtns.prev.length; i++) {
                    this._navBtns.prev[i].removeAttribute("disabled");
                }
                this._prevEnabled = true;
            }
        }

        attach = false;
        if (navigation.next) {
            if (sentinel >= this.get("numItems")) {
                if (!this.get("isCircular")) {
                    Event.removeListener(navigation.next, "click",
                            scrollPageForward);
                    Dom.addClass(navigation.next, cssClass.DISABLED);
                    for (i = 0; i < this._navBtns.next.length; i++) {
                        this._navBtns.next[i].setAttribute("disabled", "true");
                    }
                    this._nextEnabled = false;
                } else {
                    attach = !this._nextEnabled;
                }
            } else {
                attach = !this._nextEnabled;
            }

            if (attach) {
                Event.on(navigation.next, "click", scrollPageForward, this);
                Dom.removeClass(navigation.next, cssClass.DISABLED);
                for (i = 0; i < this._navBtns.next.length; i++) {
                    this._navBtns.next[i].removeAttribute("disabled");
                }
                this._nextEnabled = true;
            }
        }

        this.fireEvent(navigationStateChangeEvent,
                { next: this._nextEnabled, prev: this._prevEnabled });
    }

    /**
     * Fire custom events for synchronizing the DOM.
     *
     * @method syncUI
     * @param {Object} o The item that needs to be added or removed
     * @private
     */
    function syncUI(o) {
        var el, i, item, num, oel, pos, sibling;

        if (!JS.isObject(o)) {
            return;
        }

        switch (o.ev) {
        case itemAddedEvent:
            pos  = JS.isUndefined(o.pos) ? this._itemsTable.numItems-1 : o.pos;
            if (!JS.isUndefined(this._itemsTable.items[pos])) {
                item = this._itemsTable.items[pos];
                if (item && !JS.isUndefined(item.id)) {
                    oel  = Dom.get(item.id);
                }
            }
            if (!oel) {
                el = this._createCarouselItem({
                        className : item.className,
                        content   : item.item,
                        id        : item.id
                });
                if (JS.isUndefined(o.pos)) {
                    if (!JS.isUndefined(this._itemsTable.loading[pos])) {
                        oel = this._itemsTable.loading[pos];
                    }
                    if (oel) {
                        this._carouselEl.replaceChild(el, oel);
                    } else {
                        this._carouselEl.appendChild(el);
                    }
                } else {
                    if (!JS.isUndefined(this._itemsTable.items[o.pos + 1])) {
                        sibling = Dom.get(this._itemsTable.items[o.pos + 1].id);
                    }
                    if (sibling) {
                        this._carouselEl.insertBefore(el, sibling);
                    } else {
                        YAHOO.log("Unable to find sibling","error",WidgetName);
                    }
                }
            } else {
                if (JS.isUndefined(o.pos)) {
                    if (!Dom.isAncestor(this._carouselEl, oel)) {
                        this._carouselEl.appendChild(oel);
                    }
                } else {
                    if (!Dom.isAncestor(this._carouselEl, oel)) {
                        if (!JS.isUndefined(this._itemsTable.items[o.pos+1])) {
                            this._carouselEl.insertBefore(oel, Dom.get(
                                    this._itemsTable.items[o.pos+1].id));
                        }
                    }
                }
            }

            if (this._recomputeSize) {
                this._setClipContainerSize();
            }
            break;
        case itemRemovedEvent:
            num  = this.get("numItems");
            item = o.item;
            pos  = o.pos;

            if (item && (el = Dom.get(item.id))) {
                if (el && Dom.isAncestor(this._carouselEl, el)) {
                    Event.purgeElement(el, true);
                    this._carouselEl.removeChild(el);
                }

                if (this.get("selectedItem") == pos) {
                    pos = pos >= num ? num - 1 : pos;
                    this.set("selectedItem", pos);
                }
            } else {
                YAHOO.log("Unable to find item", "warn", WidgetName);
            }
            break;
        case loadItemsEvent:
            for (i = o.first; i <= o.last; i++) {
                el = this._createCarouselItem({
                        content : this.CONFIG.ITEM_LOADING,
                        id      : Dom.generateId()
                });
                if (el) {
                    if (!JS.isUndefined(this._itemsTable.items[o.last + 1])) {
                        sibling = Dom.get(this._itemsTable.items[o.last+1].id);
                        if (sibling) {
                            this._carouselEl.insertBefore(el, sibling);
                        } else {
                            YAHOO.log("Unable to find sibling", "error",
                                    WidgetName);
                        }
                    } else {
                        this._carouselEl.appendChild(el);
                    }
                }
                this._itemsTable.loading[i] = el;
            }
            break;
        }
    }

    /*
     * Static members and methods of the Carousel component
     */

    /**
     * Return the appropriate Carousel object based on the id associated with
     * the Carousel element or false if none match.
     * @method getById
     * @public
     * @static
     */
    Carousel.getById = function (id) {
        return instances[id] ? instances[id] : false;
    };

    YAHOO.extend(Carousel, YAHOO.util.Element, {

        /*
         * Internal variables used within the Carousel component
         */

        /**
         * The Carousel element.
         *
         * @property _carouselEl
         * @private
         */
        _carouselEl: null,

        /**
         * The Carousel clipping container element.
         *
         * @property _clipEl
         * @private
         */
        _clipEl: null,

        /**
         * The current first index of the Carousel.
         *
         * @property _firstItem
         * @private
         */
        _firstItem: 0,

        /**
         * Is the animation still in progress?
         *
         * @property _isAnimationInProgress
         * @private
         */
        _isAnimationInProgress: false,

        /**
         * The table of items in the Carousel.
         * The numItems is the number of items in the Carousel, items being the
         * array of items in the Carousel.  The size is the size of a single
         * item in the Carousel.  It is cached here for efficiency (to avoid
         * computing the size multiple times).
         *
         * @property _itemsTable
         * @private
         */
        _itemsTable: null,

        /**
         * The Carousel navigation buttons.
         *
         * @property _navBtns
         * @private
         */
        _navBtns: null,

        /**
         * The Carousel navigation.
         *
         * @property _navEl
         * @private
         */
        _navEl: null,

        /**
         * Status of the next navigation item.
         *
         * @property _nextEnabled
         * @private
         */
        _nextEnabled: true,

        /**
         * The Carousel pages structure.
         * This is an object of the total number of pages and the current page.
         *
         * @property _pages
         * @private
         */
        _pages: null,

        /**
         * Status of the previous navigation item.
         *
         * @property _prevEnabled
         * @private
         */
        _prevEnabled: true,

        /**
         * Whether the Carousel size needs to be recomputed or not?
         *
         * @property _recomputeSize
         * @private
         */
        _recomputeSize: true,

        /*
         * CSS classes used by the Carousel component
         */

        CLASSES: {

            /**
             * The class name of the Carousel navigation buttons.
             *
             * @property BUTTON
             * @default "yui-carousel-button"
             */
            BUTTON: "yui-carousel-button",

            /**
             * The class name of the Carousel element.
             *
             * @property CAROUSEL
             * @default "yui-carousel"
             */
            CAROUSEL: "yui-carousel",

            /**
             * The class name of the container of the items in the Carousel.
             *
             * @property CAROUSEL_EL
             * @default "yui-carousel-element"
             */
            CAROUSEL_EL: "yui-carousel-element",

            /**
             * The class name of the Carousel's container element.
             *
             * @property CONTAINER
             * @default "yui-carousel-container"
             */
            CONTAINER: "yui-carousel-container",

            /**
             * The class name of the Carousel's container element.
             *
             * @property CONTENT
             * @default "yui-carousel-content"
             */
            CONTENT: "yui-carousel-content",

            /**
             * The class name of a disabled navigation button.
             *
             * @property DISABLED
             * @default "yui-carousel-button-disabled"
             */
            DISABLED: "yui-carousel-button-disabled",

            /**
             * The class name of the first Carousel navigation button.
             *
             * @property FIRST_NAV
             * @default " yui-carousel-first-button"
             */
            FIRST_NAV: " yui-carousel-first-button",

            /**
             * The class name of a first disabled navigation button.
             *
             * @property FIRST_NAV_DISABLED
             * @default "yui-carousel-first-button-disabled"
             */
            FIRST_NAV_DISABLED: "yui-carousel-first-button-disabled",

            /**
             * The class name of a first page element.
             *
             * @property FIRST_PAGE
             * @default "yui-carousel-nav-first-page"
             */
            FIRST_PAGE: "yui-carousel-nav-first-page",

            /**
             * The class name of the Carousel navigation button that has focus.
             *
             * @property FOCUSSED_BUTTON
             * @default "yui-carousel-button-focus"
             */
            FOCUSSED_BUTTON: "yui-carousel-button-focus",

            /**
             * The class name of a horizontally oriented Carousel.
             *
             * @property HORIZONTAL
             * @default "yui-carousel-horizontal"
             */
            HORIZONTAL: "yui-carousel-horizontal",

            /**
             * The navigation element container class name.
             *
             * @property NAVIGATION
             * @default "yui-carousel-nav"
             */
            NAVIGATION: "yui-carousel-nav",

            /**
             * The class name of the next navigation link. This variable is not
             * only used for styling, but also for identifying the link within
             * the Carousel container.
             *
             * @property NEXT_PAGE
             * @default "yui-carousel-next"
             */
            NEXT_PAGE: "yui-carousel-next",

            /**
             * The class name for the navigation container for prev/next.
             *
             * @property NAV_CONTAINER
             * @default "yui-carousel-buttons"
             */
            NAV_CONTAINER: "yui-carousel-buttons",

            /**
             * The class name of the previous navigation link. This variable
             * is not only used for styling, but also for identifying the link
             * within the Carousel container.
             *
             * @property PREV_PAGE
             * @default "yui-carousel-prev"
             */
            PREV_PAGE: "yui-carousel-prev",

            /**
             * The class name of the selected item.
             *
             * @property SELECTED_ITEM
             * @default "yui-carousel-item-selected"
             */
            SELECTED_ITEM: "yui-carousel-item-selected",

            /**
             * The class name of the selected paging navigation.
             *
             * @property SELECTED_NAV
             * @default "yui-carousel-nav-page-selected"
             */
            SELECTED_NAV: "yui-carousel-nav-page-selected",

            /**
             * The class name of a vertically oriented Carousel.
             *
             * @property VERTICAL
             * @default "yui-carousel-vertical"
             */
            VERTICAL: "yui-carousel-vertical",

            /**
             * The class name of the (vertical) Carousel's container element.
             *
             * @property VERTICAL_CONTAINER
             * @default "yui-carousel-vertical-container"
             */
            VERTICAL_CONTAINER: "yui-carousel-vertical-container",

            /**
             * The class name of a visible Carousel.
             *
             * @property VISIBLE
             * @default "yui-carousel-visible"
             */
            VISIBLE: "yui-carousel-visible"

        },

        /*
         * Configuration attributes for configuring the Carousel component
         */

        CONFIG: {

            /**
             * The offset of the first visible item in the Carousel.
             *
             * @property FIRST_VISIBLE
             * @default 0
             */
            FIRST_VISIBLE: 0,

            /**
             * The element to be used as the progress indicator when the item
             * is still being loaded.
             *
             * @property ITEM_LOADING
             * @default The progress indicator (spinner) image
             */
            ITEM_LOADING: "<img " +
                    "src=\"../../build/carousel/assets/ajax-loader.gif\" " +
                    "alt=\"Loading\" " +
                    "style=\"margin-top:-32px;position:relative;top:50%;\">",

            /**
             * The tag name of the Carousel item.
             *
             * @property ITEM_TAG_NAME
             * @default "LI"
             */
            ITEM_TAG_NAME: "LI",

            /**
             * The maximum number of pager buttons allowed beyond which the UI
             * of the pager would be a drop-down of pages instead of buttons.
             *
             * @property MAX_PAGER_BUTTONS
             * @default 5
             */
            MAX_PAGER_BUTTONS: 5,

            /**
             * The minimum width of the Carousel container to support the
             * navigation buttons.
             *
             * @property MIN_WIDTH
             * @default 99
             */
            MIN_WIDTH: 99,

            /**
             * The number of visible items in the Carousel.
             *
             * @property NUM_VISIBLE
             * @default 3
             */
            NUM_VISIBLE: 3,

            /**
             * The tag name of the Carousel.
             *
             * @property TAG_NAME
             * @default "OL"
             */
            TAG_NAME: "OL"

        },

        /*
         * Internationalizable strings in the Carousel component
         */

        STRINGS: {

            /**
             * The next navigation button name/text.
             *
             * @property NEXT_BUTTON_TEXT
             * @default "Next Page"
             */
            NEXT_BUTTON_TEXT: "Next Page",

            /**
             * The prefix text for the pager in case the UI is a drop-down.
             *
             * @property PAGER_PREFIX_TEXT
             * @default "Go to page "
             */
            PAGER_PREFIX_TEXT: "Go to page ",

            /**
             * The previous navigation button name/text.
             *
             * @property PREVIOUS_BUTTON_TEXT
             * @default "Previous Page"
             */
            PREVIOUS_BUTTON_TEXT: "Previous Page"

        },

        /*
         * Public methods of the Carousel component
         */

        /**
         * Insert or append an item to the Carousel.
         *
         * @method addItem
         * @public
         * @param item {String | Object | HTMLElement} The item to be appended
         * to the Carousel. If the parameter is a string, it is assumed to be
         * the content of the newly created item. If the parameter is an
         * object, it is assumed to supply the content and an optional class
         * and an optional id of the newly created item.
         * @param index {Number} optional The position to where in the list
         * (starts from zero).
         * @return {Boolean} Return true on success, false otherwise
         */
        addItem: function (item, index) {
            var className, content, el, elId, numItems = this.get("numItems");

            if (!item) {
                return false;
            }

            if (JS.isString(item) || item.nodeName) {
                content = item.nodeName ? item.innerHTML : item;
            } else if (JS.isObject(item)) {
                content = item.content;
            } else {
                YAHOO.log("Invalid argument to addItem", "error", WidgetName);
                return false;
            }

            className = item.className || "";
            elId      = item.id ? item.id : Dom.generateId();

            if (JS.isUndefined(index)) {
                this._itemsTable.items.push({
                        item      : content,
                        className : className,
                        id        : elId
                });
            } else {
                if (index < 0 || index >= numItems) {
                    YAHOO.log("Index out of bounds", "error", WidgetName);
                    return false;
                }
                this._itemsTable.items.splice(index, 0, {
                        item      : content,
                        className : className,
                        id        : elId
                });
            }
            this._itemsTable.numItems++;

            if (numItems < this._itemsTable.items.length) {
                this.set("numItems", this._itemsTable.items.length);
            }

            this.fireEvent(itemAddedEvent, { pos: index, ev: itemAddedEvent });

            return true;
        },

        /**
         * Insert or append multiple items to the Carousel.
         *
         * @method addItems
         * @public
         * @param items {Array} An array of items to be added with each item
         * representing an item, index pair [{item, index}, ...]
         * @return {Boolean} Return true on success, false otherwise
         */
        addItems: function (items) {
            var i, n, rv = true;

            if (!JS.isArray(items)) {
                return false;
            }

            for (i = 0, n = items.length; i < n; i++) {
                if (this.addItem(items[i][0], items[i][1]) === false) {
                    rv = false;
                }
            }

            return rv;
        },

        /**
         * Remove focus from the Carousel.
         *
         * @method blur
         * @public
         */
        blur: function () {
            this._carouselEl.blur();
            this.fireEvent(blurEvent);
        },

        /**
         * Clears the items from Carousel.
         *
         * @method clearItems
         * public
         */
        clearItems: function () {
            var n = this.get("numItems");

            while (n > 0) {
                this.removeItem(0);
                n--;
            }
        },

        /**
         * Set focus on the Carousel.
         *
         * @method focus
         * @public
         */
        focus: function () {
            var selItem,
                numVisible,
                selectOnScroll,
                selected,
                first,
                last,
                isSelectionInvisible,
                focusEl,
                itemsTable;

            if (this._isAnimationInProgress) {
                // this messes up real bad!
                return;
            }

            selItem              = this.get("selectedItem");
            numVisible           = this.get("numVisible");
            selectOnScroll       = this.get("selectOnScroll");
            selected             = this.getItem(selItem);
            first                = this.get("firstVisible");
            last                 = first + numVisible - 1;
            isSelectionInvisible = (selItem < first || selItem > last);
            focusEl              = (selected && selected.id) ?
                                   Dom.get(selected.id) : null;
            itemsTable           = this._itemsTable;

            if (!selectOnScroll && isSelectionInvisible) {
                focusEl = (itemsTable && itemsTable.items &&
                           itemsTable.items[first]) ?
                        Dom.get(itemsTable.items[first].id) : null;
            }

            if (focusEl) {
                try {
                    focusEl.focus();
                } catch (ex) {
                    // ignore focus errors
                }
            }

            this.fireEvent(focusEvent);
        },

        /**
         * Hide the Carousel.
         *
         * @method hide
         * @public
         */
        hide: function () {
            if (this.fireEvent(beforeHideEvent) !== false) {
                this.removeClass(this.CLASSES.VISIBLE);
                this.fireEvent(hideEvent);
            }
        },

        /**
         * Initialize the Carousel.
         *
         * @method init
         * @public
         * @param el {HTMLElement | String} The html element that represents
         * the Carousel container.
         * @param attrs {Object} The set of configuration attributes for
         * creating the Carousel.
         */
        init: function (el, attrs) {
            var elId  = el,     // save for a rainy day
                parse = false;

            if (!el) {
                YAHOO.log(el + " is neither an HTML element, nor a string",
                        "error", WidgetName);
                return;
            }

            this._itemsTable = { loading: {}, numItems: 0, items: [], size: 0 };
            YAHOO.log("Component initialization", WidgetName);

            if (JS.isString(el)) {
                el = Dom.get(el);
            } else if (!el.nodeName) {
                YAHOO.log(el + " is neither an HTML element, nor a string",
                        "error", WidgetName);
                return;
            }

            if (el) {
                if (!el.id) {   // in case the HTML element is passed
                    el.setAttribute("id", Dom.generateId());
                }
                this._parseCarousel(el);
                parse = true;
            } else {
                el = this._createCarousel(elId);
            }
            elId = el.id;

            Carousel.superclass.init.call(this, el, attrs);

            this.initEvents();

            if (parse) {
                this._parseCarouselItems();
            }

            if (!attrs || typeof attrs.isVertical == "undefined") {
                this.set("isVertical", false);
            }

            this._parseCarouselNavigation(el);
            this._navEl = this._setupCarouselNavigation();

            instances[elId] = this;

            loadItems.call(this);
        },

        /**
         * Initialize the configuration attributes used to create the Carousel.
         *
         * @method initAttributes
         * @public
         * @param attrs {Object} The set of configuration attributes for
         * creating the Carousel.
         */
        initAttributes: function (attrs) {
            attrs = attrs || {};
            Carousel.superclass.initAttributes.call(this, attrs);

            /**
             * @attribute currentPage
             * @description The current page number (read-only.)
             * @type Number
             */
            this.setAttributeConfig("currentPage", {
                    readOnly : true,
                    value    : 0
            });

            /**
             * @attribute firstVisible
             * @description The index to start the Carousel from (indexes begin
             * from zero)
             * @default 0
             * @type Number
             */
            this.setAttributeConfig("firstVisible", {
                    method    : this._setFirstVisible,
                    validator : this._validateFirstVisible,
                    value     : attrs.firstVisible || this.CONFIG.FIRST_VISIBLE
            });

            /**
             * @attribute selectOnScroll
             * @description Set this to true to automatically set focus to
             * follow scrolling in the Carousel.
             * @default true
             * @type Boolean
             */
            this.setAttributeConfig("selectOnScroll", {
                    validator : JS.isBoolean,
                    value     : attrs.selectOnScroll || true
            });

            /**
             * @attribute numVisible
             * @description The number of visible items in the Carousel's
             * viewport.
             * @default 3
             * @type Number
             */
            this.setAttributeConfig("numVisible", {
                    method    : this._setNumVisible,
                    validator : this._validateNumVisible,
                    value     : attrs.numVisible || this.CONFIG.NUM_VISIBLE
            });

            /**
             * @attribute numItems
             * @description The number of items in the Carousel.
             * @type Number
             */
            this.setAttributeConfig("numItems", {
                    method    : this._setNumItems,
                    validator : this._validateNumItems,
                    value     : this._itemsTable.numItems
            });

            /**
             * @attribute scrollIncrement
             * @description The number of items to scroll by for arrow keys.
             * @default 1
             * @type Number
             */
            this.setAttributeConfig("scrollIncrement", {
                    validator : this._validateScrollIncrement,
                    value     : attrs.scrollIncrement || 1
            });

            /**
             * @attribute selectedItem
             * @description The index of the selected item.
             * @type Number
             */
            this.setAttributeConfig("selectedItem", {
                    method    : this._setSelectedItem,
                    validator : JS.isNumber,
                    value     : 0
            });

            /**
             * @attribute revealAmount
             * @description The percentage of the item to be revealed on each
             * side of the Carousel (before and after the first and last item
             * in the Carousel's viewport.)
             * @default 0
             * @type Number
             */
            this.setAttributeConfig("revealAmount", {
                    method    : this._setRevealAmount,
                    validator : this._validateRevealAmount,
                    value     : attrs.revealAmount || 0
            });

            /**
             * @attribute isCircular
             * @description Set this to true to wrap scrolling of the contents
             * in the Carousel.
             * @default false
             * @type Boolean
             */
            this.setAttributeConfig("isCircular", {
                    validator : JS.isBoolean,
                    value     : attrs.isCircular || false
            });

            /**
             * @attribute isVertical
             * @description True if the orientation of the Carousel is vertical
             * @default false
             * @type Boolean
             */
            this.setAttributeConfig("isVertical", {
                    method    : this._setOrientation,
                    validator : JS.isBoolean,
                    value     : attrs.isVertical || false
            });

            /**
             * @attribute navigation
             * @description The set of navigation controls for Carousel
             * @default <br>
             * { prev: null, // the previous navigation element<br>
             *   next: null } // the next navigation element
             * @type Object
             */
            this.setAttributeConfig("navigation", {
                    method    : this._setNavigation,
                    validator : this._validateNavigation,
                    value     : attrs.navigation || {
                                        prev: null, next: null, page: null }
            });

            /**
             * @attribute animation
             * @description The optional animation attributes for the Carousel.
             * @default <br>
             * { speed: 0, // the animation speed (in seconds)<br>
             *   effect: null } // the animation effect (like
             *   YAHOO.util.Easing.easeOut)
             * @type Object
             */
            this.setAttributeConfig("animation", {
                    validator : this._validateAnimation,
                    value     : attrs.animation || { speed: 0, effect: null }
            });

            /**
             * @attribute autoPlay
             * @description Set this to time in milli-seconds to have the
             * Carousel automatically scroll the contents.
             * @type Number
             */
            this.setAttributeConfig("autoPlay", {
                    validator : JS.isNumber,
                    value     : attrs.autoPlay || 0
            });
        },

        /**
         * Initialize and bind the event handlers.
         *
         * @method initEvents
         * @public
         */
        initEvents: function () {
            var cssClass = this.CLASSES;

            this.on("keydown", this._keyboardEventHandler);

            this.subscribe(afterScrollEvent, syncNavigation);
            this.on(afterScrollEvent, this.focus);

            this.subscribe(itemAddedEvent, syncUI);
            this.subscribe(itemAddedEvent, syncNavigation);

            this.subscribe(itemRemovedEvent, syncUI);
            this.subscribe(itemRemovedEvent, syncNavigation);

            this.on(itemSelectedEvent, this.focus);

            this.subscribe(loadItemsEvent, syncUI);

            this.subscribe(pageChangeEvent, this._syncPagerUI);

            this.subscribe(renderEvent, syncNavigation);
            this.subscribe(renderEvent, this._syncPagerUI);

            this.on("selectedItemChange", function (ev) {
                setItemSelection.call(this, ev.newValue, ev.prevValue);
                this._updateTabIndex(this.getElementForItem(ev.newValue));
                this.fireEvent(itemSelectedEvent, ev.newValue);
            });

            this.on("firstVisibleChange", function (ev) {
                if (!this.get("selectOnScroll")) {
                    this._updateTabIndex(this.getElementForItem(ev.newValue));
                }
            });

            // Handle item selection on mouse click
            this.on("click", this._itemClickHandler);

            // Handle page navigation
            this.on("click", this._pagerClickHandler);

            // Restore the focus on the navigation buttons
            Event.onFocus(this.get("element"), function (ev, obj) {
                obj._updateNavButtons(Event.getTarget(ev), true);
            }, this);

            Event.onBlur(this.get("element"), function (ev, obj) {
                obj._updateNavButtons(Event.getTarget(ev), false);
            }, this);

        },

        /**
         * Return the ITEM_TAG_NAME at index or null if the index is not found.
         *
         * @method getElementForItem
         * @param index {Number} The index of the item to be returned
         * @return {Element} Return the item at index or null if not found
         * @public
         */
        getElementForItem: function (index) {
            if (index < 0 || index >= this.get("numItems")) {
                YAHOO.log("Index out of bounds", "error", WidgetName);
                return null;
            }

            // TODO: may be cache the item
            if (this._itemsTable.numItems > index) {
                if (!JS.isUndefined(this._itemsTable.items[index])) {
                    return Dom.get(this._itemsTable.items[index].id);
                }
            }

            return null;
        },

        /**
         * Return the ITEM_TAG_NAME for all items in the Carousel.
         *
         * @method getElementForItems
         * @return {Array} Return all the items
         * @public
         */
        getElementForItems: function () {
            var els = [], i;

            for (i = 0; i < this._itemsTable.numItems; i++) {
                els.push(this.getElementForItem(i));
            }

            return els;
        },

        /**
         * Return the item at index or null if the index is not found.
         *
         * @method getItem
         * @param index {Number} The index of the item to be returned
         * @return {Object} Return the item at index or null if not found
         * @public
         */
        getItem: function (index) {
            if (index < 0 || index >= this.get("numItems")) {
                YAHOO.log("Index out of bounds", "error", WidgetName);
                return null;
            }

            if (this._itemsTable.numItems > index) {
                if (!JS.isUndefined(this._itemsTable.items[index])) {
                    return this._itemsTable.items[index];
                }
            }

            return null;
        },

        /**
         * Return all items as an array.
         *
         * @method getItems
         * @return {Array} Return all items in the Carousel
         * @public
         */
        getItems: function (index) {
            return this._itemsTable.items;
        },

        /**
         * Return the position of the Carousel item that has the id "id", or -1
         * if the id is not found.
         *
         * @method getItemPositionById
         * @param index {Number} The index of the item to be returned
         * @public
         */
        getItemPositionById: function (id) {
            var i = 0, n = this._itemsTable.numItems;

            while (i < n) {
                if (!JS.isUndefined(this._itemsTable.items[i])) {
                    if (this._itemsTable.items[i].id == id) {
                        return i;
                    }
                }
                i++;
            }

            return -1;
        },

        /**
         * Remove an item at index from the Carousel.
         *
         * @method removeItem
         * @public
         * @param index {Number} The position to where in the list (starts from
         * zero).
         * @return {Boolean} Return true on success, false otherwise
         */
        removeItem: function (index) {
            var item, num = this.get("numItems");

            if (index < 0 || index >= num) {
                YAHOO.log("Index out of bounds", "error", WidgetName);
                return false;
            }

            item = this._itemsTable.items.splice(index, 1);
            if (item && item.length == 1) {
                this.set("numItems", num - 1);

                this.fireEvent(itemRemovedEvent,
                        { item: item[0], pos: index, ev: itemRemovedEvent });
                return true;
            }

            return false;
        },

        /**
         * Render the Carousel.
         *
         * @method render
         * @public
         * @param appendTo {HTMLElement | String} The element to which the
         * Carousel should be appended prior to rendering.
         * @return {Boolean} Status of the operation
         */
        render: function (appendTo) {
            var config = this.CONFIG,
                cssClass = this.CLASSES,
                size;

            this.addClass(cssClass.CAROUSEL);

            if (!this._clipEl) {
                this._clipEl = this._createCarouselClip();
                this._clipEl.appendChild(this._carouselEl);
            }

            if (appendTo) {
                this.appendChild(this._clipEl);
                this.appendTo(appendTo);
                this._setClipContainerSize();
            } else {
                if (!Dom.inDocument(this.get("element"))) {
                    YAHOO.log("Nothing to render. The container should be " +
                            "within the document if appendTo is not "       +
                            "specified", "error", WidgetName);
                    return false;
                }
                this.appendChild(this._clipEl);
            }

            if (this.get("isVertical")) {
                size = getCarouselItemSize.call(this);
                size = size < config.MIN_WIDTH ? config.MIN_WIDTH : size;
                this.setStyle("width",  size + "px");
                this.addClass(cssClass.VERTICAL);
            } else {
                this.addClass(cssClass.HORIZONTAL);
            }

            if (this.get("numItems") < 1) {
                YAHOO.log("No items in the Carousel to render", "warn",
                        WidgetName);
                return false;
            }

            // Make sure at least one item is selected
            this.set("selectedItem", this.get("firstVisible"));

            this.fireEvent(renderEvent);

            // By now, the navigation would have been rendered, so calculate
            // the container height now.
            this._setContainerSize();

            return true;
        },

        /**
         * Scroll the Carousel by an item backward.
         *
         * @method scrollBackward
         * @public
         */
        scrollBackward: function () {
            this.scrollTo(this._firstItem - this.get("scrollIncrement"));
        },

        /**
         * Scroll the Carousel by an item forward.
         *
         * @method scrollForward
         * @public
         */
        scrollForward: function () {
            this.scrollTo(this._firstItem + this.get("scrollIncrement"));
        },

        /**
         * Scroll the Carousel by a page backward.
         *
         * @method scrollPageBackward
         * @public
         */
        scrollPageBackward: function () {
            this.scrollTo(this._firstItem - this.get("numVisible"));
        },

        /**
         * Scroll the Carousel by a page forward.
         *
         * @method scrollPageForward
         * @public
         */
        scrollPageForward: function () {
            this.scrollTo(this._firstItem + this.get("numVisible"));
        },

        /**
         * Scroll the Carousel to make the item the first visible item.
         *
         * @method scrollTo
         * @public
         * @param item Number The index of the element to position at.
         * @param dontSelect Boolean True if select should be avoided
         */
        scrollTo: function (item, dontSelect) {
            var anim,
                animate,
                animAttrs,
                animCfg    = this.get("animation"),
                isCircular = this.get("isCircular"),
                delta,
                direction,
                firstItem  = this._firstItem,
                newPage,
                numItems   = this.get("numItems"),
                numPerPage = this.get("numVisible"),
                offset,
                page       = this.get("currentPage"),
                rv,
                sentinel,
                which;

            if (item == firstItem) {
                return;         // nothing to do!
            }

            if (this._isAnimationInProgress) {
                return;         // let it take its own sweet time to complete
            }

            if (item < 0) {
                if (isCircular) {
                    item = numItems + item;
                } else {
                    return;
                }
            } else if (item > numItems - 1) {
                if (this.get("isCircular")) {
                    item = numItems - item;
                } else {
                    return;
                }
            }

            direction = (this._firstItem > item) ? "backward" : "forward";

            sentinel  = firstItem + numPerPage;
            sentinel  = (sentinel > numItems - 1) ? numItems - 1 : sentinel;
            rv = this.fireEvent(beforeScrollEvent,
                    { dir: direction, first: firstItem, last: sentinel });
            if (rv === false) { // scrolling is prevented
                return;
            }

            this.fireEvent(beforePageChangeEvent, { page: page });

            delta = firstItem - item; // yes, the delta is reverse
            this._firstItem = item;
            this.set("firstVisible", item);

            YAHOO.log("Scrolling to " + item + " delta = " + delta, WidgetName);

            loadItems.call(this); // do we have all the items to display?

            sentinel  = item + numPerPage;
            sentinel  = (sentinel > numItems - 1) ? numItems - 1 : sentinel;

            which     = this.get("isVertical") ? "top" : "left";
            offset    = getScrollOffset.call(this, delta);
            YAHOO.log("Scroll offset = " + offset, WidgetName);

            animate   = animCfg.speed > 0;

            if (animate) {
                this._isAnimationInProgress = true;
                if (this.get("isVertical")) {
                    animAttrs = { points: { by: [0, offset] } };
                } else {
                    animAttrs = { points: { by: [offset, 0] } };
                }
                anim = new YAHOO.util.Motion(this._carouselEl, animAttrs,
                        animCfg.speed, animCfg.effect);
                anim.onComplete.subscribe(function (ev) {
                    var first = this.get("firstVisible");

                    this._isAnimationInProgress = false;
                    this.fireEvent(afterScrollEvent,
                            { first: first, last: sentinel });
                }, null, this);
                anim.animate();
                anim = null;
            } else {
                offset += getStyle(this._carouselEl, which);
                Dom.setStyle(this._carouselEl, which, offset + "px");
            }

            newPage = parseInt(this._firstItem / numPerPage, 10);
            if (newPage != page) {
                this.setAttributeConfig("currentPage", { value: newPage });
                this.fireEvent(pageChangeEvent, newPage);
            }

            if (!dontSelect) {
                if (this.get("selectOnScroll")) {
                    if (item != this._selectedItem) { // out of sync
                        this.set("selectedItem", this._getSelectedItem(item));
                    }
                }
            }

            delete this._autoPlayTimer;
            if (this.get("autoPlay") > 0) {
                this.startAutoPlay();
            }

            if (!animate) {
                this.fireEvent(afterScrollEvent,
                        { first: item, last: sentinel });
            }
        },

        /**
         * Display the Carousel.
         *
         * @method show
         * @public
         */
        show: function () {
            var cssClass = this.CLASSES;

            if (this.fireEvent(beforeShowEvent) !== false) {
                this.addClass(cssClass.VISIBLE);
                this.fireEvent(showEvent);
            }
        },

        /**
         * Start auto-playing the Carousel.
         *
         * @method startAutoPlay
         * @public
         */
        startAutoPlay: function () {
            var self  = this,
                timer = this.get("autoPlay");

            if (timer > 0) {
                if (!JS.isUndefined(this._autoPlayTimer)) {
                    return;
                }
                this.fireEvent(startAutoPlayEvent);
                this._autoPlayTimer = setTimeout(function () {
                    autoScroll.call(self); }, timer);
            }
        },

        /**
         * Stop auto-playing the Carousel.
         *
         * @method stopAutoPlay
         * @public
         */
        stopAutoPlay: function () {
            if (!JS.isUndefined(this._autoPlayTimer)) {
                clearTimeout(this._autoPlayTimer);
                delete this._autoPlayTimer;
                this.set("autoPlay", 0);
                this.fireEvent(stopAutoPlayEvent);
            }
        },

        /**
         * Return the string representation of the Carousel.
         *
         * @method toString
         * @public
         * @return {String}
         */
        toString: function () {
            return WidgetName + (this.get ? " (#" + this.get("id") + ")" : "");
        },

        /*
         * Protected methods of the Carousel component
         */

        /**
         * Create the Carousel.
         *
         * @method createCarousel
         * @param elId {String} The id of the element to be created
         * @protected
         */
        _createCarousel: function (elId) {
            var cssClass = this.CLASSES;

            var el = createElement("DIV", {
                    className : cssClass.CAROUSEL,
                    id        : elId
            });

            if (!this._carouselEl) {
                this._carouselEl = createElement(this.CONFIG.TAG_NAME,
                        { className: cssClass.CAROUSEL_EL });
            }

            return el;
        },

        /**
         * Create the Carousel clip container.
         *
         * @method createCarouselClip
         * @protected
         */
        _createCarouselClip: function () {
            var el = createElement("DIV", { className: this.CLASSES.CONTENT });
            this._setClipContainerSize(el);

            return el;
        },

        /**
         * Create the Carousel item.
         *
         * @method createCarouselItem
         * @param obj {Object} The attributes of the element to be created
         * @protected
         */
        _createCarouselItem: function (obj) {
            return createElement(this.CONFIG.ITEM_TAG_NAME, {
                    className : obj.className,
                    content   : obj.content,
                    id        : obj.id
            });
        },

        /**
         * Get the value for the selected item.
         *
         * @method _getSelectedItem
         * @param val {Number} The new value for "selected" item
         * @return {Number} The new value that would be set
         * @protected
         */
        _getSelectedItem: function (val) {
            var isCircular = this.get("isCircular"),
                numItems   = this.get("numItems"),
                sentinel   = numItems - 1;

            if (val < 0) {
                if (isCircular) {
                    val = numItems + val;
                } else {
                    val = this.get("selectedItem");
                }
            } else if (val > sentinel) {
                if (isCircular) {
                    val = val - numItems;
                } else {
                    val = this.get("selectedItem");
                }
            }

            return val;
        },

        /**
         * The "click" handler for the item.
         *
         * @method _itemClickHandler
         * @param {Event} ev The event object
         * @protected
         */
        _itemClickHandler: function (ev) {
            var container = this.get("element"),
                el,
                item,
                target = YAHOO.util.Event.getTarget(ev);

            while (target && target != container &&
                   target.id != this._carouselEl) {
                el = target.nodeName;
                if (el.toUpperCase() == this.CONFIG.ITEM_TAG_NAME) {
                    break;
                }
                target = target.parentNode;
            }

            if ((item = this.getItemPositionById(target.id)) >= 0) {
                YAHOO.log("Setting selection to " + item, WidgetName);
                this.set("selectedItem", this._getSelectedItem(item));
            }
        },

        /**
         * The keyboard event handler for Carousel.
         *
         * @method _keyboardEventHandler
         * @param ev {Event} The event that is being handled.
         * @protected
         */
        _keyboardEventHandler: function (ev) {
            var key      = Event.getCharCode(ev),
                prevent  = false,
                position = 0,
                selItem;

            if (this._isAnimationInProgress) {
                return;         // do not mess while animation is in progress
            }

            switch (key) {
            case 0x25:          // left arrow
            case 0x26:          // up arrow
                selItem = this.get("selectedItem");
                if (selItem == this._firstItem) {
                    position = selItem - this.get("numVisible");
                    this.scrollTo(position);
                    this.set("selectedItem", this._getSelectedItem(selItem-1));
                } else {
                    position = this.get("selectedItem") -
                            this.get("scrollIncrement");
                    this.set("selectedItem", this._getSelectedItem(position));
                }
                prevent = true;
                break;
            case 0x27:          // right arrow
            case 0x28:          // down arrow
                position = this.get("selectedItem")+this.get("scrollIncrement");
                this.set("selectedItem", this._getSelectedItem(position));
                prevent = true;
                break;
            case 0x21:          // page-up
                this.scrollPageBackward();
                prevent = true;
                break;
            case 0x22:          // page-down
                this.scrollPageForward();
                prevent = true;
                break;
            }

            if (prevent) {
                Event.preventDefault(ev);
            }
        },

        /**
         * The "click" handler for the pager navigation.
         *
         * @method _pagerClickHandler
         * @param {Event} ev The event object
         * @protected
         */
        _pagerClickHandler: function (ev) {
            var pos, target, val;

            target = Event.getTarget(ev);
            val = target.href || target.value;
            if (JS.isString(val) && val) {
                pos = val.lastIndexOf("#");
                if (pos != -1) {
                    val = this.getItemPositionById(val.substring(pos + 1));
                    this.scrollTo(val);
                    Event.preventDefault(ev);
                }
            }
        },

        /**
         * Find the Carousel within a container. The Carousel is identified by
         * the first element that matches the carousel element tag or the
         * element that has the Carousel class.
         *
         * @method parseCarousel
         * @param parent {HTMLElement} The parent element to look under
         * @return {Boolean} True if Carousel is found, false otherwise
         * @protected
         */
        _parseCarousel: function (parent) {
            var child, cssClass, found, node;

            cssClass = this.CLASSES;
            found    = false;

            for (child = parent.firstChild; child; child = child.nextSibling) {
                if (child.nodeType == 1) {
                    node = child.nodeName;
                    if (node.toUpperCase() == this.CONFIG.TAG_NAME) {
                        this._carouselEl = child;
                        Dom.addClass(this._carouselEl,this.CLASSES.CAROUSEL_EL);
                        YAHOO.log("Found Carousel - " + node +
                                (child.id ? " (#" + child.id + ")" : ""),
                                WidgetName);
                        found = true;
                    }
                }
            }

            return found;
        },

        /**
         * Find the items within the Carousel and add them to the items table.
         * A Carousel item is identified by elements that matches the carousel
         * item element tag.
         *
         * @method parseCarouselItems
         * @protected
         */
        _parseCarouselItems: function () {
            var child,
                elId,
                node,
                parent = this._carouselEl;

            for (child = parent.firstChild; child; child = child.nextSibling) {
                if (child.nodeType == 1) {
                    node = child.nodeName;
                    if (node.toUpperCase() == this.CONFIG.ITEM_TAG_NAME) {
                        if (child.id) {
                            elId = child.id;
                        } else {
                            elId = Dom.generateId();
                            child.setAttribute("id", elId);
                        }
                        this.addItem(child);
                    }
                }
            }
        },

        /**
         * Find the Carousel navigation within a container. The navigation
         * elements need to match the carousel navigation class names.
         *
         * @method parseCarouselNavigation
         * @param parent {HTMLElement} The parent element to look under
         * @return {Boolean} True if at least one is found, false otherwise
         * @protected
         */
        _parseCarouselNavigation: function (parent) {
            var cfg, cssClass = this.CLASSES, el, i, j, nav, rv = false;

            nav = Dom.getElementsByClassName(cssClass.PREV_PAGE, "*", parent);
            if (nav.length > 0) {
                for (i in nav) {
                    if (nav.hasOwnProperty(i)) {
                        el = nav[i];
                        YAHOO.log("Found Carousel previous page navigation - " +
                                el + (el.id ? " (#" + el.id + ")" : ""),
                                WidgetName);
                        if (el.nodeName == "INPUT" ||
                            el.nodeName == "BUTTON") {
                            if (typeof this._navBtns.prev == "undefined") {
                                this._navBtns.prev = [];
                            }
                            this._navBtns.prev.push(el);
                        } else {
                            j = el.getElementsByTagName("INPUT");
                            if (JS.isArray(j) && j.length > 0) {
                                this._navBtns.prev.push(j[0]);
                            } else {
                                j = el.getElementsByTagName("BUTTON");
                                if (JS.isArray(j) && j.length > 0) {
                                    this._navBtns.prev.push(j[0]);
                                }
                            }
                        }
                    }
                }
                cfg = { prev: nav };
            }

            nav = Dom.getElementsByClassName(cssClass.NEXT_PAGE, "*", parent);
            if (nav.length > 0) {
                for (i in nav) {
                    if (nav.hasOwnProperty(i)) {
                        el = nav[i];
                        YAHOO.log("Found Carousel next page navigation - " +
                                el + (el.id ? " (#" + el.id + ")" : ""),
                                WidgetName);
                        if (el.nodeName == "INPUT" ||
                            el.nodeName == "BUTTON") {
                            if (typeof this._navBtns.next == "undefined") {
                                this._navBtns.next = [];
                            }
                            this._navBtns.next.push(el);
                        } else {
                            j = el.getElementsByTagName("INPUT");
                            if (JS.isArray(j) && j.length > 0) {
                                this._navBtns.next.push(j[0]);
                            } else {
                                j = el.getElementsByTagName("BUTTON");
                                if (JS.isArray(j) && j.length > 0) {
                                    this._navBtns.next.push(j[0]);
                                }
                            }
                        }
                    }
                }
                if (cfg) {
                    cfg.next = nav;
                } else {
                    cfg = { next: nav };
                }
            }

            if (cfg) {
                this.set("navigation", cfg);
                rv = true;
            }

            return rv;
        },

        /**
         * Setup/Create the Carousel navigation element (if needed).
         *
         * @method _setupCarouselNavigation
         * @protected
         */
        _setupCarouselNavigation: function () {
            var btn, cfg, cssClass, nav, navContainer, nextButton, pageEl,
                prevButton;

            cssClass = this.CLASSES;

            navContainer = Dom.getElementsByClassName(cssClass.NAVIGATION,
                    "DIV", this.get("element"));

            if (navContainer.length === 0) {
                navContainer = createElement("DIV",
                        { className: cssClass.NAVIGATION });
                this.insertBefore(navContainer,
                        Dom.getFirstChild(this.get("element")));
            } else {
                navContainer = navContainer[0];
            }

            this._pages.el = createElement("UL");
            navContainer.appendChild(this._pages.el);

            nav = this.get("navigation");
            if (nav.prev && nav.prev.length > 0) {
                navContainer.appendChild(nav.prev[0]);
            } else {
                // TODO: separate method for creating a navigation button
                prevButton = createElement("SPAN",
                        { className: cssClass.BUTTON + cssClass.FIRST_NAV });
                // XXX: for IE 6.x
                Dom.setStyle(prevButton, "visibility", "visible");
                btn = Dom.generateId();
                prevButton.innerHTML = "<input type=\"button\" " +
                        "id=\"" + btn + "\" " +
                        "value=\"" + this.STRINGS.PREVIOUS_BUTTON_TEXT + "\" " +
                        "name=\"" + this.STRINGS.PREVIOUS_BUTTON_TEXT + "\">";
                navContainer.appendChild(prevButton);
                btn = Dom.get(btn);
                this._navBtns.prev = [btn];
                cfg = { prev: [prevButton] };
            }

            if (nav.next && nav.next.length > 0) {
                navContainer.appendChild(nav.next[0]);
            } else {
                // TODO: separate method for creating a navigation button
                nextButton = createElement("SPAN",
                        { className: cssClass.BUTTON });
                // XXX: for IE 6.x
                Dom.setStyle(nextButton, "visibility", "visible");
                btn = Dom.generateId();
                nextButton.innerHTML = "<input type=\"button\" " +
                        "id=\"" + btn + "\" " +
                        "value=\"" + this.STRINGS.NEXT_BUTTON_TEXT + "\" " +
                        "name=\"" + this.STRINGS.NEXT_BUTTON_TEXT + "\">";
                navContainer.appendChild(nextButton);
                btn = Dom.get(btn);
                this._navBtns.next = [btn];
                if (cfg) {
                    cfg.next = [nextButton];
                } else {
                    cfg = { next: [nextButton] };
                }
            }

            if (cfg) {
                this.set("navigation", cfg);
            }

            return navContainer;
        },

        /**
         * Set the clip container size (based on the new numVisible value).
         *
         * @method _setClipContainerSize
         * @param clip {HTMLElement} The clip container element.
         * @param num {Number} optional The number of items per page.
         * @protected
         */
        _setClipContainerSize: function (clip, num) {
            var attr, currVal, isVertical, itemSize, reveal, size, which;

            isVertical = this.get("isVertical");
            reveal     = this.get("revealAmount");
            which      = isVertical ? "height" : "width";
            attr       = isVertical ? "top" : "left";

            clip       = clip || this._clipEl;
            if (!clip) {
                return;
            }

            num        = num  || this.get("numVisible");
            itemSize   = getCarouselItemSize.call(this, which);
            size       = itemSize * num;

            this._recomputeSize = (size === 0); // bleh!
            if (this._recomputeSize) {
                return;             // no use going further, bail out!
            }

            if (reveal > 0) {
                reveal = itemSize * (reveal / 100) * 2;
                size += reveal;
                // TODO: set the Carousel's initial offset somwehere
                currVal = parseFloat(Dom.getStyle(this._carouselEl, attr));
                currVal = JS.isNumber(currVal) ? currVal : 0;
                Dom.setStyle(this._carouselEl, attr, currVal+(reveal/2)+"px");
            }

            if (isVertical) {
                size += getStyle(this._carouselEl, "marginTop")     +
                        getStyle(this._carouselEl, "marginBottom")  +
                        getStyle(this._carouselEl, "paddingTop")    +
                        getStyle(this._carouselEl, "paddingBottom") +
                        getStyle(this._carouselEl, "borderTop")     +
                        getStyle(this._carouselEl, "borderBottom");
                // XXX: for vertical Carousel
                Dom.setStyle(clip, which, (size - (num - 1)) + "px");
            } else {
                size += getStyle(this._carouselEl, "marginLeft")    +
                        getStyle(this._carouselEl, "marginRight")   +
                        getStyle(this._carouselEl, "paddingLeft")   +
                        getStyle(this._carouselEl, "paddingRight")  +
                        getStyle(this._carouselEl, "borderLeft")    +
                        getStyle(this._carouselEl, "borderRight");
                Dom.setStyle(clip, which, size + "px");
            }

            this._setContainerSize(clip); // adjust the container size too
        },

        /**
         * Set the container size.
         *
         * @method _setContainerSize
         * @param clip {HTMLElement} The clip container element.
         * @param attr {String} Either set the height or width.
         * @protected
         */
        _setContainerSize: function (clip, attr) {
            var isVertical, size;

            isVertical = this.get("isVertical");
            clip       = clip || this._clipEl;
            attr       = attr || (isVertical ? "height" : "width");
            size       = parseFloat(Dom.getStyle(clip, attr), 10);

            size = JS.isNumber(size) ? size : 0;

            size += getStyle(clip, "marginLeft")   +
                    getStyle(clip, "marginRight")  +
                    getStyle(clip, "paddingLeft")  +
                    getStyle(clip, "paddingRight") +
                    getStyle(clip, "borderLeft")   +
                    getStyle(clip, "borderRight");

            if (isVertical) {
                size += getStyle(this._navEl, "height");
            }

            this.setStyle(attr, size + "px");
        },

        /**
         * Set the value for the Carousel's first visible item.
         *
         * @method _setFirstVisible
         * @param val {Number} The new value for firstVisible
         * @return {Number} The new value that would be set
         * @protected
         */
        _setFirstVisible: function (val) {
            if (val >= 0 && val < this.get("numItems")) {
                this.scrollTo(val);
            } else {
                val = this.get("firstVisible");
            }
            return val;
        },

        /**
         * Set the value for the Carousel's navigation.
         *
         * @method _setNavigation
         * @param cfg {Object} The navigation configuration
         * @return {Object} The new value that would be set
         * @protected
         */
        _setNavigation: function (cfg) {
            if (cfg.prev) {
                Event.on(cfg.prev, "click", scrollPageBackward, this);
            }
            if (cfg.next) {
                Event.on(cfg.next, "click", scrollPageForward, this);
            }
        },

        /**
         * Set the value for the number of visible items in the Carousel.
         *
         * @method _setNumVisible
         * @param val {Number} The new value for numVisible
         * @return {Number} The new value that would be set
         * @protected
         */
        _setNumVisible: function (val) {
            if (val > 1 && val < this.get("numItems")) {
                this._setClipContainerSize(this._clipEl, val);
            } else {
                val = this.get("numVisible");
            }
            return val;
        },

        /**
         * Set the number of items in the Carousel.
         * Warning: Setting this to a lower number than the current removes
         * items from the end.
         *
         * @method _setNumItems
         * @param val {Number} The new value for numItems
         * @return {Number} The new value that would be set
         * @protected
         */
        _setNumItems: function (val) {
            var num = this._itemsTable.numItems;

            if (JS.isArray(this._itemsTable.items)) {
                if (this._itemsTable.items.length != num) { // out of sync
                    num = this._itemsTable.items.length;
                    this._itemsTable.numItems = num;
                }
            }

            if (val < num) {
                while (num > val) {
                    this.removeItem(num - 1);
                    num--;
                }
            }

            return val;
        },

        /**
         * Set the orientation of the Carousel.
         *
         * @method _setOrientation
         * @param val {Boolean} The new value for isVertical
         * @return {Boolean} The new value that would be set
         * @protected
         */
        _setOrientation: function (val) {
            var cssClass = this.CLASSES;

            if (val) {
                this.replaceClass(cssClass.HORIZONTAL, cssClass.VERTICAL);
            } else {
                this.replaceClass(cssClass.VERTICAL, cssClass.HORIZONTAL);
            }
            this._itemsTable.size = 0; // invalidate our size computation cache
            return val;
        },

        /**
         * Set the value for the reveal amount percentage in the Carousel.
         *
         * @method _setRevealAmount
         * @param val {Number} The new value for revealAmount
         * @return {Number} The new value that would be set
         * @protected
         */
        _setRevealAmount: function (val) {
            if (val >= 0 && val <= 100) {
                val = parseInt(val, 10);
                val = JS.isNumber(val) ? val : 0;
                this._setClipContainerSize();
            } else {
                val = this.get("revealAmount");
            }
            return val;
        },

        /**
         * Set the value for the selected item.
         *
         * @method _setSelectedItem
         * @param val {Number} The new value for "selected" item
         * @protected
         */
        _setSelectedItem: function (val) {
            this._selectedItem = val;
        },

        /**
         * Synchronize and redraw the Pager UI if necessary.
         *
         * @method _syncPagerUI
         * @protected
         */
        _syncPagerUI: function (page) {
            var a,
                cssClass = this.CLASSES,
                i,
                markup     = "",
                numPages,
                numVisible = this.get("numVisible");

            page     = page || 0;
            numPages = Math.ceil(this.get("numItems") / numVisible);

            this._pages.num = numPages;
            this._pages.cur = page;

            if (numPages > this.CONFIG.MAX_PAGER_BUTTONS) {
                markup = "<form><select>";
            } else {
                markup = "";
            }

            for (i = 0; i < numPages; i++) {
                if (JS.isUndefined(this._itemsTable.items[i * numVisible])) {
                    break;
                }
                a = this._itemsTable.items[i * numVisible].id;
                if (numPages > this.CONFIG.MAX_PAGER_BUTTONS) {
                    markup += "<option value=\"#" + a + "\" "            +
                            (i == page ? " selected" : "") + ">"         +
                            this.STRINGS.PAGER_PREFIX_TEXT + " " + (i+1) +
                            "</option>";
                } else {
                    markup += "<li class=\""                                   +
                            (i === 0 ? cssClass.FIRST_PAGE : "")               +
                            (i == page ? " " + cssClass.SELECTED_NAV : "")     +
                            "\"><a href=\"#" + a + "\" tabindex=\"0\"><em>"    +
                            this.STRINGS.PAGER_PREFIX_TEXT + " " + (i+1)       +
                            "</em></a></li>";
                }
            }

            if (numPages > this.CONFIG.MAX_PAGER_BUTTONS) {
                markup += "</select></form>";
            }

            this._pages.el.innerHTML = markup;
            markup = null;
        },

        /**
         * Set the correct class for the navigation buttons.
         *
         * @method _updateNavButtons
         * @param el {Object} The target button
         * @param setFocus {Boolean} True to set focus ring, false otherwise.
         * @protected
         */
        _updateNavButtons: function (el, setFocus) {
            var children,
                cssClass = this.CLASSES,
                grandParent,
                parent   = el.parentNode;

            if (!parent) {
                return;
            }
            grandParent = parent.parentNode;

            if (el.nodeName.toUpperCase() == "INPUT" &&
                Dom.hasClass(parent, cssClass.BUTTON)) {
                if (setFocus) {
                    if (grandParent) {
                        children = Dom.getChildren(grandParent);
                        if (children) {
                            Dom.removeClass(children, cssClass.FOCUSSED_BUTTON);
                        }
                    }
                    Dom.addClass(parent, cssClass.FOCUSSED_BUTTON);
                } else {
                    Dom.removeClass(parent, cssClass.FOCUSSED_BUTTON);
                }
            }
        },

        /**
         * Set the correct tab index for the Carousel items.
         *
         * @method _updateTabIndex
         * @param el {Object} The element to be focussed
         * @protected
         */
        _updateTabIndex: function (el) {
            if (el) {
                if (this._focusableItemEl) {
                    this._focusableItemEl.tabIndex = -1;
                }
                this._focusableItemEl = el;
                el.tabIndex = 0;
            }
        },

        /**
         * Validate animation parameters.
         *
         * @method _validateAnimation
         * @param cfg {Object} The animation configuration
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateAnimation: function (cfg) {
            var rv = true;

            if (JS.isObject(cfg)) {
                if (cfg.speed) {
                    rv = rv && JS.isNumber(cfg.speed);
                }
                if (cfg.effect) {
                    rv = rv && JS.isFunction(cfg.effect);
                } else if (!JS.isUndefined(YAHOO.util.Easing)) {
                    cfg.effect = YAHOO.util.Easing.easeOut;
                }
            } else {
                rv = false;
            }

            return rv;
        },

        /**
         * Validate the firstVisible value.
         *
         * @method _validateFirstVisible
         * @param val {Number} The first visible value
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateFirstVisible: function (val) {
            var rv = false;

            if (JS.isNumber(val)) {
                rv = (val >= 0 && val < this.get("numItems"));
            }

            return rv;
        },

        /**
         * Validate and navigation parameters.
         *
         * @method _validateNavigation
         * @param cfg {Object} The navigation configuration
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateNavigation : function (cfg) {
            var i;

            if (!JS.isObject(cfg)) {
                return false;
            }

            if (cfg.prev) {
                if (!JS.isArray(cfg.prev)) {
                    return false;
                }
                for (i in cfg.prev) {
                    if (cfg.prev.hasOwnProperty(i)) {
                        if (!JS.isString(cfg.prev[i].nodeName)) {
                            return false;
                        }
                    }
                }
            }

            if (cfg.next) {
                if (!JS.isArray(cfg.next)) {
                    return false;
                }
                for (i in cfg.next) {
                    if (cfg.next.hasOwnProperty(i)) {
                        if (!JS.isString(cfg.next[i].nodeName)) {
                            return false;
                        }
                    }
                }
            }

            return true;
        },

        /**
         * Validate the numItems value.
         *
         * @method _validateNumItems
         * @param val {Number} The numItems value
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateNumItems: function (val) {
            var rv = false;

            if (JS.isNumber(val)) {
                rv = val > 0;
            }

            return rv;
        },

        /**
         * Validate the numVisible value.
         *
         * @method _validateNumVisible
         * @param val {Number} The numVisible value
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateNumVisible: function (val) {
            var rv = false;

            if (JS.isNumber(val)) {
                rv = val > 0 && val < this.get("numItems");
            }

            return rv;
        },

        /**
         * Validate the revealAmount value.
         *
         * @method _validateRevealAmount
         * @param val {Number} The revealAmount value
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateRevealAmount: function (val) {
            var rv = false;

            if (JS.isNumber(val)) {
                rv = val >= 0 && val < 100;
            }

            return rv;
        },

        /**
         * Validate the scrollIncrement value.
         *
         * @method _validateScrollIncrement
         * @param val {Number} The scrollIncrement value
         * @return {Boolean} The status of the validation
         * @protected
         */
        _validateScrollIncrement: function (val) {
            var rv = false;

            if (JS.isNumber(val)) {
                rv = (val > 0 && val < this.get("numItems"));
            }

            return rv;
        }

    });

})();

YAHOO.register("carousel", YAHOO.widget.Carousel, {version: "2.6.0", build: "1321"});
