/**
 * WebMD Ticker plugin
 * @param id    Parent element id
 * @param opts  Override any defaults
 *
 * @default contentNode     The parent content node which should contain all the content children
 * @default hasGradient     Bool which turns the side gradients on/off
 * @default gradientColor   The color to which the gradient fades out, any valid CSS value
 * @default gradientSize    The width of the gradient in pixels (per side)
 * @default play            Play by default boolean, only a stub for now
 * @default playRate        Easy play rates {default}, {fast} or {slow}
 * @default startPos        Start position of animation set to 0, other positions not implemented
 */
webmd.m.ticker = function(id, opts) {
    return $.fn.ticker($('#'+id), opts);
};

(function($) {

    $.fn.ticker = function($this, opts){
        return ($this.length) ? new Ticker($this, opts) : false;
    };

    var Ticker = function($this, opts){
        var defaults = {
            contentNode: 'ul',
            hasGradient: true,
            gradientColor: '#fff',
            gradientSize: 20,
            play: true,
            playRate: 'default',
            startPos: 0
        };
        var options = $.extend(defaults, opts || {});
        var $content = $(options.contentNode, $this);
        var $children = $content.children();
        if($content.length && $children.length){
            initialize();
        }

        function bindEvents(){
            $content.hover(function(){
                pause();
            }, function(){
                play();
            });
        }

        function buildGradient(){
            var $obj = $('<div></div>').css({backgroundColor: options.gradientColor, height: $this.height()+'px', position: 'absolute', top: 0, width: '1px'});
            var count = options.gradientSize;
            var opacity = 100;
            var opacityC;
            var factor = opacity/count;
            var j = 0;
            for(var i=count; i>=0; i--){
                opacityC = opacity/100;
                $obj.clone().css({left: j+'px', opacity: opacityC}).appendTo($this);
                $obj.clone().css({opacity: opacityC, right: j+'px'}).appendTo($this);
                j++;
                opacity = opacity-factor;
            }
        }

        function evaluatePosition(){
            if(options.position == -options.width){
                options.position = options.startPos;
                $content.css({left: options.position});
            }
            play();
        }

        function getPlayRate(){
            var rate;
            switch (options.playRate) {
                case 'fast':
                    rate = .01;
                    break;
                case 'slow':
                    rate = 30;
                    break;
                default:
                    rate = 12;
            }
            return rate;
        }

        function getViewportWidth(){
            var length = $children.length;
            var tWidth = $this.width();
            var width = 0;
            for(var i=0; i<length; i++){
                width = width + $($children[i]).width();
            }
            return (width >= tWidth) ? width : tWidth;
        }


        function initialize(){
            options.position = options.startPos;
            options.width = getViewportWidth();
            prepareElements();
            if(options.play){
                options.playRate = getPlayRate();
                bindEvents();
                play();
            }
            options.initialized = true;
        }

        function pause() {
            $content.stop();
        }

        function play(){
            if(options.position > -options.width){
                --options.position;
                $content.animate({left: options.position}, options.playRate, 'linear', function(){
                    evaluatePosition();
                });
            }
        }

        function prepareElements(){
            $this.css({overflow: 'hidden', position: 'relative'});
            $children.clone().appendTo($content);
            $content.css({position: 'relative', left: options.position, width: options.width*2});
            if(options.hasGradient){
                buildGradient();
            }
        }

    }

})(jQuery);
