
// Indicator for lists, that shows for current item, that it is not selectable.
var NOT_SELECTABLE_ITEM_INDICATOR = "--";

// Submit form by id.
//    id - id of the form.
function submitForm(formId) { 
  var formElement;

  formElement = $(formId);  
  if (formElement) {
    formElement.submit() ;
  }
}

// Get XMLHttpRequest (cross-browser version).
//    result - XMLHttpRequest object.
function getXMLHttpRequest(){
  var xmlhttp;
  
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e1) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
  return xmlhttp;
}

// Ask SOAP-service for information and obtain response text in the IN-parameter of callback function.
//    url - URL of the service (must contain name of the service).
//    name - name of the service.
//    xml - request XML.
//    callback - callback function; must contain one input parameter to transfer response text.
function askSoapService(url, name, xml, callback) {
  var xmlHttpReq;

  xmlHttpReq = getXMLHttpRequest(); 
     
  xmlHttpReq.onreadystatechange = function() {   
    if (xmlHttpReq.readyState == 4) {  
        if(xmlHttpReq.status == 200) {        
            callback(xmlHttpReq.responseText);
          }
      }  
  }
   
    xmlHttpReq.open('POST', url, true);
  
  // Headers
  xmlHttpReq.setRequestHeader('Content-Type','text/xml');
  xmlHttpReq.setRequestHeader('SOAPAction', name);
  
  xmlHttpReq.send(xml);
  
}

// Convert string with XML to XML-object (cross-browser version).
//    string - string with XML.
//    result - XML-object/
function convertStringToXml(string) {
  var xmlDoc;
  var parser;
  
  if (window.DOMParser) {
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(string, "text/xml");
  } else {
    // For Internet Explorer
    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async = "false";
    xmlDoc.loadXML(string);
  }
  return xmlDoc;
}

// Get XML elements by tag name with attention to prefix (cross-browser version).
//    xmlDocument - XML-object. 
//    prefix - prefix without trailing ":".
//    tagName - name of the tag.
//    result - array of the elements.
function getElementsByTagNameAndPrefix(xmlDocument, prefix, tagName) {
  var result;

  result = xmlDocument.getElementsByTagName(tagName);  
  if (result && result.length == 0) {
    result = xmlDocument.getElementsByTagName(prefix + ':' + tagName);  
  } 
  return result;
}

// Get text from child node.
//    parentNode - parent node (Object).
//    childNodeName - child node name (String).
//    result - string with the text.
function getChildNodeText(parentNode, childNodeName) {
  var child;
  
  child = parentNode.getElementsByTagName(childNodeName); 
  return child[0].childNodes[0].nodeValue;    
}

// Create an <option> element.
//    text - text for the <option>.
//    value - value for the <option>.
//    isDefaultSelected - is <option> selected by default
//    isSelected - is <option> selected
//    result - just created <option>.
function createOption(text, value, isDefaultSelected, isSelected) {
	var option 

	option = document.createElement("option");
	option.appendChild(document.createTextNode(text));
	option.setAttribute("value", value);
	
	// Check if value starts with indicator NOT_SELECTABLE_ITEM_INDICATOR
	if (text.startsWith(NOT_SELECTABLE_ITEM_INDICATOR)) {
		option.disabled = true;
	}	

	if (!option.disabled && isDefaultSelected) {
		option.defaultSelected = true;
	} else if (isSelected) {
		option.selected = true;
	}
	
	return option;
	
}

// Add new <option> to the <select> element.
//    listbox - <select> element.
//    text - text for the <option>.
//    value - value for the <option>.
//    isDefaultSelected - is <option> selected by default
//    isSelected - is <option> selected
//    result - just created <option>.
function addOption(listbox, text, value, isDefaultSelected, isSelected) {
	var option = createOption(text, value, isDefaultSelected, isSelected);
	listbox.appendChild(option);	
	return option;	
}

// Add new <option> to the beginning of the <select> element.
//    listbox - <select> element.
//    text - text for the <option>.
//    value - value for the <option>.
//    isDefaultSelected - is <option> selected by default
//    isSelected - is <option> selected
//    result - just created <option>.
function insertFirstOption(listbox, text, value, isDefaultSelected, isSelected) {
	var option = createOption(text, value, isDefaultSelected, isSelected);
	listbox.insertBefore(option, listbox.firstChild);	
	return option;	
}

// Load cities list with geo information.
//    idRegion - id of the region.
//    listBox - HTML-element "select", where to put found cities.
//    callback - callback function, that retrieves count of found cities
function getCitiesListByRegionIdWithGeoInfo(idRegion, listBox, callback) {
  var internalCallback;
  var xml;
        
  internalCallback = function (responseText) {
    var cities;
    var city;
    var cityName;
    var id;   
    var hasGeoInformation;      
    var option;   
    var xmlDocument;    

    xmlDocument = convertStringToXml(responseText);
    if (!xmlDocument) {
      return;
    }
	
    cities = getElementsByTagNameAndPrefix(xmlDocument, 'ns2', 'CitiesList');
    if (cities) {
	
		for (var i = 0; i < cities.length; ++i) {  
			city = cities[i];
			if (city.hasChildNodes()) {
			  cityName = getChildNodeText(city, 'name');
			  id = getChildNodeText(city, 'id');
			  hasGeoInformation = getChildNodeText(city, 'hasGeoInformation');
			  option = addOption(listBox, cityName, id, false, false);
			  option.setAttribute("hasgeoinformation", hasGeoInformation);
			} // if (city.hasChildNodes())
		} // for     
		
		callback(cities.length);		
      
    } // if (cities)

  }
  
  xml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' + 
        ' <SOAP-ENV:Header/>' + 
        ' <SOAP-ENV:Body>' + 
        '  <getCitiesListByRegionIdWithGeoInfo xmlns="urn:singles:operations">' + 
        '   <regionId>' + idRegion + '</regionId>' + 
        '  </getCitiesListByRegionIdWithGeoInfo>' + 
        ' </SOAP-ENV:Body>' + 
        '</SOAP-ENV:Envelope>'; 
  
            
  askSoapService('/ws/GeoService', 'GeoService', xml, internalCallback);  
  
}

// Load cities list.
//    idRegion - id of the region.
//    listBox - HTML-element "select", where to put found cities.
//    callback - callback function, that retrieves count of found cities
function getCitiesListByCountryId(idCountry, listBox, callback) {
  var internalCallback;
  var xml;  
          
  internalCallback = function (responseText) {  
    var cities;
    var city;
    var cityName;
    var id;   
    var hasGeoInformation;      
    var option;   
    var xmlDocument;  

    xmlDocument = convertStringToXml(responseText);   
    if (!xmlDocument) {
      return;
    }
	
    cities = getElementsByTagNameAndPrefix(xmlDocument, 'ns2', 'CitiesList');     
    if (cities) {

		for (var i = 0; i < cities.length; ++i) {  
			city = cities[i];
			if (city.hasChildNodes()) {
			  cityName = getChildNodeText(city, 'name');
			  id = getChildNodeText(city, 'id');
			  hasGeoInformation = getChildNodeText(city, 'hasGeoInformation');          
			  option = addOption(listBox, cityName, id, false, false);
			  option.setAttribute("hasgeoinformation", hasGeoInformation);
			} // if (city.hasChildNodes())
		} // for
		
		callback(cities.length);		
      
    } // if (cities)

  }
  
  xml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' +
        ' <SOAP-ENV:Header/>' +
        ' <SOAP-ENV:Body>' +
        '  <getCitiesListByCountryId xmlns="urn:singles:operations">' +
        '   <countryId>' + idCountry + '</countryId>' +
        '  </getCitiesListByCountryId>' +
        ' </SOAP-ENV:Body>' +
        '</SOAP-ENV:Envelope>'; 
            
  askSoapService('/ws/GeoService', 'GeoService', xml, internalCallback);    
  
}

// Load regions list.
//    idCountry - id of the country.
//    listBox - HTML-element "select", where to put found regions.
//    callback - callback function, that retrieves count of found regions
function getRegionsListByCountryId(idCountry, listBox, callback) {
  var internalCallback;
  var xml;  
          
  internalCallback = function (responseText) {  
    var regions;
    var region;
    var regionName;
    var id;     
    var option;   
    var xmlDocument;  

    xmlDocument = convertStringToXml(responseText);   
    if (!xmlDocument) {
      return;
    }
    
    regions = getElementsByTagNameAndPrefix(xmlDocument, 'ns2', 'RegionsList');       
    if (regions) {  
      
		for (var i = 0; i < regions.length; ++i) {  
			region = regions[i];
			if (region.hasChildNodes()) {
			  regionName = getChildNodeText(region, 'name');
			  id = getChildNodeText(region, 'id');
			  option = addOption(listBox, regionName, id, false, false);
			} // if (region.hasChildNodes())
		} // for
		
		callback(regions.length);			
      
    } // if (regions)

  }
  
  xml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' +
        ' <SOAP-ENV:Header/>' +
        ' <SOAP-ENV:Body>' +
        '  <getRegionsListByCountryId xmlns="urn:singles:operations">' +
        '   <countryId>' + idCountry + '</countryId>' +
        '  </getRegionsListByCountryId>' +
        ' </SOAP-ENV:Body>' +
        '</SOAP-ENV:Envelope>'; 
            
  askSoapService('/ws/GeoService', 'GeoService', xml, internalCallback);    
  
}

// Debugging function
function debug(message) {
	if (typeof console !== 'undefined' && typeof console.debug !== 'undefined') {
		console.debug.apply(console, [message]); 
	}
}