/// Copyright (c) 2008
/// Version 1.0 (BETA)
///
/// by João Pinho (jpe.pinho@gmail.com)
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this library and associated 
/// documentation files (the "Library"), to deal in the Library without restriction, including without limitation 
/// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the libraries, and 
/// to permit persons to whom the library is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
/// of the libraries.

/// *******************************************************************************************************************

/// SonicLib.Ajax Namespace

function AjaxManager(){ 
   this.XHR;
   this.callback;
};

AjaxManager.prototype = {

    createXhrObject: function(callbackHandler)
    {
        var xhrObject;
        var methods = [
            function() { return new XMLHttpRequest(); },
            function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
            function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
        ];

        for (var i = 0, len = methods.length; i < len; i++)
        {
            try { xhrObject = methods[i](); }
            catch (e) { continue; }

            if (navigator.userAgent.indexOf("MSIE") >= 0)
            {
                xhrObject.onreadystatechange = callbackHandler.bind(this);
            }
            else if (navigator.userAgent.indexOf("Mozilla") >= 0)
            {
                xhrObject.onload = callbackHandler.bind(this);
                xhrObject.onerror = callbackHandler.bind(this);
            }

            return xhrObject;
        }

        throw new Error("Ajax Manager: Não conseguiu criar o objecto XHR");
    },

    execute: function(uri, callback, sendMethod, async)
    {
        var postVars = null;
        this.callback = callback;
        this.XHR = this.createXhrObject(this.processResult);

        if (this.XHR != null)
        {
            document.body.style.cursor = "wait";
            this.XHR.open(sendMethod, uri, async);

            if (sendMethod.toUpperCase() == "POST")
            {
                postVars = uri.split("?")[1];
                this.XHR.setRequestHeader("Method", "POST " + uri + " /HTML 1.1");
                this.XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            }
            this.XHR.send(postVars);
        }
    },

    processResult: function()
    {
        if (this.XHR.readyState == 4)
        {
            if (this.XHR.status === 200)
            {
                document.body.style.cursor = "default";
                this.callback.success(this.XHR.responseText, this.XHR.responseXML);
            }
            else
            {
                this.callback.failure(this.XHR.status);
            }
        }
    },

    createCallback: function()
    {
        var callback = function() { };
        callback.prototype = {
            success: function() { },
            failure: function() { }
        };
        return callback
    }
};

// This two functions here are just for precaution
// case the prototype framework is to loaded together with this
// file.

Function.prototype.bind = function(obj) {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.clone) {
    return iterable.clone();
  } else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}
