// 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                                                         //
///////////////////////////////////////////////////////////////////////////////////////////////////////
/** DsRestAPI DataSource API calls */

function DsRestAPI(extension) {
    "use strict";
    /** private member */
    var mDsRestAPIComm;
    var mThis = this;
    /** constructor */
    mDsRestAPIComm = new CDsRestAPIComm(extension);
    /** public functions */
    this.getData = function(aHandler, aSource, aElement, aParams, aPtcName) {
        var lDSCall = [{getData : {
                source : aSource,
                element: aElement,
                ptcname: aPtcName,
                params : aParams
            }}
        ];
        get(lDSCall, aHandler);
    };

    this.setData = function(aHandler, aSource, aElement, aContent, aType, aParams, aPtcName, aIndxs) {
        var lDSCall = [{setData : {
                source : aSource,
                element: aElement,
                ptcname: aPtcName,
                params : aParams,
                content: aContent,
                indxsInList: aIndxs,
                tp: aType
            }}
        ];
        get(lDSCall, aHandler);
    };

    this.getList = function(aParam, aHandler) {
        var lDSCall = {requests: aParam, "timeOut": 5.0};
        mDsRestAPIComm.ajaxCall(lDSCall, function(data) {
            aHandler(data);
        });
    };

    this.getHelp = function(callback, aSource, aElement) {
        function gotHelp(helpAns) {
            var ok;
            var data;
            try {
                ok = true;
                data = JSON.parse(hex2a(helpAns.node.val));
            } catch (e) {
                ok = false;
                data = "Error parsing Help data";
            }
            callback(ok, data);
       }
       if (aSource !== undefined && aElement !== undefined) {
           this.getData(gotHelp, "DataSource", "help", [{"paramName": "Format", "paramValue": "JSON"}, {"paramName": "Source", "paramValue": aSource }, {"paramName": "Element", "paramValue": aElement}]);
       } else if (aSource !== undefined) {
           this.getData(gotHelp, "DataSource", "help", [{"paramName": "Format", "paramValue": "JSON"}, {"paramName": "Source", "paramValue": aSource }]);
       } else {
           this.getData(gotHelp, "DataSource", "help", [{"paramName": "Format", "paramValue": "JSON"}]);
       }
    };
   
    /** private functions */

    function get(aParam, aHandler) {
        function localHandler(aData) {
            if (aHandler != undefined) {
                if (aData && typeof aData[0] !== 'undefined') {
                    aHandler(aData[0]);
                } else {
                    aHandler();
                }
            }
        }
        mThis.getList(aParam, localHandler);
    }
}
