if (typeof(rating) != "object") {
var rating = new Object();

// We use this to avoid the GC from collecting objects from loadXml before
// they have actually loaded their documents and processed them:

rating.requests = new Array();

rating.loadXmlDone = function (xmlDoc, process)
{
  if (xmlDoc.readyState == 4) { // if "loaded"
    if (xmlDoc.status == 200) { // if "OK"
      process(xmlDoc.responseXML); // pass DOM
    } else if (xmlDoc.status >= 400) {
      alert("There was a problem (status = "+xmlDoc.status+")\nretrieving the XML data:\n" + xmlDoc.statusText);
    }
    rating.removeRequest(xmlDoc);
  }
}

rating.loadXml = function (href, process)
{
  var xmlDoc;
  var registerstatechange = true;

  if (window.XMLHttpRequest && !(window.ActiveXObject)) {
    try {
      xmlDoc = new XMLHttpRequest();
      xmlDoc.onreadystatechange = function () { rating.loadXmlDone(xmlDoc, process); };
      xmlDoc.open("GET", href, true);
      xmlDoc.send("");
    }
    catch(e) {
      xmlDoc = false;
    }
  }

  if (!xmlDoc && document.implementation && document.implementation.createDocument) {
    xmlDoc = document.implementation.createDocument("", "", null);
    xmlDoc.onload = function () { rating.removeRequest(xmlDoc); process(xmlDoc) };
    xmlDoc.load(href);
  }

  if (!xmlDoc && window.ActiveXObject) {
    try {
      xmlDoc = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e) {
      try {
        xmlDoc = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch(e) {
        xmlDoc = false;
      }
    }
    if (xmlDoc) {
      xmlDoc.onreadystatechange = function() { rating.loadXmlDone(xmlDoc, process); }
      xmlDoc.load(href);
    }
  }

  if (!xmlDoc) {
    alert('Your browser can\'t handle this script');
    return;
  }

  rating.requests.push(xmlDoc);
}

rating.removeRequest = function (element)
{
  var rd, wr;
  for (rd = 0, wr = 0; rd < rating.requests.length; rd ++)
    if (rating.requests[rd] != element)
      rating.requests[wr ++] = rating.requests[rd];
  while (wr < rating.requests.len)
    rating.requests.pop();
}

rating.cleanContent = function (element)
{
  while (element.hasChildNodes())
    element.removeChild(element.firstChild);
}

rating.makeLink = function ( target, content )
{
  var link = makeElement('A', content);
  link.setAttribute('href', target);
  return link;
}

rating.makeElement = function (type, content)
{
  var elem = document.createElement(type);
  if (content)
    elem.appendChild(content);
  return elem;
}

rating.vote = function ( direction, file, id ) {
  var content = document.getElementById(id);
  rating.cleanContent(content);
  content.appendChild(rating.makeElement('i', document.createTextNode("Updating...")));
  rating.loadXml(rating.url + file + "?action=extension&extension=rating&vote=" + direction, function (x) { rating.updateStats(x, id); });
}

rating.updateStats = function ( xmlDoc, id ) {
  var content = document.getElementById(id);
  rating.cleanContent(content);
  var data = xmlDoc.getElementsByTagName('data');
  if (data && data[0]) {
    content.appendChild(document.createTextNode('Rating: '));
    content.appendChild(rating.makeElement('b', document.createTextNode(data[0].getAttribute('score') || data[0].getAttribute('rating'))));
    votes = data[0].getAttribute('votes');
    if (votes) {
      content.appendChild(document.createTextNode(' ('));
      content.appendChild(document.createTextNode(votes));
      content.appendChild(document.createTextNode(' votes)'));
    }
  }
}
}