/*
	This note must stay intact.
	
	Author:
		Mattias Rundqvist, Webparts (www.webparts.se)
	License:
		Creative Commons Attribution-Share Alike 3.0 License
		http://creativecommons.org/licenses/by-sa/3.0/
*/

function wp_XMLHttpRequest( mcfg ) {
	
	var self = this;
	var obj = null;
	var data = null;
	
	var cfg = {
		uri : mcfg.uri ? mcfg.uri : "",
		query_string : mcfg.query_string ? mcfg.query_string : "",
		data : mcfg.data ? mcfg.data : "",
		form : mcfg.form ? mcfg.form : "",
		method : mcfg.method || "",
		field : mcfg.field || "",
		cache : (mcfg.cache==false)?false:true,
		onload : mcfg.onload,
		onerror : mcfg.onerror
	};
	
	// -- debug
	try{var debug = new wp_Log();}catch(e){var debug = new Object();debug.log = function(){};};
	this._function = "wp_XMLHttpRequest";
	this.debug = debug;
	// --
	
	function createConnection() {
		
		debug.log(self,"createConnection()");
	
		// -- Loading data as text
		if(window.XMLHttpRequest && !(window.ActiveXObject)) {
			debug.log(self,"...with XMLHttpRequest");
			obj = new XMLHttpRequest();
		} else if(window.ActiveXObject) {
			debug.log(self,"...with ActiveXObject");
		
			var ver = new Array("Msxml6","Msxml5","Msxml3","Msxml2","Msxml4","Microsoft");
			var i = 0;
			
			do {
				debug.log(self,"Trying to create instance of "+ver[i++]+".XMLHTTP");
				try {
					obj = new ActiveXObject(ver[i++]+".XMLHTTP");
				} catch(e) {
					obj = null;
				}
			} while( !obj && i<ver.length );
		}
		// --	
		
		if( !obj ) {
			return false;
		} else {
			obj.onreadystatechange = onstatechange;
		}
		
		return true;
	}
	
	function onerror( e, result ) {
		if( cfg.onerror ) {
		    var er = new Object();
		    var status = 0;
		    try {
		        status = obj.status;
		    } catch ( se) {
		        obj = new Object();
		        obj.status = new Number(0);
		    }
		        		    
		    er.error = e;
		    er.response = new Object();
		    er.response.http = obj;
		    er.response.text = (result ? result.text : null);
		    er.response.dom = (result ? result.dom : null);
		    er.request = self;
		    er.config = cfg;
			cfg.onerror( er );
		}
	}
	
	// -- public functions ------------------------------
	this.cancel = function() {
		if( obj )
			obj.abort();
	}
	
	this.execute = function() {
	
		// -- Kolla så vi har en uri eller ett formulär -----
		if( !cfg.uri && !cfg.form ) {
			onerror( ((cfg.method.toUpperCase() == "GET") ? new Error("No URI in GET request") : new Error("No action in POST request")) );
			return false;
		}
		// --------------------------------------------------
		
		// -- Skapa variabler -------------------------------
		var method = null;
		var action = null;
		var data = null;
		var wpform = null;
		var field_collection = null;
		// --------------------------------------------------
		
		// -- Hämta värden från cfg.form? -------------------
		if( cfg.form && document.getElementById(cfg.form) ) {
			method = ((cfg.method || document.getElementById(cfg.form).method) || "POST").toUpperCase();
			action = cfg.uri || document.getElementById(cfg.form).action;
			
			// -- Skapa wp_Form objekt --
			try {
				wpform = new wp_Form({ id : cfg.form });
			} catch( err ) {
				// -- wp_Form.js verkar inte finnas...
				debug.log(self,"FATAL: wp_Form missing...");
				onerror( new Error("wp_Form.js is missing") );
				return;
			}
			// --
			
			// -- Kan vi genomföra requesten? --
			if( !wpform || !cfg.form || (cfg.field && !document[cfg.form][cfg.field]) ) {
				debug.log(self,"Failed to send request...");
				onerror( new Error( ( ( cfg.field?"Field":"Form")+" does not exist") ) );
				return;
			}
			// --
		
			// -- Skicka hela formuläret eller endast ett fält? --
			if( cfg.field ) {
				field_collection = wpform.collect( cfg.field );
			} else {
				field_collection = wpform.collect();
			}
			// --
			
			// -- Bygg fältvärden till en query_string --
			data = buildQueryString( field_collection );
			// --
		}
		// --------------------------------------------------
		
		// -- Hämta värden från cfg.uri? --------------------
		else if( cfg.uri && !cfg.form ) {
			method = (cfg.method || "GET").toUpperCase();
			action = cfg.uri;
			data = (cfg.data ? buildQueryString( cfg.data ) : cfg.query_string);
		}
		// --------------------------------------------------
		
		// -- Kommer vi hit är det felkonfigurerat ----------
		else {
			debug.log(self,"No uri and no form. Failed to send request...");
			onerror( new Error("Form not found"));
		}
		// --------------------------------------------------
		
		// -- Förhindra cache? ------------------------------
		if( !cfg.cache ) {
			if( data.length ) {
				data += "&";
			}
			data += "__wp_nocache=";
			data += Math.random();	
		}
		// --------------------------------------------------
		
		// -- Skicka request --------------------------------
		if( createConnection() ) {
			debug.log(self,"Connection created, sending request");
			debug.log(self,"Method: "+method);
			debug.log(self,"Action: "+action);
			debug.log(self,"Data: "+data);
			if( method == "GET" ) {
				action = action + ((data.length) ? ("?" + data) : "");
				
				try {
				    obj.open("GET", action, true);
    				obj.send(null);
    			} catch( e ) {
    			    onerror( e );
    			    return;
    			}
			} else if( method == "POST" ) {
			
			    try {
				    obj.open("POST", action, true);
				    obj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				    //obj.setRequestHeader("Encoding","UTF-8");
				    obj.setRequestHeader("Content-length", data.length);
				    obj.setRequestHeader("Connection", "close");
				    obj.send( data );			
				} catch( e ) {
    			    onerror( e );
    			    return;
    			}
			}
		} else {
			debug.log(self,"Could not create connection");
			onerror( new Error("Could not create XML HTTP Object") );
			return false;
		}
		// --------------------------------------------------
		
	}
	// --------------------------------------------------
	
	function buildQueryString( field_collection ) {
	
	    var data = null;
	    
	    for( field in field_collection ) {
			if( typeof field_collection[field] != "function" ) {				
				if( data ) {
					data += "&";
				} else {
					data = "";
				}
				if( typeof field_collection[field] == "string" ) {
					data += (field + "=" + encodeURI( field_collection[field] ).replace(/&/g,"%26"));
		            debug.log(self,"adding field: "+field);
				} else {
					for( var count = 0; count < field_collection[field].length; count++ ) {
						if( data && count ) {
							data += "&";
						}
						data += (field + "=" + encodeURI( field_collection[field][count] ).replace(/&/g,"%26"));
					}
				}
			}
		}
		debug.log(self,"Constructed query string: "+data);
		return data;
	}
	
	// -- event functions -------------------------------
	function onstatechange() {
	
		if( cfg["onstatechange"] ) {
			cfg["onstatechange"]( obj.readyState );
		}
		
		if(obj.readyState == 4) {
			onload();
		}
	}
	
	function onload() {
	
		var doc = null;
		var result = new Object();
		
		debug.log(self,"receiving: ");
		
		if( typeof DOMParser == "function" ) {
			debug.log(self,"using DOMParser");
			var dp = new DOMParser();
			doc = dp.parseFromString( obj.responseText, "text/xml" );
		} else if( window.ActiveXObject ) {
			debug.log(self,"using ActiveXObject");
			doc=new ActiveXObject("Microsoft.XMLDOM");
			doc.async="false";
			doc.loadXML(obj.responseText);
		}
		result.dom = doc.documentElement;
		result.text = obj.responseText;
		
		debug.log(self,"Recieving "+result.text.length +" bytes of data");
		
		
		if( obj.status != 200 ) {
		    onerror( new Error("HTTP error"), result );
		    return;
		}
		
		if( cfg["onload"] ) {
			cfg["onload"]( result );
		}
	}
	// --------------------------------------------------
	
}
