var KNOWN_HTTP_METHODS = [ "GET", "POST", "PUT", "HEAD", "PROPFIND" ];


/*
 * Executes a *synchronic* HTTP request.
 *
 * @param url    URL to send the request to (may contain arguments)
 *               -= Note: encodeURI() will be applied to it =-
 * @param method HTTP method to use (GET, POST, HEAD, etc)
 * @param body   for POST requests: request body to add (should be undefined
 *               for all other requests),
 *               -= Note: if defined - encodeURIComponent() will be applied to it =-
 * @return       HTTP response as plain text if response code was 200
 * @throws Error if response code wasn't 200
 */
function httpRequest ( url, method, body ) 
{
	
    verifyType( url,    "string", "httpRequest(): url" );
    verifyType( method, "string", "httpRequest(): method" );
	
    verifyHttpMethod( url, method );
    verifyRequestBody( url, method, body );

    var requester = getHttpRequester();
    var response;

    requester.onreadystatechange = function () {

        var state = requester.readyState;
       verifyTrue((( state >= 0 ) && ( state <= 4 )),
                   "httpRequest(): state is [" + state + "] (should be in [0..4] range)" );

        if ( state == 4 ) {
            response = requester;
			
			//response = requester.responseText;
            if ( requester.status != 200 ) {
               /* error( "Failed to successfully send an HTTP request:\n" +
                       "URL = [" + url + "]\n" +
                       "method = [" + method + "]\n" +
                       "response status = [" + requester.status + "]\n" +
                       "response = [" + response + "]" );*/
            }
        }
    }

    requester.open( method, encodeURI( url ), false ); // Note the synchronous call
    if ( isNullOrUndefined( body )) requester.send();
    else                            requester.send( encodeURIComponent( body ));

    verifyNotNullOrUndefined( response, "httpRequest(): response" );
    return response;
}


/**
 * Verifies that method specified is a known HTTP method
 */
function verifyHttpMethod ( url, method ) {

    verifyType( url,    "string", "verifyHttpMethod(): url" );
    verifyType( method, "string", "verifyHttpMethod(): method" );

    for ( var j = 0; j < KNOWN_HTTP_METHODS.length; j++ ) {
        if ( method.toUpperCase() == KNOWN_HTTP_METHODS[ j ] ) {
            return;
        }
    }

    f_showMsg( "Unknown HTTP method [" + method + "]\n" +
           "(url = [" + url + "], method = [" + method + "])" );
}


/**
 * Verifies that 'body' is defined if method is "POST".
 */
function verifyRequestBody ( url, method, body ) {

    verifyType( url,    "string", "verifyRequestBody(): url" );
    verifyType( method, "string", "verifyRequestBody(): method" );

    if ( method.toUpperCase() == "POST" ) {
        verifyType( body, "string",
                    "verifyRequestBody(): POST request - body is undefined or not a string\n" +
                    "(url = [" + url + "], method = [" + method + "], body = [" + body + "])" );
    }
    else if ( notNullOrUndefined( body )) {
        error( "'body' argument is ignored for non-POST requests\n" +
               "(url = [" + url + "], method = [" + method + "], body = [" + body + "])" );
    }
}

/**
 * Sends a POST HTTP request to the URL specified.
 *
 * @param url  URL to send the request to
 * @param data request body to send
 * @return HTTP response as plain text if response code was 200
 * @throws Error if response code wasn't 200
 */
function postHttpRequest ( url, data ) {

    verifyType( url,  "string", "postHttpRequest(): url" );
    verifyType( data, "string", "postHttpRequest(): data" );

    var response = httpRequest( url, "POST", data );
    return response;
}



/**
 * Retrieves an HTTP "requester" object
 * @return HTTP "requester" object
 *
 * See the following URLs for creation strategies:
 * - http://www.mozilla.org/xmlextras/
 * - http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/63409298-0516-437d-b5af-68368157eae3.asp
 */
function getHttpRequester() {

    var requester;

    try {
        requester = new XMLHttpRequest()
    }
    catch ( e ) {
        try {
            requester = new ActiveXObject( "MSXML2.XMLHTTP.3.0" );
        }
        catch ( e ) {
            error( "All attempts to create an XMLHttpRequest object failed" );
        }
    }
	
    verifyNotNullOrUndefined( requester, "getHttpRequester(): requester" );
    return requester;
}

