// Live offers AJAX methods
var Live =
{   
  IE: (navigator.appName == "Microsoft Internet Explorer"),
  
  // api for xhr gets
  get: function(url, handler, tId)
  {
    if (!handler)
      handler = Live.scatter;
    Live.httpRequest(url, "GET", handler, tId?document.getElementById(tId.replace(/^#/,"")):0);
  },
  // generic xhr call
  httpRequest: function(url, httpMethod, handler, targetEl)
  {
    // generate the xhr and set the readystatechange handler
    var xhr = Live.IE? new ActiveXObject("Microsoft.XmlHttp") : new XMLHttpRequest();
    url += (url.indexOf("?")==-1?"?":"&") + "livetime=" + new Date() * 1;
    xhr.open(httpMethod, url, true);
    xhr.onreadystatechange = function()
    {
      if (xhr.readyState == 4)
        handler(xhr, targetEl);
    }
    xhr.send(null);
  },
  // filters script and executes it after scattering one or elements in xhr's contents
  scatter: function(xhr, targetEl)
  {     
    var script = "", 
        els = [],
        html = xhr.responseText.replace(/<script[^>]*?>(.*?)<\/script>/gi, 
               function(a,b,c){script+=b; return "";}),    
        temp = document.createElement("div");
    
    temp.innerHTML = html;
    for (var i=0, l=temp.childNodes.length; i<l; i++)
      els.push(temp.childNodes[i]);
    for (i=0; i<l; i++)
    {
      var child = els[i];
      if (child.nodeType == 1)
      {
        if (!(targetEl && l == 1))
          targetEl = document.getElementById(child.id);
        if (targetEl)
          Live.replaceElement(targetEl, child);
      }
    }
    eval(script);
  },  
  // replaces one element with the other
  replaceElement: function(el, newEl)
  {
    el.style.display = "none";
    el.parentNode.insertBefore(newEl, el);
    el.parentNode.removeChild(el);
  },
  // retrieve a Live.Form object by id or by element
  form: function(idOrElement)
  {
    var formEl = idOrElement;
    if (typeof(idOrElement) == "string")
      formEl = document.getElementById(formEl);
    return new Live.Form(formEl);
  }
};

// The form object has a submit method to submit by xmlhttp
Live.Form = function(formEl)
{
  this.formEl = formEl;
}
Live.Form.prototype =
{
  // optionally pass a handler for the resyStateChange event. 
  // Its only argument is the Live.Form instance, which exposes the xhr and formEl.
  submit: function(h)
  {
    h = h? h : this.defaultResponseHandler;
    var xhr = Live.IE? new ActiveXObject("Microsoft.XmlHttp") : new XMLHttpRequest();
    var ps = this.getParameterString();
    var attrs = this.formEl.attributes;
    var method = attrs.method.nodeValue;
    var url = attrs.action.nodeValue;
    url += (url.indexOf("?")==-1?"?":"&") + "livetime=" + new Date() * 1;
    xhr.open(method, url, true);
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.setRequestHeader("Content-length", ps.length);
    xhr.onreadystatechange = function() { h(xhr); };
    xhr.send(ps);
  },
  // builds up the parameterstring from the form elements
  getParameterString: function()
  {
    var ps = "";
    for (var i=0, el; el = this.formEl.elements[i++];)
    {
      if (!el.name)
        continue;
      var name = el.name;
      var value = escape(el.value);
      switch(true)
      {
        case el.type == "submit" && !el.clicked:
          el.clicked = undefined;
        case el.type == "radio" && !el.checked:
        case el.type == "checkbox" && !el.checked:
          continue;
        case el.type == "submit":
          el.clicked = undefined;
        default:
          ps += ((ps == "")? "" : "&") + name + "=" + value;
      }  
    }
    return ps;
  },
  // the default handler for the readyStateChange event
  defaultResponseHandler: function(xhr)
  {
    if (xhr.readyState == 4)
      Live.scatter(xhr);
  }
};
