// 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 RequestTester_View(p_viewmodel, p_parentId, p_mainId) {
    "use strict";
    
    var HTML = "WebApplications/RequestTester/View.html";
    var v_parentId = p_parentId;
    var parentDiv = document.getElementById(p_parentId);
    var v_mainId = p_mainId;
    
    var v_viewmodel = p_viewmodel;
    
    var v_autoGuiView;
    var v_helpTree;
    var v_requestEditor;
    var v_responseEditor;
    var v_this = this;
    
    var EDITOROPTIONS = {
        mode: "javascript",
        lineNumbers: true,
        smartIndent: true,
        indentUnit: 4,
        lineWrapping: true,
        foldGutter: true,
        gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
        matchBrackets: true,
        autoCloseBrackets: true,
        highlightSelectionMatches: true,
        styleActiveLine: true
    };
    
    this.init = function(p_callback) {
        var mainDiv = document.createElement("div");
        mainDiv.setAttribute("id", v_mainId);
        parentDiv.appendChild(mainDiv);
        
        function htmlLoaded(ok, data) {
            if (ok) {
                $("#" + v_mainId).append(data);
                v_viewmodel.loadCss("WebAppStyle", "WebApplications/RequestTester/View.css");

                p_callback(true);
            } else {
                p_callback(false, "Error loading " + HTML);
            }
        }
        
        v_viewmodel.loadFile(HTML, htmlLoaded);
    };
    
    this.destroy = function() {
        $("#" + v_mainId).remove();
    };

    this.applicationCreated = function(request) {
        v_autoGuiView = new CAutoGuiView(
            [v_viewmodel.getAutoGuiViewModel()],
            "autogui",
            "autogui_container"
        );
        v_autoGuiView.applicationCreated();
        
        v_helpTree = $("#helptree");
        
        refreshHelpJSTree(v_viewmodel.getHelpTree());
        setupCallbacks();
        
        v_requestEditor = CodeMirror(document.getElementById("request"), EDITOROPTIONS);
        v_requestEditor.setValue(JSON.stringify(request, null, 4));
        
        v_responseEditor = CodeMirror(document.getElementById("response"), EDITOROPTIONS);
    };
    
    function refreshHelpJSTree(p_data) {
        v_helpTree.jstree("destroy");
        v_helpTree = v_helpTree.jstree({
            "core": {
                "data": p_data,
                "check_callback" : true,
                "multiple" : false
            },
            "plugins" : ["search"],
            "search" : {
                "show_only_matches" : true
            }
        });
        v_helpTree.bind("hover_node.jstree", function(e, data) {
            $("#"+data.node.id).prop("title", data.node.data);
        });
    }
    
    function searchHelpTree() {
        v_helpTree.jstree("search", $(this).val());
    }
    
    function prettyPrintJSON() {
        var str = indentJSON(v_requestEditor.getValue(), 4);
        if(str) {
            v_requestEditor.setValue(str);
            return true;
        } else {
            alert("Malformed JSON!");
            return false;
        }
    }

    function loading() {
        v_responseEditor.setValue("loading...");
    }
    
    function sendRequest() {
        var requestStr = indentJSON(v_requestEditor.getValue(), 4);
        if (requestStr) {
            loading();
            var request = JSON.parse(v_requestEditor.getValue());
            v_viewmodel.sendRequest(v_this.refresh, request);
        } else {
            alert("Malformed JSON");
        }
    };
    
    function sendFullRequest() {
        loading();
        
        var request = DSHelpToRequest_full(v_viewmodel.getHelp());
        v_viewmodel.sendRequest(v_this.refresh, request);
    };
    
    function getHelp() {
        var help = v_viewmodel.getHelp();
        v_responseEditor.setValue(JSON.stringify(help, null, 4));
    };
    
    this.refresh = function() {
        var request = v_viewmodel.getRequest();
        v_requestEditor.setValue(JSON.stringify(request, null, 4));
        
        var response = v_viewmodel.getResponse();
        v_responseEditor.setValue(JSON.stringify(response, null, 4));
        
        v_autoGuiView.refresh(true);
                
        document.getElementById("time").innerHTML = v_viewmodel.getTime();
    }

    function setupCallbacks() {
        $("#send").on('click', sendRequest);
        $("#full").on('click', sendFullRequest);
        $("#help").on('click', getHelp);
        $('#helpsearch').on('input', searchHelpTree);
        $('#jsonindent').on('click', prettyPrintJSON);
    }
}
//# sourceURL=RequestTester\View.js
