/**
* @author Theo van Oostrum theo@a2.nl
* @version 1.0
* @copyright A2 Automatisering B.V. 30-12-2008
*/
(function(){
	NCVajax = function ( options )
	{
		merge ( ajaxDefaultSettings , options );
		
		if ( options.data && typeof ( options.data ) !== 'string' )
		{
			var data = '';
			
			for ( var key in options.data )
			{
				data += encodeURIComponent ( key ) + '=' + encodeURIComponent ( options.data [ key ] ) + '&';
			}
			
			options.data = data;
		}
		
		if ( options.data && options.type === 'get' )
		{
			options.url += ( options.url.indexOf ( '?' ) === -1 ? '?' : '&' ) + options.data;
			options.data = null;
		}
		
		if ( typeof ( options.callbacks ) === 'function' )
		{
			options.callbacks = { onsuccess : options.callbacks };
		}
		
		var request = getAjaxSocket ( );
		request.open ( options.type , encodeURI ( options.url ) , options.async , options.username , options.password ); 
		
		request.setRequestHeader ( 'X-Requested-With' , 'XMLHttpRequest' );
		request.setRequestHeader ( 'Content-Type' , options.content );
		request.setRequestHeader ( 'Accept' , ajaxDefaultResponseTypes [ options.accept ] || options.accept );
		request.setRequestHeader ( 'Accept-Charset' , ajaxDefaultResponseCharsets [ options.charset ] || options.charset );
		
		if ( options.headers )
		{
			for ( var header in options.headers )
			{
				request.setRequestHeader( header , options.headers [ header ] );
			}
		}
		
		if ( options.async )
		{
			options.interval_id = window.setInterval ( function ( ) 
			{ 
				ajaxRequestObserver ( request , options ); 
			} , options.poll_interval );
			
			if ( options.max_execution_time )
			{
				window.setTimeout ( function ( )
				{
					request.abort ( );
					ajaxRequestObserver ( request , options );
				} , options.max_execution_time );
			}
		}
		
		request.send ( options.data );
		
		if ( ! options.async ) 
		{
			ajaxRequestObserver ( request , options ); 
		}		
		
		return request;
	};
	
	var merge = function ( source , target )
	{
		for ( var key in source )
		{
			if ( typeof ( target [ key ] ) == 'undefined' )
			{
				target [ key ] =  source [ key ];
			}
			else if ( typeof ( source [ key ] ) == 'object' && typeof ( target [ key ] ) == 'object' )
			{
				Object.merge ( source [ key ] , target [ key ] );
			}
		}
	};
	
	var ajaxRequestObserver = function ( request , options )
	{
		if ( ! options.done )
		{						
			if ( request.readyState == 4 )
			{
				options.done = true;
				
				if ( options.interval_id )
				{
					window.clearInterval ( options.interval_id );
				}
				
				if ( request.status == 200 )
				{
					onsuccess ( getAjaxResponseData ( request ) , options );
				}
				else
				{
					onfailure ( options );
				}
				
				oncomplete ( options );
			}
		}
	};
	
	var onsuccess = function ( data  , options )
	{
		if ( options.callbacks && options.callbacks.onsuccess )
		{
			options.callbacks.onsuccess ( data );
		}
	};
	
	var onfailure = function ( options )
	{
		if ( options.callbacks && options.callbacks.onfailure )
		{
			options.callbacks.onfailure ( );
		}
	};
	
	var oncomplete = function ( options )
	{
		if ( options.callbacks && options.callbacks.oncomplete )
		{
			options.callbacks.oncomplete ( );
		}
	};
	
	var getAjaxSocket = function ( )
	{
		if ( window.ActiveXObject )
		{
			if ( ! ajaxActiveXSocket )
			{
				for ( var index = 0 , socket ; socket = ajaxActiveXSockets [ index ] ; index ++ )
				{
					try
					{
						new ActiveXObject ( socket );
						ajaxActiveXSocket = socket;
					}
					catch ( e ) { }
				}
			}
			
			return new ActiveXObject ( ajaxActiveXSocket );
		}
		else
		{
			return new XMLHttpRequest ( );
		}
	};
	
	var ajaxActiveXSocket = null;
	
	var ajaxActiveXSockets = [
	 
		'Msxml2.XMLHTTP.7.0' , 
		'Msxml2.XMLHTTP.6.0' , 
		'Msxml2.XMLHTTP.5.0' , 
		'Msxml2.XMLHTTP.4.0' , 
		'MSXML2.XMLHTTP.3.0' , 
		'MSXML2.XMLHTTP' , 
		'Microsoft.XMLHTTP'
	];
	
	var ajaxDefaultSettings = {	
	
		async : true ,
		type : 'post' ,
		content : 'application/x-www-form-urlencoded' ,
		charset : 'standard' ,
		accept : 'standard' ,
		username : null ,
		password : null ,
		max_execution_time : 0 ,
		poll_interval : 10
	};
	
	var ajaxDefaultResponseTypes = 
	{
		standard : '*/*',
		xml: "application/xml , text/xml" ,
		xhtml: "application/xhtml , text/xhtml , text/html" ,
		script: "text/javascript , application/javascript" ,
		json: "application/json , text/javascript" ,
		text: "text/plain"
	};
	
	var ajaxDefaultResponseCharsets = 
	{
		standard : '*',
		utf8 : 'UTF-8' 
	};
	
	var getAjaxResponseData = function ( request )
	{
		var type = request.getResponseHeader ( 'content-type' );

		if ( type.indexOf ( 'xml' ) > -1 )
		{
			return request.responseXML;
		}
		else if ( type.indexOf ( 'json' ) > -1 )
		{
			return eval ( '(' + request.responseText + ')' );
		}
		else
		{
			return request.responseText;
		}
	};
	
})();


