// Copyright (c) 2000-2019 Ericsson Telecom AB Telecom AB                                                       //
// All rights reserved. This program and the accompanying materials are made available under the     //
// terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
var WebApplications = WebApplications || [];

WebApplications.push({'application': new RequestTesterApp()});

function RequestTesterApp() {
    "use strict";

    var main = new WebAppBase();
    var webAppModel;

    var jsfiles = [
        "WebApplications/RequestTester/ViewModel.js",
        "WebApplications/RequestTester/View.js"
    ];

    var extension;
    var viewModel;
    var view;

    this.info = function() {
        return {
            defaultIcon: "WebApplications/RequestTester/main_icon.png",
            defaultName: "DsRestAPI Console"
        };
    };

    this.load = function(p_webAppModel, p_params) {
        webAppModel = p_webAppModel;

        function setupLoaded() {
            main.load(jsfiles, [], start, webAppModel.getFileHandler());
        }

        function customAppJsImported(ok, p_extension) {
            extension = p_extension;
            if (p_params.setup != undefined) {
                webAppModel.getSetupModel().setSetupDirectory(p_params.customization + '/Setups');
                webAppModel.getSetupModel().loadSetup(p_params.setup, setupLoaded, false, p_params.setupParams);
            } else {
                setupLoaded(true, webAppModel.getSetupModel().newSetup());
            }
        }

        if (p_params.customization != undefined) {
            new JsImportFromConfigTask(p_params.customization + '/AppConfig.json', webAppModel.getFileHandler()).taskOperation(customAppJsImported);
        } else {
            alert("No application specified, can't choose API")
        }
    };

    function destroy() {
        view.destroy();

        view = undefined;
        viewModel = undefined;
    }

    this.unload = function(webappUnloaded) {
        main.unload(destroy);
        webappUnloaded(true);
    };

    function start(p_callback) {
        viewModel = new RequestTester_ViewModel(webAppModel.getFileHandler(), new DsRestAPI(extension));
        view = new RequestTester_View(viewModel, "TSGuiFrameworkMain", "requestTesterMainView");

        viewModel.setBinder({
            "notifyChange": function() {
                viewModel.sendRequest(view.refresh);
            }
        });

        function callback(ok, msg) {
            if (ok) {
                view.applicationCreated(webAppModel.getSetupModel().getSetup().request.getData());
            } else {
                alert(msg);
            }
          if (typeof p_callback === "function") {
            p_callback();
          }
        }

        var taskList = new TaskList([new GenericTask(viewModel.init), new GenericTask(view.init)], callback);
        taskList.taskOperation();
    }
}
//# sourceURL=RequestTester\Main.js
