Source: managers/bookmark.js

define('application/managers/bookmark', [
    'application/managers/api',
    'rofl/lib/utils',
    'antie/runtimecontext',
    'application/events/bookmarkevent'
], function (
    ApiManager,
    Utils,
    RuntimeContext,
    BookmarkEvent
) {
    'use strict';

    var STATES = {
            'PAUSED': 'PAUSED',
            'PLAYING': 'PLAYING',
            'STOPPED': 'STOPPED'
        },
        api = ApiManager.getKPNAPI(),
        state = STATES.STOPPED,
        app = RuntimeContext.getCurrentApplication(),
        startTime,
        pauseTime,
        type,
        id;

    return {

        /**
         * Marks a playstart.
         *
         * @param {string} contentId - The content id.
         * @param {string} contentType - The content type.
         */
        onPlayStart: function (contentId, contentType) {

            if (state === STATES.PAUSED) {
                this.onResume();
                return;
            }

            state = STATES.PLAYING;
            id = contentId;
            type = contentType;
            startTime = app.getDate().getTime();
        },

        /**
         * Marks a pause.
         */
        onPause: function () {
            state = STATES.PAUSED;
            pauseTime = app.getDate().getTime();
        },

        /**
         * Marks a resume.
         */
        onResume: function () {
            var diff = app.getDate().getTime() - pauseTime;

            state = STATES.PLAYING;
            startTime += diff;
        },

        /**
         * Marks a stop.
         *
         * @param {number} [channelId] - Force call in any player state.
         * @param {number} [time] - Video time to set in bookmark.
         */
        onStop: function (channelId, time) {
            if (!channelId && state === STATES.STOPPED) {
                return;
            }

            if (channelId) {
                id = channelId;
            }

            state = STATES.STOPPED;
            this._callBookmark(time);
        },

        /**
         * Calls the bookmark.
         *
         * @param {number} [time] - Player time.
         * @private
         */
        _callBookmark: function (time) {
            var data = {},
                bookmarkTime,
                bookmarkType;

            if (id && type) {

                data.deltaThreshold = this._calculateBookmark();

                if ((type === 'VOD' || type === 'VOD_MOVIE' || type === 'RECORDING') && Utils.isNumber(time)) {
                    bookmarkTime = Math.floor(time);
                    data.bookmark = {
                        startDeltaTime: bookmarkTime,
                        bookmarkTitle: 'lastViewPoint',
                        bookmarkType: 'Application'
                    };
                    bookmarkType = type === 'VOD_MOVIE' ? 'VOD' : type;

                    // Currently only VOD contents shows bookmarks.
                    if (bookmarkType === 'VOD') {
                        this._updateBookmarkList(id, bookmarkType, bookmarkTime);
                        app.broadcastEvent(new BookmarkEvent(id, type, bookmarkTime));
                    }
                }

                api.create('userdata', {
                    params: {
                        contentId: id,
                        contentType: type
                    },
                    data: data,
                    withCredentials: true,
                    headers: {
                        'Content-Type': 'application/json'
                    }
                });
            }
        },

        /**
         * Calculates the bookmark.
         *
         * @returns {number} - The bookmark number.
         * @private
         */
        _calculateBookmark: function () {
            return Math.round((app.getDate().getTime() - startTime) / 1000);
        },

        /**
         * Sets a bookmark list.
         *
         * @param {Object} bookmarkList - The bookmark list.
         */
        setBookmarkList: function (bookmarkList) {
            var contentId,
                contentType;

            this._bookmarkList = {};

            Utils.each(bookmarkList, Utils.bind(function (bookmark) {
                contentId = bookmark.bookmarkSet.contentId;
                contentType = bookmark.bookmarkSet.contentType.toLowerCase();

                if (this._bookmarkList[contentType]) {
                    this._bookmarkList[contentType][contentId] = bookmark;
                } else {
                    this._bookmarkList[contentType] = {};
                    this._bookmarkList[contentType][contentId] = bookmark;
                }
            }, this));
        },

        /**
         * Updates a bookmark entry in the internal bookmark list for the given contentId.
         *
         * @param {number} contentId - The content ID.
         * @param {string} contentType - The content type of the content to be updated.
         * @param {number} bookmarkTime - The new bookmark time.
         * @private
         */
        _updateBookmarkList: function (contentId, contentType, bookmarkTime) {
            var bookmarkData;

            contentType = contentType.toLowerCase();
            bookmarkData = this._bookmarkList && this._bookmarkList[contentType] && this._bookmarkList[contentType][contentId];

            if (bookmarkData) {
                bookmarkData.startDeltaTime = bookmarkTime;
            }
        },

        /**
         * Gets the bookmark time (in seconds) for the given contentId and contentType.
         *
         * @param {number} contentId - The id of the content to retrieve bookmark.
         * @param {string} contentType - The type of the content.
         * @returns {number} - The bookmark time.
         */
        getBookmark: function (contentId, contentType) {
            var bookmarkData;

            contentType = contentType.toLowerCase();
            bookmarkData = this._bookmarkList && this._bookmarkList[contentType] && this._bookmarkList[contentType][contentId];

            return bookmarkData && bookmarkData.startDeltaTime;
        },

        /**
         * Parse the bookmark object and returns the bookmark time.
         *
         * @param {Object} data - The data.
         * @returns {number} - The retrieved startDeltaTime aka bookmarktime.
         */
        parsedBookmarkTime: function (data) {
            var containers = Utils.getNested(data, 'resultObj', 'containers'),
                bookmarks;

            if (!Utils.isUndefined(containers) && containers.length) {
                bookmarks = Utils.getNested(containers[0], 'metadata', 'bookmarks');
            }

            if (!Utils.isUndefined(bookmarks) && bookmarks.length) {
                return Utils.getNested(bookmarks[0], 'startDeltaTime');
            }
        }
    };
});