/* $Id: ajax.js,v 1.1 2007/09/28 20:08:34 cvsuser Exp $
 * ---------------------------------------------------------------------
 * An XMLHttpRequest wrapper for running Gyrobase macros.
 * ---------------------------------------------------------------------
 */

// ---------------------------------------------------------------------
// document.getElementById() shortcut from the Prototype library

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1) 
      return element;

    elements.push(element);
  }

  return elements;
}

// ---------------------------------------------------------------------
// Make sure arrays support push().

if (!Array.prototype.push) {
    Array.prototype.push = function (obj) {
        this[this.length] = obj;
    }
}

// ---------------------------------------------------------------------
// Method to test if XMLHttpRequest object is supported
function gyrobaseAjaxIsSupported () {
    if (window.XMLHttpRequest) return true;

    if (window.ActiveXObject && navigator.platform != 'MacPPC') {
        if (new ActiveXObject("Msxml2.XMLHTTP")) return true;
        if (new ActiveXObject("Microsoft.XMLHTTP")) return true;
    }

    return false;
}

// ---------------------------------------------------------------------
// GyrobaseAjaxLibrary Constructor
function GyrobaseAjaxLibrary (template, username, password, url) {
    if (!template) throw "Missing template parameter for GyrobaseAjaxLibrary().";

    this.template = template;
    this.username = username;
    this.password = password;
    this.url = url ? url : "/gyrobase/tools/ajax/run-macro.html";

    this.requests = new Array();
}

// ---------------------------------------------------------------------
// runMacro()
GyrobaseAjaxLibrary.prototype.runMacro = function (macro, params, callback) {
    if (!macro) throw "No macro specifed!";
    if (params && typeof(params) != "object") throw "The macro's parameters must be specified as an object (hash).";
    if (callback && typeof(callback) != "function") throw "The 'callback' parameter must be a function reference.";

    // Create a new XMLHttpRequest object.
    var req = false;
    if (window.XMLHttpRequest) {
        try { req = new XMLHttpRequest(); }
        catch (e) { req = false; }
    }
    else if (window.ActiveXObject) {
        try { req = new ActiveXObject("Msxml2.XMLHTTP"); }
        catch (e) {
            try { req = new ActiveXObject("Microsoft.XMLHTTP"); }
            catch (e) { throw "Failed to create XMLHTTPRequest object!"; }
        }
    }

    // It would be nice if these next two lines could be atomic. Oh well,
    // just cross your fingers.
    this.requests.push(req);
    var reqNum = this.requests.length - 1;

    // Set up the POST query string.
    var q = "__t="+escape(this.template)+"&";
    q += "__m="+encodeURIComponent(macro)+"&";
    if (this.username) q += "__u="+encodeURIComponent(this.username)+"&";
    if (this.password) q += "__p="+encodeURIComponent(this.password)+"&";
    for (var i in params) {
        q += encodeURIComponent(i)+"="+encodeURIComponent(params[i])+"&";
    }

    // Set up the callback. Yay for javascript closures!
    var me = this;
    var callbackClosure = function () {
        if (req.readyState == 4) {
            if (req.status == 200) {
                eval("var _response = " + req.responseText + ";");
                if (_response.gyrobaseAjaxResponseHeader.error)
                    throw _response.gyrobaseAjaxResponseHeader.error;
                if (callback) callback(_response.gyrobaseAjaxResult);
            }
            else {
                throw "Error executing macro: " + req.statusText;
            }

            // Remove request reference so it can be garbage collected.
            me.requests[reqNum] = null;

            // Break circular references for IE's crappy garbage collector.
            delete req.onreadystatechange;
            req = null;
        }
    };

    // Do the request!
    req.onreadystatechange = callbackClosure;
    req.open("POST", this.url, true);
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send(q);
}

// ---------------------------------------------------------------------
