/**
 * @author Andrea Bruglia, Davide Stefanini
 */
Ext.lib.Ajax.isCrossDomain = function(u) {
	var match = /(?:(\w*:)\/\/)?([\w\.]*(?::\d*)?)/.exec(u);
	if (!match[1]) return false; // No protocol, not cross-domain
	return (match[1] != location.protocol) || (match[2] != location.host);
};

Ext.override(Ext.data.Connection, {
	
	request : function(o){
		var online = (session == undefined ) ? true : session.isOnline;
		
		this.isGetReady(o);
		
		if (online || o.bypassOffline) {
			if (this.fireEvent("beforerequest", this, o) !== false) {
				var p = o.params;
				var enableCrypt = (Ext.isEmpty(o.enableCrypt) && (o.enableCrypt !== false)) ? ENABLE_CRYPT : false;

				if (typeof p == "function") {
					p = p.call(o.scope || window, o);
				}
				if (typeof p == "object") {
					for(var key in p){
						if (key == 's'){
							if (enableCrypt) {
								p[key] = _c2(p[key]);
							}else{
								p[key] = '@'+p[key];
							}
						}
					}
					p = Ext.urlEncode(p);
				}
				if (this.extraParams) {
					var extras = Ext.urlEncode(this.extraParams);
					p = p ? (p + '&' + extras) : extras;
				}
				
				var url = o.url || this.url;
				if (typeof url == 'function') {
					url = url.call(o.scope || window, o);
				}
				
				if (o.form) {
					var form = Ext.getDom(o.form);
					url = url || form.action;
					
					var enctype = form.getAttribute("enctype");
					if (o.isUpload || (enctype && enctype.toLowerCase() == 'multipart/form-data')) {
						return this.doFormUpload(o, p, url);
					}
					var f = Ext.lib.Ajax.serializeForm(form);
					p = p ? (p + '&' + f) : f;
				}
				
				var hs = o.headers;
				if (this.defaultHeaders) {
					hs = Ext.apply(hs ||
					{}, this.defaultHeaders);
					if (!o.headers) {
						o.headers = hs;
					}
				}
				
				var cb = {
					success: this.handleResponse,
					failure: this.handleFailure,
					scope: this,
					argument: {
						options: o
					},
					timeout: this.timeout
				};
				
				var method = o.method || this.method || (p ? "POST" : "GET");
				
				if (method == 'GET' && (this.disableCaching && o.disableCaching !== false) || o.disableCaching === true) {
					url += (url.indexOf('?') != -1 ? '&' : '?') + '_dc=' + (new Date().getTime());
				}
				
				if (typeof o.autoAbort == 'boolean') { // options gets top priority
					if (o.autoAbort) {
						this.abort();
					}
				}
				else 
					if (this.autoAbort !== false) {
						this.abort();
					}
				if ((method == 'GET' && p) || o.xmlData || o.jsonData) {
					url += (url.indexOf('?') != -1 ? '&' : '?') + p;
					p = '';
				}
				
				if (!this.isLongerAvailable(o,url,p))
					url = this.changeUrl(o.url);

				if (o.scriptTag || this.scriptTag) {
					this.transId = this.scriptRequest(method, url, cb, p, o);
				}
				else {
					this.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
				}
				return this.transId;
			}
			else {
				Ext.callback(o.callback, o.scope, [o, null, null]);
				return null;
			}
		}else{
			hideLoading();
			Toast('Attenzione!','Non '+UNI_E+' possibile eseguire questa operazione in modalit'+UNI_A+' non in linea.');
			return null;
		}
    },
	
	handleResponse : function(response){
		try{
	        this.transId = false;
	        var options = response.argument.options;
	        response.argument = options ? options.argument : null;
			try{
				response.responseObject = Ext.decode(response.responseText);
			}catch(e){
				response.responseObject = null;
			}
	        this.fireEvent("requestcomplete", this, response, options);
	        Ext.callback(options.success, options.scope, [response, options]);
	        Ext.callback(options.callback, options.scope, [options, true, response]);
		}catch(e){
			if (log) {
				log.error(e);
			}
		}
    },
	
	
	scriptRequest : function(method, url, cb, data, options) {
        var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
        var trans = {
            id : transId,
            cb : options.callbackName || "stcCallback"+transId,
            scriptId : "stcScript"+transId,
            options : options
        };

        url += (url.indexOf("?") != -1 ? "&" : "?") + data + String.format("&{0}={1}", options.callbackParam || this.callbackParam || 'callback', trans.cb);

        var conn = this;
        window[trans.cb] = function(o){
            conn.handleScriptResponse(o, trans);
        };

//      Set up the timeout handler
        trans.timeoutId = this.handleScriptFailure.defer(cb.timeout, this, [trans]);

        var script = document.createElement("script");
        script.setAttribute("src", url);
        script.setAttribute("type", "text/javascript");
        script.setAttribute("id", trans.scriptId);
        document.getElementsByTagName("head")[0].appendChild(script);
        return trans;
    },

    handleScriptResponse : function(o, trans){
        this.transId = false;
        this.destroyScriptTrans(trans, true);
        var options = trans.options;
//      Attempt to parse a string parameter as XML.
        var doc;
        if (typeof o == 'string') {
            if (window.ActiveXObject) {
                doc = new ActiveXObject("Microsoft.XMLDOM");
                doc.async = "false";
                doc.loadXML(o);
            } else {
                doc = new DOMParser().parseFromString(o,"text/xml");
            }
        }
//      Create the bogus XHR
        response = {
            responseObject: o,
            responseText: (typeof o == "object") ? Ext.util.JSON.encode(o) : String(o),
            responseXML: doc,
            argument: options.argument
        }
        this.fireEvent("requestcomplete", this, response, options);
        Ext.callback(options.success, options.scope, [response, options]);
        Ext.callback(options.callback, options.scope, [options, true, response]);
    },
    
    handleScriptFailure: function(trans) {
        this.transId = false;
        this.destroyScriptTrans(trans, false);
        var options = trans.options;
        response = {
            argument:  options.argument,
            status: 500,
            statusText: 'Server failed to respond',
            responseText: ''
        };
        this.fireEvent("requestexception", this, response, options, {
            status: -1,
            statusText: 'communication failure'
        });
        Ext.callback(options.failure, options.scope, [response, options]);
        Ext.callback(options.callback, options.scope, [options, false, response]);
    },
    
    // private
    destroyScriptTrans : function(trans, isLoaded){
        document.getElementsByTagName("head")[0].removeChild(document.getElementById(trans.scriptId));
        clearTimeout(trans.timeoutId);
        if(isLoaded){
            window[trans.cb] = undefined;
            try{
                delete window[trans.cb];
            }catch(e){}
        }else{
            // if hasn't been loaded, wait for load to remove it to prevent script error
            window[trans.cb] = function(){
                window[trans.cb] = undefined;
                try{
                    delete window[trans.cb];
                }catch(e){}
            };
        }
    },
	
	/**
	 * E' qui che verifico se la chiamata deve essere fatta in CrossDomain
	 * oppure deve essere fatta passando per il file ASP
	 * @param {Object} o
	 */
	isGetReady : function(o){
		try{
			if ((o.url.indexOf(SERVER_URL) == -1) && (o.url.indexOf(CROSS_DOMAIN_FORWARD) == -1)){
				this.setScriptTag(false,o)
			}else{
				if ((this.scriptTag == undefined) || (o.scriptTag == undefined)) 
					this.setScriptTag(true,o);
				if (!o.scriptTag || !this.scriptTag){
					if (log) {
						log.info('Chiamata Ajax tramite il file CROSSDOMAIN FORWARD');
					}
					if (o.url.indexOf(SERVER_URL) != -1){
						o.url = this.changeUrl(o.url);
					}
				}
			}
		}catch(e){
			if (log) {
				log.error(e);
			}
		}
	},
	/**
	 * Faccio chiamare il file CROSSDOMAIN FORWARD sono quando è necessario e quindi 
	 * quando l'url supera il numero di caratteri impostato da MAX_LENGTH_QUERYSTRINGs
	 * @param {Object} o
	 * @param {Object} url
	 * @param {Object} param
	 */
	isLongerAvailable : function(o,url,param){
		try{
			var returnValue = true;
			if ((convertiStrNum(url.length) + convertiStrNum((param)?param.length:0)) > MAX_LENGTH_QUERYSTRING && isIE7()){
				if (log) {
					log.info('Chiamata Ajax troppo lunga chiamo il file CROSSDOMAIN FORWARD');
				}
				this.setScriptTag(false,o);
				returnValue = false;
			}
			return returnValue;
		}catch(e){
			if (log) {
				log.error(e);
			}
		}
	},
	/**
	 * Cambio SERVER_URL con CROSS_DOMAIN_FORWARD
	 * @param {Object} url
	 */
	changeUrl : function(url){
		if (log) {
			log.info('Url originale -> '+url);
		}
		url = url.replace(SERVER_URL,CROSS_DOMAIN_FORWARD);
		log.info('Url cambiata -> '+url);
		return url;
	},
	/**
	 * Setto lo ScriptTag
	 * @param {Object} val
	 * @param {Object} o
	 */
	setScriptTag : function(val,o){
		this.scriptTag = val;
		o.scriptTag = val;
	}
	
   
});