Source: modules/pagecount.js

/**
 * Load the metadata for the report. Will start the rendering if not done already
 * 
 * @class
 * @param   {boolean}  reset             if the metadata should be loaded again
 * @param   {function} hasLoadedFunction function to execute when metadata has been loaded
 * @returns {object}   new getPageCount instance
 */

/* global MenubarActions */
/* global TIMEOUTBEFOREERROR */
/* global amIOnline */
/* global buildBASEURLForPageFile */
/* global errorPacketHandler */
/* global getId */
/* global getTranslation */
/* global groupTreeJson */
/* global grouptree */
/* global menubar */
/* global menubarLoading */
/* global tabbedPanel */

var getPageCount = (function () {

    var finishedFunction = [];
    var jsonNotFoundErrorHandler = null;
    var processResponse = function (data) {

        // 2016-09-19 - there is a new indicator for that.
        menubarLoading.stop('reload');

        if (typeof data == "string" && data !== '') {

            if (jsonNotFoundErrorHandler != null) {
                jsonNotFoundErrorHandler.closeFunction();

                // 2016-07-04 - try not to show/hide loading, so that we can display the UI uninterrupted
                // (new LoadingView()).show();
                jsonNotFoundErrorHandler = null;
            }

            try {
                /* jshint -W061 */
                _getPageCount.DATA = eval('(' + data + ')');
                _getPageCount.preliminaryDATA = null;
                /* jshint +W061 */
            } catch (e) {
                // Cancel potential first page
                new errorPacketHandler({
                    errorHeader: getTranslation("pageCount.dataNotFoundError.subject"),
                    errorMessage: e,
                    JSONData: data
                });
                return;
            }

            if (_getPageCount.DATA.errorCode) {
                // Was an error - should be handled differently
                new errorPacketHandler(_getPageCount.DATA);
                return;
            }

            finishedFunction.push(function (data) {

                var menu = new menubar();
                var menuactions = new MenubarActions();
                menuactions.maxPages = data.pageCount;

                (new tabbedPanel()).setCurrentTitle(data.title);

                // Trigger a re-layout (page indicator), but not reload.
                menuactions.setPage(menuactions.currentPage);

                getPageCount.setSizeOfContent();

                new grouptree(true);

                menuactions.updatePermissions();
                
                if (menu.endlessModeRef && menu.endlessModeRef.id == 'endless-mode') {
                    menu.endlessModeRef.setEnabled(true);
                }
            });

            finishedFunction.forEach(function (finishingFunction) {
                if (typeof finishingFunction == 'function') {
                    finishingFunction(_getPageCount.DATA);
                }
            });

            // Not sure why, but I think the list of functions should be emptied after they have been called
            // if not it will result in multiple callings
            finishedFunction = [];
        }
    };


    var scriptHasLoaded = function () {

        _getPageCount.running = false; // Directly say we are done ...

        // Needs the dynamic Version!!!!
        // groupTreeJson is defined in the global script if all works fine
        var jsonTree = typeof groupTreeJson != 'undefined' ? groupTreeJson : null;
        processResponse(jsonTree);
    };

    var runCheck = function () {

        if (_getPageCount.running) {
            return;
        }

        _getPageCount.running = true;

        // Build Script Part
        var scriptElement = getId('__pageCountIframe');
        if (scriptElement) {
            scriptElement.parentNode.removeChild(scriptElement);
        }

        var pageCountLoading = getId('__pageCountLoading');
        if (pageCountLoading) {
            pageCountLoading.parentNode.removeChild(pageCountLoading);
        }

        menubarLoading.start('reload');

        scriptElement = document.createElement("script");
        // scriptElement.src = buildBASEURLForPageFile('0.js', false, {}, false); // 2018-08-07 encode parameters like prompts. This will be a query URL 
        scriptElement.src = buildBASEURLForPageFile('0.js', false); // 2019-05-13 we do not need to re-encode parameters. The user may have made a mistake!
        scriptElement.type = "text/javascript";
        scriptElement.id = '__pageCountIframe';

        var jsonDataNotFoundError = {
            errorHeader: getTranslation("pageCount.dataNotFoundError.subject"),
            errorMessage: getTranslation("pageCount.dataNotFoundError.body"),
            fileThatCouldNotBeFound: scriptElement.src
        };

        // load event for the iframe to display the content
        scriptElement.addEvent('load', scriptHasLoaded);

        // This is technically correct, BUT generating the full report file may take
        // longer
        // In addition, this part is only triggered after a successfully loaded
        // page.
        // In case of no error, it is safe to assume this action will at some time
        // be successfull.
        // So the message is not really needed
        amIOnline.check(function (isOnline) {
            if (isOnline) {
                return; // Not needed if online mode.
            }

            window.setTimeout(function () {
                if (_getPageCount.running) {
                    jsonNotFoundErrorHandler = new errorPacketHandler(jsonDataNotFoundError);
                }
            }, TIMEOUTBEFOREERROR);
        });

        window.setTimeout(function(){
            document.getElementsByTagName("head")[0].appendChild(scriptElement);
        }, 0);
    };

    var _getPageCount = {

        DATA: null,
        preliminaryDATA: null,
        running: false,
        
        supplyWithData: function (evaluate) {
            if (_getPageCount.DATA === null) {
                finishedFunction.push(evaluate);

                // Only run once
                if (!_getPageCount.running) {
                    runCheck();
                }
            } else if( typeof evaluate == 'function' ) {
                evaluate(_getPageCount.DATA);
            }

            return _getPageCount.DATA;
        },

        /**
         * Update the size of each page to the size that is provided by the data.
         */
        setSizeOfContent: function () {
            //see: #28325 Paperformat only set via json.
            _getPageCount.supplyWithData(_getPageCount.updateSizeOfContent);
        },

        /**
         * Returns the ration of the width / height
         */
        getPageRatio: function() {
            var data = this.DATA || this.preliminaryDATA;
            return data && data.page ? data.page.width / data.page.height : 1;
        },

        updateSizeOfContent: function (data) {
            // If values are know, use them as fallback
            var dataWidth, dataHeight;
            if (data.page) {
                dataWidth = data.page.width;
                dataHeight = data.page.height;
            }

            // Set size for every element!
            var actions = new MenubarActions();
            var contentWrapperInner = (actions.getCurrentTab() || document).getElementsByClassName('__contentwrapperinner');
            for (var i = 1; i <= contentWrapperInner.length; i++) {
                var elem = getId(actions.getCurrentPageName(i));
                if (elem) {
                    elem.htmlViewerPage = elem.htmlViewerPage || {};
                    var width = ( elem.htmlViewerPage.width || dataWidth || 0 ) + "px";
                    var height = ( elem.htmlViewerPage.height || dataHeight || 0 ) + "px";

                    elem.style.width = width;
                    elem.style.height = height;
                    elem.parentNode.style.width = width;
                    elem.parentNode.style.height = height;
                }
            }
        },
        
        reset: function () {
            finishedFunction = [];
            _getPageCount.DATA = null;
            _getPageCount.preliminaryDATA = null;
            _getPageCount.finished = false;
        }
    };

    _getPageCount.reset();
    return _getPageCount;
})();