﻿// id - числовой идентификатор (int).
// reqType - "GET" или "POST"
// verb - действие (например: "deleteFoo", "submitFoo"
// paramNames - иассив имен параметров. Пример: ["fooId", "gooId"]. Может быть null
// handler - функция - обработчик ответа сервера

function AjaxAction(id, reqType, verb, paramNames, handler, isExtended)
{
    this.id = id;
    this.reqType = reqType.toLowerCase() == "get" ? "GET" : "POST";
    this.verb = verb;
    this.paramNames = paramNames;
    this.handler = handler;
    
    this.isExtended = isExtended;
    
    this.listener = this.isExtended ? AjaxAction.makeListenerEx(this.id) : AjaxAction.makeListener(this.id);
    
}

AjaxAction.url = Global.root + Global.aspNetPath + "DoAjaxAction.ashx";
AjaxAction.verbParam = "jacverb";
AjaxAction.actions = [];
AjaxAction.actionsInProgress = 0;

// executes AJAX request and returns the <XMLHttpRequest> object has been created
AjaxAction.prototype.exec = function(params, doc)
{
    //_trace(this.verb);
    
    AjaxAction.beforeExec();
    

    if (!this.inProgress)
    {
        AjaxAction.actionsInProgress++;
        this.inProgress = true;
        AjaxAction.onActionsInProgressChange();
    }
    
    var ajx = this;

    ajx.reqObj = AjaxAction.createXmlHttp();
    ajx.reqObj.onreadystatechange = ajx.listener;

    var url = AjaxAction.url + "?" + AjaxAction.verbParam + "=" + ajx.verb;
    
    var paramString = null;
    
    if (ajx.paramNames && params && ajx.paramNames.length == params.length)
    {
        paramString = "";
        var len = ajx.paramNames.length;
        
        for (var i = 0; i < len; ++i)
        {
            var parVal = params[i];
            if (!parVal) parVal = "";
            
            paramString += "&" + ajx.paramNames[i] + "=" + parVal;
        }
    }
    
    if (paramString)
    {
        url += paramString;
    }
    
    var req = ajx.reqObj;
    
    req.open(ajx.reqType, url);
    
    if (doc)
    {
        req.setRequestHeader("Content-Type", "text/xml");
        req.send(doc);
    }
    else
    {
        req.send(null);
    }
    
    return req;
}

AjaxAction.getResponseInfo = function(doc)
{
    var resElem = doc.getElementsByTagName("Result")[0];
    var statusVal = resElem.getAttribute("Status");
    
    var ex = null;
    
    var exEl = XmlTool.getSingleChildElem(resElem, "Exception");
    if (exEl) ex = new AjaxException(exEl);
    
    var res = 
    {
        dataElem: doc.getElementsByTagName("Data")[0],
        status: statusVal,
        ok: statusVal == "OK",
        message: resElem.getAttribute("Message"),
        exception: ex
    };
    
    return res;
}

AjaxAction.beforeExec = function()
{
}

AjaxAction.preprocessResponse = function(doc)
{
}

AjaxAction.makeListener = function(id)
{
    var code = 
    "var f = function() \n" +
    "{ \n" +
    "    var ajx = AjaxAction.actions['" + id + "']; \n" +
    "    var req = ajx.reqObj; \n" +
    "    if (req.readyState == 4) \n" +
    "    { \n" +
    "        ajx.inProgress = false; \n" +
    "        AjaxAction.actionsInProgress--; \n" +
    "        AjaxAction.onActionsInProgressChange(); \n" +
    "        if (ajx.traceResponse) _trace(req.responseText); \n" +
    "        var doc = req.responseXML; \n" +
    "        if (doc) \n" +
    "        { \n" +
    "            var ok = AjaxAction.preprocessResponse(doc); \n" +
    "            var dataElem = null; try{ dataElem = AjaxAction.getResponseInfo(doc).dataElem; }catch(ex){} \n" +
    "            ajx.handler(doc, ok, dataElem); \n" +
    "            req.abort(); \n" + 
    "        } \n" +
    "    } \n" +
    "} \n";

    eval(code);
    
    return f;
}

AjaxAction.makeListenerEx = function(id)
{
    var code = 
    "var f = function() \n" +
    "{ \n" +
    "    var ajx = AjaxAction.actions['" + id + "']; \n" +
    "    var req = ajx.reqObj; \n" +
    "    if (req.readyState == 4) \n" +
    "    { \n" +
    "        ajx.inProgress = false; \n" +
    "        AjaxAction.actionsInProgress--; \n" +
    "        AjaxAction.onActionsInProgressChange(); \n" +
    "        if (ajx.traceResponse) _trace(req.responseText); \n" +
    "        var doc = req.responseXML; \n" +
    "        if (doc) \n" +
    "        { \n" +
    "            var ok = AjaxAction.preprocessResponse(doc); \n" +
    "            var dataElem = null; \n" +
    "            try \n" +
    "            { \n" +
    "               var info = AjaxAction.getResponseInfo(doc); \n" +
    "               dataElem = info.dataElem; \n" +
    "               ex = info.exception; \n" +
    "            } \n" +
    "            catch(dummy_ex) \n" +
    "            { \n" +
    "            } \n" +
    "            ajx.handler(doc, ok, dataElem, ex); \n" +
    "            req.abort(); \n" + 
    "        } \n" +
    "    } \n" +
    "} \n";

    eval(code);
    
    return f;
}

AjaxAction.createXmlHttp = function()
{
    var xReq = null;
    
    if (window.XMLHttpRequest)
    {
        xReq = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        xReq = new ActiveXObject("Microsoft.XMLHTTP");        
    }
    
    return xReq;
}

AjaxAction.register = function(id, reqType, action, paramName, handler)
{
    var ajx = new AjaxAction(id, reqType, action, paramName, handler, false);
    AjaxAction.actions[id] = ajx;
}

AjaxAction.registerEx = function(action, reqType, paramNames, handler)
{
    var ajx = new AjaxAction(action, reqType, action, paramNames, handler, true);
    AjaxAction.actions[action] = ajx;
}

AjaxAction.createRequestXmlObj = function()
{
    var doc = XmlTool.createDocument();
    var docElem = doc.createElement("Request");
    doc.appendChild(docElem);
    
    var dataElem = doc.createElement("Data");
    docElem.appendChild(dataElem);
    
    return {doc: doc, dataElem: dataElem};
}

AjaxAction.onActionsInProgressChange = function()
{
    // todo[ank]
    //_trace(AjaxAction.actionsInProgress);
}

