﻿(function ($)
{
    //private members
    var Direction = { next: -1, prev: 1 }; /* camel case means treat this like an enum, don't mutate it! */
    var $buttons = { next: null, prev: null };
    var $list;
    var _timer, _currentVisibleIndex, _maxItemIndex;
    var _settings = { delay: 6, mode: 'auto', visible: 2, speed: 300, easing: 'swing', next: '.wNext', prev: '.wPrev', disabledClass: 'disabled' };

    var timer = function () { _timer = setTimeout(function () { pulse(); }, _settings.delay * 1000); }

    var pulse = function ()
    {
        if ((_settings.mode == 'auto') && (canMove(Direction.next)))
        {
            move(Direction.next);
            timer();
        }
    }

    var move = function (dir)
    {
        var index = (dir == Direction.next) ? _currentVisibleIndex + _settings.visible : _currentVisibleIndex - 1;
        var w = $('li:eq(' + index + ')', $list).width();
        if (w == null)
            return;
        $list.animate({ left: '+=' + w * dir + 'px', easing: _settings.easing }, _settings.speed);
        _currentVisibleIndex += -1 * dir;
        checkDisabled();
    }

    var canMove = function (dir)
    {
        //if ($list.is(':animated'))
        //    return false;

        if (dir == Direction.prev)
            return (_currentVisibleIndex > 0);
        else
            return (_currentVisibleIndex + _settings.visible <= _maxItemIndex);
    }

    var checkDisabled = function ()
    {
        $buttons.next.toggleClass(_settings.disabledClass, !canMove(Direction.next));
        $buttons.prev.toggleClass(_settings.disabledClass, !canMove(Direction.prev));
    }

    var methods = {
        init: function (options)
        {
            if (options)
                $.extend(_settings, options);

            return $(this).each(function ()
            {
                _currentVisibleIndex = 0;
                var totalWidth = 0;
                var initWidth = 0;
                var t = 0;
                $('li', $(this)).each(function ()
                {
                    var w = $(this).width();
                    if (t < _settings.visible)
                        initWidth += w;
                    totalWidth += w;
                    t++;
                });
                _maxItemIndex = t - 1;
                $('div:first', $(this)).addClass('wViewport').width(initWidth);
                $(this).width(initWidth);
                $list = $('ul', $(this));
                $list.width(totalWidth);
                if (_settings.mode == 'auto')
                    timer();

                //button setup
                $buttons.next = $(_settings.next).attr('data-wjs-dir', Direction.next);
                $buttons.prev = $(_settings.prev).attr('data-wjs-dir', Direction.prev);

                $buttons.next.add($buttons.prev).click(function (e)
                {
                    e.preventDefault();
                    var dir = $(this).attr('data-wjs-dir');
                    _settings.mode = 'manual';
                    if (canMove(dir))
                        move(dir);
                });
                checkDisabled();
            });
        }
    };

    $.fn.wcarousel = function (method)
    {
        if (methods[method])
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        else if (typeof method === 'object' || !method)
            return methods.init.apply(this, arguments);
        else
            $.error('Method ' + method + ' does not exist on jQuery.wcarousel');
    };
})(jQuery);

