var msie = false;
if (navigator.userAgent.match ('MSIE') !== null) msie = true;

var DELAY = 100;
var AJAX_DEBUG = false;

var http_response_code = new Array ();
http_response_code[404] = 'page not found';

var queue = new Queue;


function Queue () {
  this.request_queue = new Array ();
  this.requester_active = false;
  this.created = true;
  
  this.request = function (method, url, action, post_data, asynch) {
    var req = new Request (method, url, action, post_data);
    if (asynch === true) {
      req.send ();
    }
    this.request_queue.push (req);
    this.activate ();
  }
  
  
  this.activate = function () {
    if (this.requester_active != true && this.request_queue.length > 0) {
      this.requester_active = true;
      
      var req = this.request_queue[0];
      
      if (!req.sent) {
        req.send ();
      }
      
      window.setTimeout ('queue.process ();', DELAY);
      
    } else if (this.request_queue.length == 0) {
      
    }
  }
  
  this.process = function () {
    if (this.request_queue.length > 0) {
      
      // process request from FIFO buffer
      var first_request = this.request_queue[0];
      if (first_request.ready_state () == 4) {
        if (first_request.status () == 200) {
          
          // process response
          first_request.process ();
          
        } else if (first_request.status () != 0) {
          var ajax_error = 'AJAX call to ' + first_request.url + ' returned server error:\n' +
            first_request.status ();
          if (http_response_code[first_request.status ()]) {
            ajax_error += ' (' + http_response_code[first_request.status ()] + ')';
          }
          alert (ajax_error);
        }
        
        // remove item from queue
        this.request_queue.shift ();
        
        this.requester_active = false;
        this.activate ();
        
      } else {
        // keep waiting
        window.setTimeout ('queue.process ();', DELAY);
      }
    }
  }
}

function Request (method, url, action, post_data) {
  this.url = url;
  this.action = action;
  this.method = method.toUpperCase ();
  this.requester = null;
  this.internet_explorer = false;
  this.node_id = null;
  this.post_data = post_data;
  this.sent = false;
  
  this.ready_state = function () {
    if (this.requester == null) {
      return -1;
    } else {
      return this.requester.readyState;
    }
  }
  
  this.status = function () {
    if (this.requester == null) {
      return -1;
    } else {
      return this.requester.status;
    }
  }
  
  this.send = function () {
    // try Moz/Safari method, then IE
    if (window.XMLHttpRequest) {
      this.requester = new XMLHttpRequest ();
    } else if (this.requester = new ActiveXObject("MSXML2.XMLHTTP.3.0")) {
      this.internet_explorer = true;
    }
    
    if (this.requester != null) {
      this.requester.open(method, url, true);
      if (this.method == 'POST') {
        this.requester.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      }
      this.requester.send(this.post_data);
      this.sent = true;
    } else {
      alert ('Your browser does not appear to support AJAX');
    }
  }
  
  this.process = function () {
    if (this.requester != null) {
      // check for errors
      var top_node = false;
      
      // skip any comments, whitespace, etc. and find the first real XML node
      var top_children = this.requester.responseXML.childNodes;
      var curr_child_num = 0;
      var curr_child = null;
      while (!top_node) {
        if (top_children.length <= curr_child_num) {
          break;
        }
        curr_child = top_children.item (curr_child_num);
        if (curr_child.nodeType == 1) {
          top_node = curr_child;
        } else {
          curr_child_num++;
        }
      }
      
      if (!top_node) {
        alert ('Invalid XML returned via AJAX, please contact the web site administrator');
        return false;
      }
      
      if (top_node.nodeName.toLowerCase () == 'error') {
        alert (top_node.firstChild.data);
      } else {
        
        // New mechanism -- use handler if provided
        if (typeof (this.action) == 'object') {
          this.action.process (top_node);
          return;
        } else {
          alert ("No request handler provided");
        }
        
      }
    } else {
      alert ('Request.function called on null requester');
    }
  }
}

function update_select_lists (top_node) {
  var select_nodes = top_node.getElementsByTagName ('select');
  var select_node;
  var option_nodes;
  var option_node;
  
  for (var i = 0; i < select_nodes.length; i++) {
    select_node = select_nodes.item (i);
    option_nodes = select_node.childNodes;
    for (var j = 0; j < option_nodes.length; j++) {
      option_node = option_nodes.item (j);
      if (option_node.nodeName && option_node.nodeName.toUpperCase () == 'OPTION') {
        if (option_node.getAttribute ('selected') != null) {
          select_node.value = option_node.value;
          break;
        }
      }
    }
  }
}

function determine_radio_value (radio_el) {
  
  for (var i = 0; i < radio_el.length; i++) {
    if (radio_el[i].checked == true) {
      return radio_el[i].value;
    }
  }
  
  return false;
}


function create_el (name, attrs) {
  
  var node;
  
  if (!msie) {
    node = document.createElement (name);
    if (node && typeof (attrs) == 'object') {
      for (var attr in attrs) {
        node.setAttribute (attr, attrs[attr]);
      }
    }
  } else {
    var attrs_str = '';
    if (typeof (attrs) == 'object') {
      for (var attr in attrs) {
        attrs_str += ' ' + attr + '="' + String (attrs[attr]).replace ('"', '\\"') + '"';
      }
    }
    node = document.createElement ('<' + name + ' ' + attrs_str + '>');
  }
  
  return node;
}

/* makes labels (and corresponding inputs) highlight when you rollover them */
function nice_label (current_label, input_parent) {
  current_label.className = 'label_plain';
  current_label.onmouseover = function () {
    current_label.className = 'label_highlight';
    if (input_parent) {
      input_parent.className = 'label_highlight';
    }
  }
  current_label.onmouseout = function () {
    current_label.className = 'label_plain';
    if (input_parent) {
      input_parent.className = 'label_plain';
    }
  }
  
  if (input_parent) {
    input_parent.onmouseover = function () {
      current_label.className = 'label_highlight';
      input_parent.className = 'label_highlight';
    }
    input_parent.onmouseout = function () {
      current_label.className = 'label_plain';
      input_parent.className = 'label_plain';
    }
  }
}

function var_dump (operand, is_sub) {
  
  var alert_text = '';
  var op_type = typeof (operand)
  alert_text += op_type + ':' + (is_sub? ' ': '\n');
  
  if (op_type == 'object') {
    for (var id in operand) {
      if (typeof (operand[id]) == 'function') {
        alert_text += id + ' = function...\n';
      } else {
        alert_text += id + ' = ' + operand[id] + "\n";
      }
    }
  } else {
    alert_text += String (operand);
  }
  
  window.alert (alert_text);
  
}
