/*
 * Funkcja "czy zmienna jest tablica"
 */
function is_array(input) {
    return typeof(input) == 'object' && (input instanceof Array);
}

/*
 * Klasa "Zbior funkcji z parametrami"
 * Autor: Bartlomiej Czesak
 * ver 1.0, 2008-10-31
 */
function SetOfFunctions()
{
	var set = Array();
	
	this.addFunction = function(functionName, aParams) {
		if (!aParams)
			aParams = Array();
		var singleFunction = new Object();
		singleFunction.functionName = functionName;
		singleFunction.aParams = aParams;
		set.push(singleFunction);
	}
	
	this.getSet = function() {
		return set;
	}
} // koniec SetOfFunctions()

/*
 * Klasa "Zapytanie ajax"
 * Autor: Bartlomiej Czesak
 * ver 1.0, 2008-10-31
 */
function Request(url)
{
	this.url		 = url;
	this.method		 = 'GET';
	this.postParams  = '';
	this.onSuccess   = new SetOfFunctions();
	this.onFail 	 = new SetOfFunctions();
	this.onSubmit 	 = new SetOfFunctions();
    this.header 	 = 'application/x-www-form-urlencoded';
    this.mime 		 = 'text/xml';
	
	// ustaw naglowek zapytania
	this.setHeader = function(name, mime) {
        if (name != null) 
            this.header = name;
        if (mime != null) 
            this.mime = mime;
    }
	
	// ustaw metode POST lub GET
	this.setMethod = function(method) {
		this.method = method.toUpperCase();
	}
	
	// ustaw parametry
	this.setPostParams = function(aParams) {
		if (!is_array(aParams)) {
			alert('Parametry POST powinny być tablicą!');
			return;
		}
		for (var key in aParams) {
			var key   = encodeURIComponent(key);
			var value = encodeURIComponent(aParams[key]);
			this.postParams += key + '=' + value + '&';
		}
		this.setMethod('POST');
	}	
	
	// ustaw funkcje do wykonania po udanym zapytaniu
	this.setOnSuccess = function(set) {
		this.onSuccess = set;
	}
	
	// ustaw funkcje do wykonania po nieudanym zapytaniu
	this.setOnFail = function(set) {
		this.onFail = set;
	}
	
	// ustaw funkcje do wykonania na czas zapytania
	this.setOnSubmit = function(set){
		this.onSubmit = set;
	}
} // koniec Request(url)

/*
 * Klasa "Interfejs do obslugi zapytan Ajax"
 * Autor: Bartlomiej Czesak
 * ver 1.0, 2008-10-31
 */
function Ajaxer() {
	this.ajaxNoCache = null;
	this.ajaxCache	 = null;
	this.ajaxMulti 	 = Array();	
	
	// dodaj zapytanie Ajax do wykonania
	this.addRequest = function (request, mode) {
		switch (mode) {
			case 'noCache':
				if (!this.ajaxNoCache)
					this.ajaxNoCache = new AjaxConnection();
				var state = this.ajaxNoCache.getState();
				if (state == 0 || state == 4) {
					this.ajaxNoCache.addRequest(request);
				}
				break;
			case 'cache':
				if (!this.ajaxCache)
					this.ajaxCache = new AjaxConnection();
				this.ajaxCache.addRequest(request);				
				break;
			case 'multi':
				var index = Ajaxer.ajaxMulti.push(new AjaxConnection()) - 1;
				Ajaxer.ajaxMulti[index].addRequest(request);
				delFunction = function(){
					delete Ajaxer.ajaxMulti[index];
				}
				// skasuj obiekt po zakonczeniu zapytania ajax	
				request.onSuccess.addFunction(function(){ delFunction()	}, Array());
				request.onFail.addFunction(function(){ delFunction() }, Array());
				break;	
		}
	}	
} // koniec Ajaxer()

/*
 * Klasa "Bardziej rozbudowany obiekt XMLHttpRequest"
 * Autor: Bartlomiej Czesak
 * ver 1.0, 2008-10-31
 */
function AjaxConnection() {
	this.aCache = Array();
    this.handle = null;
	
	// powinno działać dla wszystkich przeglądarek z wyjątkiem IE6 i starszych
	try
	{
		// próbuje stworzyć obiekt XMLHttpRequest
    	this.handle = new XMLHttpRequest();
  	}
  	catch(e)
  	{
    	// zakładając, że IE6 lub starsza
    	var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
           	                     	    "MSXML2.XMLHTTP.5.0",
               	                  	    "MSXML2.XMLHTTP.4.0",
                   	                	"MSXML2.XMLHTTP.3.0",
                       	            	"MSXML2.XMLHTTP",
                           	        	"Microsoft.XMLHTTP");
    	// sprawdza każdy prog id aż któryś zadziała
    	for (var i=0; i<XmlHttpVersions.length && !this.handle; i++) 
    	{
    		try 
    		{ 
     			// próbuje stworzyć obiekt XMLHttpRequest
       			this.handle = new ActiveXObject(XmlHttpVersions[i]);
    		} 
    		catch (e) {} // ignoruje potencjalne błędy
    	}
  	}
	
	if (!this.handle) {
    	alert('Błąd tworzenia obiektu XMLHttpRequest');
        return false;
    }
	
	// dodaj zapytanie Ajax do wykonania przez obiekt
	this.addRequest = function(request) {
		if (request)
		{
			this.aCache.push(request);
		}
		try
		{
			if ((this.handle.readyState == 4 || this.handle.readyState == 0) && this.aCache.length > 0)
			{
				//alert('wejscie w addrequest');
				var cacheEntry = this.aCache.shift();
				var url        = cacheEntry.url;
				var method 	   = cacheEntry.method;
				var postParams = cacheEntry.postParams;
				var onSuccess  = cacheEntry.onSuccess;
				var onFail 	   = cacheEntry.onFail;
				var onSubmit   = cacheEntry.onSubmit;
				var header     = cacheEntry.header;
				var mime       = cacheEntry.mime;
				
				if (this.handle.overrideMimeType)
            		this.handle.overrideMimeType(mime);
				
				this.handle.open(method, url, true);
				this.handle.setRequestHeader('Content-Type', header);
				var temp = this;
				this.executeFunctionSet(onSubmit);
				this.handle.onreadystatechange = function() {
            		temp.handleRequestStateChange(onSuccess, onSubmit, onFail);
        		};
				if (method != 'POST')
					postParams = '';
				this.handle.send(postParams);
			}
		}
		catch (e)
		{
			//this.executeFunctionSet(onFail);
			alert(e.toString());
			return;
		}
	
	}
	
	// wykonaj kolejno zbior funkcji
	this.executeFunctionSet = function(functionSet) {
		var functionSet  = functionSet.getSet();				
		if (is_array(functionSet)) {
			for (var i = 0; i < functionSet.length; i++) {
				if (functionSet[i].functionName != null) {
					var functions = new Function('return ' + functionSet[i].functionName);
					var result = functions();
					result.apply(this, functionSet[i].aParams);
				}
			}
		}		
	}
	
	// wykonuje kazdorazowo po zmianie statusu obslugi zapytania Ajax
	this.handleRequestStateChange = function (onSuccess, onSubmit, onFail) {
		//alert('stan: '+this.handle.readyState);	
		if (this.handle.readyState == this.lastState)
			return;
		
		switch (this.handle.readyState) {
			// zainicjowane zapytanie
			case 0:
			case 1:
			case 2:
			case 3:
				// tu nie warto nic dodawac bo w roznych przegladarkach obiekt XMLHttpRequest
				// roznie przechodzi przez stany
				break;
			// zapytanie zakonczone	
			case 4:
				// sukcesem
				if (this.handle.status == 200) {
					this.executeFunctionSet(onSuccess);
					var temp = this;
					setTimeout(function() { temp.addRequest(); }, 1000);
				// bledem
				} else {
					alert("Wystąpił błąd i operacja mogła zostać niezakończona sukcesem. \n" +
					      "Odśwież stronę i spróbuj ponownie lub skontaktuj się z administratorem strony");
					this.executeFunctionSet(onFail);
				}
				break;
		} // end switch
	}
	
	// zwroc stan obiektu
	this.getState = function() {
		return this.handle.readyState;
	}
    
	// zwroc odpowiedz XML
    this.getXML = function(){
        if (this.handle.readyState == 4) {
            return this.handle.responseXML;
        }
    }
    
	// zwroc odpowiedz HTML
    this.getHTML = function(){
        if (this.handle.readyState == 4) {
            return this.handle.responseText;
        }
    }
    
	// zwroc odpowiedz JSON
    this.getJSON = function(){
        if (this.handle.readyState == 4) {
            eval('var json=' + this.handle.responseText + ';');
            return json;
        }
    }
} //koniec AjaxConnection() 

