/**
    restlikeApi client
    @PARAM specify which php-setClass to call
    @PARAM server the server where restlikeApi exists; defaults to the server this script is from
    @PARAM customErrMsg the error-message which is used for statusMsg when there was a connection problem
      if this variable is set, jsonp will be used
*/
var restlikeApi = function (phpClass,server,customErrMsg, timeout) {
    
    var url = "/mariaLibs/restlikeapi/index.php";
    var dataType = "json";
    var timeout = timeout || 60000;
    var setClass = '';
    var errMsg = "Sorry, there was a temporary problem connecting to the server. Please try again later.";
    var requestsFinished = {};
    
    if (typeof(phpClass) == "string" && phpClass.length > 0) {
        setClass = phpClass;
    }
    
    if (typeof(server) == "string" && (server.substring(0,7) == "http://" || server.substring(0,8) == "https://")) {
        if (server.substring(server.length-1) == "/") {
            server = server.substring(0,server.length-1);
        }
        url = server+url;
        dataType = 'jsonp';
    }
    
    if (typeof(customErrMsg) == "string" && customErrMsg.length > 0) {
        errMsg = customErrMsg;
    }
    
    var ajaxSetup = {
        "async":true,
        "type": "GET",
        "cache":false,
        "dataType": dataType,
        "timeout": timeout,
        "url": url
    };
    
    //internal handler
    var ajaxSuccess = function (reqId, successCb, errorCb, data, textStatus, jqXHR) {
        if (!requestsFinished[reqId]) {
            requestsFinished[reqId] = true;
            log(reqId+": received data: "+textStatus);
            if (!data.isError) {
                successCb(data.data,false,data.statusMesg);
                return ;
            }
            if($.browser.msie && !data.isError)
                for (var i in jqXHR) {
                    if(typeof jqXHR[i] !== "function") {
                        console.log(reqId + ": " + i + " -> " + jqXHR[i]);
                    }
                }
            errorCb(data.data,true,data.statusMesg);
        } else {
            delete(requestsFinished[reqId]);
        }
    };
    
    var ajaxError = function (reqId,successCb,errorCb, XMLHttpRequest, textStatus, errorThrown) {
        if (!requestsFinished[reqId]) {
            requestsFinished[reqId] = true;
            log(reqId+": connection error: "+textStatus);
            for (var i in XMLHttpRequest) {
                log(reqId+": "+i+" -> "+XMLHttpRequest[i]);
            }
            errorCb('',true,errMsg);
        } else {
            delete(requestsFinished[reqId]);
        }
    };
    
    var disableRequest = function (reqId,errorCb) {
        if (!requestsFinished[reqId]) {
            requestsFinished[reqId] = true;
            log (reqId+": connection timeout");
            errorCb('',true,errMsg);
        } else {
            delete(requestsFinished[reqId]);
        }
    };
    
    var stdParams = {};
    
    if (typeof(maria_restlikeapi_stdParams) == 'object') {
        stdParams = maria_restlikeapi_stdParams;
    }
    
    var getBaseParams = function (func) {
        return objectMerge({
            'setClass':setClass,
            'call':func
        },stdParams);
    };
    
    //dummies for user-functions
    var callError = function (data,isError,statusMsg) {
        log("an error occured: "+statusMsg);
    };
    
    var callSuccess = function (data,isError,statusMsg) {
        log("success! "+statusMsg);
    };

    /**
        send an ajax-call to the restlikeApi
        @PARAM func the php-function to call
        @PARAM data an object containing the data to send, defaults to {}
        @PARAM successCb the function to be called on successful load: function (data,isError,statusMsg); may be ommitted
        @PARAM errorCb the function to be called on error: function (data,isError,statusMsg); may be ommitted
    */
    this.call = function (func,data,successCb,errorCb) {
        if (typeof(func) != 'string' || func.length <=0) {
            log("restlikeApi::call requires a php function name to call");
            return;
        }
        if (typeof(data) != "object") {
            data = {};
        }
        if (typeof(successCb) != "function") {
            successCb = callSuccess;
        }
        if (typeof(errorCb) != "function") {
            errorCb = callError;
        }
        data = objectMerge(data,getBaseParams(func));
        
        var reqId = $.maria.uuid();
        requestsFinished[reqId] = false;
        
        $.ajax(objectMerge(ajaxSetup,{
            "error": partial(ajaxError,reqId,successCb,errorCb),
            "success": partial(ajaxSuccess,reqId,successCb,errorCb),
            "data": data
        }));
        //jquery doesn't apply the timeout to jsonp, so we apply a general timeout
        setTimeout(partial(disableRequest,reqId,errorCb),timeout);
    };
    
    /**
        returns the base-url, eg /mariaLibs/reslikeapi/index.php
    */
    this.getUrl = function () {
        return url;
    };
    
    /**
        returns the basic parameters, eg setClass and call
        @PARAM func the php-function to call
    */
    this.getParams = function (func) {
        return getBaseParams(func);
    };
    
    /**
        returns the datatype
    */
    this.getDatatype = function () {
        return dataType;
    };
    
};

