/*************************************************
*
*	project:  	liteAccordion - horizontal accordion plugin for jQuery
*	author:   	Nicola Hibbert
*	url:	  	http://nicolahibbert.com/horizontal-accordion-jquery-plugin
*	demo:	  	http://www.nicolahibbert.com/demo/liteAccordion
*
*	Version:  	1.1.3
*	Copyright: 	(c) 2010-2011 Nicola Hibbert
*
/*************************************************/
; (function ($) {

    $.fn.liteAccordion = function (options) {

        // defaults
        var defaults = {
            containerWidth: 741,
            containerHeight: 287,
            headerWidth: 33,

            firstSlide: 1,
            onActivate: function () { },
            slideSpeed: 800,
            slideCallback: function () { },

            autoPlay: false,
            pauseOnHover: false,
            cycleSpeed: 6000,

            theme: 'basic', // basic, light*, dark, stitch*
            rounded: false,
            enumerateSlides: false
        },

        // merge defaults with options in new settings object				
			settings = $.extend({}, defaults, options),

        // define key variables
			$accordion = this,
			$slides = $accordion.find('li'),
			slideLen = $slides.length,
			slideWidth = settings.containerWidth - (slideLen * settings.headerWidth),
			$header = $slides.children('h2'),

        // core utility and animation methods
			utils = {
			    getGroup: function (pos, index) {
			        if (this.offsetLeft === pos.left) {
			            return $header.slice(index + 1, slideLen).filter(function () { return this.offsetLeft === $header.index(this) * settings.headerWidth });
			        } else if (this.offsetLeft === pos.right) {
			            return $header.slice(0, index + 1).filter(function () { return this.offsetLeft === slideWidth + ($header.index(this) * settings.headerWidth) });
			        }
			    },
			    nextSlide: function (slideIndex) {
			        var slide = slideIndex + 1 || settings.firstSlide;

			        // get index of next slide
			        return function () {
			            return slide++ % slideLen;
			        }
			    },
			    play: function (slideIndex) {
			        var getNext = utils.nextSlide((slideIndex) ? slideIndex : ''), // create closure
						start = function () {
						    $header.eq(getNext()).click();
						};

			        utils.playing = setInterval(start, settings.cycleSpeed);
			    },
			    pause: function () {
			        clearInterval(utils.playing);
			    },
			    playing: 0,
			    sentinel: false
			};

        // set container heights, widths, theme & corner style
        $accordion
			.height(settings.containerHeight)
			.width(settings.containerWidth)
			.addClass(settings.theme)
			.addClass(settings.rounded && 'rounded');

        // set tab width, height and selected class
        $header
			.width(settings.containerHeight)
			.height(settings.headerWidth)
			.eq(settings.firstSlide - 1).addClass('selected');

        // ie :(
        if ($.browser.msie) {
            if ($.browser.version.substr(0, 1) > 8) {
                $header.css('filter', 'none');
            } else if ($.browser.version.substr(0, 1) < 7) {
                return false;
            }
        }

        // set initial positions for each slide
        $header.each(function (index) {
            var $this = $(this),
				left = index * settings.headerWidth;

            if (index >= settings.firstSlide) left += slideWidth;

            $this
				.css('left', left)
				.next()
					.width(slideWidth)
					.css({ left: left, paddingLeft: settings.headerWidth });

            // add number to bottom of tab
            settings.enumerateSlides && $this.append('<b>+</b>');

        });

        // bind event handler for activating slides
        $header.click(function (e) {
            var $this = $(this),
				index = $header.index($this),
				$next = $this.next(),
				pos = {
				    left: index * settings.headerWidth,
				    right: index * settings.headerWidth + slideWidth,
				    newPos: 0
				},
				$group = utils.getGroup.call(this, pos, index);

            // set animation direction
            if (this.offsetLeft === pos.left) {
                pos.newPos = slideWidth;
            } else if (this.offsetLeft === pos.right) {
                pos.newPos = -slideWidth;
            }

            // check if animation in progress
            if (!$header.is(':animated')) {

                // activate onclick callback with slide div as context		
                if (e.originalEvent) {
                    if (utils.sentinel === this) return false;
                    settings.onActivate.call($next);
                    utils.sentinel = this;
                } else {
                    settings.onActivate.call($next);
                    utils.sentinel = false;
                }

                // remove, then add selected class
                $header.removeClass('selected').filter($this).addClass('selected');

                // get group of tabs & animate			
                $group
					.animate({ left: '+=' + pos.newPos }, settings.slideSpeed, function () { settings.slideCallback.call($next) })
					.next()
					.animate({ left: '+=' + pos.newPos }, settings.slideSpeed);

            }
        });

        // pause on hover			
        if (settings.pauseOnHover) {
            $accordion.hover(function () {
                utils.pause();
            }, function () {
                utils.play($header.index($header.filter('.selected')));
            });
        }

        // start autoplay, call utils with no args = start from firstSlide
        settings.autoPlay && utils.play();

        return $accordion;

    };

})(jQuery);
