/// <reference name="MicrosoftAjax.js" />
/// <reference name="dnn.js" assembly="DotNetNuke.WebUtility" />

//dnn.xmlhttp Namespace 
Type.registerNamespace('dnn.xmlhttp');

dnn.xmlhttp.callbackType = function(){};
dnn.xmlhttp.callbackType.prototype = {
    simple: 0,
    processPage: 1,
    callBackMethod: 2,
    processPageCallbackMethod: 3
}
dnn.xmlhttp.callbackType.registerEnum("dnn.xmlhttp.callbackType");

dnn.xmlhttp.callbackStatus = function(){};
dnn.xmlhttp.callbackStatus.prototype = {
    ok: 200,
    genericFailure: 400,
    controlNotFound: 404,
    interfactNotSupported: 501
}
dnn.xmlhttp.callbackStatus.registerEnum("dnn.xmlhttp.callbackStatus");


dnn.extend(dnn.xmlhttp, {
	pns: 'dnn',
	ns: 'xmlhttp',
	parserName: null,
	contextId: 0,
	requests: [],
	cleanUpTimer: null,
    callBackMethods: null,

    init: function()
    {
    	this.parserName = this._getParser();
    },
    
    onload: function()
    {
    	dnn.xmlhttp._fillCallBackMethods();
    },

    doCallBack: function(sControlId, sArg, pSuccessFunc, sContext, pFailureFunc, pStatusFunc, bAsync, sPostChildrenId, iType)
    {
	    var oReq = dnn.xmlhttp.createRequestObject();
	    var sURL = document.location.href;
	    oReq.successFunc = pSuccessFunc;
	    oReq.failureFunc = pFailureFunc;
	    oReq.statusFunc = pStatusFunc;
	    oReq.context = sContext;
	    if (bAsync == null)
		    bAsync = true;

//		if (sURL.substring(sURL.length - 1, sURL.length) == '/')	//CAP-8897 - WCT-8651
//		    sURL += 'default.aspx';

    	if (sURL.indexOf('#') != -1)
    	    sURL = sURL.substring(0, sURL.indexOf('#'));
    	
	    oReq.open('POST', sURL, bAsync);
    	
    	//js xmlhttp cannot do double encoding
    	if (this.parserName == 'JS')
	        sArg = dnn.encode(sArg, false);   
    	else
	        sArg = dnn.encode(sArg, true);   
    		
	    if (sPostChildrenId)
		    sArg += '&' + dnn.dom.getFormPostString($get(sPostChildrenId));

	    if (iType != 0)
		    sArg += '&__DNNCAPISCT=' + iType;
    		
	    oReq.send('__DNNCAPISCI=' + sControlId + '&__DNNCAPISCP=' + sArg);

	    return oReq; //1.3
    },

    callControlMethod: function(ns, method, args, successFunc, failFunc, context, type)
    {
        if (this.callBackMethods == null)
            this._fillCallBackMethods();
        
        if (type == null)
            type = dnn.xmlhttp.callbackType.callBackMethod;
        
        if (this.callBackMethods[ns])
        {
            //var argAry = [];
            //for (var i = 0; i < args.length; i++) 
            //    argAry[i] = args[i];
            if (args == null)
                args = {};
            var callContext = {context: context, success: successFunc, fail: failFunc};
            var payload = Sys.Serialization.JavaScriptSerializer.serialize({method:method,args:args});
            dnn.xmlhttp.doCallBack(this.callBackMethods[ns], payload, dnn.xmlhttp.callBackMethodComplete, callContext, dnn.xmlhttp.callBackMethodError, null, true, null, type);  //2 = CallbackMethod
        }
        else
        {
            alert('Namespace not registered');
        }
    },

    callBackMethodComplete: function(result, context, req) 
    {
        result = Sys.Serialization.JavaScriptSerializer.deserialize(result);
        if (context.success)
            context.success(result.result, context.context, req);
    },
        
    callBackMethodError: function(message, context, req) 
    {
        if (context.fail)
            context.fail(message, context.context, req);
    },


    createRequestObject: function()
    {
	    if (this.parserName == 'ActiveX')
	    {
		    var o = new ActiveXObject('Microsoft.XMLHTTP');
		    dnn.xmlhttp.requests[dnn.xmlhttp.requests.length] = new dnn.xmlhttp.XmlHttpRequest(o);
		    return dnn.xmlhttp.requests[dnn.xmlhttp.requests.length-1]; 
	    }
	    else if (this.parserName == 'Native')
	    {
		    return new dnn.xmlhttp.XmlHttpRequest(new XMLHttpRequest()); 
	    }
	    else
	    {
		    var oReq = new dnn.xmlhttp.XmlHttpRequest(new dnn.xmlhttp.JsXmlHttpRequest());
		    dnn.xmlhttp.requests[oReq._request.contextId] = oReq;
		    return oReq; 
	    }	
    },
    
    _getParser: function()
    {
	    if (dnn.xmlhttp.JsXmlHttpRequest != null)
		    return 'JS';
	    if (dnn.dom.browser.isType(dnn.dom.browser.InternetExplorer))
		    return 'ActiveX'; //'ActiveX';
	    else if (typeof(XMLHttpRequest) != "undefined") 
		    return 'Native'; //'Native';
	    else
		    return 'JS';
    },
    
    _fillCallBackMethods: function()
    {
        this.callBackMethods = [];
        var methods = dnn.getVar('__dnncbm', '').split(' ');
        var pair;
        if (methods)
        {
            for (var i=0; i<methods.length; i++)
            {
                if (methods[i].length > 0)
                {
                    pair = methods[i].split('=');
                    this.callBackMethods[pair[0]] = pair[1];
                }
            }
        }
    },

    _cleanupxmlhttp: function()
    {
	    for (var i=0; i<dnn.xmlhttp.requests.length;i++)
	    {
		    if (dnn.xmlhttp.requests[i] != null)
		    {
			    if (dnn.xmlhttp.requests[i].completed)
			    {
				    dnn.xmlhttp.requests[i].dispose();
				    if (dnn.xmlhttp.requests.length == 1)
				        dnn.xmlhttp.requests = new Array();
				    else
				        dnn.xmlhttp.requests.splice(i,i);
			    }
		    }
	    }
    }
});

//dnn.xmlhttp.XmlHttpRequest Object 
dnn.xmlhttp.XmlHttpRequest = function(o)
{
	this._request = o;
	this.successFunc = null;
	this.failureFunc = null;
	this.statusFunc = null;
	this._request.onreadystatechange = dnn.dom.getObjMethRef(this, 'onreadystatechange');
	this.context = null;
	this.completed = false;
}

dnn.xmlhttp.XmlHttpRequest.prototype = 
{
    dispose: function()
    {
	    if (this._request != null)
	    {
		    this._request.onreadystatechange = new function() {};//stop IE memory leak.  Not sure why can't set to null;
		    this._request.abort();
		    this._request = null;
		    this.successFunc = null;
		    this.failureFunc = null;
		    this.statusFunc = null;
		    this.context = null;
		    this.completed = null;
		    this.postData = null;	//1.3
	    }
    },

    open: function(sMethod, sURL, bAsync)
    {
	    this._request.open(sMethod, sURL, bAsync);
	    if (typeof(this._request.setRequestHeader) != 'undefined')
		    this._request.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
	    return true;
    },

    send: function(postData)
    {
	    this.postData = postData;
	    if (dnn.xmlhttp.parserName == 'ActiveX')	
		    this._request.send(postData);
	    else
		    this._request.send(postData);
	    return true;
    },

    onreadystatechange: function()
    {
	    if (this.statusFunc != null)
		    this.statusFunc(this._request.readyState, this.context, this); //1.3
    		
	    if (this._request.readyState == '4')
	    {
		    this.complete(this._request.responseText);
		    if (dnn.xmlhttp.parserName == 'ActiveX')
			    window.setTimeout(dnn.xmlhttp._cleanupxmlhttp, 1);	//cleanup xmlhttp object
	    }
    },

    complete: function (res)
    {
	    var statusCode = this.getResponseHeader('__DNNCAPISCSI');
	    this.completed=true;
	    if (new Number(statusCode) == dnn.xmlhttp.callbackStatus.ok)	
		    this.successFunc(res, this.context, this);	//1.3
	    else
	    {
		    var statusDesc = this.getResponseHeader('__DNNCAPISCSDI');
		    if (this.failureFunc != null)
			    this.failureFunc(statusCode + ' - ' + statusDesc, this.context, this); //1.3
		    else
			    alert(statusCode + ' - ' + statusDesc);
	    }
    },

    getResponseHeader: function (key)
    {
	    return this._request.getResponseHeader(key);
    }
}

dnn.xmlhttp.XmlHttpRequest.registerClass('dnn.xmlhttp.XmlHttpRequest');

dnn.xmlhttp.init();
Sys.Application.add_load(dnn.xmlhttp.onload);

