// holds an instance of XMLHttpRequest
var taxon_xmlHttp = createXmlHttpRequestObject();

// creates an XMLHttpRequest instance
function createXmlHttpRequestObject() 
{
  // will store the reference to the XMLHttpRequest object
  var taxon_xmlHttp;
  // this should work for all browsers except IE6 and older
  try
  {
    // try to create XMLHttpRequest object
    taxon_xmlHttp = new XMLHttpRequest();
  }
  catch(e)
  {
    // assume IE6 or older
    var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
                                    "MSXML2.XMLHTTP.5.0",
                                    "MSXML2.XMLHTTP.4.0",
                                    "MSXML2.XMLHTTP.3.0",
                                    "MSXML2.XMLHTTP",
                                    "Microsoft.XMLHTTP");
    // try every prog id until one works
 
    for (var i=0; i<XmlHttpVersions.length && !taxon_xmlHttp; i++) 
    {
      try 
      { 
        // try to create XMLHttpRequest object
        taxon_xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
      } 
      catch (e) {}
    }
  }
  // return the created object or display an error message
  if (!taxon_xmlHttp)
    alert("Error creating the XMLHttpRequest object.");
  else 
    return taxon_xmlHttp;
}

// read a file from the server
function populate_taxon(taxon_type,filter_type)
{
    if ( taxon_type == 'kingdom' 
         && document.getElementById('kingdom_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var kingdom_list = document.getElementById('kingdom_list');
        if ( kingdom_list )
        {
            taxon_clearOptions(kingdom_list);
            taxon_addToOptionList(kingdom_list, '', 'loading...');
        }
        taxon_connect("populate_taxon_lists.php?type=kingdom&filter="+filter_type)
    }
    else if ( taxon_type == 'division' 
         && document.getElementById('division_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var division_list = document.getElementById('division_list');
        if ( division_list )
        {
            taxon_clearOptions(division_list);
            taxon_addToOptionList(division_list, '', 'loading...');
        }
        var kingdom_selected = '';
        if ( document.getElementById('kingdom_list') )
            kingdom_selected = document.getElementById('kingdom_list').value;
        if ( kingdom_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=division&filter="+filter_type+"&parent_id="+kingdom_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=division&filter="+filter_type)
    }
    else if ( taxon_type == 'class' 
         && document.getElementById('class_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var class_list = document.getElementById('class_list');
        if ( class_list )
        {
            taxon_clearOptions(class_list);
            taxon_addToOptionList(class_list, '', 'loading...');
        }
        var division_selected = '';
        if ( document.getElementById('division_list') )
            division_selected = document.getElementById('division_list').value;
        if ( division_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=class&filter="+filter_type+"&parent_id="+division_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=class&filter="+filter_type)
    }
    else if ( taxon_type == 'subclass' 
         && document.getElementById('subclass_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var subclass_list = document.getElementById('subclass_list');
        if ( subclass_list )
        {
            taxon_clearOptions(subclass_list);
            taxon_addToOptionList(subclass_list, '', 'loading...');
        }
        var class_selected = '';
        if ( document.getElementById('class_list') )
            class_selected = document.getElementById('class_list').value;
        if ( class_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=subclass&filter="+filter_type+"&parent_id="+class_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=subclass&filter="+filter_type)
    }
    else if ( taxon_type == 'order' 
         && document.getElementById('order_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var order_list = document.getElementById('order_list');
        if ( order_list )
        {
            taxon_clearOptions(order_list);
            taxon_addToOptionList(order_list, '', 'loading...');
        }
        var subclass_selected = '';
        if ( document.getElementById('subclass_list') )
            subclass_selected = document.getElementById('subclass_list').value;
        if ( subclass_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=order&filter="+filter_type+"&parent_id="+subclass_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=order&filter="+filter_type)
        //taxon_connect("populate_taxon_lists.php?type=family&filter="+filter_type)
    }
    else if ( taxon_type == 'family' 
         && document.getElementById('family_list_status').innerHTML == 'uninitialized' 
         && document.getElementById('taxon_list_status').innerHTML != 'loading...' 
         )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var family_list = document.getElementById('family_list');
        if ( family_list )
        {
            taxon_clearOptions(family_list);
            taxon_addToOptionList(family_list, '', 'loading...');
        }
        var order_selected = '';
        if ( document.getElementById('order_list') )
            order_selected = document.getElementById('order_list').value;
        if ( order_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=family&filter="+filter_type+"&parent_id="+order_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=family&filter="+filter_type)
        //taxon_connect("populate_taxon_lists.php?type=family&filter="+filter_type)
    }
    else if ( taxon_type == 'genus' 
        && document.getElementById('genus_list_status').innerHTML == 'uninitialized' 
        && document.getElementById('taxon_list_status').innerHTML != 'loading...' )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var genus_list = document.getElementById('genus_list');
        if ( genus_list )
        {
            taxon_clearOptions(genus_list);
            taxon_addToOptionList(genus_list, '', 'loading...');
        }
        var family_selected = document.getElementById('family_list').value;
        if ( family_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=genus&filter="+filter_type+"&parent_id="+family_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=genus&filter="+filter_type)
    }
    else if ( taxon_type == 'species' 
        && document.getElementById('species_list_status').innerHTML == 'uninitialized' 
        && document.getElementById('taxon_list_status').innerHTML != 'loading...' )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var species_list = document.getElementById('species_list');
        if ( species_list )
        {
            taxon_clearOptions(species_list);
            taxon_addToOptionList(species_list, '', 'loading...');
        }
        var genus_selected = document.getElementById('genus_list').value;
        if ( genus_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=species&filter="+filter_type+"&parent_id="+genus_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=species&filter="+filter_type)
    }
    else if ( taxon_type == 'infraspecific_taxon' 
        && document.getElementById('infraspecific_taxon_list_status').innerHTML == 'uninitialized' 
        && document.getElementById('taxon_list_status').innerHTML != 'loading...' )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading...';
        var infraspecific_taxon_list = document.getElementById('infraspecific_taxon_list');
        if ( infraspecific_taxon_list )
        {
            taxon_clearOptions(infraspecific_taxon_list);
            taxon_addToOptionList(infraspecific_taxon_list, '', 'loading...');
        }
        var species_selected = document.getElementById('species_list').value;
        if ( species_selected != '' )
            taxon_connect("populate_taxon_lists.php?type=infraspecific_taxon&filter="+filter_type+"&parent_id="+species_selected)
        else
            taxon_connect("populate_taxon_lists.php?type=infraspecific_taxon&filter="+filter_type)
    }
}

function refresh_taxon_list(taxon_type,parent_id)
{
    if ( taxon_type == 'division' || taxon_type == 'class' || taxon_type == 'subclass' || taxon_type == 'order' || taxon_type == 'family' || taxon_type == 'genus' || taxon_type == 'species' || taxon_type == 'infraspecific_taxon' )
    {
        document.getElementById('taxon_list_status').innerHTML = 'loading';
        var taxon_list = document.getElementById(taxon_type+'_list');
        if ( taxon_list )
        {
            taxon_clearOptions(taxon_list);
            taxon_addToOptionList(taxon_list, '', 'loading...');
        }
        taxon_connect("populate_taxon_lists.php?type="+taxon_type+"&filter="+filter_type+"&parent_id="+parent_id)
    }
}

function taxon_connect(url_string)
{
    if (taxon_xmlHttp)
    {
        // try to connect to the server
        try
        {
            // initiate reading a file from the server
            taxon_xmlHttp.open("GET", url_string, true);
            taxon_xmlHttp.onreadystatechange = taxon_handleRequestStateChange;
            taxon_xmlHttp.send(null);
        }
        // display the error in case of failure
        catch (e)
        {
            alert("Can't connect to server:\n" + e.toString());
        }
    }
}

// function called when the state of the HTTP request changes
function taxon_handleRequestStateChange() 
{
    // when readyState is 4, we are ready to read the server response
    if (taxon_xmlHttp.readyState == 4) 
    {
        // continue only if HTTP status is "OK"
        if (taxon_xmlHttp.status == 200) 
        {
            try
            {
                // do something with the response from the server
                taxon_handleServerResponse();
            }
            catch(e)
            {
                // display error message
                alert("Error reading the response: " + e.toString());
            }
        } 
        else
        {
            // display status message
            alert("There was a problem retrieving the data:\n" + taxon_xmlHttp.statusText);
        }
    }
}

// handles the response received from the server
function taxon_handleServerResponse()
{
    var filter_text;
    // read the message from the server
    var xmlResponse = taxon_xmlHttp.responseXML;
    // catching potential errors with IE and Opera
    if (!xmlResponse || !xmlResponse.documentElement)
        throw("Invalid XML structure:\n" + taxon_xmlHttp.responseText);
    // catching potential errors with Firefox
    var rootNodeName = xmlResponse.documentElement.nodeName;
    if (rootNodeName == "parsererror") throw("Invalid XML structure");
    // obtain the XML's document element
    xmlRoot = xmlResponse.documentElement;  

    //document.getElementById('family_list_status').innerHTML = 'populated';
    filterNode = xmlRoot.getElementsByTagName("filter_type");
    if ( filterNode.item(0).firstChild )
        filter_type = filterNode.item(0).firstChild.data;
    else 
        filter_type = '';
        
    taxonNode = xmlRoot.getElementsByTagName("taxon_type");
    if ( taxonNode.item(0).firstChild )
        taxon_type = taxonNode.item(0).firstChild.data;
    else 
        taxon_type = '';
    //alert('taxon_type='+taxon_type);    
    taxonArray = xmlRoot.getElementsByTagName("taxon_list");
    //familyArray = xmlRoot.getElementsByTagName("families");
    //genusArray = xmlRoot.getElementsByTagName("genera");
    //speciesArray = xmlRoot.getElementsByTagName("species");
    //infraspecific_taxonArray = xmlRoot.getElementsByTagName("infraspecific_taxon");

    if ( taxonArray.length > 0 )
    {
        if ( document.getElementById('filter_text') )
            filter_text = document.getElementById('filter_text').value;
        else
            filter_text = 'indetermined';
            
        if ( document.getElementById(taxon_type+'_list_status') )
            document.getElementById(taxon_type+'_list_status').innerHTML = 'populated';
        if ( document.getElementById('taxon_list_status') )
            document.getElementById('taxon_list_status').innerHTML = 'idle';
        taxonArray = xmlRoot.getElementsByTagName("n");
        idArray = xmlRoot.getElementsByTagName("i");
        rankArray = xmlRoot.getElementsByTagName("r");
        
        var taxon_select = document.getElementById(taxon_type+'_list');
        if ( taxon_select )
        {
            taxon_clearOptions(taxon_select);
            taxon_addToOptionList(taxon_select, '0', filter_text);
            for (var i=0; i<taxonArray.length; i++)
            {
                if ( rankArray.item(i).firstChild ) 
                {
                    if ( rankArray.item(i).firstChild.data == "variety" )
                        rankString = "var. ";
                    else if ( rankArray.item(i).firstChild.data == "subspecies" )
                        rankString = "ssp. ";
                    else if ( rankArray.item(i).firstChild.data == "form" )
                        rankString = "f. ";
                    else 
                        rankString = "";
                }
                    
                taxon_addToOptionList(taxon_select, idArray.item(i).firstChild.data, rankString+taxonArray.item(i).firstChild.data);
            }
        }
        //var field = document.getElementById('family_select');
        //if ( field )
        //    field.options[0].selected = true;
        //var field = document.getElementById('genus_select');
        //if ( field )
        //    field.options[0].selected = true;
        
        //console.log('taxon_type='+taxon_type);
        //console.log('taxon_id_value='+document.getElementById(taxon_type+'_id_value').innerHTML);
        
        if ( document.getElementById(taxon_type+"_id_value") )    
            taxon_id_value = document.getElementById(taxon_type+"_id_value").innerHTML;
        //alert(taxon_type+"_id_value="+taxon_id_value);
        select_taxon_list_item(taxon_select,taxon_id_value);
        if ( taxon_type == 'kingdom' ) 
            child_taxon_type = 'division';
        else if ( taxon_type == 'division' ) 
            child_taxon_type = 'class';
        else if ( taxon_type == 'class' ) 
            child_taxon_type = 'subclass';
        else if ( taxon_type == 'subclass' ) 
            child_taxon_type = 'order';
        else if ( taxon_type == 'order' ) 
            child_taxon_type = 'family';
        else if ( taxon_type == 'family' ) 
            child_taxon_type = 'genus';
        else if ( taxon_type == 'genus' ) 
            child_taxon_type = 'species';
        else if ( taxon_type == 'species' ) 
            child_taxon_type = 'infraspecific_taxon';
        else
            child_taxon_type = '';
        var taxon_name = '';
        if ( taxon_type == 'kingdom' || taxon_type == 'division' || taxon_type == 'class' || taxon_type == 'subclass' || taxon_type == 'order' || taxon_type == 'family' || taxon_type == 'genus' )
        {
	        var taxon_name_index = document.getElementById(taxon_type+'_list').options.selectedIndex;
	        if ( taxon_name_index >= 0 && document.getElementById(taxon_type+'_list').options[taxon_name_index] )
	            taxon_name = document.getElementById(taxon_type+'_list').options[taxon_name_index].text;
	        else
	            taxon_name = '';
        }
        //console.log('child_taxon_type='+child_taxon_type);
        //console.log('child_taxon_id_value='+document.getElementById(child_taxon_type+'_id_value').innerHTML);
        if ( child_taxon_type != '' && taxon_name != filter_text )
        {
            if ( document.getElementById(child_taxon_type+'_list') )
                refresh_taxon_list(child_taxon_type,taxon_id_value,filter_type);
            if ( document.getElementById(child_taxon_type+'_id_value') )
            {
                if ( document.getElementById(child_taxon_type+'_id_value').innerHTML != '' )
                {
                    child_taxon_id_value = document.getElementById(child_taxon_type+'_id_value').innerHTML;
                    var child_taxon_select = document.getElementById(child_taxon_type+'_list');
                    select_taxon_list_item(child_taxon_select,child_taxon_id_value);
                }
            }
        }
        if(typeof update_preview == 'function') // Check to see if the update_preview() function exists. If so, then call it.
        {
            update_preview();
        } 
    }
}

function taxon_clearOptions(OptionList) 
{
   OptionList.length = 0; 
}

function taxon_addToOptionList(OptionList, OptionValue, OptionText) 
{
   // Add option to the bottom of the list
   if ( OptionList )
       OptionList[OptionList.length] = new Option(OptionText, OptionValue);
}

function select_taxon_list_item(OptionList,list_value) 
{
    if ( OptionList )
    {
        for (x = OptionList.length-1; x >= 0; x = x - 1) 
        {
            if ( OptionList[x].value == list_value )
                OptionList[x].selected = true;
        }
    }
}

