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

/*
 * jQuery UI playercaptionpanel
 *
 * Depends:
 *   jquery.ui.core.js
 *   jquery.ui.widget.js
 *   Mediasite.Player.Localization.js
 *
 */

(function ($) {
    var _ages = {
        raw: 'raw',
        fresh: 'fresh',
        stale: 'stale',
        expiring: 'expiring',
        expired: 'expired'
    };

    $.widget("ui.playercaptionpanel", {
        options: {
            classes: {
                slider: 'ui-playercaptionpanel-slider',
                captionPanel: 'ui-playercaptionpanel',
                captionItem: 'ui-playercaptionpanel-item',
                roundedCorner: 'ui-corner-all',
                ages: {
                    stale: 'ui-playercaptionpanel-stale-item',
                    expiring: 'ui-playercaptionpanel-expiring-item'
                }
            },
            fadeSpeed: 400, // ms

            currentPosition: 0,

            maxVisibleCaptions: 3,
            expiredAfter: 30000, // ms
            expiringAfter: 25000, // ms
            staleAfter: 20000, // ms
            allowBefore: 1000 // ms
        },

        _setOption: function (key, value) {
            var self = this, o = this.options;

            this._super(key, value);

            if (key == 'currentPosition') {
                this.pruneAndAge();
            }
        },

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

            self.element.addClass(o.classes.captionPanel);

            $('<div>').addClass(o.classes.slider)
                .appendTo(self.element);

            this.captions = [];
        },

        _destroy: function () {
            var self = this, o = this.options;
            this.element
                .removeClass(o.classes.captionPanel)
                .empty();
        },

        _getSlider: function() {
            return this.element.find('.' + this.options.classes.slider);
        },


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

            this.element
				.stop(true, true)
				.css('visibility', 'visible')
				.animate({ opacity: 1 }, o.fadeSpeed);

            this.visible = true;
        },

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

            this.element
				.stop(true, true)
				.animate({ opacity: 0 }, {
				    duration: o.fadeSpeed,
				    complete: function () { self.element.css('visibility', 'hidden'); }
				});


            this.visible = false;
        },

        toggle: function() {
            if (this.visible) { 
                this.hide();
            } else {
                this.show();
            }
        },

        addCaption: function (caption) {
            var self = this, o = this.options;
            var captionRecord = $.extend({}, caption);

            var element = this._createElement(captionRecord);
            captionRecord.element = element;
            this.captions.push(captionRecord);

            this._slideCaption(element);

            this.pruneExcessiveCaptions();
            this.ageCaptions();
        },

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

            var contents = caption.Text || "";
            contents = contents.formatAsHtml();

            var $element = $('<div>')
                .addClass(o.classes.captionItem)
                .html(contents);

            return $element;
        },

        _slideCaption: function ($element) {
            var self = this, o = this.options;

            if (Mediasite.Player.Support.csstransforms3d) {
                self._cssSlideCaption($element);
            }
            else {
                self._jqSlideCaption($element);
            }
        },

        _jqSlideCaption: function ($element) {
            var self = this, o = this.options;

            var $slider = this._getSlider();

            var sHeight = 0;
            this.element.find('.' + o.classes.captionItem).each(function (i) {
                sHeight += $(this).outerHeight(true);
            });

            $element.appendTo($slider);

            var iHeight = 0;
            this.element.find('.' + o.classes.captionItem).each(function (i) {
                iHeight += $(this).outerHeight(true);
            });
            iHeight = sHeight - iHeight;

            this.element.find('.' + o.classes.captionItem)
                .css("position", "absolute")
                .stop(true, true).animate({ top: ['+=' + iHeight, 'swing'] }, 1500);
        },

        _cssSlideCaption: function ($element) {
            var self = this, o = this.options;

            var $slider = this._getSlider();
            var sHeight = $slider.height();

            $element.appendTo($slider);
            var iHeight = $slider.height() - sHeight;

            var captionItems = this.element.find('.' + o.classes.captionItem);
            captionItems.css("position", "absolute");

            var heights = new Array();
            var totalHeight = 0;
            captionItems.each(function (i) {
                totalHeight += $(this).outerHeight(true);
            });
            captionItems.each(function (i) {
                var translate = 'translate3d(0px,-' + (totalHeight + 3) + 'px,0px)'
                $(this).css({ "-moz-transform": translate, '-webkit-transform': translate, 'transform': translate });
                totalHeight -= $(this).outerHeight(true);
            });
        },

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

            if (!captionIndex) captionIndex = 0;

            var caption = this.captions.splice(captionIndex, 1);
            caption = caption[0];

            if (caption && caption.element) {
                if (this.visible) {
                    caption.element.fadeOut(o.fadeSpeed, remove);
                    var timeout = setTimeout(remove, o.fadeSpeed + 10); // fadeOut not reliably firing callback in IE9
                } else {
                    remove();
                }

            }

            function remove() { 
                clearTimeout(timeout);
                caption.element.remove();
            }

            return caption;
        },

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

            this.pruneExcessiveCaptions();
            this.pruneAgedOutCaptions();
            this.ageCaptions();
        },

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

            for (var i = 0; i < this.captions.length; i++) {
                var caption = this.captions[i];
                var age = this.getAge(caption.Time);

                var ageClass = o.classes.ages[age];
                caption.element
                    .removeClass([ o.classes.ages.stale, o.classes.expiring ].join(' '))
                    .addClass(ageClass);
            }
        },

        pruneExcessiveCaptions: function() {
            while (this.captions.length > this.options.maxVisibleCaptions) {
                this.removeCaption();
            }
        },

        pruneAgedOutCaptions: function() {
            for (var i = 0; i < this.captions.length; i++) {
                var caption = this.captions[i];
                var age = this.getAge(caption.Time);

                if (age === _ages.expired || age === _ages.raw) {
                    this.removeCaption(i);
                    i--;
                }
            }
        },


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

            var age;

            if (time + o.expiredAfter < o.currentPosition) { 
                age = _ages.expired;
            } else if (time + o.expiringAfter < o.currentPosition) {
                age = _ages.expiring;
            } else if (time + o.staleAfter < o.currentPosition) {
                age = _ages.stale;
            } else if (o.currentPosition < time - o.allowBefore) {
                age = _ages.raw;
            } else {
                age = _ages.fresh;
            }


            return age;
        }

    });
})(jQuery);



window.Mediasite = Mediasite || {};
Mediasite.Player = Mediasite.Player || {};


Mediasite.Player.CaptionPanel = function (element) {
    var self = this;
    var $element;
    var containerCssClass = 'mediasite-player-caption-panel';
    var captionCssClass = 'mediasite-player-caption-item';

    function init() {
        $element = $(element);

        $element.addClass(containerCssClass);
    }


    self.setCaptions = function (newCaptions) {
        var i, caption, item;

        $element.empty();

        for (i = 0; i < newCaptions.length; i += 1) {
            caption = newCaptions[i];
            if (caption.Text && caption.Text.length > 0) {
                item = makeCaptionElement(newCaptions[i]);
                $element.append(item);
            }
        }
    };


    self.isHidden = function () {
        return ($element.css('visibility') == 'hidden');
    };

    self.show = function () {
        $element.css('visibility', 'visible');
    };

    self.hide = function () {
        $element.css('visibility', 'hidden');
    };

    self.toggleVisibility = function () {
        if (self.isHidden()) {
            self.show();
        } else {
            self.hide();
        }
    };


    function makeCaptionElement(caption) {
        var text;
        var el = $('<div>');
        el.addClass(captionCssClass);
        text = caption.Text || "";
        text = text.formatAsHtml();
        el.html(text);
        return el;
    }

    function captionObjectToString(caption) {
        var result;

        var addPart = function (val, expectedType) {
            if (typeof val !== expectedType) {
                return;
            }

            if (result.length > 0) {
                result += '|';
            }

            result += val;
        }

        if (typeof caption !== 'string') {
            return '';
        }

        addPart(caption.Time, 'number');
        addPart(caption.EndTime, 'number');
        addPart(caption.Text, 'string');
    }


    init();
}