// 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                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
/** App specific runtime behaviour */
function CViewModel(aModel, aDataSourceUtils)
{
    "use strict";

    /** private members */
    var mDataSourceUtils = aDataSourceUtils;
    var mWebAppModel = aModel.getWebAppModel();
    var mFileHandler = mWebAppModel.getFileHandler();
    var mDsRestAPI = aModel.getDsRestApi();
    var mUIConfig = mWebAppModel.getAppConfig();
    var mViewIsDisabledBecauseConnectionWasInterrupted = false;
    var mBinder;
    var mRequest = [];
    var mViewModels = [];
    var mSetupList;
    var mResponse;
    var mModel = aModel;
    var mThis = this;
    var mRequestCache = {};

    var mSelectionToChangeToValue = [];

    this.getSetupModel = mWebAppModel.getSetupModel;
    this.getSetupList = function() {
        if (mSetupList == undefined) {
            alert("callback for mSetupList should be called sooner");
            return [];
        }
        return mSetupList;
    };

    this.initRequestSelectionsAndFiltersAtStart = function() {
        mSelectionToChangeToValue = [];
        triggerSelectionChangeAtStart(mRequest, []);
        loadRangeFilters(mRequest, []);
    };

    this.initRequestSelectionsAndFilters = function()
    {
        if (mSelectionToChangeToValue.length != 0) {
            for (var i = 0; i < mSelectionToChangeToValue.length; ++i) {
                var request = mThis.getRequestFromPath(mSelectionToChangeToValue[i]);
                var response = mThis.getResponseElement(mSelectionToChangeToValue[i]);
                if (response != undefined && response.list != undefined && response.list[0] != undefined && response.list[0].node != undefined) {
                    request.getData.selectionValues = [response.list[0].node.val];
                    request.getData.selection = [0];
                    var value = {
                        "selection": request.getData.selection,
                        "selectionValues": request.getData.selectionValues
                    };
                    sessionStorage.setItem(getRequestKey(mSelectionToChangeToValue[i], "selection"), JSON.stringify(value));
                    sessionStorage.setItem(getRequestKeyAlternative(mSelectionToChangeToValue[i], "selection"), JSON.stringify(value));
                }
            }
            mSelectionToChangeToValue = [];
        }
    };

    this.getRequest = function()
    {
        return mRequest;
    };

    this.getDsRestAPI = function()
    {
        return mDsRestAPI;
    };

    this.getFileHandler = function() {
        return mFileHandler;
    }

    this.init = function(p_callback) {
        function setupsLoaded(setups) {
            mSetupList = setups;
            p_callback(true);
        }

        sessionStorage.clear();
        mWebAppModel.getSetupModel().listSetups(setupsLoaded);
        //p_callback(true);
    };

    function getSelectionObject(aRequest, aPath)
    {
        var lRq = mRequest[aPath[0]].getData;
        for (var i = 1; i < aPath.length; ++i)
        {
            lRq = lRq.children[aPath[i]].getData;
        }
        return lRq;
    }

    this.applicationCreated = function()
    {
        mRequest = [];
        mViewModels = [];
        mRequest = mWebAppModel.getSetupModel().getSetup().request.getData();
        var viewModelDescriptors = mWebAppModel.getSetupModel().getSetup().viewmodels.getData();
        var viewModelCount = viewModelDescriptors.length;
        for (var i = 0; i < viewModelCount; ++i)
        {
            if (window[viewModelDescriptors[i].class])
            {
                mViewModels[i] = new window[viewModelDescriptors[i].class](this, viewModelDescriptors[i].customData);
                mViewModels[i].loadFile = mThis.loadFile;
                mViewModels[i].getDataList = mDsRestAPI.getList;
                for (var j = 0; j < viewModelDescriptors[i].dataPathList.length; ++j)
                    mViewModels[i].setReponseDataPath(j, viewModelDescriptors[i].dataPathList[j]);
                if (viewModelDescriptors[i].selectionToControlPathList && mViewModels[i].setSelectionToControl)
                {
                    for (var j = 0; j < viewModelDescriptors[i].selectionToControlPathList.length; ++j)
                        mViewModels[i].setSelectionToControl(getSelectionObject(mRequest, viewModelDescriptors[i].selectionToControlPathList[j]));
                }
            }
            else
            {
                alert("Viewmodel class " + viewModelDescriptors[i].class + " does not exist!");
            }
        }
        for (var i = 0; i < mViewModels.length; ++i)
            mViewModels[i].setBinder(mBinder);
    };

    this.getViewDescriptors = function()
    {
        return mWebAppModel.getSetupModel().getSetup().views.getData();
    };

    this.getSetupStyle = function()
    {
        return mWebAppModel.getSetupModel().getSetup().css.getData();
    };

    this.getSetupHtml = function()
    {
        return mWebAppModel.getSetupModel().getSetup().html.getData();
    };

    this.getResponseElement = function(aReponseDataPath, aLastSelectionIndexes)
    {
        if (aLastSelectionIndexes == undefined)
            aLastSelectionIndexes = [];

        var lNextSelectionIndex = 0;

        var lElement = undefined;
        if (aReponseDataPath && mResponse)
        {
            lElement = mResponse[aReponseDataPath[0]];
            if (lElement)
            {
                var lRq = mRequest[aReponseDataPath[0]];
                for (var i = 1; i < aReponseDataPath.length; ++i)
                {
                    if (lElement && lElement.list && lRq.getData.selection && lRq.getData.selection.length > 0)
                    {
                        if (lRq.getData.selectionValues && lRq.getData.selectionValues.length > 0 && lElement.list[0] && lElement.list[0].node.childVals) {
                            lElement = lElement.list[0].node.childVals[aReponseDataPath[i]];
                        } else if (lElement.list[lRq.getData.selection[0]] && lElement.list[lRq.getData.selection[0]].node.childVals) {
                            lElement = lElement.list[lRq.getData.selection[0]].node.childVals[aReponseDataPath[i]];
                        } else {
                            lElement = undefined;
                            break;
                        }
                    }
                    else if (lElement && lElement.list && aLastSelectionIndexes[lNextSelectionIndex] != undefined) {
                        lElement = lElement.list[aLastSelectionIndexes[lNextSelectionIndex]].node.childVals[aReponseDataPath[i]];
                        ++lNextSelectionIndex;
                    }
                    else if (lElement && lElement.node)
                    {
                        if (lElement.node.childVals)
                            lElement = lElement.node.childVals[aReponseDataPath[i]];
                        else {
                            lElement = undefined;
                            break;
                        }
                    }
                    else
                        lElement = {"error": "cannot determine node"};
                    if (lRq.getData.children)
                        lRq = lRq.getData.children[aReponseDataPath[i]];
                }
            }
        }
        else
            lElement = mResponse;
        return lElement;
    };

    this.setResponseElement = function(aReponseDataPath, aValue, aIndexInList, aLastSelectionIndexes, aCallback, aAdditionalData)
    {
        function dataSet(response) {
            if (mUIConfig.overlayEnabledOnSetData)
                mBinder.enableViews();
            if (aCallback != undefined)
                aCallback(response);
            mBinder.notifyChange(false, false, response);
        }

        if (aAdditionalData == undefined) {
            aValue = "" + aValue;
            var setData = mDataSourceUtils.setValue(mRequest, mResponse, aReponseDataPath, aIndexInList, aValue, aLastSelectionIndexes);
            if (setData != undefined) {
                if (mUIConfig.overlayEnabledOnSetData) {
                    mBinder.disableViews();
                }
                mDsRestAPI.getList([setData], dataSet);
            }
        } else if (aAdditionalData.setAppParams != undefined) {
            for (var i = 0; i < aAdditionalData.setAppParams.params.length; ++i) {
                var param = aAdditionalData.setAppParams.params[i];
                mModel.setAppParam(aAdditionalData.setAppParams.appName, param.key, param.value);
            }
        } else if (aAdditionalData.loadApp != undefined) {
            mModel.loadApp(aAdditionalData.loadApp);
        }
    };

    this.select = function(aSelectionObject, aValue) {
        saveRangeFilters(mRequest, []);

        aSelectionObject.selectionValues = undefined;
        if (aSelectionObject.selection)
            aSelectionObject.selection[0] = aValue;
        else
            aSelectionObject.selection = [aValue];

        updateSelectionsFromStorage(aSelectionObject);
        loadRangeFilters(mRequest, []);
    };

    this.selectByValue = function(aSelectionObject, aValue, aIndex) {
        saveRangeFilters(mRequest, []);

        if (aSelectionObject.selectionValues)
            aSelectionObject.selectionValues[0] = aValue;
        else
            aSelectionObject.selectionValues = [aValue];

        if (aSelectionObject.selection)
            aSelectionObject.selection[0] = aIndex;
        else
            aSelectionObject.selection = [aIndex];

        updateSelectionsFromStorage(aSelectionObject);
        loadRangeFilters(mRequest, []);
    };

    this.getSubViewModels = function(aIndexes)
    {
        var lViewmodels = [];
        for (var i = 0; i < aIndexes.length; ++i) {
            lViewmodels.push(mViewModels[aIndexes[i]]);
        }
        return lViewmodels;
    };

    this.setBinder = function(aBinder)
    {
        mBinder = aBinder;
        for (var i = 0; i < mViewModels.length; ++i)
            mViewModels[i].setBinder(mBinder);
    };

    this.getChangedData = function(aHandler)
    {
        function saveResponse(aResponse) {
            if (aResponse != undefined && aResponse.length > 0) {
                if (aResponse[0].node == undefined || aResponse[0].node.val != "No answer") {
                    if (mViewIsDisabledBecauseConnectionWasInterrupted) {
                        mViewIsDisabledBecauseConnectionWasInterrupted = false;
                        mBinder.enableViews();
                    }
                    processStaticResponses(aResponse, mRequest, []);
                    mResponse = aResponse;
                } else {
                    mViewIsDisabledBecauseConnectionWasInterrupted = true;
                    mBinder.disableViews();
                }
            }
            aHandler(aResponse);
        }
        processStaticRequests(mRequest, []);
        mDsRestAPI.getList(mRequest, saveResponse);
    };

    this.getUIConfig = function() {
        return mUIConfig;
    };

    this.loadFile = function(url, callback) {
        return mFileHandler.loadFile(url, callback);
    };

    this.loadSetup = function(a_setup, a_setupParams, a_doNotShowSpinningCircle) {
        if (mSetupList == undefined) {
            alert("callback for mSetupList should be called sooner");
            return;
        }

        function setupLoaded(ok, setup, setupLocation) {
            mResponse = undefined;
            mRequest = mWebAppModel.getSetupModel().getSetup().request.getData();
            mThis.initRequestSelectionsAndFiltersAtStart();
            mBinder.reloadSetup();
        }
        var setupExists = false;
        for (var i = 0; i < mSetupList.length; ++i)
            if (mSetupList[i] == a_setup)
                setupExists = true;
        if (setupExists)
        {
            saveRangeFilters(mRequest, []);
            mBinder.disableViews(a_doNotShowSpinningCircle);
            if (mBinder.isRunning()) {
                mBinder.stop();
                mWebAppModel.getSetupModel().loadSetup(a_setup, setupLoaded, false, a_setupParams);
            }
        }
        else
            alert("No such setup to load: " + a_setup);
    };

    this.isRunning = function() {
        return mBinder.isRunning();
    };

    // ------------------------------------------------------------------------------------------------

    this.getRequestFromPath = function(aReponseDataPaths)
    {
        var lRequest = null;
        if (aReponseDataPaths)
        {
            lRequest = mRequest[aReponseDataPaths[0]];
            for (var i = 1; i < aReponseDataPaths.length; ++i)
                lRequest =  lRequest.getData.children[aReponseDataPaths[i]];
        }
        else
            lRequest = mRequest;
        return lRequest;
    };

    function updateSelectionsFromStorage(p_request) {
        var requestPath = [];
        getRequestPath(p_request, mRequest, requestPath);

        var value = {
            "selection": p_request.selection,
            "selectionValues": p_request.selectionValues
        };
        sessionStorage.setItem(getRequestKey(requestPath, "selection"), JSON.stringify(value));
        sessionStorage.setItem(getRequestKeyAlternative(requestPath, "selection"), JSON.stringify(value));

        setSelections(requestPath, mThis.getRequestFromPath(requestPath).getData.children);
    }

    function getRequestPath(p_request, p_list, p_path) {
        for (var i = 0; i < p_list.length; ++i) {
            p_path.push(i);

            if (p_request == p_list[i].getData) {
                return true;
            }

            if (p_list[i].getData.children != undefined && getRequestPath(p_request, p_list[i].getData.children, p_path)) {
                return true;
            }

            p_path.pop(i);
        }
    }

    function getRequestKeyVMS(p_path) {
        var key = '';
        var currentPath = [];
        for (var i = 0; i < p_path.length - 1; ++i) {
            currentPath.push(p_path[i]);
            var request = mThis.getRequestFromPath(currentPath);
            if (request.getData.selectionValues != undefined) {
                key += request.getData.selectionValues + "SV_";
            } else if (request.getData.selection != undefined) {
                key += request.getData.selection[0] + 'S_';
            }
        }

        key += JSON.stringify(p_path) + 'P_';

        return key;
    }
    
    function getRequestKey(p_path, p_type) {
        var key = '';
        var currentPath = [];
        for (var i = 0; i < p_path.length - 1; ++i) {
            currentPath.push(p_path[i]);
            var request = mThis.getRequestFromPath(currentPath);
            if (request.getData.selectionValues != undefined) {
                key += request.getData.selectionValues + "_";
            } else if (request.getData.selection != undefined) {
                var response = mThis.getResponseElement(currentPath);
                if (response != undefined && response.list != undefined && response.list[request.getData.selection[0]] != undefined && response.list[request.getData.selection[0]].node != undefined) {
                    key += response.list[request.getData.selection[0]].node.val + "_";
                } else {
                    return getRequestKeyAlternative(p_path, p_type);
                }
            }
        }

        key += JSON.stringify(p_path);
        key = mWebAppModel.getSetupModel().getSetup().name + "_" + p_type + "_" + key;

        return key;
    }

    function getRequestKeyAlternative(p_path, p_type) {
        var key = '';
        var currentPath = [];
        for (var i = 0; i < p_path.length - 1; ++i) {
            currentPath.push(p_path[i]);
            var request = mThis.getRequestFromPath(currentPath);
            if (request.getData.selection != undefined) {
                key += request.getData.selection[0] + "_";
            }
        }

        key += JSON.stringify(p_path);
        key = mWebAppModel.getSetupModel().getSetup().name + "_" + p_type + "_" + key;

        return key;
    }

    function setSelections(p_path, p_list) {
        if (p_list != undefined) {
            for (var i = 0; i < p_list.length; ++i) {
                p_path.push(i);

                if (p_list[i].getData.selection != undefined || p_list[i].getData.selectionValues != undefined) {
                    var key = getRequestKey(p_path, "selection");
                    var value = sessionStorage.getItem(key);
                    if (value != undefined) {
                        value = JSON.parse(value);
                        p_list[i].getData.selection = value.selection;
                        p_list[i].getData.selectionValues = value.selectionValues;
                    } else {
                        p_list[i].getData.selectionValues = undefined;
                        p_list[i].getData.selection = [0];
                        mSelectionToChangeToValue.push(mcopy(p_path));
                    }
                }

                setSelections(p_path, p_list[i].getData.children);

                p_path.pop(i);
            }
        }
    }

    function triggerSelectionChangeAtStart(a_requests, a_path) {
        for (var i = 0; i < a_requests.length; ++i) {
            a_path.push(i);

            if (a_requests[i].getData.selection != undefined && a_requests[i].getData.selection.length > 0) {
                var response = mThis.getResponseElement(a_path);

                var key = getRequestKey(a_path, "selection");
                var value = sessionStorage.getItem(key);
                if (value != undefined) {
                    value = JSON.parse(value);
                    a_requests[i].getData.selectionValues = value.selectionValues;
                    a_requests[i].getData.selection = value.selection;
                } else {
                    mSelectionToChangeToValue.push(mcopy(a_path));
                }
            }
            if (a_requests[i].getData.children != undefined) {
                triggerSelectionChangeAtStart(a_requests[i].getData.children, a_path);
            }

            a_path.pop(i);
        }
    }

    function saveRangeFilters(p_requests, p_path) {
        for (var i = 0; i < p_requests.length; ++i) {
            p_path.push(i);

            if (p_requests[i].getData.rangeFilter != undefined) {
                sessionStorage.setItem(getRequestKey(p_path, "rangeFilter"), JSON.stringify(p_requests[i].getData.rangeFilter));
                sessionStorage.setItem(getRequestKeyAlternative(p_path, "rangeFilter"), JSON.stringify(p_requests[i].getData.rangeFilter));
            }

            if (p_requests[i].getData.children != undefined) {
                saveRangeFilters(p_requests[i].getData.children, p_path);
            }
            p_path.pop(i);
        }
    }

    function loadRangeFilters(p_requests, p_path) {
        for (var i = 0; i < p_requests.length; ++i) {
            p_path.push(i);

            if (p_requests[i].getData.rangeFilter != undefined) {
                var key = getRequestKey(p_path, "rangeFilter");
                var rangeFilter = sessionStorage.getItem(key);
                if (rangeFilter != undefined) {
                    p_requests[i].getData.rangeFilter = JSON.parse(rangeFilter);
                } else {
                    var origKey = JSON.stringify(p_path)+"origRangeFilter"+mWebAppModel.getSetupModel().getSetup().name;
                    rangeFilter = sessionStorage.getItem(origKey);
                    if (rangeFilter == undefined) {
                      sessionStorage.setItem(origKey, JSON.stringify(p_requests[i].getData.rangeFilter));
                      rangeFilter = p_requests[i].getData.rangeFilter;
                    } else {
                      rangeFilter = JSON.parse(rangeFilter);
                    }
                    p_requests[i].getData.rangeFilter = rangeFilter;
                }
            }

            if (p_requests[i].getData.children != undefined) {
                loadRangeFilters(p_requests[i].getData.children, p_path);
            }
            p_path.pop(i);
        }
    }
    
    function processStaticResponses(p_contentList, p_requests, p_path, indxInList) 
    {
        for (var i = 0; i < p_requests.length; ++i) 
        {
            var request = p_requests[i].getData;
            var response = p_contentList[i];
            p_path.push(i);
            if (request.clientSideCache != undefined && request.clientSideCache)
            {
                var key = getRequestKeyVMS(p_path);
                if (mRequestCache[key] == undefined && indxInList == undefined)
                {
                    if (response.node != undefined && response.node.val.includes('Unhandled request'))
                    {}
                    else
                        mRequestCache[key] = response;
                }
                else if (indxInList != undefined) 
                {
                    if (mRequestCache[key] == undefined)
                        mRequestCache[key] = {};
                    if (mRequestCache[key][indxInList] == undefined)
                    {
                        if (response.node != undefined && response.node.val.includes('Unhandled request'))
                            mRequestCache[key] = undefined;
                        else
                            mRequestCache[key][indxInList] = response;
                    }
                }
                
                if (mRequestCache[key] != undefined)
                {
                    if (indxInList == undefined)
                        p_contentList[i] = mRequestCache[key];
                    else 
                        p_contentList[i] = mRequestCache[key][indxInList];
                }
            }
         
            if (response.node != undefined)
            {
                if (request.children != undefined && response.node.childVals != undefined)
                    processStaticResponses(response.node.childVals, request.children, p_path);
            }
            else if (response.list != undefined) 
            {
                for (var j = 0; j < response.list.length; ++j) 
                {
                    var responseNode = response.list[j];
                    if (responseNode.node.childVals != undefined && responseNode.node.childVals.length > 0) 
                        processStaticResponses(responseNode.node.childVals, request.children, p_path, j);
                }
            }
            p_path.pop(i);
        }
    }
    
    function processStaticRequests(p_requests, p_path) 
    {        
        for (var i = 0; i < p_requests.length; ++i) 
        {
            var request = p_requests[i].getData;
            p_path.push(i);
            if (request.clientSideCache != undefined && request.clientSideCache)
            {
                var key = getRequestKeyVMS(p_path, "selection");
                if (mRequestCache[key] != undefined)
                {
                    if (request.element != "")
                    {
                        request.StoredRqElement = request.element;
                        request.element = "";
                    }
                }
                else if (request.element == "")
                    request.element = request.StoredRqElement;
            }

            if (request.children != undefined) 
                processStaticRequests(request.children, p_path);
            p_path.pop(i);
        }
    }
}
//# sourceURL=CustomizableApp\ViewModel.js
