Mediasite.namespace("Mediasite.Player.DataProvider");

Mediasite.Player.DataProviderType =
{
    None: 0,
    Server: 1,
    PublishToGo: 2,
    Recorder: 3
};

Mediasite.Player.DataProvider.Utilities = (function () {
    function unescapeRawPresentationMetadata(presentation) {

        if (presentation.Title != undefined) {
            unescapeProperty('Title', null, presentation);
            unescapeProperty('Description', null, presentation);
            $.each(presentation.Presenters, unescapeProperty.bind(this, 'Name'));
            $.each(presentation.Transcript, unescapeProperty.bind(this, 'Text'));
            $.each(presentation.Transcript, cleanTranscriptText);
            fixTranscriptEndTimes(presentation.Transcript);
            $.each(presentation.Chapters, unescapeProperty.bind(this, 'Text'));
            $.each(presentation.TimedEvents, unescapeProperty.bind(this, 'Type'));
            $.each(presentation.SupportingLinks, unescapeProperty.bind(this, 'Url'));
            $.each(presentation.SupportingLinks, unescapeProperty.bind(this, 'Description'));
            $.each(presentation.Streams, function (index, stream) {
                $.each(stream.Slides, unescapeProperty.bind(this, "Description"));
                $.each(stream.Slides, unescapeProperty.bind(this, "Text"));
            });
        }

        return presentation;
    }
    function unescapeProperty(property, index, object) {

        if (object[property] == undefined) return;

        object[property] = object[property].unescapeJavascriptSerialized();
    }

    function cleanTranscriptText(index, item) {
        if (item.Text) {
            item.Text = removeIndentingTabs(trim(item.Text));
        }
    }

    function removeIndentingTabs(text) {
        var pattern = /((\n\t))/g;
        text = text || '';
        return text.replace(pattern, '\n');
    }

    function trim(text) {
        var pattern = /(^\s+|\s+$)/g;
        text = text || '';
        return text.replace(pattern, '');
    }

    function fixTranscriptEndTimes(transcript) {
        // Sometimes captions will not have reasonable end times. 
        // Usually, this means that a caption should expire when the next one starts. 
        // This function attempts to fill in those end times.
        var i, start, end, isLastItem, nextItemStart;
        var fallbackCaptionDuration = 10 * 1000;
        var calculateFallbackCaptionEndTime = function (startTime) { return startTime + fallbackCaptionDuration - 1; };

        for (i = 0; i < transcript.length; i += 1) {
            start = transcript[i].Time;
            end = transcript[i].EndTime;
            isLastItem = (i == transcript.length - 1);
            if (!end || end < start) {
                if (isLastItem) {
                    // There is no caption after this one, so set the end time to allow the 
                    // caption to remain on screen for a reasonable default time.
                    end = calculateFallbackCaptionEndTime(start);
                } else {
                    // There is a caption after this one.
                    nextItemStart = transcript[i + 1].Time;
                    if (nextItemStart > start) {
                        end = nextItemStart - 1;
                    } else {
                        end = calculateFallbackCaptionEndTime(start); // Fall back to the default caption duration;
                    }
                }
            }

            transcript[i].EndTime = end;
        }
    }

    return {
        unescapeRawPresentationMetadata: unescapeRawPresentationMetadata
    };

})();



Mediasite.Player.DataProvider.GetProvider = function (dataProviderType, presentationId, serviceLocation, parentElementId, urlReferrer, customHeader) {
    switch (dataProviderType) {
        case Mediasite.Player.DataProviderType.Server:
            return new Mediasite.Player.DataProvider.Server(presentationId, serviceLocation, parentElementId, urlReferrer, customHeader);
        case Mediasite.Player.DataProviderType.PublishToGo:
            return new Mediasite.Player.DataProvider.PublishToGo();
        case Mediasite.Player.DataProviderType.Recorder:
            return new Mediasite.Player.DataProvider.Recorder(presentationId, serviceLocation, parentElementId);
        default:
            return new Mediasite.Player.DataProvider.Server(presentationId, serviceLocation, parentElementId, urlReferrer);
    }
};


Mediasite.Player.DataProvider.Server = function (presentationId, serviceLocation, parentElementId, urlReferrer, customHeader) {
    var playerContext;
    var serviceContentType = "application/json; charset=utf-8";
    var self = this;

    //*********************************************************************************
    // UserPreferences
    //*********************************************************************************
    this.UserPreferences = new Mediasite.Player.UserPreferences();

    //*********************************************************************************
    // LoadPlayerData
    //*********************************************************************************
    this.LoadPlayerData = function (callback) {
        playerContext = {};

        var getPlayerOptionsRequest =
        {
            getPlayerOptionsRequest:
          {
              ResourceId: presentationId,
              QueryString: window.location.search,
              UseScreenReader: this.UserPreferences.GetValue(Mediasite.Player.Options.UseScreenReader, false),
              UrlReferrer: urlReferrer
          }
        };

        $.ajax({
            async: true,
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: getServiceLocation("GetPlayerOptions"),
            data: JSON.stringify(getPlayerOptionsRequest),
            beforeSend: function (xhr) {
                if (customHeader) {
                    xhr.setRequestHeader(customHeader, true);
                }
            },
            error: function (data) {

                var message = "Unknown Error";
                try {
                    message = JSON.parse(data.responseText).Message;
                } catch (e) { }

                playerContext.Success = false;

                var errorObject =
                    {
                        errorCode: 600,
                        details: message
                    };

                playerContext.error = errorObject;

                callback(playerContext);
            },
            success: function (data) {
                if (data.d.PlayerPresentationStatus == Mediasite.Player.PlayerPresentationStatus.Viewable) {

                    data.d.Presentation.ServerClockSkew = new Date().getTime() - data.d.Presentation.ServerTimeForClockSkew;

                    playerContext.Success = true;
                    playerContext.PlayerLayoutOptions = $.extend({}, data.d.PlayerLayoutOptions);
                    playerContext.GlobalOptions = $.extend({
                        AllowPlayerStreamPopout: true // Not currently a SiteProperty. Always true for EVP Server based playback.
                    }, data.d.GlobalOptions);
                    playerContext.UserData = {};
                    playerContext.UserData.PresentationBookmark = {
                        position: data.d.PresentationBookmark.position * 1000, // Server gives us seconds, but code expects milliseconds.
                        savedAt: data.d.PresentationBookmark.savedAt
                    };
                    playerContext.UserData.UserPreferences = getUserPreferences();
                    playerContext.UserData.PastSessionPlayedSegments = transformCoverageEvents(data.d.CoverageEvents);
                    var presentationMetadata = Mediasite.Player.DataProvider.Utilities.unescapeRawPresentationMetadata(data.d.Presentation);
                    absolutizeSlideBaseUrls(presentationMetadata.Streams);
                    fixSlideBaseUrlSchemes(presentationMetadata.Streams);
                    playerContext.CurrentPresentation = new Mediasite.Presentation(presentationMetadata);
                    playerContext.PlaybackOptions = new Mediasite.Player.PlaybackOptions(playerContext.CurrentPresentation, playerContext.UserData.PresentationBookmark);
                    playerContext.GlobalOptions.UseScreenReader = self.UserPreferences.GetBoolValue(Mediasite.Player.Options.UseScreenReader, false);
                    Mediasite.Player.IosAppDetectionOptions = $.extend({}, data.d.IosAppDetectionOptions);

                    if (playerContext.CurrentPresentation.PlayStatus !== "Live") {
                        // DEBUG: 
                        //hackInHlsVideoUrls(playerContext.CurrentPresentation.Streams);
                    }
                }
                else if (data.d.LoginUrl) {
                    window.location = data.d.LoginUrl + '?ReturnUrl=' + encodeURIComponent(window.location);
                }
                else {
                    playerContext.Success = false;

                    var errorObject =
                    {
                        errorCode: 600 + data.d.PlayerPresentationStatus,
                        details: data.d.PlayerPresentationStatusMessage
                    };

                    playerContext.error = errorObject;

                    Mediasite.Player.DisplayMessage({
                        message: data.d.PlayerPresentationStatusMessage,
                        isError: true,
                        width: '500',
                        buttons: []

                    });
                }

                if (Mediasite.GetQueryParam("useConvivaTouchstone", Mediasite.GetQueryParam.AsBool)) {
                    playerContext.GlobalOptions.ConvivaServiceUrl = Mediasite.Player.Configurations.conviva.touchstoneServiceUrl;
                }

                callback(playerContext);
            }
        });
    };


    function transformCoverageEvents(serverItems) {
        if (!serverItems || serverItems.length <= 0) {
            return;
        }

        var i, start, end;
        var items = [];
        for (i = 0; i < serverItems.length; i += 1) {
            start = serverItems[i].StartTime;
            end = serverItems[i].StartTime + serverItems[i].Duration;
            items.push({ start: start, end: end });
        }

        return items;
    }


    function hackInDashVideoUrls(streams) {
        var streamIndex, urlIndex, stream, url;

        for (streamIndex = 0; streamIndex < streams.length; streamIndex++) {
            stream = streams[streamIndex];
            for (urlIndex = 0; urlIndex < stream.VideoUrls.length; urlIndex++) {
                url = stream.VideoUrls[urlIndex];
                if (url.MimeType == Mediasite.Player.MimeTypes.SS) {
                    stream.VideoUrls.push(makeDashUrlItem(url));
                    break; // break out of the inner loop to continue on to the next stream.
                }
            }
        }
    }

    function hackInHlsVideoUrls(streams) {
        var streamIndex, urlIndex, stream, url;

        for (streamIndex = 0; streamIndex < streams.length; streamIndex++) {
            stream = streams[streamIndex];
            for (urlIndex = 0; urlIndex < stream.VideoUrls.length; urlIndex++) {
                url = stream.VideoUrls[urlIndex];
                if (url.MimeType == Mediasite.Player.MimeTypes.Dash) {
                    stream.VideoUrls.push(makeHlsUrlItem(url));
                    break; // break out of the inner loop to continue on to the next stream.
                }
            }
        }
    }

    function makeDashUrlItem(ssUrlItem) {
        var newUrlObj = $.extend({}, ssUrlItem, {
            Location: ssUrlItem.Location.replace(/manifest/i, 'manifest(format=mpd-isoff)'),
            MediaType: Mediasite.Player.MediaTypes.Dash,
            MimeType: Mediasite.Player.MimeTypes.Dash,
            ServerType: Mediasite.Player.ServerTypes.IIS
        });

        return newUrlObj;
    }

    function makeHlsUrlItem(dashUrlItem) {
        var newUrlObj = $.extend({}, dashUrlItem, {
            Location: dashUrlItem.Location.replace(/format=mpd-isoff/i, 'format=m3u8-aapl-isoff'),
            MediaType: Mediasite.Player.MediaTypes.MP4,
            MimeType: Mediasite.Player.MimeTypes.M3U,
            ServerType: Mediasite.Player.ServerTypes.Deliver
        });

        return newUrlObj;
    }


    function processAllBaseSlideUrls(streams, process) {
        var i;

        if (!streams) {
            return;
        }

        for (i = 0; i < streams.length; i += 1) {
            var stream = streams[i];
            if (stream.SlideBaseUrl !== null) {
                stream.SlideBaseUrl = process(stream.SlideBaseUrl);
            }
        }
    }

    function absolutizeSlideBaseUrls(streams) {
        processAllBaseSlideUrls(streams, function (url) {
            if (url.indexOf('://') === -1) {
                var baseUri = baseUri || Mediasite.BrowserDetect.GetBaseUri();
                return baseUri + '/' + url;
            } else {
                return url;
            }
        });
    }

    function fixSlideBaseUrlSchemes(streams) {
        processAllBaseSlideUrls(streams, function (url) {
            var httpsPattern = /^https\:/i;
            var httpPattern = /^http\:/i;
            var pageIsHttps = httpsPattern.test(window.location.href);
            var urlIsHttp = httpPattern.test(url);
            if (pageIsHttps && urlIsHttp) {
                return url.replace(httpPattern, 'https:');
            } else {
                return url;
            }
        });
    }


    //*********************************************************************************
    // LoadMarkup
    //*********************************************************************************
    this.LoadMarkup = function (url, buildNumber, callback) {

        $.ajax({
            type: 'GET',
            dataType: 'text',
            contentType: 'application/x-www-form-urlencoded',
            url: url + "?version=" + buildNumber,
            async: true,
            success: function (markup) {
                $('#' + parentElementId).empty().append(markup);
                callback();
            },
            error: function () {
                callback();
            }
        });
    };

    //*********************************************************************************
    // GetLiveStatus
    //*********************************************************************************
    this.GetLiveStatus = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("GetLiveStatus"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // GetLiveEvents
    //*********************************************************************************
    this.GetLiveEvents = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("GetLiveEvents"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // GetStreams
    //*********************************************************************************
    this.GetStreams = function (playbackTicket, successCallback, errorCallback) {
        var getStreamsRequest =
        {
            getStreamsRequest:
            {
                PlaybackTicket: playbackTicket
            }
        };


        $.ajax({
            async: true,
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: getServiceLocation("GetStreams"),
            data: JSON.stringify(getStreamsRequest),
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // GetInvite
    //*********************************************************************************
    this.GetInvite = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("GetInvite"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // GetUsersEmailAddress
    //*********************************************************************************
    this.GetUsersEmailAddress = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("GetUsersEmailAddress"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };




    //*********************************************************************************
    // SendInvite
    //*********************************************************************************
    this.SendInvite = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("SendInvite"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // SendQuestion
    //*********************************************************************************
    this.SendQuestion = function (jsonData, successCallback, errorCallback) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("SendQuestion"),
            data: jsonData,
            success: successCallback,
            error: errorCallback
        });
    };

    //*********************************************************************************
    // Search
    //*********************************************************************************
    var searchRequest;
    this.Search = function (searchTerm, successCallback, errorCallback) {
        if (searchRequest) searchRequest.abort();

        var jsonData = JSON.stringify({ playbackTicketId: playerContext.CurrentPresentation.PlaybackTicketId, searchTerm: searchTerm });
        searchRequest = $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("SearchPresentationText"),
            data: jsonData,
            success: function (data) {
                if (data && data.d && data.d.SearchResults) {
                    successCallback && successCallback(data.d.SearchResults, searchTerm);
                } else {
                    errorCallback && errorCallback();
                }
            },
            error: errorCallback
        });
    };


    //*********************************************************************************
    // ReportMediaOpen
    //*********************************************************************************
    this.ReportMediaOpen = function (jsonData) {

        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("ReportMediaOpen"),
            data: jsonData
        });
    };

    //*********************************************************************************
    // ReportMediaView
    //*********************************************************************************
    this.ReportMediaView = function (jsonData, runAsync) {

        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: serviceContentType,
            url: getServiceLocation("ReportMediaView"),
            async: runAsync,
            data: jsonData
        });
    };

    //*********************************************************************************
    // Private Methods
    //*********************************************************************************
    function ajaxSetup() {

        //Handle errors and authorization issues 
        $(document).ajaxComplete(function (e, hxr, settings) {
            var result;

            try {
                result = JSON.parse(hxr.responseText);
            } catch (e) {
                //return;
                if (hxr.statusCode().status == 404) {
                    result = { Message: 'An error occurred.  Please check the server logs.', Success: false };
                }
                else {
                    return;
                }
            }

            // redirect to login on session timeout
            if (result.FaultType == 2 && result.LoginUrl) {
                window.location = result.LoginUrl + '?ReturnUrl=' + encodeURIComponent(window.location);
                return;
            }

            if (result.Message != null) {
                Mediasite.Player.DisplayMessage({
                    message: result.Message,
                    width: '500'
                });
                return;
            }
        });
    }

    function getServiceLocation(methodName) {
        //var servicePath = $('#GlobalData > #ServicePath').text();
        return serviceLocation + '/' + methodName;
    }

    function getUserPreferences() {
        var userPreferences = {
            UserFromName: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromName, ""),
            UserFromEmail: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromEmail, ""),
            Volume: self.UserPreferences.GetValue(Mediasite.Player.Options.Volume, "100"),
            SlideDisplay: self.UserPreferences.GetValue(Mediasite.Player.Options.SlideDisplay, Mediasite.Player.SlideDisplayPref.LargeThumbs),
            ShowSlideDescriptions: self.UserPreferences.GetValue(Mediasite.Player.Options.ShowSlideDescriptions, false)
        };

        return userPreferences;
    };


    

    (function () {
        ajaxSetup();
    })();

};

Mediasite.Player.DataProvider.PublishToGo = function () {
    var playerContext;
    var self = this;

    //*********************************************************************************
    // UserPreferences
    //*********************************************************************************
    this.UserPreferences = new Mediasite.Player.UserPreferences();

    //*********************************************************************************
    // LoadPlayerData
    //*********************************************************************************
    this.LoadPlayerData = function (callback) {

        playerContext = {};
        playerContext.Success = true;
        playerContext.PlayerLayoutOptions = $.extend({}, JSON.parse(Mediasite.PlayerLayoutOptions.JSON));
        var presentationMetadata = Mediasite.Player.DataProvider.Utilities.unescapeRawPresentationMetadata(Mediasite.CurrentPresentation.JSON);
        setAbsoluteSlideBaseUrl(presentationMetadata);
        playerContext.CurrentPresentation = new Mediasite.Presentation(presentationMetadata);
        playerContext.GlobalOptions = {
            AppRoot: "",
            EnableContextMenuForPlayer: true,
            ErrorPage: "",
            ServiceEndpoint: "",
            SessionTimeout: 1200000,
            SlideGroupMaxInGroup: 10,
            SlideGroupMinToTrigger: 25,
            SlideGroupThreshold: 2000,
            UseLiveEventPolling: false,
            CompatiblePlugins: undefined,
            DesiredPlugins: Mediasite.Player.MediaPlugins.None,
            UseExtensions: false,
            EnableConviva: false,
            AllowPlayerVideoStreamPopout: false, // Should stream popout windows be allowed to play video?
            AllowPlayerStreamPopout: false // Should stream popout windows be alloed at all?
        };
        playerContext.PlayerLayoutOptions.PlayerType = globalPlayerType;
        playerContext.PlaybackOptions = new Mediasite.Player.PlaybackOptions(playerContext.CurrentPresentation, null);
        playerContext.UserData = {};
        playerContext.UserData.UserPreferences = getUserPreferences();

        removeUnplayableVideos(playerContext.CurrentPresentation.Streams);

        callback(playerContext);
    };

    function removeUnplayableVideos(streams) {
        var i, ii, vids, v;
        var mimes = Mediasite.Player.MimeTypes;

        for (i = 0; i < streams.length; i += 1) {
            vids = streams[i].VideoUrls;
            for (ii = vids.length - 1; ii >= 0; ii -= 1) {
                v = vids[ii];
                if (v.MimeType !== mimes.MP4 && v.MimeType !== mimes.WMV) {
                    vids.splice(ii, 1); // Remove it.
                }
            }
        }
    }

    function setAbsoluteSlideBaseUrl(presentationMetadata) {
        for (var i = 0, length = presentationMetadata.Streams.length; i < length; i++) {
            var stream = presentationMetadata.Streams[i];
            if (stream.SlideBaseUrl !== null && stream.SlideBaseUrl.indexOf('://') === -1) {
                var baseUri = baseUri || Mediasite.BrowserDetect.GetBaseUri();
                stream.SlideBaseUrl = baseUri + '/' + stream.SlideBaseUrl;
            }
        }
    }

    //*********************************************************************************
    // LoadMarkup
    //*********************************************************************************
    this.LoadMarkup = function (url, buildNumber, callback) {
        callback();
    };

    //*********************************************************************************
    // GetLiveStatus
    //*********************************************************************************
    this.GetLiveStatus = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // GetLiveEvents
    //*********************************************************************************
    this.GetLiveEvents = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // GetStreams
    //*********************************************************************************
    this.GetStreams = function (playbackTicket, successCallback, errorCallback) {
        errorCallback({});
    };

    //*********************************************************************************
    // GetInvite
    //*********************************************************************************
    this.GetInvite = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // SendInvite
    //*********************************************************************************
    this.SendInvite = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // SendQuestion
    //*********************************************************************************
    this.SendQuestion = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // Search
    //*********************************************************************************
    this.Search = function (searchTerm, successCallback, errorCallback) {
        var presentation = playerContext.CurrentPresentation;

        var transcript = presentation.Transcript;
        var slideStream = slideStream = presentation.GetStream(Mediasite.ContentStreamType.Slide);

        var slides = slideStream ? slideStream.Slides : [];
        var transcriptResults = [];
        var slideResults = [];
        var convertedSlideResults = [];
        var regex = new RegExp('(' + searchTerm + ')', 'gi');

        //Transcript
        if (jQuery.isArray(transcript) && transcript.length > 0) {
            transcriptResults = jQuery.grep(transcript, function (item, i) {
                return (item && item.Text.match(regex));
            });
            transcriptResults = jQuery.map(transcriptResults, function (item, index) {
                return jQuery.extend({}, item, { Type: Mediasite.TimingEventType.Caption });
            });
        }

        if (jQuery.isArray(slides) && slides.length > 0) {
            slideResults = jQuery.grep(slides, function (item, i) {
                var text = item.Text + ' ' + item.Description;
                return (item && text.match(regex));
            });

            $.each(slideResults, function (index, item) {
                convertedSlideResults.push(
                {
                    Type: Mediasite.TimingEventType.SlideText,
                    Text: item.Text + ' ' + item.Description,
                    Time: item.Time,
                    Number: item.Number
                });
            });
        }

        //Merge & Sort
        $.merge(transcriptResults, convertedSlideResults);
        transcriptResults = transcriptResults.sort(function (a, b) { return a.Time - b.Time; });

        successCallback(transcriptResults, searchTerm);
    };

    //*********************************************************************************
    // ReportMediaOpen
    //*********************************************************************************
    this.ReportMediaOpen = function (jsonData) {
    };

    //*********************************************************************************
    // ReportMediaView
    //*********************************************************************************
    this.ReportMediaView = function (jsonData, runAsync) {
    };

    //*********************************************************************************
    // Private Methods
    //*********************************************************************************
    function getUserPreferences() {
        var userPreferences = {
            UserFromName: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromName, ""),
            UserFromEmail: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromEmail, ""),
            Volume: self.UserPreferences.GetValue(Mediasite.Player.Options.Volume, "100"),
            SlideDisplay: self.UserPreferences.GetValue(Mediasite.Player.Options.SlideDisplay, Mediasite.Player.SlideDisplayPref.LargeThumbs),
            ShowSlideDescriptions: self.UserPreferences.GetValue(Mediasite.Player.Options.ShowSlideDescriptions, false)
        };

        return userPreferences;
    };
};

Mediasite.Player.DataProvider.Recorder = function (presentationId, serviceLocation, parentElementId) {

    var self = this;

    //ServiceLocation parameter loses scope in the LoadDataPlayer closure, set this here to send it in.
    self.serviceLocation = serviceLocation;

    //*********************************************************************************
    // UserPreferences
    //*********************************************************************************
    this.UserPreferences = new Mediasite.Player.UserPreferences();

    //*********************************************************************************
    // LoadPlayerData
    //*********************************************************************************
    this.LoadPlayerData = function (callback) {

        var getPlayerPresentationRequest = {
            PresentationId: Mediasite.GetQueryParam('presentationId')

        };


        var playerContext = {};
        playerContext.Success = false;
        $.ajax({
            async: true,
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: self.serviceLocation,
            data: JSON.stringify(getPlayerPresentationRequest),
            success: function (data) {

                data.Presentation.ServerClockSkew = new Date().getTime() - data.Presentation.ServerTimeForClockSkew;
                data.PlayerLayoutOptions.PlayerType = Mediasite.Player.PlayerType.ContentOnlyPlayer;

                playerContext.PlayerLayoutOptions = $.extend({}, data.PlayerLayoutOptions);

                playerContext.PlayerLayoutOptions.PlayerLoader = "Javascript/Players/ContentOnlyPlayer/Mediasite.Player.ContentOnlyPlayerView.js";
                playerContext.GlobalOptions = {
                    AppRoot: "",
                    EnableContextMenuForPlayer: true,
                    ErrorPage: "",
                    ServiceEndpoint: "",
                    SessionTimeout: 1200000,
                    SlideGroupMaxInGroup: 10,
                    SlideGroupMinToTrigger: 25,
                    SlideGroupThreshold: 2000,
                    UseLiveEventPolling: false,
                    CompatiblePlugins: undefined,
                    DesiredPlugins: Mediasite.Player.MediaPlugins.None,
                    UseExtensions: false
                };
                playerContext.UserData = Mediasite.UserData ? Mediasite.UserData : {};
                playerContext.UserData.PresentationBookmark = playerContext.UserData.PresentationBookmark ? $.extend(playerContext.UserData, data.PresentationBookmark) : $.extend({}, data.PresentationBookmark);
                playerContext.UserData.UserPreferences = getUserPreferences();

                playerContext.CurrentPresentation = new Mediasite.Presentation(data.Presentation);
                playerContext.CurrentPresentation.SharingEnabled = false;
                playerContext.PlaybackOptions = new Mediasite.Player.PlaybackOptions(playerContext.CurrentPresentation, null);
                playerContext.PlaybackOptions.AutoStart = true;

                playerContext.Success = true;

                callback(playerContext);
            },
            error: function (data) {
                callback(playerContext);
            }
        });
    };

    //*********************************************************************************
    // LoadMarkup
    //*********************************************************************************
    //Recorder will load markup from file
    this.LoadMarkup = function (url, buildNumber, callback) {
        $.ajax({
            url: url,
            type: 'get',
            dataType: 'html',
            async: true,
            success: function (markup) {
                $('#PlayerContent').empty();
                $('#PlayerContent').append(markup);
                callback();
            },
            error: function () {
                callback();
            }
        });
    };

    //*********************************************************************************
    // GetLiveStatus
    //*********************************************************************************
    this.GetLiveStatus = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // GetLiveEvents
    //*********************************************************************************
    this.GetLiveEvents = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // GetStreams
    //*********************************************************************************
    this.GetStreams = function (playbackTicket, successCallback, errorCallback) {
        errorCallback({});
    };

    //*********************************************************************************
    // GetInvite
    //*********************************************************************************
    this.GetInvite = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // SendInvite
    //*********************************************************************************
    this.SendInvite = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // SendQuestion
    //*********************************************************************************
    this.SendQuestion = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // Search
    //*********************************************************************************
    this.Search = function (jsonData, successCallback, errorCallback) {
        return undefined;
    };

    //*********************************************************************************
    // ReportState
    //*********************************************************************************
    this.ReportState = function (jsonData, successCallback, errorCallback) {
    };

    //*********************************************************************************
    // ReportMediaOpen
    //*********************************************************************************
    this.ReportMediaOpen = function (jsonData) {
    };

    //*********************************************************************************
    // ReportMediaView
    //*********************************************************************************
    this.ReportMediaView = function (jsonData, runAsync) {
    };

    //*********************************************************************************
    // Private Methods
    //*********************************************************************************
    function ajaxSetup() {

        //Handle errors 
        $(document).ajaxComplete(function (e, hxr, settings) {
            var result;

            try {
                result = JSON.parse(hxr.responseText);
            } catch (e) {
                //return;
                if (hxr.statusCode().status == 404) {
                    result = { Message: 'An error occurred.  Please check the recorder logs.', Success: false };
                }
                else {
                    return;
                }
            }

            if (result.Message != null) {
                Mediasite.Player.DisplayMessage({
                    message: result.Message,
                    width: '500'
                });
                return;
            }
        });
    }

    function getUserPreferences() {
        var userPreferences = {
            UserFromName: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromName, ""),
            UserFromEmail: self.UserPreferences.GetValue(Mediasite.Player.Options.UserFromEmail, ""),
            Volume: self.UserPreferences.GetValue(Mediasite.Player.Options.Volume, "100"),
            SlideDisplay: self.UserPreferences.GetValue(Mediasite.Player.Options.SlideDisplay, Mediasite.Player.SlideDisplayPref.LargeThumbs),
            ShowSlideDescriptions: self.UserPreferences.GetValue(Mediasite.Player.Options.ShowSlideDescriptions, false)
        };

        return userPreferences;
    };

    $(function () {
        ajaxSetup();
    });

}
