/**
* EfocusAjax,js 
* Object en functies om eenvoudig json-gecodeerde ajax-aanroepen te verzorgen
* @author Erik Winter <erik@efocus.nl>
*
* Zie voor meer informatie: http://devnet.efocus.nl/article/62
*
* 29 juni 2006, Erik:
* Standaardobjecten uitbreiden met eigen functies is toch niet zo gewenst, vandaarde json-methodes nu afgehandeld worden in een eigen object
*
*/


/**
* Ajax-object constructor
* Deze wrapper om xmlhttprequest geeft de mogelijkheid om synchrone en asynchrone http-requests te doen
* Met als toevoeging automatische JSON-encoding
* @author Erik Winter <erik@efocus.nl>
*
* @param serverUrl String (Optioneel)
* @return void
*/


function EfocusAjax(serverUrl) {

	// variabelen initialiseren
	this.xmlHttpReq = false;
	this.serverUrl = (serverUrl) ? serverUrl : '';
	this.isAsynchroon = false;
	this.actie = '';
	this.actieParameter = false;
	this.vervolgActie = false;
	this.vervolgParameter = false;
	this.formulierMethode = 'POST';
}

/**
* Zet eventueel een nieuwe serverUrl
* @author Erik Winter <erik@efocus.nl>
*
* @param serverUrl String
* @return void
*/
EfocusAjax.prototype.zetServerUrl = function(serverUrl) {
	this.serverUrl = serverUrl;
}

/**
* Geef aan of data geGet of gePOST moet worden (default is POST)
* @author Erik Winter <erik@efocus.nl>
*
* @param formulierMethode String
* @return void
*/
EfocusAjax.prototype.zetFormulierMethode = function(formulierMethode) {
	if(formulierMethode != 'GET' && formulierMethode != 'POST') {
		alert('Ajax.zetFormulierMethode: formuliermethode moet "GET" of "POST" zijn')
	}
	
	this.formulierMethode = formulierMethode;
}

/**
* Zet de verstuurmethode op asynchroon of synchroon (default is synchroon)
* In het geval van asynchroon moet de naam worden opgegeven van de functie die het resultaat gaat verwerken
* Eventueel kunnen aan die functie extra parameters worden opgegeven
* @author Erik Winter <erik@efocus.nl>
*
* @param isAsynchroon Boolean
* @param vervolgActie String (Optioneel)
* @param vervolgParameter Object (Optioneel)
* @return void
*/
EfocusAjax.prototype.zetAsynchroon = function(isAsynchroon, vervolgActie, vervolgParameter) {

	if(isAsynchroon && !vervolgActie) {
		alert('Ajax.zetSynchroon: Bij asynchrone acties is een vervolgfunctie verplicht.');
		return;
	}
	
	this.isAsynchroon = isAsynchroon;
	this.vervolgActie = vervolgActie;
	this.vervolgParameter = vervolgParameter;
}

/**
* Zet de actie die op de server uitgevoerd moet worden bij het request
* Geef eventueel functieparameters voor die actie mee
* @author Erik Winter <erik@efocus.nl>
*
* @param actie String
* @param actieParameter Object (Optioneel)
* @return void
*/
EfocusAjax.prototype.zetActie = function(actie, actieParameter) {
	this.actie = actie;
	this.actieParameter = actieParameter;
}

/**
* Voer het eerder gespecificeerde request uit en onderneem eventueel vervolgacties
* @author Erik Winter <erik@efocus.nl>
*
* @param void
* @return void
*/
EfocusAjax.prototype.doeRequest = function() {

	// controleren of alles ingevuld is
	if(this.serverUrl == '') {
		alert('Ajax.doeRequest: geen serverUrl ingevuld.');
		return;
	}
	if(this.actie == '') {
		alert('Ajax.doeRequest: geen actie ingevuld.');
		return;
	}	

	// bouwen request-object
	if(window.XMLHttpRequest)		// Mozilla/Safari/Opera
		var xmlHttpReq = new XMLHttpRequest();
	else if(window.ActiveXObject)	// IE
		var xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");

	if(!xmlHttpReq)	{
		alert('Ajax: geen xmlHttpRequest');
		return;
	}

//var jsObj = jsonStr);
//	var jsonStr = JSON.stringify(jsObj);

	// voer request uit
	xmlHttpReq.open(this.formulierMethode, this.serverUrl, this.isAsynchroon);
	xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	xmlHttpReq.send('actie='+this.actie+((this.actieParameter) ? '&actieParameter='+JSON.stringify(this.actieParameter) : ''));

	// stuur resultaat naar gewenste plek
	if(this.isAsynchroon) {
		var vervolgActie = this.vervolgActie;	// "this" verwijst in de volgende functie naar iets anders dan dit object, dus stoppen we de benodigde parameters even in lokale variabelen
		var vervolgParameter = this.vervolgParameter;
		xmlHttpReq.onreadystatechange = function () {			
			if(xmlHttpReq.readyState == 4) {
				var antwoord = JSON.parse(xmlHttpReq.responseText);
				eval(vervolgActie+'(antwoord'+((vervolgParameter) ? ', vervolgParameter' : '')+')');
			}
		}
	}
	else {
		return JSON.parse(xmlHttpReq.responseText);
	}
}


/*
Parse en stringify van en naar json
Oorspronkelijk script: http://www.json.org/js.html

Aanpassingen op aanwijzing van: http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/f0bbf5188b8fe9b8/4f495096154d04c5?lnk=st&q=javascript+f+%3D+s%5Btypeof+v%5D%3B&rnum=1&hl=en#4f495096154d04c5

    json.js (modified 2006-05-02)

	USAGE:
	var jsObj = JSON.parse(jsonStr);
	var jsonStr = JSON.stringify(jsObj);
*/
var JSON = (function () {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            array: function (x) {
                var a = ['['], b, f, i, l = x.length, v;
                for (i = 0; i < l; i += 1) {
                    v = x[i];
                    f = s[typeof v];
                    if (f) {
                        v = f(v);
                        if (typeof v == 'string') {
                            if (b) {
                                a[a.length] = ',';
                            }
                            a[a.length] = v;
                            b = true;
                        }
                    }
                }
                a[a.length] = ']';
                return a.join('');
            },
            'boolean': function (x) {
                return String(x);
            },
            'null': function (x) {
                return "null";
            },
            number: function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            object: function (x) {
                if (x) {
                    if (x instanceof Array) {
                        return s.array(x);
                    }
                    var a = ['{'], b, f, i, v;
                    for (i in x) {
                        v = x[i];
                        f = s[typeof v];
                        if (f) {
                            v = f(v);
                            if (typeof v == 'string') {
                                if (b) {
                                    a[a.length] = ',';
                                }
                                a.push(s.string(i), ':', v);
                                b = true;
                            }
                        }
                    }
                    a[a.length] = '}';
                    return a.join('');
                }
                return 'null';
            },
            string: function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            }
        };

    /*Object.prototype.toJSONString = function () {
        return s.object(this);
    };

    Array.prototype.toJSONString = function () {
        return s.array(this);
    };*/
	
	return {
		parse: function(s) {
			try {
				return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
					s.replace(/"(\\.|[^"\\])*"/g, ''))) &&
					eval('(' + s + ')');
			} catch (e) {
			alert(e);
				return false;
			}
		},
		stringify: s.object
	};
})();

/*String.prototype.parseJSON = function () {
    try {
        return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
            eval('(' + this + ')');
    } catch (e) {
        return false;
    }
};*/