// 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 v2.0 which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
function PlaylistEditor_PlaylistItem_ViewModel(p_model, p_help) {
    "use strict";

    var v_model = p_model;
    var v_help = p_help;
    var v_dataSourceUtils = new DataSourceUtils();

    this.requestBuilder = new DSHelpToRequest_manual();
    this.requestBuilder.setRequest(v_model.requests);
    this.requestBuilder.setHelp(v_help);

    this.filterBuilder = new DSHelpToRequest_manual();
    this.filterBuilder.setRequest(v_model.condition.expression);
    this.filterBuilder.setHelp(v_help);

    this.getRelativeTo = function() {
        return v_model.relativeTo;
    };

    this.getRepresentation = function() {
        var tree = [
            {
                "text": "next step",
                "data": {"tooltip": "Drag this to another 'next step' node to create a connection."}
            },
            {
                "text": "api: " + v_model.api,
                "data": {"tooltip": "The api url where the request and condition will be sent."}
            },
            {
                "text": "startTime: " + v_model.startTime,
                "data": {"tooltip": "Wait " + v_model.startTime + " seconds after previous steps were executed before the condition evaluation starts."}
            },
            {
                "text": "requests",
                "children": [],
                "data": {"tooltip": "The request to send. Drag requests from the help on the left. Drop while pressing control to insert a SetData instead of a GetData request."}
            },
            {
                "text": "condition",
                "children": [
                    {
                        "text": "evaluatingPeriod" + (v_model.condition.evaluatingPeriod == undefined ? "" : ": " + v_model.condition.evaluatingPeriod),
                        "data": {"tooltip": "The condition is evaluated periodically with this number of seconds period. If undefined, the condition will be evaluated instantly after the previous evaluation finishes."}
                    },
                    {
                        "text": "numberOfExecutions" + (v_model.condition.numberOfExecutions == undefined ? "" : ": " + v_model.condition.numberOfExecutions),
                        "data": {"tooltip": "The maximum number of condition evaluations. If the last evaluation is also false, the Playlist will terminate. If undefined, the condition will be checked until it becomes true."}
                    },
                    {
                        "text": "cancelingTimeout" + (v_model.condition.cancelingTimeout == undefined ? "" : ": " + v_model.condition.cancelingTimeout),
                        "data": {"tooltip": "The maximum time in seconds spent waiting for the condition to be true after the previous steps were executed."}
                    },
                    {
                        "text": "expression",
                        "children": [],
                        "data": {"tooltip": "Only send the request if the condition evaluates to true."}
                    }
                ],
                "data": {"tooltip": "The condition of the step."}
            }
        ];
        traverseRequest(v_model.requests, tree[3].children);
        this.traverseFilter(v_model.condition.expression[0].getData.filter, tree[4].children[3].children);

        return tree;
    };

    this.getName = function() {
        var name = 'Not set';
        var request = v_model.requests[0];
        while (request != undefined) {
            if (request.setData != undefined) {
                name = request.setData.element;
                if (request.setData.params != undefined && request.setData.params.length != 0) {
                    name += ' - ' + request.setData.params[0].paramName + ': ' + request.setData.params[0].paramValue;
                }
            }
            if (request.getData != undefined && request.getData.children != undefined) {
                request = request.getData.children[0];
            } else {
                request = undefined;
            }
        }
        return name;
    };

    function traverseRequest(requests, treeData) {
        for (var i = 0; i < requests.length; ++i) {
            if (requests[i].getData != undefined) {
                var highlight = requests[i].getData.filter == undefined ? undefined : "Filter";
                var node = {"text": requests[i].getData.element, "data": {"tooltip": JSON.stringify(requests[i], null, 4), "highlight": highlight}};
                if (requests[i].getData.children != undefined) {
                    node.children = [];
                    traverseRequest(requests[i].getData.children, node.children)
                }
                treeData.push(node);
            } else if (requests[i].setData != undefined) {
                var highlight = "Set";
                if (requests[i].setData.tp < 1 || requests[i].setData.tp > 11) {
                    highlight = "Warning";
                }
                treeData.push({"text": requests[i].setData.element, "data": {"tooltip": JSON.stringify(requests[i], null, 4), "highlight": highlight}});
            }
        }
    }

    this.traverseFilter = function(filter, treeData, paramName) {
        if (filter != undefined) {
            var treeNode;
            var treeNodeText = "";
            if (paramName != undefined) {
                treeNodeText = paramName + ": ";
            }
            if (filter.dataValue != undefined) {
                treeNode = {"text": treeNodeText + filter.dataValue, "data": {"tooltip": JSON.stringify(filter, null, 4)}};
                treeData.push(treeNode);
            } else if (filter.request != undefined) {
                treeNode = {"text": treeNodeText + filter.request.element, "children": [], "data": {"tooltip": JSON.stringify(filter, null, 4)}};
                treeData.push(treeNode);
                if (filter.request.params != undefined && filter.request.params.length > 0) {
                    for (var i = 0; i < filter.request.params.length; ++i) {
                        this.traverseFilter(filter.request.params[i].paramValue, treeNode.children, filter.request.params[i].paramName);
                    }
                }
                if (filter.request.remapTo != undefined) {
                    this.traverseFilter(filter.request.remapTo, treeNode.children, "remapTo");
                }
            }
        }
    }

    this.getDesktopData = function() {
        return v_model.desktopData;
    };

    this.changeValue = function(path, value) {
        if (path[0] == 1) {
            v_model.api = (value == undefined ? (window.location.protocol + "//" + window.location.host + "/api.appagent") : value);
        } else if (path[0] == 2) {
            v_model.startTime = (isNaN(value) ? 0 : parseFloat(value));
        } else if (path[1] == 0) {
            v_model.condition.evaluatingPeriod = (isNaN(value) ? undefined : parseFloat(value));
        } else if (path[1] == 1) {
            v_model.condition.numberOfExecutions = (isNaN(value) ? undefined : parseInt(value));
        } else if (path[1] == 2) {
            v_model.condition.cancelingTimeout = (isNaN(value) ? undefined : parseFloat(value));
        }
    };

    this.deleteRequest = function() {
        v_model.requests.splice(0, v_model.requests.length);
    };
}