"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var ig_utilities_1 = require("@intelligentgraphics/ig.utilities");
var Connector_1 = require("./Connector");
var EPageToHostCmd_1 = require("./EPageToHostCmd");
var Logger_1 = require("./Logger");
var AppLogger = Logger_1.default.createSubLogger("App");
/**
 * Base class for all Pages.
 * A page in this context is a functionally complete step in an
 * interactive planning process AKA wizard step.
 * It should be created when a corresponend HTML page is loaded and it
 * needs an instance of IConnector as parameter.
 */
var Page = /** @class */ (function () {
    /**
     * Constructor. Don't put your application's code in the constructor
     * of you derived Page class, as vital functions like HostInfo() are
     * not available here. Instead, override the protected function
     * initialize() and put your code there.
     */
    function Page() {
        var _this = this;
        this._connector = new Connector_1.Connector(function (hostInfo) {
            _this._hostInfo = hostInfo;
            if (!hostInfo.Debug) {
                console.log = function () { };
                console.info = function () { };
                console.debug = function () { };
            }
            _this.initialize();
        });
    }
    /**
     * Override this method in your application's derived page class, doing
     * the stuff needed to be done first upon loading the page.
     */
    Page.prototype.initialize = function () {
        //
    };
    Object.defineProperty(Page.prototype, "Connector", {
        /**
         * Returns the initialized Connector object.
         */
        get: function () {
            return this._connector;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Page.prototype, "OnBeforePageChange", {
        /**
         * Returns the OnBeforePageChange callback.
         */
        get: function () {
            return this._onBeforePageChange;
        },
        /**
         * Sets the OnBeforePageChange callback.
         * @param param Callback method to be called when the
         *        OnBeforePageChange function finishes. Return false when the
         *        page is not allowed to change.
         */
        set: function (param) {
            this._onBeforePageChange = param;
        },
        enumerable: true,
        configurable: true
    });
    Page.prototype.getHostParameters = function (callback) {
        var _this = this;
        var tConnHP = this._connector.getHostParameters();
        if (tConnHP == undefined) {
            throw new Error(Connector_1.Connector.NoHostException);
        }
        else {
            if (tConnHP["ready"] === true) {
                if (callback) {
                    callback(tConnHP["config"]);
                }
            }
            else {
                window.setTimeout(function () {
                    _this.getHostParameters(callback);
                }, 20);
            }
        }
    };
    /**
     * Executes log() with the scope IGD_log.ELogScope.App
     * @param level Severity of the message
     * @param message The log message(s).
     */
    Page.prototype.appLog = function (level) {
        var message = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            message[_i - 1] = arguments[_i];
        }
        AppLogger.log.apply(AppLogger, tslib_1.__spread([level, ""], message));
    };
    /**
     * Tells the Host the module wants to be finished and the data should be submitted.
     */
    Page.prototype.submit = function () {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.FinishModuleSubmitData, undefined, undefined);
    };
    /**
     * Tells the Host the module wants to be finished without submission of data.
     */
    Page.prototype.cancel = function () {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.CancelModule, undefined, undefined);
    };
    /**
     * Tells the Host to store the state of the current page.
     * @param state Any variable. Most certainly an object.
     * @param callback Callback function with boolean parameter, which is true when the command succeeded.
     */
    Page.prototype.storePageState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.StorePageState, state, callback);
    };
    /**
     * Tells the Host to send back a previously stored state of the current page.
     * @param callback Callback function with the returned data as parameter.
     */
    Page.prototype.restorePageState = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestPageState, undefined, callback);
    };
    /**
     * Tells the Host to store the state of the whole dialog (accessible on any page).
     * @param state Any variable. Most certainly an object.
     * @param callback Callback function with boolean parameter, which is true when the command succeeded.
     */
    Page.prototype.storeSessionState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.StoreSessionState, state, callback);
    };
    /**
     * Tells the Host to add the given state to the storage of the whole dialog (accessible on any page).
     * @param state Any variable. Most certainly an object.
     * @param callback Callback function with boolean parameter, which is true when the command succeeded.
     */
    Page.prototype.addSessionState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.AddSessionState, state, callback);
    };
    /**
     * Tells the Host to send back a previously stored state of the whole dialog.
     * @param callback Callback function with the returned data as parameter.
     */
    Page.prototype.restoreSessionState = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestSessionState, undefined, callback);
    };
    /**
     * Tells the Host to store an object session-independend.
     * @param state A stringify-able object.
     * @param callback Callback function with boolean parameter, which is true when the command succeeded.
     */
    Page.prototype.storeClientState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.StoreClientState, state, callback);
    };
    /**
     * Tells the Host to add the given state to the session-independend storage.
     * @param state A stringify-able object.
     * @param callback Callback function with boolean parameter, which is true when the command succeeded.
     */
    Page.prototype.addClientState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.AddClientState, state, callback);
    };
    /**
     * Tells the Host to send back a previously stored state of the session-independend client.
     * @param callback Callback function with the returned data as parameter.
     */
    Page.prototype.restoreClientState = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestClientState, undefined, callback);
    };
    /**
     * Tells the Host the page to load, when the user clicks on the
     * "next" button. Submit an empty url to disable the "next" button.
     * @param path relative path to the next page.
     * @param callback Callback function with boolean parameter, which is
     *                 true when the "next"-button is enabled as
     *                 consequence of the call.
     */
    Page.prototype.setNextPage = function (path, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.NextPageUrl, path, callback);
    };
    Page.prototype.jumpToPage = function (param, callback) {
        var tThis = this;
        if (this.OnBeforePageChange) {
            this.OnBeforePageChange(function (ok2change) {
                if (ok2change) {
                    tThis._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.LoadPageUrl, param, callback);
                }
                else {
                    if (callback) {
                        callback(false);
                    }
                }
            });
        }
        else {
            this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.LoadPageUrl, param, callback);
        }
    };
    /**
     * Tells the Host to set a progress percentage. 100 means the Module can
     * be completed. This must be taken into account by the host.
     * @param newProgress progress percentage from 0 to 100.
     * @param callback Callback function with number parameter, which
     *                 contains the progress set by the Host (maybe the
     *                 value had to be corrected)
     */
    Page.prototype.setProgress = function (newProgress, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.SetProgress, newProgress, callback);
    };
    /**
     * Tells the Host to return the current progress percentage.
     * @param callback Callback function with number parameter, which
     *                 contains the progress.
     */
    Page.prototype.getProgress = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestProgress, undefined, callback);
    };
    /**
     * Returns the current page url.
     * @param callback Callback function with string parameter.
     */
    Page.prototype.getCurrentPageUrl = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestCurrentPageUrl, undefined, callback);
    };
    /**
     * Get the localized resources for this page.
     * @param callback Callback function with the returned data or null, as parameter.
     */
    Page.prototype.getTextResources = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestTextResources, undefined, callback);
    };
    Page.prototype.getJsonFile = function (file, finishCallback, progressCallback) {
        if (typeof file === "string") {
            // request just 1 JSON
            this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestJsonFile, file, function (f) {
                if (progressCallback) {
                    progressCallback(0);
                }
                finishCallback(f);
            });
        }
        else {
            // request multiple JSONs simultaneously
            var tCompletedCallbacks_1 = 0;
            var tCallbackParams_1 = new Array();
            var tValueList = file;
            var tThis_1 = this;
            if (tValueList.length === 0) {
                if (progressCallback) {
                    progressCallback(0);
                }
                finishCallback.apply(tThis_1);
            }
            else {
                for (var tI = 0; tI < tValueList.length; tI++) {
                    tCallbackParams_1.push(undefined);
                }
                tValueList.forEach(function (val, idx, arr) {
                    tThis_1._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestJsonFile, val, function (f) {
                        tCallbackParams_1[idx] = f;
                        tCompletedCallbacks_1++;
                        if (progressCallback) {
                            progressCallback(arr.length - tCompletedCallbacks_1);
                        }
                        if (tCompletedCallbacks_1 === arr.length) {
                            finishCallback.apply(tThis_1, tCallbackParams_1);
                        }
                    });
                });
            }
        }
    };
    /**
     * Get the content of a localized JSON file.
     * @param file Path to file, relative to the Module root. Without language dependant parts. E.g. test.json
     * @param callback Callback function with the returned data or null, as parameter.
     */
    Page.prototype.getJsonFileLocalized = function (file, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestJsonFileLocalized, file, callback);
    };
    /**
     * Get an image file.
     * @param file Path to image file, relative to the Module root.
     * @param callback Callback function with the returned data or null, as parameter.
     */
    Page.prototype.getImageFile = function (file, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestImageFile, file, callback);
    };
    Page.prototype.getTextFile = function (file, finishCallback, progressCallback) {
        if (typeof file === "string") {
            // request just 1 file
            this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestTextFile, file, function (f) {
                if (progressCallback) {
                    progressCallback(0);
                }
                finishCallback(f);
            });
        }
        else {
            // request multiple text files simultaneously
            var tCompletedCallbacks_2 = 0;
            var tCallbackParams_2 = new Array();
            var tValueList = file;
            var tThis_2 = this;
            if (tValueList.length === 0) {
                if (progressCallback) {
                    progressCallback(0);
                }
                finishCallback.apply(tThis_2);
            }
            else {
                for (var tI = 0; tI < tValueList.length; tI++) {
                    tCallbackParams_2.push(undefined);
                }
                tValueList.forEach(function (val, idx, arr) {
                    tThis_2._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.RequestTextFile, val, function (f) {
                        tCallbackParams_2[idx] = f;
                        tCompletedCallbacks_2++;
                        if (progressCallback) {
                            progressCallback(arr.length - tCompletedCallbacks_2);
                        }
                        if (tCompletedCallbacks_2 === arr.length) {
                            finishCallback.apply(tThis_2, tCallbackParams_2);
                        }
                    });
                });
            }
        }
    };
    /**
     * Requests the Host to validate the passed user credentials.
     * @param state Should contain string objects 'login' and 'password'.
     * @param callback Callback function with boolean parameter, which is true when the credentials are valid.
     */
    Page.prototype.validateUserCredentials = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.ValidateUserCredentials, state, callback);
    };
    /**
     * Shows a message box to the user.
     * @param text Message to be shown,
     * @param type Dialog type
     * @param callback Callback function with the dialog result as parameter.
     */
    Page.prototype.showMessageBox = function (text, type, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.ShowMessageBox, { text: text, type: type }, callback);
    };
    /**
     * The host should save the given state in some way. How exactly is
     * unspecified here.
     * @param state The object to be saved. If this parameter is undefined,
     * the current sessionstate will be saved.
     * @param callback Callback function with boolean parameter, which is true
     * when the host saved the state successfully.
     */
    Page.prototype.saveModuleState = function (state, callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.SaveModuleState, state, callback);
    };
    /**
     * The host should load a formerly saved state in some way. How exactly is
     * unspecified here.
     * @param callback Callback function. On unsuccessful load, the callback
     * parameter will be false, otherwise the loaded object.
     */
    Page.prototype.loadModuleState = function (callback) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.LoadModuleState, undefined, callback);
    };
    /**
     * Tells the Host to initiate outside import
     */
    Page.prototype.initiateImportFromUniversal = function () {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.InitiateImportFromJSBU, undefined, undefined);
    };
    /**
     * Tells the Host to initiate outside load
     */
    Page.prototype.initiateLoadFromUniversal = function () {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.InitiateLoadFromJSBU, undefined, undefined);
    };
    /**
     * Tells the Host to initiate outside save or export
     */
    Page.prototype.initiateSaveToUniversal = function () {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.InitiateSaveToJSBU, undefined, undefined);
    };
    /**
     * Tells the Host to initiate outside save or export
     */
    Page.prototype.showSaveDialog = function (params, cb) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.ShowSaveDialog, params, cb);
    };
    /**
     * Change host properties like CurrentLocale. Support for this must be implemented in the host.
     * @param params Parameters to be changed.
     * @param cb Function to be called when command has finished.
     */
    Page.prototype.setHostProperties = function (params, cb) {
        this._connector.sendToHost(EPageToHostCmd_1.EPageToHostCmd.SetHostProperties, params, cb);
    };
    Page.createPage = function (pageClassName) {
        if (Page.Page) {
            return Page.Page;
        }
        if (pageClassName) {
            var pcA = pageClassName.split(".");
            pcA.reverse();
            var instance = Object.create(window[pcA.pop()]);
            while (pcA.length > 0) {
                instance = instance[pcA.pop()];
            }
            instance = instance.prototype;
            instance.constructor.apply(instance);
            Page.Page = instance;
            console.log('IGD Page "' + pageClassName + '" initialized');
            return instance;
        }
    };
    Object.defineProperty(Page, "CurrentPage", {
        /** Access current page instance */
        get: function () {
            return this.Page;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(Page.prototype, "HostInfo", {
        /** Access host information */
        get: function () {
            return this._hostInfo;
        },
        enumerable: true,
        configurable: true
    });
    Page.getJSONFile = function (path) {
        return new Promise(function (resolve, reject) {
            if (Page.CurrentPage) {
                Page.CurrentPage.getJsonFile(path, function (json) {
                    if (json) {
                        resolve(json);
                    }
                    else {
                        reject(new Error("Cannot load json: " + path));
                    }
                });
            }
            else {
                ig_utilities_1.Http.getJSON(path)
                    .then(resolve)
                    .catch(function () {
                    return reject(new Error("Cannot load json: " + path));
                });
            }
        });
    };
    return Page;
}());
exports.Page = Page;
