(function( $ )
{
$.fn.news_selector = function( method )
{
    var update = function( self, value, preventEvent )
    {
        var scroll = $(self).children(".news-scroll").first();
        var cursor = $(self).children(".news-cursor").first();

        if (value < 0)
            value = 0;
        if (value > $(self).data('max') - 1)
            value = $(self).data('max') - 1;

        var offset = value * $(self).data('cursorRange') / ($(self).data('max') - 1);
        cursor.css('left', offset + 'px');
        cursor.data('left', offset);

        offset = value * $(self).data('scrollRange') / ($(self).data('max') - 1);
        scroll.css('left', offset + 'px');
        scroll.data('left', offset);

        $(self).data('value', value);

        if (!preventEvent && $(self).data('onValueChange'))
            $(self).data('onValueChange').call(self, value);
    };

    var updateMaxNews = function( self, maxNews )
    {
        var scroll = $(self).children(".news-scroll").first();
        var cursor = $(self).children(".news-cursor").first();

        $(self).data('max', maxNews);

        var range = $(self).width() - $(self).data('itemWidth') * $(self).data('max');

        if (range > 0)
            range = 0;

        $(self).data('scrollRange', range);

        range = $(self).data('itemWidth') * $(self).data('max');

        if (range > $(self).width())
            range = $(self).width();

        $(self).data('cursorRange', range - cursor.width());
    };

    var animate = function( self, value, step )
    {
        var curVal = $(self).data('value');
        var interval = $(self).data('animInt');

        if (Math.abs(value - curVal) <= Math.abs(step))
        {
            $(self).data('animation', false);
            update(self, value);

            if ($(self).data('onEndChange'))
                $(self).data('onEndChange').call(self, $(self).data('value'));
        }
        else
        {
            update(self, curVal + step);
            
            var f = function() { animate(self, value, step); };

            $(self).data('animation', true);
            setTimeout(f, interval);
        }
    };
    
    var methods =
    {
        init: function ( options )
        {
            var options = $.extend(
            {
                maxNews: 40,
                index: 0,
                newsScrollSize: 40,
                animationInterval: 30,
                animationSteps: 5,
                
            }, options);

            return this.each(function()
            {
                var self = this;

                var scroll = $(self).children(".news-scroll").first();
                var cursor = $(self).children(".news-cursor").first();

                $(self).data('itemWidth', Number(scroll.width()) / options.newsScrollSize);
                $(self).data('animInt', options.animationInterval);
                $(self).data('animSteps', options.animationSteps);

                $(self).data('onValueChange', options.onValueChange);
                $(self).data('onBeginChange', options.onBeginChange);
                $(self).data('onEndChange', options.onEndChange);

                
                updateMaxNews(self, options.maxNews);
                update(self, options.value);

                var onScrollMove = function ( e )
                {
                    e.preventDefault();
                    var left = scroll.data('left') + e.pageX - $(self).data('dragX');
                    update(self, Number(left) * ($(self).data('max') - 1) / $(self).data('scrollRange'));

                    if (!$(self).data('changeEvents') && e.pageX != $(self).data('dragX'))
                    {
                        $(self).data('changeEvents', true);
                        if ($(self).data('onBeginChange'))
                            $(self).data('onBeginChange').call(self);
                    }

                    $(self).data('dragX', e.pageX);
                };

                var onCursorMove = function ( e )
                {
                    e.preventDefault();
                    var left = cursor.data('left') + e.pageX - $(self).data('dragX');
                    update(self, Number(left) * ($(self).data('max') - 1) / $(self).data('cursorRange'));

                    $(self).data('dragX', e.pageX);
                };

                var onUp = function ( e )
                {
                    e.preventDefault();
                    var moveHandler = $(self).data('handler');

                    $(document).unbind('mousemove', moveHandler);
                    $(document).unbind('mouseup', onUp);

                    if ($(self).data('onEndChange'))
                        $(self).data('onEndChange').call(self, $(self).data('value'));
                };

                var onDown = function ( e, moveHandler )
                {
                    e.preventDefault();

                    if ($(self).data('animation'))
                        return;
                    
                    $(document).bind('mousemove', moveHandler);
                    $(document).bind('mouseup', onUp);

                    $(self).data('dragX', e.pageX);
                    $(self).data('handler', moveHandler);

                    if ($(self).data('onBeginChange'))
                        $(self).data('onBeginChange').call(self);

                };

                scroll.bind('mousedown', function (e) { onDown(e, onScrollMove); } );
                cursor.bind('mousedown', function (e) { onDown(e, onCursorMove); } );

                var onScrollClick = function( e )
                {
                    e.preventDefault();
                    if ($(self).data('animation'))
                        return;
                    if ($(self).data('dragX', e.pageX) != e.pageX)
                        return;


                    var left = e.pageX - scroll.offset().left;

                    var value = Math.floor(Number(left) / $(self).data('itemWidth'));

                    if (value >= 0 && value < $(self).data('max'))
                        animate(self, value, (value - $(self).data('value')) / $(self).data('animSteps'));
                }

                //scroll.click(onScrollClick);
            });
        },

        setValue: function ( value, animation )
        {
            return this.each(function()
            {
                if ($(this).data('animation'))
                    return;

                if (animation)
                {
                    if ($(self).data('onBeginChange'))
                        $(self).data('onBeginChange').call(self);

                    animate(this, value, (value - $(this).data('value')) / $(this).data('animSteps'));
                }
                else
                    update(this, value, true);
            });
        },

        setMaxNews: function( maxNews )
        {
            return this.each(function()
            {
                updateMaxNews(this, maxNews);
                update(this, $(this).data('value'));
            });
        }
    };

    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' );
};
})( jQuery );

