/* Same content slider used on http://www2.illinois.gov/Pages/default.aspx */

var Rotator =
{
    SELECTOR_FOR_ROTATOR_PARENT: 'div.rotator',

    SELECTOR_FOR_THUMBNAILS: 'ol.thumbnails',
    SELECTOR_FOR_TABS: 'ul.tabsRotator',

    TAGNAME_FOR_THUMBNAIL_ELEMENTS: 'li',
    TAGNAME_FOR_TAB_ELEMENTS: 'li',

    CLASS_FOR_CURRENT_ELEMENT: 'current',
    CLASS_FOR_HOVER_STATE: 'hover',

    /* 
    If the keyboard is used to navigate (which is fine), 
    this flag is added. At present, this flag prevents
    any auto-rotation with the idea that keyboard-based
    users may find auto-rotation non-ideal.
    */
    CLASS_FOR_HAS_KEYBOARD_USE_FLAG: 'has-keyboard-use',

    TIME_IN_SECONDS_BETWEEN_ROTATIONS: 12, 

    rotatorElements: [],

    init: function() {
        var self = this;

        $(this.SELECTOR_FOR_ROTATOR_PARENT).each(function() {
            /*
            Comments:

        * The "aria-hidden" attribute tells screen readers that the element is hidden from view. 
            http://www.w3.org/TR/2009/WD-wai-aria-20091215/states_and_properties#aria-hidden
            */

            // If no items are marked as "current", auto-mark the first one as such
            var currentThumbnail = $(this)
              .find(self.SELECTOR_FOR_THUMBNAILS)
              .children('.' + self.CLASS_FOR_CURRENT_ELEMENT);

            if (!currentThumbnail || !currentThumbnail.length) {
                // Add the 'current' class to the thumbnails
                $(this).find(self.SELECTOR_FOR_THUMBNAILS)
          .children().eq(0).addClass(self.CLASS_FOR_CURRENT_ELEMENT);

                // Add the 'current' class to the tabs
                $(this).find(self.SELECTOR_FOR_TABS)
          .children().eq(0).addClass(self.CLASS_FOR_CURRENT_ELEMENT)
                //.siblings().hide();
            }

            // Initialize some WAI-ARIA bits
            $(this).find(self.SELECTOR_FOR_TABS)
        .children('.' + self.CLASS_FOR_CURRENT_ELEMENT)
            //.attr('aria-hidden','false')
            //.siblings().attr('aria-hidden','true');

            /* This helps track whether the rotator should pause */
            $(this)
        .mouseenter(function() {
            $(this).addClass(self.CLASS_FOR_HOVER_STATE);

                    // 10 December 2010 removed do to user feedback regarding focus shift issue
            // Make sure the current tab is focused
//            $(this).find(self.SELECTOR_FOR_TABS)
//            .children('.' + self.CLASS_FOR_CURRENT_ELEMENT)
//            .attr('tabindex', '-1')
//            .focus();
        })
        .mouseleave(function() {
            $(this).removeClass(self.CLASS_FOR_HOVER_STATE);
        });

            $(this).find(self.SELECTOR_FOR_THUMBNAILS).find('a')
          .bind('mouseenter focus', function() {
              self.selectThisThumbnail(this, { shouldFocusElement: true });
          }); // end of bind

            self.rotatorElements.push(this);

            $(this).keydown(function(event) {
                /* 
                9 - tab
                37 - left
                38 - up
                39 - right
                40 - down 
                */

                switch (event.which) {
                    case 9:
                        // Tab

                        $(this).addClass(self.CLASS_FOR_HAS_KEYBOARD_USE_FLAG);
                        break;

                    case 37:
                        // Left
                        self.moveRotatorToPrevious(this,
              {
                  shouldCheckForHoverState: false,
                  shouldFocusElement: true
              });
                        event.preventDefault();
                        event.stopPropagation();

                        $(this).addClass(self.CLASS_FOR_HAS_KEYBOARD_USE_FLAG);
                        break;

                    case 38:
                        // Up
                        self.moveRotatorToPrevious(this,
              {
                  shouldCheckForHoverState: false,
                  shouldFocusElement: true
              });
                        event.preventDefault();
                        event.stopPropagation();

                        $(this).addClass(self.CLASS_FOR_HAS_KEYBOARD_USE_FLAG);
                        break;

                    case 39:
                        // Right
                        self.moveRotatorToNext(this,
              {
                  shouldCheckForHoverState: false,
                  shouldFocusElement: true
              });
                        event.preventDefault();
                        event.stopPropagation();

                        $(this).addClass(self.CLASS_FOR_HAS_KEYBOARD_USE_FLAG);
                        break;

                    case 40:
                        // Down
                        self.moveRotatorToNext(this,
              {
                  shouldCheckForHoverState: false,
                  shouldFocusElement: true
              });
                        event.preventDefault();
                        event.stopPropagation();

                        $(this).addClass(self.CLASS_FOR_HAS_KEYBOARD_USE_FLAG);
                        break;
                }


            }); // end of arrow-key bindings

        }); // end of rotator-this-iteration


        if (this.rotatorElements && this.rotatorElements.length) {
            this.timeInMillisecondsBetweenRotations = this.TIME_IN_SECONDS_BETWEEN_ROTATIONS * 1000;

            window.setTimeout(function() {
                self.rotateIt();
            }, this.timeInMillisecondsBetweenRotations);
        }
    },

    /*
    Potential option:
    { shouldFocusElement: true }
    - or -
    { shouldFocusElement: false }
    */
    selectThisThumbnail: function(anchorElement, options) {
        $(anchorElement)
      .parent().addClass(this.CLASS_FOR_CURRENT_ELEMENT)
      .siblings().removeClass(this.CLASS_FOR_CURRENT_ELEMENT);

        // Get the position of this guy
        var position = $(anchorElement).parents(this.SELECTOR_FOR_THUMBNAILS)
          .children().index($(anchorElement).parents(this.TAGNAME_FOR_THUMBNAIL_ELEMENTS));

        // console.log("Position of thumbnail: " + position);


        // Set the appropriate tab to show
        var tabChildren = $(anchorElement)
              .parents(this.SELECTOR_FOR_ROTATOR_PARENT)
              .find(this.SELECTOR_FOR_TABS).children();

        // If the current guy == index, then nevermind

        var currentTab = tabChildren.filter('.' + this.CLASS_FOR_CURRENT_ELEMENT);

        if (position == tabChildren.index(currentTab)) {
            // console.log("already selected");
            return;
        }
        else {
            /* Hide the currently-displayed tab */
            currentTab
            //.hide()
            //.attr('aria-hidden','true')
        //.attr('tabindex', '-1')
        .removeClass(this.CLASS_FOR_CURRENT_ELEMENT);

            /* Show the newly selected tab */
            tabChildren.eq(position)
            //.show()
            //.attr('aria-hidden','false')
        //.attr('tabindex', '-1')
        .addClass(this.CLASS_FOR_CURRENT_ELEMENT);


            if (
        (typeof options != "undefined") &&
        (options.shouldFocusElement)
        ) {
                tabChildren.eq(position).focus();
            }
        }
    },

    /*
    THe options parameter is an object literal:
    options:
    { 
    shouldCheckForHoverState: true/false,
    shouldFocusElement: true/false
    }
    */
    moveRotatorToPrevious: function(rotatorElement, options) {
        // If it's currently being hovered (and if shouldCheckForHoverState is true), skip over it.
        if (
      (typeof options != "undefined") &&
      (options.shouldCheckForHoverState) &&
      ($(rotatorElement).hasClass(this.CLASS_FOR_HOVER_STATE))
      ) {
            // console.log("currently hovered -- skipping");
            return;
        }

        // Find the selected thumbnail
        var thumbnailChildren = $(rotatorElement).find(this.SELECTOR_FOR_THUMBNAILS).children();

        var previousThumbnail = $(thumbnailChildren)
      .filter('.' + this.CLASS_FOR_CURRENT_ELEMENT)
      .prev();

        // console.info("Previous thumbnail li:");
        // console.log(previousThumbnail);

        // If there is no "previous" thumbnail, reset to the last one
        if (!previousThumbnail || !previousThumbnail.length) {

            // console.log("Resetting to last thumbnail");
            previousThumbnail = thumbnailChildren.eq(thumbnailChildren.length - 1);
        }

        // Then, show that guy
        this.selectThisThumbnail(previousThumbnail.children('a'), { shouldFocusElement: options.shouldFocusElement });
    },

    /*
    THe options parameter is an object literal:
    options:
    { 
    shouldCheckForHoverState: true/false,
    shouldFocusElement: true/false
    }
    */
    moveRotatorToNext: function(rotatorElement, options) {
        // If it's currently being hovered (and if shouldCheckForHoverState is true), skip over it.
        if (
      (typeof options != "undefined") &&
      (options.shouldCheckForHoverState) &&
      ($(rotatorElement).hasClass(this.CLASS_FOR_HOVER_STATE))
      ) {
            // console.log("currently hovered -- skipping");
            return;
        }

        // Find the selected thumbnail
        var thumbnailChildren = $(rotatorElement).find(this.SELECTOR_FOR_THUMBNAILS).children();

        var nextThumbnail = $(thumbnailChildren)
      .filter('.' + this.CLASS_FOR_CURRENT_ELEMENT)
      .next();

        // console.info("Next thumbnail li:");
        // console.log(nextThumbnail);

        // If there is no "next" thumbnail, reset to the first one
        if (!nextThumbnail || !nextThumbnail.length) {
            // console.log("Resetting to first thumbnail");
            nextThumbnail = thumbnailChildren.eq(0);
        }

        // Then, show that guy
        this.selectThisThumbnail(nextThumbnail.children('a'), { shouldFocusElement: options.shouldFocusElement });
    },

    rotateIt: function() {
        // If there're no rotator elements, well, nevermind
        if (!this.rotatorElements || !this.rotatorElements.length) {
            return;
        }

        for (var i = 0, len = this.rotatorElements.length; i < len; i++) {
            var currentRotator = this.rotatorElements[i];

            // Disable auto-rotating if the keyboard has been used to navigate
            if ($(currentRotator).hasClass(this.CLASS_FOR_HAS_KEYBOARD_USE_FLAG)) {
                continue;
            }

            this.moveRotatorToNext(currentRotator,
        {
            shouldCheckForHoverState: true,
            shouldFocusElement: false
        });

        } // end of for loop

        var self = this;

        window.setTimeout(function() {
            self.rotateIt();
        }, this.timeInMillisecondsBetweenRotations);
    }
};


$(document).ready(function()
{
  Rotator.init();
});
