/// <reference path="../ScriptReference/jquery-1.7.1-vsdoc.js"/>

/*
* jQuery UI PlayerVolume
*
* Depends:
*   jquery.ui.core.js
*   jquery.ui.widget.js	
*   jquery.imageButton.js
*   Mediasite.Player.Localization.js
*
*/
(function ($) {
    $.widget("ui.playerfidelity", {
        options: {
            minBarHeight: 4, // px
            maxBars: 6,
            ids: {

            }
        },

        _setOption: function (key, value) {
            this.options[key] = value;
            this._super("_setOption", key, value);
        },

        _create: function () {
            var self = this,
				o = this.options;

            this.element.addClass("ui-playerfidelity");

        },

        _formatBitRate: function (bitrate) {
            var bytesInK = 1000;
            var bytesInM = bytesInK * 1000;

            if (bitrate >= bytesInM) {
                var displayRate = Math.floor(bitrate / bytesInM);

                return Mediasite.Player.Localization.MediaPlayer.BitrateMbpsFormat.replaceholders(displayRate);
            }
            else {
                var displayRate = bitrate / bytesInK;
                displayRate = Math.floor(displayRate * 1000) / 1000;
                return Mediasite.Player.Localization.MediaPlayer.BitrateKbpsFormat.replaceholders(displayRate);
            }
        },

        update: function (fidelityInfo) {
            var self = this;

            if (!(this.element && this.element.length)) return;

            var totalBars = this._enforceBarCountBounds(fidelityInfo.tracks.length);
            var highlightedBars = this._enforceBarCountBounds(fidelityInfo.currentTrackIndex + 1);

            this._updateChart(totalBars, highlightedBars);
            this._updateTooltip(fidelityInfo.currentTrack.bitrate);
        },

        _enforceBarCountBounds: function (bars) {
            return Math.max(0, Math.min(bars, this.options.maxBars));
        },

        _updateTooltip: function (bitrate) {
            var tooltip = this._getToolTip(bitrate);
            this.element.attr('title', tooltip);
        },


        _getToolTip: function (bitrate) {
            return Mediasite.Player.Localization.MediaPlayer.MediaFidelityToolTipFormat.replaceholders(this._formatBitRate(bitrate));
        },


        _updateChart: function (totalBars, highlightedBars) {
            var self = this;

            // Clear old bars.
            this.element.empty();

            // Quit if applicable
            if (totalBars < 1) return;


            // Calculate width stuff.
            var barWidth = (totalBars < 3) ? 3 : 2;
            var padding = this._calculatePadding(totalBars, barWidth);


            // Calculate array of bar heights.
            var heights = this._calculateBarHeights(totalBars, this.options.minBarHeight);
            var totalHeight = this.element.height();


            // Add new bars to container, highlighting the active bars.
            var lastHighlightedSegmentIndex = highlightedBars - 1;

            for (var i = 0; i < heights.length; i++) {
                var bar = $("<div></div>");
                bar.addClass('ui-playerfidelity-bar');

                bar.css('height', heights[i] + 'px');
                var marginTop = totalHeight - Math.ceil(heights[i]);
                bar.css('margin-top', marginTop + 'px');  // bottom-align the bar


                bar.css('width', barWidth + 'px');

                if (i > 0) {
                    bar.css('margin-left', padding + 'px');
                }

                if (i <= lastHighlightedSegmentIndex) {
                    bar.addClass('ui-playerfidelity-bar-highlighted');
                }

                bar.appendTo(this.element);
            }

            // Center everything by adding whitespace on the left
            var elementWidth = this.element.width();
            var usedWidth = 0;
            this.element.children().each(function (i, elm) {
                usedWidth += $(elm).outerWidth(true);
            });

            var sidePadding = Math.floor((elementWidth - usedWidth) / 2);
            sidePadding = Math.max(0, sidePadding); // no negative margins
            this.element.children(":first-child").css('margin-left', sidePadding + 'px');
        },

        _calculateBarHeights: function (totalBars, smallestBarHeight) {
            var heights = [];

            var maxHeight = this.element.height();

            if (totalBars > 0) {
                heights.push(smallestBarHeight);
            }


            for (var i = 1; i < totalBars; i++) {
                var lastBarHeight = heights[i - 1];
                var nextStep = this._calculateStep(lastBarHeight, totalBars - heights.length, maxHeight);
                var currentBarHeight = lastBarHeight + nextStep;
                heights.push(currentBarHeight);
            }

            // Make sure that the bars are never less than 
            // half the height of the next taller bar.
            for (var i = totalBars - 2; i >= 0; i--) {
                var halfOfNextHeight = Math.ceil(heights[i + 1] / 2.0);
                heights[i] = (heights[i] < halfOfNextHeight) ? halfOfNextHeight : heights[i];
            }

            return heights;
        },

        _calculatePadding: function (totalBars, barWidth) {
            var padding = 2;

            while (padding > 0 && !this._barsWillFit(totalBars, barWidth, padding)) {
                padding--;
            }

            if (!this._barsWillFit(totalBars, barWidth, padding)) {
                // Ummm... We're not going to be able to show each distinct bar.
                // TODO: Make each bar represent a percentage of available tracks 
                //       rather than an individual track.
            }

            return padding;
        },


        _calculateStep: function (lastBarHeight, barsRemaining, maxHeight) {
            /// Calculates a percentage for step height

            var range = maxHeight - lastBarHeight;
            var step = range / (barsRemaining);
            step = Math.floor(step);
            return step;
        },

        _barsWillFit: function (numBars, barWidth, padding) {
            return numBars * (barWidth + padding) - padding <= this.element.width();
        },



        destroy: function () {
            this.element.removeClass("ui-playerfidelity");
        }
    });
})(jQuery);