// Used to show a three-tier select list for choosing a school (state-city-school)
//
// Depends on an array of data like this:
//   var schoolData = new Array();
//   schoolData[0] = "CA,Clayton,dvms,Diablo View Middle School";
//   schoolData[1] = "CA,Clayton,mdes,Mt. Diablo Elementary School";
//   schoolData[2] = "CA,Morgan Hill,nordstrom,Nordstrom Elementary School";
//   schoolData[3] = "WA,Seattle,seaprep,Seattle Prepatory School";
// and a function:
//   schoolSelected(node), which can use node.value ('dvms') and node.name ('Diablo View...')
//
// Based on code initially found at JavaScript Kit (http://javascriptkit.com)

//Global variables
var topNode          = NewTopNode();
var currentStateNode = NewStateNode("__DUMMY__", null);
var currentCityNode  = NewCityNode("__DUMMY__", null);
var allNodes         = new Array();
var theSelectObject;
var theHelpSpanObject;

function Node(level, levelfromleaf, parent, displaytext, value, type, childtype, helpmsg) {
  this.level          = level;
  this.levelfromleaf  = levelfromleaf;
  this.parent         = parent;
  this.displaytext    = displaytext;
  this.value          = value;
  this.type           = type;
  this.childtype      = childtype;
  this.helpmsg        = helpmsg;
  this.children       = new Array();
  this.addChild       = function(child) { this.children.push(child); }
}

function NewTopNode() {
  var obj = new Node(0, 3, null, "", "root", "root", "state", 
                     "Step 1: Choose your state. If your state is not listed, enter your school name below.");
  return obj;
}

function NewStateNode(abbrev, parent) {
  var obj = new Node(1, 2, parent, abbrev, abbrev, "state", "city", 
                     "Step 2: Choose your city. If your city is not listed, enter your school name below.");
  return obj;
}

function NewCityNode(name, parent) {
  var obj = new Node(2, 1, parent, name, name, "city", "school", 
                     "Step 3: Choose your school. If your school is not listed, enter your school name below.");
  return obj;
}

function NewSchoolNode(key, name, parent) {
  var obj = new Node(3, 0, parent, name, key, "school", "", "");
  return obj;
}

function loadNodes() {
  var theSchoolNode, theCityNode, theStateNode;
  var state, city, schoolkey, schoolname;
  var dataElements;
  for ( ii = 0; ii < schoolData.length; ii++ ) {
    // Parse line (state,city,key,name)
    dataElements = schoolData[ii].split(",");
    state       = dataElements[0]; city       = dataElements[1]; 
    schoolkey   = dataElements[2]; schoolname = dataElements[3];

    // New state:
    // Create a state node as child of topNode and make this new state node the currentStateNode
    if ( state != currentStateNode.value ) {
      theStateNode = NewStateNode(state, "root_root");
      topNode.addChild(theStateNode);
      currentStateNode = theStateNode;
      allNodes["state_"+state] = theStateNode;
    }

    // New state OR new city:
    // Create a city node as child of currentStateNode and make this new city node the currentCityNode
    if ( ( state != currentStateNode.value ) || ( city != currentCityNode.value ) ) {
      theCityNode = NewCityNode(city, "state_"+currentStateNode.value);
      currentStateNode.addChild(theCityNode);
      currentCityNode = theCityNode;
      allNodes["city_"+city] = theCityNode;
    }

    // Always:
    // Create the school node as child of currentCityNode
    theSchoolNode = NewSchoolNode(schoolkey, schoolname, "city_"+currentCityNode.value);
    currentCityNode.addChild(theSchoolNode);
    allNodes["school_"+schoolkey] = theSchoolNode;
  }
  allNodes["root_root"] = topNode;
}

function NodeToString(node, indentLevel) {
  var out     = "";
  var newline = "\n";
  var spaces  = "                       ";
  var indent  = spaces.substring(0, indentLevel*4);
  var indent2 = spaces.substring(0, indentLevel*4 + 2);
  out = out + indent + node.type + ": " + newline;
  out = out + indent2 + "parent/childtype:" + node.parent + "/" + node.childtype + newline;
  out = out + indent2 + "level info: (" + node.level + "," + node.levelfromleaf + ")" + newline;
  out = out + indent2 + "displaytext/value: " + node.displaytext + "/" + node.value + newline;
  return out;
}

function dump() {
  var ss,cc,kk;
  var out;
  out = "";
  for ( ss=0; ss<topNode.children.length; ss++ ) {
    var stateNode = topNode.children[ss];
    out = out + NodeToString(stateNode, 0);
    for ( cc=0; cc<stateNode.children.length; cc++ ) {
      var cityNode = stateNode.children[cc];
      out = out + NodeToString(cityNode, 1);
      for ( kk=0; kk<cityNode.children.length; kk++ ) {
        var schoolNode = cityNode.children[kk];
        out = out + NodeToString(schoolNode, 2);
      }
    }
  }
  alert(out);
}

function populate(node) {
  //Clear old options first
  for (ii = theSelectObject.options.length-1; ii >= 0; ii--) {
    theSelectObject.options[ii]=null;
  }
  //Add "select..." option
  theSelectObject.options[theSelectObject.options.length] = 
    new Option("--- Select your " + node.childtype + " ---","");
  //Add options for each child of given node
  for ( ii = 0; ii < node.children.length; ii++ ) {
    theSelectObject.options[theSelectObject.options.length] = 
      new Option(node.children[ii].displaytext, node.childtype + "_" + node.children[ii].value);
  }
  //Add "go up" option, but not for top-most, root, level
  if ( node.level > 0 ) {
    theSelectObject.options[theSelectObject.options.length] =
      new Option("--- Back to " + node.type + " list ---", 
                 allNodes[node.parent].type + "_" + allNodes[node.parent].value);
  }
  //Set first as default
  theSelectObject.options[0].selected=true;

  //Show help msg
  theHelpSpanObject.innerHTML = node.helpmsg;
}

function displaysub() {
  var val = theSelectObject.options[theSelectObject.selectedIndex].value;
  var node = allNodes[val];
  if ( node.levelfromleaf >= 1 ) {
    populate(node);
  } else {
    gothere(node);
  }
}

function gothere(node) {
  if ( node.levelfromleaf == 0 ) {
    if ( theSelectObject.selectedIndex==theSelectObject.options.length-1 ) {
      //Last item was chosen. This is the "go back up a level" choice
      populate(allNodes[node.parent]);
    } else {
      //A "real" leaf node was chosen
      //alert(node.value);
      schoolSelected(node);
      //Clear help msg
      theHelpSpanObject.innerHTML = "";
    }
  } else {
    //Quiet failure...do nothing
  }
}

function init(idOfSelectObject, idOfHelpSpanObject) {
  loadNodes();
  //dump();
  theSelectObject   = document.getElementById(idOfSelectObject);
  theHelpSpanObject = document.getElementById(idOfHelpSpanObject);
  populate(topNode);
}

