/* ********************* */
if(!window.AddNamespace) {
	window.AddNamespace = function( ns ) 	{
		var nsParts = ns.split(".");
		var root = window;
		for( var i = 0; i < nsParts.length; i++ ) 		{
			if( typeof root[ nsParts[ i ] ] == 'undefined' ) {
				root[ nsParts[ i ] ] = new Object();
			}
			root = root[ nsParts[ i ] ];
		}
	}
}

// JavaScript objects wrappers
JSONObject = function( obj ) {
	this.obj = obj;
	this.toJSON = function() {
		if ( this.obj == null ) {
			return 'null';
		}
	//	debugger
		switch(this.obj.constructor) {
			case Array: return ArrayToJSON( this.obj ); break;
			case String: return StringToJSON( this.obj ); break;
			case Date: return DateToJSON( this.obj ); break;
			case Object: return ObjectToJSON( this.obj ); break;
			case Number:
			case Boolean: return String( this.obj ); break;
		}
	}
	
	function ObjectToJSON( obj ) {
		var v=[];
		for( attr in obj ) 	{
			if( typeof obj[ attr ] != "function" ) {
				var attribute = new JSONObject( obj[attr] );
				v.push('"' + attr + '": ' + ( obj[attr] != null ? attribute.toJSON() : 'null' ) );
			}
		}
		if( v.length > 0 ) {
			return "{" + v.join(", ") + "}";
		} else {
			return "{}";
		}
	
	}
	
	function StringToJSON( obj ) {
		var s = obj; // .encodeURI();
		s = '"' + s.replace(/(["\\])/g, '\\$1') + '"';
		s = s.replace(/\n/g,"\\n");
		s = s.replace(/\r/g,"\\r");
		s = s.replace(/\t/g,"\\t");
		return s;	
	}
	
	function DateToJSON( obj ) {
		var o = new Object();
		o.__type = "System.DateTime";
		o.Year = obj.getUTCFullYear();
		o.Month = obj.getUTCMonth() + 1;
		o.Day = obj.getUTCDate();
		o.Hour = obj.getUTCHours();
		o.Minute = obj.getUTCMinutes();
		o.Second = obj.getUTCSeconds();
		o.Millisecond = obj.getUTCMilliseconds();
		o.TimezoneOffset = obj.getTimezoneOffset();
		return new JSONObject( o ).toJSON();
	}
	
	function ArrayToJSON( obj ) {
		var v = [];

		for( var i = 0; i < obj.length; i++ ) {
			var elem = new JSONObject( obj[ i ] );
			v[v.length] = obj[ i ] != null ? elem.toJSON() : 'null';
		}
		return "[" + v.join(", ") + "]";
	}
}


JSONArray = function() {
	this.inherits = Array;
	this.inherits();
	
	this.push = function( o ) 	{
		this[ this.length ] = o;
	}
	
	this.getLast = function() 	{
		if( this.length == 0 ) {
			return null;
		}
		return this[ this.length -1 ];
	}
	
	this.getFirst = function() {
		if( this.length == 0 ) {
			return null;
		}
		return this[ 0 ];
	}
}


// .NET wrapper objects
AddNamespace( "System.Data" );

System.Data.DataSet = function( name ) {
	this.__type = "System.Data.DataSet, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
	this.Name = name != null ? name : "";
	this.Tables = [];
}

System.Data.DataTable = function( name ) {
	this.__type = "System.Data.DataTable, System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
	this.Name = name != null ? name : "";
	this.Columns = [];
	this.Rows = [];
	
	this.addColumn = function( name, type ) {
		var c = new Object();
		c.Name = name;
		c.__type = type;
		this.Columns.push( c );
	}
}

// Browser related members
AddNamespace("MS.Browser" );

MS.Browser.isIE = (window.navigator.appName.toLowerCase().indexOf('explorer') != -1 || window.navigator.appName.toLowerCase().indexOf('msie') != -1 );

// Debug
AddNamespace( "MS.Debug" );

MS.Debug.enabled = false;
MS.Debug.trace = function(s) {}

AddNamespace( "SNAJAX" );

var ___tracerAvailable = -1;
SNAJAX.Trace = function( msg ) { return; } 
SNAJAX.LastRequestID = 0;

SNAJAX.NewRequestID = function() {
	return ++SNAJAX.LastRequestID;
}

SNAJAX.RequestCache = new Array();
SNAJAX.GetXmlRequestObject = function () {
	var xml = null
	var len = SNAJAX.RequestCache.length;
	for( var i = 0; i < len; i++ ) {
		if ( SNAJAX.RequestCache[i].readyState == 4 ) {
			SNAJAX.RequestCache[i].abort();
			SNAJAX.Trace( "SNAJAX RequestCache: Hit" );
			return SNAJAX.RequestCache[i];
		}
	}	
	
	if( ! window.XMLHttpRequest ) {
		try { 
			xml = new ActiveXObject( "Msxml2.XMLHTTP.4.0" ); 
		} catch( ex ) { xml = null; }
		try { 
			xml = new ActiveXObject( "MSXML2.XMLHTTP" ); 
		} catch( ex ){ xml = null; }
		try { 
			xml = new ActiveXObject( "Microsoft.XMLHTTP" ); 
		} catch( ex ){ xml = null; }
	} else {
		xml = new XMLHttpRequest();
	}
	
	if ( xml == null ) {
		alert("Fatal ERROR: Could not initialise an XMLHttpReuqest object");
		return
	}
	SNAJAX.RequestCache[SNAJAX.RequestCache.length] = xml;
	SNAJAX.Trace( "SNAJAX RequestCache: Created new request object" );
	SNAJAX.Trace( "SNAJAX RequestCache: Using " + SNAJAX.RequestCache.length + " requests" );
	return xml;
}

SNAJAX.PendingRequestCount = 0;
SNAJAX.RequestStarted = function() {
	SNAJAX.PendingRequestCount++;
	SNAJAX.CheckLoading();
}
SNAJAX.RequestFinished = function() {
	SNAJAX.PendingRequestCount--;
	SNAJAX.CheckLoading();
}
SNAJAX.CheckLoading = function() {
	if ( SNAJAX.PendingReuqestCount > 0 ) {
		if ( typeof( SNAJAX.ShowLoading ) == 'function' ) {
			SNAJAX.ShowLoading();
		}
	} else {
		if ( typeof( SNAJAX.HideLoading ) == 'function' ) {
			SNAJAX.HideLoading();
		}
	}
}
SNAJAX.ShowLoading = null;
SNAJAX.HideLoading = null;

SNAJAX.NoOperation = function() {}
SNAJAX.cryptProvider = null;
SNAJAX.token = "";
SNAJAX.Invoke = function( m, args, c, url ) {
	var xml = SNAJAX.GetXmlRequestObject(); //new XMLHttpRequest();
	var requestData = new Object();
	requestData.method = m;
	requestData.args = args;
	requestData.callback = c[ 1 ].length > c[ 0 ] ? c[ 1 ][ c[ 0 ] ] : SNAJAX.NoOperation;
	requestData.context = c[ 1 ].length > c[ 0 ] + 1 ? c[ 1 ][ c[ 0 ]+1 ] : null;
	requestData.session = c[ 2 ];
	var data = "";
	var async = typeof requestData.callback == "function" && requestData.callback != SNAJAX.NoOperation;
	var requestID = SNAJAX.NewRequestID();

	SNAJAX.Trace( "SNAJAX Request: " + requestID + " Invoke" );
		
	for( attr in requestData.args )	{
		if( typeof requestData.args[ attr ] != "function") {
			var attribute = new JSONObject( requestData.args[attr] );
			data += attr + "=" + (requestData.args[attr] != null ? attribute.toJSON() : 'null') + "\r\n";
		}
	}

	if( MS.Debug.enabled ) {
		MS.Debug.trace( "JSON string: " + data );
	}
	
	if( async ) {
		xml.onreadystatechange = stateChanged;
	}
	var dataLength = 0;
	if( data.length != 0 ) {
		dataLength = data.length;
	} else {
		data = new Date().getTime();
		dataLength = String( new Date().getTime() ).length;
	}
	
	xml.open( "POST", url, async );
	xml.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
	xml.setRequestHeader( "Content-length", dataLength );
	xml.setRequestHeader( "Ajax-method", requestData.method );
	xml.setRequestHeader( "Ajax-session", requestData.session );
	// xml.setRequestHeader( "Ajax-token", SNAJAX.token );
	
	if( MS.Browser.isIE ) {
		xml.setRequestHeader( "Accept-Encoding", "gzip, deflate" );
	} else {
		xml.setRequestHeader( "Connection", "close" );		// Mozilla Bug #246651
	}
	
	if( SNAJAX.cryptProvider != null ) {
		data = SNAJAX.cryptProvider.encrypt( data );
	}
	if( MS.Debug.enabled ) {
		MS.Debug.trace( "XMLHttpRequest: " + url + "\r\n  Method: " + requestData.method + "\r\n  Data: " + data );
	}
	SNAJAX.RequestStarted();

	try{
	    xml.send( data );
	    if(!async) {
		    return createResponse();
	    }
    } catch(e){
	    if( MS.Debug.enabled ) {
		    MS.Debug.trace("Send errored.");
	    }
    }
	return true;	
		
		
	function stateChanged() {
	    if(typeof(SNAJAX)=='undefined') return;
	    if(!xml){
	        SNAJAX.RequestFinished();
	        return;
        }	            

		// SNAJAX.Trace( "SNAJAX.Invoke: stateChanged()" );
		/*
		if ( xml.readyState == 1 ) { req.onLoadingInternal(req); }
		if ( xml.readyState == 2 ) { req.onLoadedInternal(req); }
		if ( xml.readyState == 3 ) { req.onInteractiveInternal(req); }
		*/
		if ( xml.readyState == 4 ) { doCallback(); }
	}	
		
	function doCallback() {
	    if(typeof(SNAJAX)=='undefined') return;
		SNAJAX.Trace( "SNAJAX Request: " + requestID + " doCallback()" );
		
		if( xml.readyState != 4 ) {
			return;
		}

		if(typeof(xml.status) == 'undefined') {
			alert('xml.status == undefined');
			return;
		}
		
		if(xml.status == 200) {
			requestData.callback( createResponse() );
		}
		xml=null; //TV-25.01.2006
	}
	
	function OnTimeout() {
	    if(typeof(SNAJAX)=='undefined') return;
		SNAJAX.Trace( "SNAJAX.Invoke: OnTimeout()" );
		if ( typeof( SNAJAX.TimeOut ) == 'function' ) {
			SNAJAX.TimeOut();
		}
	}
	
	function createResponse() {
		var responseData = new Object();
		responseData.url = url;
		responseData.error = null;
		responseData.request = requestData;
		responseData.value = null;
		responseData.responseText = xml.responseText;

		if( MS.Debug.enabled ) {
			MS.Debug.trace( "XMLHttpResponse: " + url + "\r\n  Method: " + requestData.method + "\r\n  Response: " + responseData.responseText );
		}
		if( SNAJAX.cryptProvider != null ) {
			responseData.responseText = SNAJAX.cryptProvider.decrypt( responseData.responseText );
		}
		if( MS.Debug.enabled ) {
			MS.Debug.trace( "JSON string: " + responseData.responseText );
		}
		
		//alert( responseData.responseText );
		try{
		    eval( "responseData.value = " + responseData.responseText + ";" );
		}catch(e){
		    //TODO:
		}
		
		SNAJAX.RequestFinished();
		return responseData;
	}
}
