/// <reference path="Mediasite.Core.js"/>
/// <reference path="Mediasite.Player.Core.js"/>

Mediasite = window.Mediasite || {};
Mediasite.Player = Mediasite.Player || {};
Mediasite.Player.StandaloneStreamInspector = function (element, options) {
    function debug() {
        var args = [].slice.call(arguments);
        var ownerWindow = $(element)[0].ownerDocument.defaultView;
        ownerWindow.console && ownerWindow.console.log.apply(ownerWindow.console, args);
    }

    Mediasite.babel = new BabelFish({
        dictionary: window.LocalizedDictionary
    }).translate;
    Mediasite.Player.Localization.initialize();

    var self = this != window ? this : {};
    var defaults = {
        allowVideo: true,
        canSeek: true,
        onSeek: $.noop,
        formatTime: function (milliseconds) { return milliseconds; },
        classes: {
            canSeek: 'standalone-inspector-canseek',
            noVideo: 'standalone-inspector-novideo',
            noSlides: 'standalone-inspector-noslides',
            unsynced: 'standalone-inspector-unsynced',
            syncedThumbnailInFuture: 'player-current-position-future',
            syncedThumbnailVisibleInNav: 'player-current-position-current'
            //slideNavSyncedThumbnail: 'slide-navigator-player-current'
        },
        slideUrlProvider: {
            GetSlideUrl: getSlideUrl,
            GetCacheFriendlySlideUrl: getSlideUrl
        }
    };
    var options = $.extend({}, defaults, options);

    var select = Mediasite.ElementSelector(element);
    select.addSelectorMethods({
        moreButton: '.popout-tools',
        moreButtonContainer: '.standalone-synced-control',
        closeButton: '.close-slide-controls',

        playerState: '.playerState',
        timeText: '.timeText',

        syncedThumbnail: '.player-current-position',
        syncedImage: '.player-current-position img',
        syncedTime: '.player-current-position .time',

        syncedNavThumbnail: '.player-slide-thumb-caption',

        contentArea: '.contentBox',
        inspector: '.inspector',

        slideNav: '.slide-navigator',
        selectedThumbnail: '.slide-navigator .selection-Selected',
        inspectedSlideControls: '.inspected-slide-controls',
        inspectedSlideTime: '.inspected-slide-time',
        inspectedSlideTitle: '.inspected-slide-title'
    });

    var _stream;

    var _streamViewer;

    var _slideInspector;
    var _slideTracker;
    var _currentSlideIndex;

    var _staySynced = true;
    var _isLive;

    var _slideNav;
    var _slidePartitions;
    var _previewedSlide;

    var _timeDisplay;
    var _shouldBePlaying, _startAt, _playbackRate, _allowVideo;

    function init() {
        // Initialize
        _slides = [];
        _staySynced = true;
        _allowVideo = options.allowVideo;
        _isLive = options.isLive;

        // Rehydrate functions
        populateStream(options.stream);
        _duration = options.duration;
        _presentationCurrentTime = options.currentTime;
        initControls();
        initSlideNav();
        initSlideInspector();
        initStreamViewer();

        _shouldBePlaying = options.playing;
    }

    function populateStream(stream) {
        _stream = stream = $.extend(true, {}, stream);
        _stream.IsMainStream = false;
        _stream.StreamOrdinal = 0;

        var slides = _stream.Slides || [];
        _stream.Slides = [];
        _stream.LiveSlideQueue = _stream.LiveSlideQueue || [];
        setSlides(slides);


        _stream.HasSlides = function () { return _stream.Slides.length > 0 || _stream.HasSlideContent; }
        _stream.hasAllowedVideo = (function (hasVideo) {
            return function () {
                return hasVideo && _allowVideo;
            }
        })(_stream.HasVideo);

        if (options.mediaPlayerModelOptions.isStandAlone) {
            $.each(_stream.VideoUrls, function (index, videoUrl) {
                if (videoUrl.Location.indexOf('://') === -1) {
                    videoUrl.Location = options.baseUrl + videoUrl.Location;
                }
            });
        }
    }

    function initControls() {
        if (_stream.HasSlides()) {
            new Mediasite.Player.SingleImageButton(select.moreButton().get(0), {
                click: onToggleSynced,
                title: Mediasite.Player.Localization.Buttons.ShowSlideControls
            });
            new Mediasite.Player.SingleImageButton(select.closeButton().get(0), {
                click: onToggleSynced
            });

            select.inspectedSlideTime()
                .on('click', onPlayFromHere)
                .attr('title', Mediasite.Player.Localization.FullSize.PlayFromSlide);

            select.syncedThumbnail()
                .on('click', onClickCurrentPresentationImage)
                .attr('title', Mediasite.Player.Localization.FullSize.ShowSlideCurrentlyPlaying);

            select.element().on('keyup', onKey);
        }
    }

    function initSlideInspector() {
        if (!_stream.HasSlides()) {
            select.inspector().remove();
        } else {
            _slideInspector = new Mediasite.Player.SlideInspector(select.inspector());
        }
        _slideTracker = createSlideTracker(_stream);
    }

    function initStreamViewer(stream) {
        if (!_stream.hasAllowedVideo()) {
            return;
        }

        var viewContext = {
            contentCapability: Mediasite.Player.ContentCapability.VideoAndSlides,
            getStreamViewHandler: getStreamViewHandler
        };

        var streamViewHandlerOptions =
            {
                DisplayContent: _stream.DisplayContent,
                StreamType: _stream.StreamType,
                StreamOrdinal: _stream.StreamOrdinal,
                IsMainStream: _stream.IsMainStream,
                VideoAvailable: _stream.hasAllowedVideo,
                StreamThumbnailUrl: _stream.ThumbnailUrl,
                AspectRatio: _stream.AspectRatio
            };

        var streamViewHandler = viewContext.getStreamViewHandler(streamViewHandlerOptions);
        if (streamViewHandler == undefined) return true;

        //Video
        var mediaPlayerModel = createMediaPlayerModel(_stream, streamViewHandler);

        var streamViewerOptions =
            {
                Stream: _stream,
                MediaPlayerModel: mediaPlayerModel,
                SlideTracker: new Mediasite.Player.SlideTracker({  // dummy slidetracker, don't use _slideTracker so it can run independently from the video
                    Stream: _stream,
                    EventHandlers: {}
                }),
                StreamViewHandler: streamViewHandler,
                IsMainStream: _stream.IsMainStream
            };

        _streamViewer = new Mediasite.Player.StreamViewer(streamViewerOptions);

        _streamViewer.MediaPlayerModel.SetupMediaElement(_streamViewer.Stream.VideoUrls);
    }

    var streamView;

    var _defaultAspect = 16 / 9;
    function getStreamViewHandler(streamViewHandlerOptions) {

        var streamBoxElement;
        var priorityClass, initialPositionClass;
        var stageStreamView;

        streamViewHandlerOptions.AspectRatio = (streamViewHandlerOptions.AspectRatio > 0) ? streamViewHandlerOptions.AspectRatio : _defaultAspect;

        if (!streamView) {
            streamView = new Mediasite.Player.StreamView.BasicStreamView(select.contentArea(), streamViewHandlerOptions, "../../../Javascript/Players/SmartPlayer/Images/default_slide.png" /* TODO: playerContext.PlayerLayoutOptions.Images.DefaultStreamImage.ImageFilename */);

            if (false /* TODO: playerContext.GlobalOptions.IsLayoutPreview */) {
                var imageBackground = $('<img src="../../../Javascript/Players/SmartPlayer/Images/default_slide.png" class="previewLayoutStreamBackground" />');
                imageBackground.appendTo(streamView.outerElement);
            }


            return new Mediasite.Player.StreamViewHandler({
                MediaContainer: streamView.mediaElementContainer,
                UpdateCurrentSlide: streamView.updateCurrentSlide,
                AddNewSlide: streamView.updateCurrentSlide,
                SetDisplayContent: streamView.setDisplayContent
            });
        } else {
            // Too many streams
            return;
        }
    }

    function createMediaPlayerModel(stream, streamViewHandler, mediaPlayerEventHandlers) {

        var mediaPlayerModel = undefined;
        if (stream.DisplayContent == Mediasite.ContentType.Video) {
            var strat = stream.playbackStrategies[0];
            var selectedMediaPlayerType = Mediasite.Player.MediaPlayerType.FromPluginType(strat.pluginType);
            var selectedVideoSource = strat.source;

            var streamOptions = $.extend({}, options.mediaPlayerModelOptions, {
                isMobile: Mediasite.BrowserDetect.Mobile(),
                mediaPlayerType: options.playerContentPlugin.MediaPlayerType,
                pluginMimeType: options.playerContentPlugin.MimeType,
                playButtonText: Mediasite.Player.Localization.Buttons.Play,
                selectedMediaPlayerType: selectedMediaPlayerType,
                selectedVideoSource: selectedVideoSource
            });
            $.extend(streamOptions, {
                allowFullScreenVideo: false,
                silverlightFullScreenPrompt: "",
                disableVolume: true,
                enableContextMenu: false,
                playbackRates: [],
                playCoverOnPause: false,

                backgroundElement: $(streamViewHandler.MediaContainer),

                width: "100%",
                height: "100%",
                mediaContainer: streamViewHandler.MediaContainer,

                pauseAt: -1,
                isMainStream: false,
                streamType: stream.StreamType
            });

            var convivaConfigurationFactory = new Mediasite.Player.ConvivaConfiguration.ConvivaConfigurationFactory();
            streamOptions.getConvivaConfiguration = convivaConfigurationFactory.makeGetConvivaConfiguration(options.partialConvivaConfiguration);

            mediaPlayerModel = Mediasite.MediaPlayer.CreateModel(streamOptions);
            mediaPlayerModel = $.extend({}, new Mediasite.MediaPlayer.BaseModel(), mediaPlayerModel);

            mediaPlayerModel.AddEventHandler(getMediaPlayerEventHandlers(mediaPlayerModel));
        }

        return mediaPlayerModel;
    };

    function getMediaPlayerEventHandlers(mediaPlayerModel) {
        return {
            MediaLoaded: function () {

                if (!_startAt) {
                    _startAt = options.currentTime;
                }
                if (_startAt > 0) {
                    mediaPlayerModel.SetPosition(_startAt);
                }

                if (_shouldBePlaying) {
                    mediaPlayerModel.Play();
                } else {
                    mediaPlayerModel.Pause();
                }

                if (_playbackRate) {
                    self.setPlaybackRate();
                }
            }
        };
    }

    function createSlideTracker(stream) {
        var slideTracker;
        if (stream.HasSlides()) {
            var slideTrackerOptions = {
                Stream: stream,
                EventHandlers: {
                    AddNewSlide: function () { /* todo? */ },
                    SlideChange: function (slide) {
                        showSlide(slide.Number - 1);
                    }
                }
            };

            slideTracker = new Mediasite.Player.SlideTracker(slideTrackerOptions);
        }

        return slideTracker;
    }

    function initSlideNav() {
        if (!_stream.HasSlides()) {
            select.slideNav().remove();
            return;
        }

        _slideNav = new Mediasite.Player.SlideNav(select.slideNav(), function (number, width, height) {
            var aspect = (height > 0) ? width / height : 4 / 3;

            return options.slideUrlProvider.GetCacheFriendlySlideUrl(number, height, aspect);
        });
        _slideNav.setUpdateDisableDelays(0, 0);

        _slideNav.getElement().bind({
            'seek': slideNav_seek,
            'scroll': slideNav_scroll
        });
        _slideNav.getElement().enableTouch();
    }

    function slideNav_seek(event, data) {
        _slideTracker.UpdateCurrentSlide(data.position);
    }

    var _positionThumbnailTimeout;
    function slideNav_scroll(event) {
        if (!event) return;

        clearTimeout(_positionThumbnailTimeout);
        _positionThumbnailTimeout = setTimeout(
            function () {
                var slides = event.getSlides();
                if (!slides) return;

                positionCurrentPresentationImageThumbnail(slides.first, slides.last);
            }, 200);
    }

    function slideNav_setSlides(reset) {
        if (!_slidePartitions || reset) {
            _slidePartitions = new Mediasite.Player.SlidePartitions(_stream.Slides);
            _slidePartitions.bind('currentpagechanged', slideNav_updateSlideItems); // when stack is expanded/collapsed
        } else {
            _slidePartitions.updateSlides(_stream.Slides);
        }

        slideNav_updateSlideItems();
        slideNav_setDuration();
    }

    function slideNav_updateSlideItems() {
        if (_slideNav) {
            _slideNav.setSlides(_slidePartitions.getCurrentPageItems());
        }
    }

    function slideNav_setDuration() {
        if (_slideNav) {
            var duration = getDuration();
            _slideNav.setDuration(duration);
        }
    }

    function slideNav_setPosition(slideIndex) {
        if (_slideNav) {
            slideIndex = typeof slideIndex != "undefined" ? slideIndex : _currentSlideIndex;
            var time = getTime(slideIndex);
            var duration = getDuration();
            var position = time / duration;
            _slideNav.setNormalizedPosition(position);
        }
    }

    function getTime(slideIndex) {
        if (typeof slideIndex === "undefined") slideIndex = _currentSlideIndex;
        if (typeof slideIndex === "undefined") return 0;
        if (typeof _stream.Slides[slideIndex] === "undefined") return 0;

        var time = _stream.Slides[slideIndex].Time;
        return time;
    }

    var _presentationCurrentTime;
    self.setCurrentTime = function (currentTime) {
        if (_startAt === void 0) {
            _startAt = currentTime;
        }

        _presentationCurrentTime = currentTime;

        updateContent();
    };

    self.play = function () {
        _shouldBePlaying = true;
        if (_streamViewer) {
            _streamViewer.MediaPlayerModel.Play();
        }
    };

    self.pause = function () {
        _shouldBePlaying = false;
        if (_streamViewer) {
            _streamViewer.MediaPlayerModel.Pause();
        }
    };

    self.setPlaybackRate = function (playbackRate) {
        if (playbackRate) {
            _playbackRate = playbackRate;
        }

        if (_streamViewer && _playbackRate) {
            _streamViewer.MediaPlayerModel.SetPlaybackRate(playbackRate);
        }
    };

    self.setDuration = function (duration) {
        _duration = duration;
    };

    var _duration;
    function getDuration() {
        return _duration || 0;
    }


    function getSlideUrl(slideNumber) {
        var slide = _stream.Slides[slideNumber - 1];
        var url = slide.url;
        return url;
    }

    self.updateContent = function () { updateContent(); };
    self.updateLayout = function () { updateLayout(true); };

    function updateLayout(resized) {
        select.element().toggleClass(options.classes.canSeek, options.canSeek);
        select.element().toggleClass(options.classes.unsynced, !_staySynced);
        select.element().toggleClass(options.classes.noVideo, !_stream.hasAllowedVideo());
        select.element().toggleClass(options.classes.noSlides, !_stream.HasSlides());

        if (resized !== false) {
            select.inspector().trigger('containerresize');
        }

        if (_slideInspector) {
            _slideInspector.setCanZoom(!_staySynced);
        }
        if (!_staySynced && _slideNav) {
            slideNav_setPosition();
        }
        positionCurrentSlideControls();

    }

    self.setSlides = function (slides) {
        if (_slideNav) {
            slides = Array.prototype.slice.call(arguments);
            var initialize = !slides.length;

            setSlides(slides);
            slideNav_setSlides();
            updateContent();

            if (initialize) {
                updateLayout();
                _slideNav.setNormalizedPosition(0);
            }
        }
    };

    function setSlides(sourceItems) {
        var slides = _stream.Slides;
        for (var i = slides.length, length = sourceItems.length; i < length; i++) {
            var sourceItem = sourceItems[i];

            slides[i] = {};
            for (var prop in sourceItem) {
                if (!sourceItem.hasOwnProperty(prop)) { continue; }

                slides[i][prop] = sourceItem[prop];
            }

            // For the benefit of SlideNav
            slides[i].Number = i + 1;
            slides[i].Caption = '<span class="time">' + options.formatTime(slides[i].Time) + '</span>';
        }
    }

    function updateContent() {
        if (_stream.HasSlides()) {

            if (_staySynced) {
                slideNav_setSlides(true);
                showCurrentPresentationImage();
            }

            showCurrentPresentationImageThumbnail();
        }

        if (_streamViewer) {
            if (_staySynced) {
                if (_shouldBePlaying) {
                    _streamViewer.MediaPlayerModel.Play();
                }
                _streamViewer.SyncCurrentTime(_presentationCurrentTime, _isLive);
            } else {
                _streamViewer.MediaPlayerModel.Pause();
            }
        }
    }

    function changeSlide(step) {
        step = step || 1;
        var slideIndex = _currentSlideIndex || 0;
        slideIndex = bound((slideIndex + step), 0, _stream.Slides.length - 1);

        toggleSync(false);
        showSlide(slideIndex);
    }

    function bound(number, min, max) {
        number = number || 0;
        min = min || 0;
        max = max || 0;
        if (min > max) {
            var temp = min;
            min = max;
            max = min;
        }

        var bounded = Math.max(min, Math.min(number, max));
        return bounded;
    }


    function showCurrentPresentationImage() {
        _slideTracker.UpdateCurrentSlide(_presentationCurrentTime);
    }

    function showSlide(slideIndex) {
        if (typeof slideIndex !== "undefined") {
            _currentSlideIndex = slideIndex;
        }

        if (typeof _currentSlideIndex === "undefined") {
            return;
            // TODO: instead send default image
        }


        var slideImage = new Mediasite.Player.SlideImage(_currentSlideIndex + 1, options.slideUrlProvider);
        _slideInspector.setSlideImage(slideImage);

        slideNav_setPosition(slideIndex);

        updateCurrentSlideControls();
        positionCurrentSlideControls();
    }


    function showCurrentPresentationImageThumbnail() {
        var slideImage = new Mediasite.Player.SlideImage(getPresentationCurrentSlideIndex() + 1, options.slideUrlProvider);
        slideImage.getFullUrl().done(function (url) {
            select.syncedImage().attr('src', url);
        });

        positionCurrentPresentationImageThumbnail();
    }

    var _firstSlideVisible, _lastSlideVisible;
    function positionCurrentPresentationImageThumbnail(firstSlideVisible, lastSlideVisible) {
        _firstSlideVisible = firstSlideVisible || _firstSlideVisible || 0;
        _lastSlideVisible = lastSlideVisible || _lastSlideVisible || _firstSlideVisible;

        var currentSlideIndex = getPresentationCurrentSlideIndex();
        var currentSlideNumber = currentSlideIndex + 1;

        var midpoint = (_firstSlideVisible + _lastSlideVisible) / 2;
        var positionFuture = currentSlideNumber > midpoint;
        select.syncedThumbnail().toggleClass(options.classes.syncedThumbnailInFuture, positionFuture);

        var inSlideNav = _firstSlideVisible <= currentSlideNumber && currentSlideNumber <= _lastSlideVisible;
        select.syncedThumbnail().toggleClass(options.classes.syncedThumbnailVisibleInNav, inSlideNav);

        if (inSlideNav) {
            var navThumbnail = _slideNav.getSlideThumbElement(currentSlideNumber);
            var className = options.classes.slideNavSyncedThumbnail;


            $(navThumbnail).attr('data-slide-preview', true);
        }
        select.element().find('[data-slide-preview]').not(navThumbnail).removeAttr('data-slide-preview');
    }

    function updateCurrentSlideControls() {
        var slide = _stream.Slides[_currentSlideIndex];

        var displayTime = slide && options.formatTime(slide.Time);
        select.inspectedSlideTime().text(displayTime);

        var title = slide && slide.Text || '';
        select.inspectedSlideTitle()
            .text(title)
            .toggle(!!title);
    }

    function positionCurrentSlideControls() {
        var controls = select.inspectedSlideControls();
        var showControls = !_staySynced && (options.canSeek || select.inspectedSlideTitle().text());
        controls.toggle(!!showControls);


        if (showControls) {
            var controlsWidth = controls.outerWidth();
            var leftOffset = 0 - (controlsWidth / 2);
            controls.css({
                'left': '50%',
                'margin-left': leftOffset + 'px'
            });
        }
    }

    function toggleSync(toggleOn) {
        if (typeof toggleOn === "undefined") toggleOn = !_staySynced;
        _staySynced = toggleOn;

        updateContent();
        updateLayout();
    }

    function onToggleSynced(e) {
        toggleSync();
    }

    function onPlayFromHere(e) {
        playPresentationFromCurrentSlide();
    }

    function onClickCurrentPresentationImage(e) {
        showCurrentPresentationImage();
    }

    function playPresentationFromCurrentSlide() {
        var slide = _previewedSlide || _stream.Slides[_currentSlideIndex];
        if (typeof slide === "undefined") return;

        var time = slide.Time;

        // toggleSync(true);
        if (options.onSeek && options.canSeek) {
            options.onSeek(time);
        }
    }

    function onKey(e) {
        switch (e.which) {
            case 37:
                changeSlide(-1);
                break;
            case 39:
                changeSlide(1);
                break;
            case 32:
                if (e.shiftKey) {
                    playPresentationFromCurrentSlide();
                } else {
                    toggleSync();
                }
                break;
            default:
                return;
        }
    }

    function getPresentationCurrentSlideIndex() {
        var presentationCurrentSlide = _slideTracker.GetSlideAtPosition(_presentationCurrentTime);
        var slideIndex = presentationCurrentSlide.Number - 1;
        return slideIndex || 0;
    }
    function getPresentationCurrentSlide() {
        var index = getPresentationCurrentSlideIndex();
        var slide = _stream.Slides[index];
        return slide;
    }



    init();
    return self;
};

$(function () {
	
    var messageBroker = Mediasite.Player.WindowMessageBroker.fromPopoutToMainWindow();
    var _inspector;
	var urlMemoizer = new Mediasite.Player.Memoization();
	
	messageBroker.sendMessage("initialize", null, onInitialize);
	
	function onInitialize(data) {
        var options = $.extend(true, data, {
            onSeek: function (time) {
                if (!data.canSeek) return;
                messageBroker.sendMessage("seekTo", time / 1000);
            },
            formatTime: function (ms) {
                return Mediasite.Player.TimeHelper.Duration(ms).toString();
            },
            slideUrlProvider: {
                GetSlideUrl: function (slideNumber, width, height) {
                    var deferred = $.Deferred();

                    if (slideNumber === 0) {
                        deferred.resolve(data.defaultStreamImage);
                    } else {
						var cachedUrl = urlMemoizer.getValue(slideNumber, width, height);
						
						if (cachedUrl) {
							deferred.resolve(cachedUrl);
						} else {
							messageBroker.sendMessage("getSlideUrl",
								[slideNumber, width, height],
								function (url) {
									urlMemoizer.setValue(slideNumber, width, height, url);
									deferred.resolve(url);
								});							
						}
                    }

                    return deferred;
                },
                GetCacheFriendlySlideUrl: function (slideNumber, height, aspectRatio, callback) {

                    var deferred = $.Deferred();

                    if (slideNumber === 0) {
                        deferred.resolve(data.defaultStreamImage);
                    } else {
						
						var cachedUrl = urlMemoizer.getValue(slideNumber, height, aspectRatio);
						
						if (cachedUrl) {
							deferred.resolve(cachedUrl);
						} else {
							messageBroker.sendMessage("getCacheFriendlySlideUrl",
								[slideNumber, height, aspectRatio],
								function (url) {
									urlMemoizer.setValue(slideNumber, height, aspectRatio, url);
									deferred.resolve(url);
								});
						}
                    }

                    return deferred;
                }
            }
        });

        function continueInit() {
            _inspector = Mediasite.Player.StandaloneStreamInspector(document.body, options);
            _inspector.updateContent();
            _inspector.updateLayout();
        }

        var convivaScripts = ["../../../Javascript/Scripts/3rdParty/conviva-html5native-library.min.jsx", "../../../Javascript/Scripts/ConvivaImplementation.js"];

        if (options.partialConvivaConfiguration.isEnabled) {
            Mediasite.loadScripts(convivaScripts, continueInit);
        } else {
            continueInit();
        }
    }

    messageBroker.setHandler("play", function () {
        if (!_inspector) {
            // This might happen, but initialization should send this
            return;
        }

        _inspector.play();
    });

    messageBroker.setHandler("pause", function () {
        if (!_inspector) {
            // This might happen, but initialization should send this
            return;
        }

        _inspector.pause();
    });

    messageBroker.setHandler("setPlaybackRate", function (playbackRate) {
        if (!_inspector) {
            // This might happen, but initialization should send this
            return;
        }
        _inspector.setPlaybackRate(playbackRate);
    });

    messageBroker.setHandler("setCurrentTime", function (time) {
        if (!_inspector) {
            // This might happen, but another update should come along soon.
            return;
        }
        _inspector.setCurrentTime(time);
    });


    messageBroker.setHandler("updateCurrentSlide", function (time) {
        if (!_inspector) {
            // This might happen, but initialization should send this
            return;
        }
        _inspector.updateCurrentSlide(time);
    });

    messageBroker.setHandler("setDuration", function (time) {
        if (!_inspector) {
            // This might happen, but initialization should send this
            return;
        }
        _inspector.setDuration(time);
    });

    messageBroker.setHandler("setSlides", function (slides) {
        if (!_inspector) {
            // Uh oh.  This shouldn't really happen.
            return;
        }
        _inspector.setSlides.apply(_inspector, slides);
    });

    $(window).on("resize", function (e) {
        if (!_inspector) {
            // This might happen before the _inspector gets instantiated, so this is irrelevant.
            return;
        }
        _inspector.updateLayout();
    });

    window.logs = function () {
        messageBroker.logMessages();
    }
});
