// 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                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
function GuiEditor_ViewModelEditor_ViewModel(p_model, p_parent) {
    "use strict";

    var v_model = p_model;
    var v_parent = p_parent;

    var v_this = this;

    ///////////////////// GENERAL EDITOR FUNCTIONS /////////////////////

    this.getTreeData = function() {
        var data = [{"text" : "View connection point"}, {"text": "Data connections", "children": []}, {"text": "Selection connections", "children": []}];
        getTreeDataFromLists(data, 1, v_model.getDataConnections(), v_model.getDataConnectionsStr());
        getTreeDataFromLists(data, 2, v_model.getSelectionConnections(), v_model.getSelectionConnectionsStr());
        return data;
    };

    function getTreeDataFromLists(data, index, pathList, strPathList) {
        for (var i = 0; i < pathList.length; ++i) {
            var text;
            if (strPathList[i].lastIndexOf(".") === -1) {
                text = strPathList[i];
            } else {
                text = strPathList[i].substr(strPathList[i].lastIndexOf(".") + 1);
            }
            data[index].children.push({"text" : text});
        }
    }

	this.getName = function() {
        var name = v_model.getClassName();
        if (v_model.getCustomData().name != undefined) {
            name += " - " + v_model.getCustomData().name;
        }
        return name;
	};

    this.getTooltip = function() {
        return this.getName() + "\n" + v_parent.getHelp(v_model.getClassName()) + "\nCurrent custom data:\n" + JSON.stringify(v_model.getCustomData(), null, 4);
    };

    this.matches = function(string) {
        return JSON.stringify(v_model.getDescriptorCopy()).toLowerCase().indexOf(string) != -1;
    };

    ///////////////////// GENERAL VIEW AND VIEWMODEL EDITOR FUNCTIONS /////////////////////

    this.getCustomData = v_model.getCustomData;
    this.setCustomData = function(data) {
        v_model.setCustomData(data);
        v_parent.setupChanged("Custom data changed");
    };

    this.getClass = v_model.getClassName;
	this.setClass = function(data) {
        v_model.setClass(data);
        v_parent.setupChanged("Class changed");
    };

    this.getCustomDataSchema = function() {
        return v_parent.getCustomDataSchema(v_model.getClassName());
    };

    this.isValid = function() {
        return v_parent.isValidViewmodel(v_this);
    };

    ///////////////////// VIEWMODEL EDITOR SPECIFIC FUNCTIONS /////////////////////

    this.addDataPath = function(strpath, path, index) {
        v_model.addDataPath(strpath, path, index);
        v_parent.setupChanged("Request connection added");
    };

    this.deleteDataPath = function(data) {
        v_model.deleteDataPath(data);
        v_parent.setupChanged("Request connection deleted");
    };

    this.moveDataPath = function(fromIndex, toIndex) {
        v_model.moveDataPath(fromIndex, toIndex);
        v_parent.setupChanged("Connection order changed");
    };

    this.addSelectionPath = function(strpath, path, index) {
        v_model.addSelectionPath(strpath, path, index);
        v_parent.setupChanged("Request connection added");
    };

    this.deleteSelectionPath = function(data) {
        v_model.deleteSelectionPath(data);
        v_parent.setupChanged("Request connection deleted");
    };

    this.moveSelectionPath = function(fromIndex, toIndex) {
        v_model.moveSelectionPath(fromIndex, toIndex);
        v_parent.setupChanged("Connection order changed");
    };

    this.updateConnections = function(path, amount) {
        var deleted = [];
        if (amount === -1) {
            deleted = v_model.deleteConnectionsWithPrefix(mcopy(path));
        }
        v_model.updateConnections(mcopy(path), amount);
        return deleted;
    };

    this.pathsMoved = v_model.prefixChanged;
    this.getDataConnections = v_model.getDataConnections;
    this.getSelectionConnections = v_model.getSelectionConnections;

    this.getDataPathString = function(index) {
        return v_model.getDataConnectionsStr()[index];
    };

    this.getSelectionPathString = function(index) {
        return v_model.getSelectionConnectionsStr()[index];
    };

    this.requestRenamed = function(p_path, name) {
        var paths = v_model.requestRenamed(p_path, name);
        var toReturn = [];
        for (var i = 0; i < paths["data"].length; ++i) {
            toReturn.push([1, paths["data"][i]]);
        }
        for (var i = 0; i < paths["selection"].length; ++i) {
            toReturn.push([2, paths["selection"][i]]);
        }
        return toReturn;
    };
}
//# sourceURL=GuiEditor\ViewModels\ViewModel_ViewModelEditor.js
