var req;
var res_tag;
//craeate request object or return failure
function makeRequest() {
  var http_request = false;
  if (window.XMLHttpRequest) { // Mozilla, Safari,...
     http_request = new XMLHttpRequest();
     if (http_request.overrideMimeType) {
       http_request.overrideMimeType('text/xml');
     }
  } else if (window.ActiveXObject) { // IE
    try {
      http_request = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
    }
  }
  if (!http_request) {
    return false;
  }
  return http_request;
}
//get data from the server if form name specified results will be filled in it. specify fail function to be executed in case browser doesn't support AJAX and DOM
function get_data(form_name, url, fail_function) {
  req = makeRequest();
  if(!req){
    eval(fail_function);
  }else{
    if(form_name != ""){
      if(url.search(/\?/)){
        url += "&" + build_req_str(form_name);
      }else{
        url += "\?" + build_req_str(form_name);
      }
    }
    req.open("GET",url,true);
    req.onreadystatechange = updatePage;
    req.send(null);
  }
}
//get data from server to fill single input field
function get_data_input(input, url, result_tag){
  res_tag = result_tag;
  var data_input = document.getElementById(input);
  if(url.search(/\?/)){ url += "&"; } else { url += "?";}
  url += data_input.name + "=" + escape(data_input.value);
  get_data("",url,result_tag);
}
//parse results and update page
function updatePage(){
 if (req.readyState == 1) {
   var parent = document.getElementById("loading_parent");
   if (!parent){ parent = document.createElement("span");
     parent.id = "loading_parent";
   }
   var loading = document.createElement("blink");
   loading.id = 'loading';
   loading.style.background = "red";
   loading.style.color = 'white';
   loading.style.top = 0;
   loading.style.fontSize = 12;
   loading.style.right = 20;
   loading.style.width = 80;
   loading.style.height = 15;
   loading.style.position = "absolute";
   loading.innerHTML = "Loading...";
   parent.appendChild(loading);
   var main = document.body;
   main.appendChild(parent);
 }
 if (req.readyState == 4) {
   var load_parent = document.getElementById('loading_parent');
   while (load_parent.hasChildNodes()){
     load_parent.removeChild(load_parent.childNodes[0]);
   }
   if (req.status == 200) {
      if (req.getResponseHeader('Content-Type') == 'text/xml'){
	fill_xml(req.responseXML);
      }else{
        fill_input( req.responseText);
      }
   }else{

   }
 }
}
//update page with returned xml data from server
function fill_xml(xmldoc){
  var root;
  for(var y = 0; y < xmldoc.childNodes.length; y++){
    if(xmldoc.childNodes[y].nodeName == 'root'){
      root = xmldoc.childNodes[y];
      break;
    }
  }
  for (i = 0; i < root.childNodes.length; i++){
    var node = root.childNodes[i];
    switch (node.attributes.getNamedItem('type').nodeValue) {
      case 'select':
       var target = document.getElementById(node.attributes.getNamedItem('id').nodeValue);
       clean_select(target);
       for(var j = 0; j < node.childNodes.length; j++){
	 var new_node = build_up_node(node.childNodes[j]);
	 target.appendChild(new_node);
       }
      break;
      case 'input' :
      break;
      case 'radio' :
       var target = document.getElementById(node.attributes.getNamedItem('id').nodeValue);
       clean_select(target);
       for(var j = 0; j < node.childNodes.length; j++){
         var temp = create_html_from_xml(node.childNodes[j]);
         if(node.childNodes[j].nodeName == 'input'){
	   target.innerHTML = target.innerHTML + build_string(node.childNodes[j]);
	 }
	 else{
	   target.appendChild(temp);
	 }
       }
      break;
      case 'textarea' : 
      break; 
      case 'href' :
      break;
      case 'url' :
        document.search.action = node.attributes.getNamedItem('value').nodeValue;
      break;
    }//switch
  }//for 
}//function
//debuging purpose function. Prints out node attributes
function print_out_attributes(node){
  for(i=0; i<node.attributes.length; i++){
    alert(node.attributes.item(i).nodeName + ' - ' + node.attributes.item(i).nodeValue);
  }
}
//recursive html node building function, mainly for select, optiongroup, etc. inputs
function build_up_node(node){
  var flag = 0;
  for(i=0; i<node.childNodes.length; i++){
    if(node.childNodes[i].nodeType == 1){
      flag = 1;
      break;
    }
  }
  if(flag){
    var option = create_html_from_xml(node);
    for(var i=0; i<node.childNodes.length; i++){
      option.appendChild(build_up_node(node.childNodes[i]));
    } 
    return option;
  }else{
    return create_html_from_xml(node);
  }
}
//create single html node element from xml node
function create_html_from_xml (xml_node){
    var option = document.createElement(xml_node.nodeName);
    for(var k=0; k < xml_node.attributes.length; k++){
      if(xml_node.attributes.item(k).nodeName == 'SELECTED'){
        option.selected = true;
      }else if(xml_node.attributes.item(k).nodeName == 'CHECKED'){
      }else{
        option.setAttribute(xml_node.attributes.item(k).nodeName, xml_node.attributes.item(k).nodeValue);
      }
    }
    if(xml_node.childNodes.length > 0 && xml_node.firstChild.nodeType == 3){
      option.innerHTML = xml_node.firstChild.nodeValue;
    }
    return option;
}
//get string representation of xml node. Used for radio inputs workaround on IE(standart adding nodes doesn't work properly  on IE).
function build_string(node){
  var str = '<';
  str = str + node.nodeName + " ";
  for(i=0; i<node.attributes.length; i++){
    str = str + node.attributes.item(i).nodeName + ' = \'' +
    		node.attributes.item(i).nodeValue + '\' ';
  }
  if(node.childNodes.length > 0 && node.firstChild.nodeType == 3){
    str = str + ">" + node.firstChild.nodeValue + "<" + node.nodeName + "/>";
  }else{
    str = str + '/>';
  }
  return str;
}
//remove all child nodes from passed html node
function clean_select(input){
  while(input.hasChildNodes()){
     input.removeChild(input.childNodes[0]);
  }	   
}
//fill returned server data to single input. | used as a separator of separate values in return string.
function fill_input(response){
  var input = document.getElementById(res_tag);
  var response_str = req.responseText;
  var response = response_str.split('|');
  switch (input.tagName){
	case 'INPUT' :
	  input.value = response_str; 
	break;
	case 'SELECT' : 
	  while (input.hasChildNodes()){
	    input.removeChild(input.childNodes[0]);
	  } 
	  for (i=0; i < response.length; i = i + 2){
	    var select = document.createElement("OPTION");
	    select.value = response[i];
	    select.innerHTML = response[i + 1];
	    input.appendChild(select);
	  }
	break;
	case 'TEXTAREA' : 
	  input.value = response_str;
	break;
	case 'DIV' :
	  input.innerHTML = response_str;
	break;
	case 'SPAN' : 
	  input.innerHTML = response_str;
	break;
	case 'P' :
	  input.innerHTML = response_str;
	case 'A' :
	  input.setAttribute('href', response[0]);
	  input.innerHTML = response[1];
	break;
	case 'url' :
	break;
  }
}
//build request string from form inputs.
function build_req_str(form){
  var form = document.forms[form];
  var str = '';
  for(var i = 0;i < form.elements.length;i++){
    switch(form.elements[i].type){
      case "text":
       str += form.elements[i].name + "=" + escape(form.elements[i].value) + "&";
     break;
     case "select-one":
       str += form.elements[i].name + "=" + form.elements[i].options[form.elements[i].selectedIndex].value + "&";
     break;
     case "select-multiple":
       str += form.elements[i].name + "=" + form.elements[i].options[form.elements[i].selectedIndex].value + "&";
     break;
     case "textarea" :
       str += form.elements[i].name + "=" + escape(form.elements[i].value) + "&";
     break;
     case "radio" :
       if(form.elements[i].checked == true){
         str += form.elements[i].name + "=" + escape(form.elements[i].value) + "&";
       }
     break;
   }
 }
 str = str.substr(0,(str.length - 1));
 return str; 
} 
