// 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                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
function CViewModel_ResponseMerger(p_viewmodel, p_options) {
    "use strict";

    /** constructor */
    
    var v_viewmodel = p_viewmodel;
    var v_options = p_options;
    
    var v_binder;
    var v_dataPaths = [];
    var v_selections = [];
    
    var v_rowData = [];
    var v_selected = 0;
    
    /** public functions - interface for parent */
    
    this.setSelectionToControl = function(p_selection) {
        v_selections.push(p_selection);
    };
    
    this.setReponseDataPath = function(p_index, p_path) {
        v_dataPaths[p_index] = p_path;
    };
    
    this.setBinder = function(p_binder) {
        v_binder = p_binder;
    };
	
    /** public functions - interface for views */ 
    
    this.getList = function() {
        v_rowData = [];
        var counter = 0;
        var newList = [[]];
        for (var i = 0; i < v_dataPaths.length; ++i) {
            var response = v_viewmodel.getResponseElement(v_dataPaths[i]);
            if (response != undefined) {
                v_rowData.push({"rowIndex": counter, "isNode": response.node != undefined});
                if (response.node != undefined) {
                    ++counter;
                    newList[0].push(getNodeLabel(response.node, i));
                } else if (response.list != undefined) {
                    for (var j = 0; j < response.list.length; ++j) {
                        ++counter;
                        newList[0].push([response.list[j].node.val, [], response.list[j].node.tp > 0]);
                    }
                }
            } else {
                v_rowData.push({"rowIndex": counter, "isNode": true});
            }
        }
        
        return {
            "values": newList,
            "selections": [[v_selected]]
        }
    };
    
    this.select = function(p_index) {
        var connection = 0;
        var index = 0;
        for (var i = v_rowData.length - 1; i >= 0; --i) {
            if (p_index >= v_rowData[i].rowIndex) {
                connection = i;
                index = p_index - v_rowData[i].rowIndex;
                break;
            }
        }
        
        for (var i = 0; i < v_selections.length; ++i) {
            if (v_rowData[i] == undefined || v_rowData[i].isNode) {
                v_selections[i].filter = {"dataValue": "false"};
            } else {
                v_selections[i].selection = [];
            }
        }
        
        if (v_rowData[connection] == undefined || v_rowData[connection].isNode) {
            v_selections[connection].filter = {"dataValue": "true"};
        } else {
            v_selections[connection].selection = [index];
        }
        
        v_selected = p_index;
        v_binder.notifyChange(true);
    };
    
    function getNodeLabel(node, index) {
        if (v_options.predefinedValues != undefined) {
            for (var i = 0; i < v_options.predefinedValues.length; ++i) {
                if (v_options.predefinedValues[i].dataPathIndex == index) {
                    return [v_options.predefinedValues[i].value, [], node.tp > 0];
                }
            }
        }
        return [node.val, [], node.tp > 0];
    }
}

CViewModel_ResponseMerger.getHelp = function() {
    return "The viewmodel will create a single list form all its data connections.\n" +
        "When selecting an element, the request will be modified:\n" +
            "\tif the element returns a single node, a false filter will be added\n" +
            "\tif the element returns a list, its selection will be modified" +
        "It will not work if the selection connections are different than the data connections or there are other filters on the connected requests.";
};

CViewModel_ResponseMerger.providesInterface = function() {
    return ["getList", "select"];
};

CViewModel_ResponseMerger.getCustomDataSchema = function() {
    return {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "Custom data for CViewModel_ResponseMerger",
        "type": "object",
        "properties": {
            "predefinedValues": {
                "description": "The predefined values for the non-iterator elements (WARNING: do not use with iterators).",
                "type": "array",
                "format": "table",
                "items": {
                    "type": "object",
                    "properties": {
                        "dataPathIndex": {
                            "type": "integer"
                        },
                        "value": {
                            "type": "string"
                        }
                    },
                    "required": ["dataPathIndex", "value"],
                    "additionalProperties": false
                }
            }
        },
        "additionalProperties": false
    };
};

//# sourceURL=CustomizableApp\ViewModels\CViewModel_ResponseMerger.js