var AJAX = function(){
    function getHttpRequest() {
        var httpRequest = false;
        /*@cc_on @*/
        /*@if (@_jscript_version >= 5)
        // JScript gives us Conditional compilation, we can cope with old IE versions.
        // and security blocked creation of the objects.
        try {
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (E) {
                httpRequest = false;
            }
        }
        @end @*/
        if (!httpRequest && typeof(XMLHttpRequest) !== 'undefined') {
            httpRequest = new XMLHttpRequest();
        }
        return httpRequest;
    }

    function request(method, url, async, data, handle) {
        if (typeof(async) == 'undefined') {
            async = false;
        }
        if (typeof(data) == 'undefined') {
            data = null;
        }
        var httpRequest = getHttpRequest();
        httpRequest.open(method, url, async);
        if (method === "POST") {
            httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            httpRequest.setRequestHeader("Content-length", data !== null ? data.length : 0);
            httpRequest.setRequestHeader("Connection", "close");
        }
        if (async && handle !== null && typeof(handle) !== 'undefined') {
            httpRequest.onreadystatechange = function() {
                if (httpRequest.readyState === 4) {
                    if (httpRequest.responseText !== '') {
                        var response = httpRequest.responseText;
                        handle(response);
                    }
                }
            };
        }
        httpRequest.send(data);
        if (!async) {
            var response = null;
            if (httpRequest.responseText !== '') {
                response = httpRequest.responseText;
            }
            if (handle !== null && typeof(handle) !== 'undefined') {
                handle(response);
            }
            return response;
        }
    }

    function encodeQueryUrl(url, queryMap) {
        if (queryMap === null || typeof(queryMap) === 'undefined') {
            return url;
        }
        var query = '';
        for(var field in queryMap) {
            if (query !== '') {
                query += '&';
            }
            query += field + '=' + encodeURIComponent(queryMap[field]);
        }
        if (query !== '') {
            url = url + '?' + query;
        }
        return url;
    }

    function encodePostData(parameters) {
        var request = '';
        for(var field in parameters) {
            if (request !== '') {
                request += '&';
            }
            request += field + '=' + encodeURIComponent(parameters[field]);
        }
        return request;
    }

    function parseJSON(json) {
        if (json === '') {
            return {};
        }
        return eval('(' + json + ')');
    }

    function createJSONHandler(handle) {
        if (handle) {
            return function(response) {
                handle(parseJSON(response));
            };
        }
        return null;
    }

    return {
        get: function(url, parameters, async, handle) {
            var queryUrl = encodeQueryUrl(url, parameters);
            return request("GET", queryUrl, async, null, handle);
        },

        post: function(url, parameters, async, handle) {
            var postData = encodePostData(parameters);
            return request("POST", url, async, postData, handle);
        },

        getJSON: function(url, parameters, async, handle) {
            var response = this.get(url, parameters, async, createJSONHandler(handle));
            return parseJSON(response);
        },

        postJSON: function(url, parameters, async, handle) {
            var response = this.post(url, parameters, async, createJSONHandler(handle));
            return parseJSON(response);
        }
    };
}();

