// Copyright (c) 2000-2017 Ericsson Telecom AB                                                       //
// All rights reserved. This program and the accompanying materials are made available under the     //
// terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at //
// http://www.eclipse.org/legal/epl-v10.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
var WebApplications = WebApplications || [];

WebApplications.push({'application': new GuiEditor_Application()});

function GuiEditor_Application() {
    "use strict";

    var v_appBase = new WebAppBase();
    var v_webAppModel;

    var jsfiles = [];

    var v_extension;
    var v_framework;
    var v_model;
    var v_viewmodel;
    var v_view;
    var v_binder;

    this.info = function() {
        return {
            defaultIcon: "WebApplications/GuiEditor/Res/main_icon.png",
            defaultName: "GuiEditor"
        };
    };

    this.load = function(p_webAppModel, p_params, p_framework)  {
        v_webAppModel = p_webAppModel;
        v_framework = p_framework;

        function appConfigLoaded(config) {
            if (config.lastEditedApp != undefined) {
                new JsImportFromConfigTask(config.lastEditedApp + '/AppConfig.json', v_webAppModel.getFileHandler()).taskOperation(function(ok, extension) {
                    v_extension = extension;
                    v_appBase.load(jsfiles, [], start, v_webAppModel.getFileHandler());
                });
            } else {
                alert("Error, lastEditedApp missing from config, can't choose API.");
            }
        }

        new MultipleDirectoryListTask(
            [
                "WebApplications/GuiEditor/Models",
                "WebApplications/GuiEditor/Views",
                "WebApplications/GuiEditor/ViewModels"
            ],
            v_webAppModel.getFileHandler()
        ).taskOperation(function(ok, resources) {
            jsfiles = resources.jsfiles;
            v_webAppModel.loadAppConfig('CustomizableContent/GuiEditor/AppConfig.json', appConfigLoaded);
        });
    };

    this.unload = function(webappUnloaded) {
        function callback(exitApp) {
            if (exitApp) { v_appBase.unload(destroy); }
            webappUnloaded(exitApp);
        }

        v_view.unload(callback);
    };

    function destroy() {
        v_view.destroy();
        v_viewmodel.destroy();

        v_model = undefined;
        v_view = undefined;
        v_viewmodel = undefined;
        v_binder = undefined;
    }

    function start(p_callback) {
        v_model = new GuiEditor_Model(v_webAppModel, v_framework, v_extension);
        v_viewmodel = new GuiEditor_ViewModel(v_model);
        v_view = new GuiEditor_View(v_viewmodel, "TSGuiFrameworkMain", "GuiEditor_MainView");
        v_binder = new GuiEditor_Binder(v_viewmodel, v_view);
        v_viewmodel.setBinder(v_binder);

        function callback(ok, data) {
            if (ok) {
                v_view.applicationCreated();
                v_binder.fullRefresh();
            } else {
                alert(data);
            }
            if (typeof p_callback === "function") {
                p_callback();
            }
        }

        function setupLoaded() {
            v_viewmodel.setSetup(v_model.getSetup());
            var taskList = new SyncTaskList([new GenericTask(v_viewmodel.init), new GenericTask(v_view.init)], callback);
            taskList.taskOperation();
        }

        var config = v_webAppModel.getAppConfig();
        v_webAppModel.getSetupModel().setSetupDirectory(config.lastEditedApp + '/Setups');
        if (config.lastEditedSetup != undefined) {
            v_model.switchSetup(config.lastEditedSetup, setupLoaded);
        } else {
            v_model.newSetup();
            setupLoaded();
        }
    }
}

function GuiEditor_Binder(p_viewModel, p_view) {
    "use strict";

    var v_viewmodel = p_viewModel;
    var v_view = p_view;

    this.fullRefresh = function() {
        v_view.getRequestEditorView().destroy();
        v_view.getRequestEditorView().fullRefresh();
        v_view.updateSetupName();
    };

    this.removeViewConnection = function(viewIndex, connectionIndex) {
        v_view.getRequestEditorView().getEditorContainerView().removeViewConnection(viewIndex, connectionIndex);
    };

    this.selectionOrFilterChanged = function(p_path, p_selection, p_filter, p_rangeFilter, p_writableInfo) {
        v_view.getRequestEditorView().selectionOrFilterChanged(p_path, p_selection, p_filter, p_rangeFilter, p_writableInfo);
    };
}
//# sourceURL=GuiEditor\Main.js