(function ($) {

    $.fn.extend({
        sliderAccess: function (options) {
            options = options || {};
            options.touchonly = options.touchonly !== undefined ? options.touchonly : true;

            if (options.touchonly === true && !("ontouchend" in document))
                return $(this);

            return $(this).each(function (i, obj) {
                var $t = $(this),
                    o = $.extend({}, {
                        where: 'after',
                        step: $t.slider('option', 'step'),
                        upIcon: 'ui-icon-plus',
                        downIcon: 'ui-icon-minus',
                        text: false,
                        upText: '+',
                        downText: '-',
                        buttonset: true,
                        buttonsetTag: 'span',
                        speed: 150
                    }, options),
                    $buttons = $('<' + o.buttonsetTag + ' class="ui-slider-access">' +
                        '<button data-icon="' + o.downIcon + '" data-step="-' + o.step + '">' + o.downText + '</button>' +
                        '<button data-icon="' + o.upIcon + '" data-step="' + o.step + '">' + o.upText + '</button>' +
                        '</' + o.buttonsetTag + '>');

                $buttons.children('button').each(function (j, jobj) {
                    var $jt = $(this),
                        timeout = null,
                        increment = function ($jt, $t, e) {
                            var step = $jt.data('step'),
                                curr = $t.slider('value'),
                                newval = curr += step * 1,
                                minval = $t.slider('option', 'min'),
                                maxval = $t.slider('option', 'max');
                            e.preventDefault();
                            if (newval < minval || newval > maxval)
                                return;
                            $t.slider('value', newval);
                            $t.slider("option", "slide").call($t, null, {value: newval});
                        };

                    $jt.button({
                        text: o.text,
                        icons: {primary: $jt.data('icon')}
                    })
                        .bind('touchstart mousedown', function (e) {
                            increment($jt, $t, e);
                            timeout = setInterval(function () {
                                increment($jt, $t, e);
                            }, o.speed);
                        });

                    $(document).bind('touchend mouseup', function (e) {
                        clearInterval(timeout);
                        return e.type == 'touchend';
                    });

                });

                // before or after
                $t[o.where]($buttons);

                if (o.buttonset) {
                    $buttons.removeClass('ui-corner-right').removeClass('ui-corner-left').buttonset();
                    $buttons.eq(0).addClass('ui-corner-left');
                    $buttons.eq(1).addClass('ui-corner-right');
                }

                // adjust the width so we don't break the original layout
                var bOuterWidth = $buttons.css({
                    marginLeft: (o.where == 'after' ? 10 : 0),
                    marginRight: (o.where == 'before' ? 10 : 0)
                }).outerWidth(true) + 5;
                var tOuterWidth = $t.outerWidth(true);

                // support "always" hide the slider
                if (o.hideSlider == 'always' || (o.hideSlider == 'touch' && ("ontouchend" in document))) {
                    $t.css('display', 'none');
                } else {
                    $t.css('display', 'inline-block').width(tOuterWidth - bOuterWidth);
                }
            });
        }
    });

})(jQuery);
