// expected structure for expandcollapse to work:
// - there is an icon (img) or a description (span)
// - the icon is to the left of the description
// - there exists a div with id matching the contents of the span
//   (minus any space characters) under the icon and description
// - these are enclosed within a parent div element
function expandcollapse(element)
{
  expandcollapse(element, "");
}
function expandcollapse(element, uidsuffix)
{
  var icon = element;
  var description = element;
  var expansion;
  if (element.tagName.toLowerCase() == "img")
  {
    do { description = description.nextSibling; }
    while ((null == description) || (undefined == description) ||
            (null == description.tagName) || (undefined == description.tagName) ||
            (description.tagName.toLowerCase() != "span"));
    if (description == undefined || description == null) return;
  }
  else if (element.tagName.toLowerCase() == "span")
  {
    do { icon = icon.previousSibling; }
    while ((null == icon) || (undefined == icon) ||
            (null == icon.tagName) || (undefined == icon.tagName) ||
            (icon.tagName.toLowerCase() != "img"));
    if (icon == undefined || icon == null) return;
  }
  else // huh? what happened?
    return;
    
  expansion = description.nextSibling;
  if (expansion == undefined || expansion == null) return;
  
  if (undefined == uidsuffix || null == uidsuffix) uidsuffix = "";
  var sectionid = description.innerHTML.replace(/ /g, "").toLowerCase();
  var sectionuid = sectionid + uidsuffix;
  
  var start = icon.src.lastIndexOf("/") + 1;
  var imgname = icon.src.substring(start);
  if (imgname == "collapsed.gif")
  {
    document.getElementById(sectionuid).style.visibility = "visible";
    document.getElementById(sectionuid).style.display = "block";
    icon.src = "../images/expanded.gif";
    
    // every time something is expanded, use it for the source for the info window
    info(sectionid, description.innerHTML);
  }
  else if (imgname == "expanded.gif")
  {
    // okay, let's skip collapse if the description was what was clicked...
    // instead, show the info for what was clicked
    if (element == description)
    {
      info(sectionid, description.innerHTML);
      return;
    }
    else
    {
      document.getElementById(sectionuid).style.visibility = "hidden";
      document.getElementById(sectionuid).style.display = "none";
      icon.src = "../images/collapsed.gif";
    }
  }
}

function expanddetails(element)
{
  var sectionid = element.innerHTML.replace(/ /g, "").toLowerCase();
  info(sectionid, element.innerHTML);
}

function expandproduct(reference)
{
  var path = reference.split(",");
  var i = 0;
  var parent = document.getElementById(path[0]);
  if (undefined != parent && null != parent)
  {
    expandproductdiv(parent);
    i = 1;
  }
  while (i < path.length) 
  {
    var target = document.getElementById(path[i]);
    if (undefined != target && null != target)
    {
      expandproductdiv(target);
      parent = target;
    }
    else
    {
      // search for the span with the matching name under "parent"
      for (var j = 0; j < parent.childNodes.length; j++)
      {
        var node = parent.childNodes.item(j);
        if ((null != node) && (undefined != node) && 
            (null != node.tagName) && (undefined != node.tagName) && 
            (node.tagName.toLowerCase() == "span") && 
            (node.innerHTML.replace(/ /g, "").toLowerCase() == path[i]))
        {
          target = node;
          j = parent.childNodes.length;
        }
      }
      
      // expand...
      if ((undefined != target) && (null != target)) expanddetails(target);
      // do not reset the parent to target... shouldn't be another iteration left
    }
    i++;
  }
}
function expandproductdiv(div)
{
  // search for the preceding "span" node, and call "expandcollapse" on it
  do { div = div.previousSibling; }
  while ((null == div) || (undefined == div) ||
          (null == div.tagName) || (undefined == div.tagName) ||
          (div.tagName.toLowerCase() != "span"));
  if (div == undefined || div == null) return;
  
  expandcollapse(div);
}

var info_window;
function close_info()
{
  info_window.style.visibility = "hidden";
}
function info(code, defaulttitle)
{
  // defeat browser caching for revision changes!
  var rev_no = 104;
  loadXMLDoc('data_xml.php?code='+code+'&default='+defaulttitle+'&rev_no='+rev_no);
}
function furtherinfo(result)
{
  if (null == info_window || undefined == info_window)
  {
    info_window = document.getElementById("info_window");
  }
  if (info_window)
  {
    var itemCode = result.getElementsByTagName('code')[0].firstChild.data;
    var itemName = result.getElementsByTagName('name')[0].firstChild.data;
    var itemPhoto = result.getElementsByTagName('photo')[0].firstChild.data;
    var itemInfoNode = result.getElementsByTagName('info')[0];
    var i = 0;
    while (info_window.childNodes[i].id != 'info_window_title') i++;
    info_window.childNodes[i].innerHTML = "&nbsp;" + itemName;
    i++;
    while (info_window.childNodes[i].id != 'info_window_picframe') i++;
    info_window.childNodes[i].getElementsByTagName('img')[0].src = 
      (itemPhoto == "blank") ? "images/blank.png" : "images/" + itemPhoto + ".jpg";
    i++;
    while (info_window.childNodes[i].id != 'info_window_details') i++;
    while (info_window.childNodes[i].childNodes.length > 0) 
      info_window.childNodes[i].removeChild(info_window.childNodes[i].childNodes[0]);
    for (var j = 0; j < itemInfoNode.childNodes.length; j++) 
    {
      info_window.childNodes[i].appendChild(copyelement(itemInfoNode.childNodes[j]));
    }
    info_window.style.visibility = "visible";
  }
}
function copyelement(node)
{
  if (undefined == node.tagName)
    return document.createTextNode(node.data);
  
  var element = document.createElement(node.tagName);
  element.className = node.getAttribute("class");
  for (var x = 0; x < node.attributes.length; x++)
    element.setAttribute(node.attributes[x].name, node.attributes[x].value);
  if (node.childNodes.length > 0)
    element.appendChild(document.createTextNode(node.firstChild.data));
  return element;
}

function processReqChange() 
{
  // iff req state is "complete" - all other states are tossed out and ignored
  if (xml_http_req.readyState == 4) 
  {
    // iff "OK"
    if (xml_http_req.status == 200) 
    {
      var response = xml_http_req.responseXML.documentElement;
      
      var action = response.getElementsByTagName('action')[0].firstChild.data;
      var result = response.getElementsByTagName('result')[0];
      
      if (action == "alert") alert(result.firstChild.data);
      else eval(action + '(result)');
    } 
    // else ignore any errors
  }
}
// url must contain a URL that returns an xml document with two child elements:
// action - the name of a callback javascript function
// result - the value of the xml response that will be returned (as an argument) to the callback javascript function
//          (value is an XML node object)
function loadXMLDoc(url) 
{
  // branch for native XMLHttpRequest object
  if (window.XMLHttpRequest) 
  {
    xml_http_req = new XMLHttpRequest();
    xml_http_req.onreadystatechange = processReqChange;
    xml_http_req.open("GET", url, true);
    xml_http_req.send(null);
  } 
  // branch for IE/Windows ActiveX version
  else if (window.ActiveXObject) 
  {
    xml_http_req = new ActiveXObject("Microsoft.XMLHTTP");
    if (xml_http_req) 
    {
      xml_http_req.onreadystatechange = processReqChange;
      xml_http_req.open("GET", url, true);
      xml_http_req.send();
    }
  }
}
