/*

*/
function Guider(){
  
  var xmldoc;
  //This is the array of nodes by node id
  var nodearray = new Object();
  
  this.setXML = function(xmlstr){
    xmldoc = new XMLDoc();
    xmldoc.setXML(xmlstr);
    //build map of nodes by id
    var root  = xmldoc.getRoot();
    var noderoot = root.getChildByName("nodes");
    var nodes = noderoot.getChildrenByName("node");
    for (var i=0; i<nodes.length; i++){
        var node = nodes[i];
        var id = node.getAttribute("id");
        nodearray[id]=node;
    }
  }
  this.getTitle = function(){
    var rootNodeElement = xmldoc.getRoot().getChildByName("name");
    return rootNodeElement.getText();
  }
  this.getRootQuestion = function(){
    var rootNodeElement = xmldoc.getRoot().getChildByName("root-node");
    var rootid = rootNodeElement.getText();
    var node = nodearray[rootid];
    var rootQ = new Question(node);
    rootQ.setGuider(this);
    return rootQ;
  }
  this.getNode = function(id){
    var node = nodearray[id];
    var desttype = node.getAttribute('type');
    var dest = null;
    switch (desttype){
      case "Question":
           dest = new Question(node);
           break;  
      case "GoogleSearch":
           dest = new Results(node);
           break;  
      case "ExternalLink":
           dest = new Results(node);
           break;
      default:
           alert("Unknown destination type of '"+desttype+"' in Answer.getDestination");
           break;
    }
    dest.setGuider(this);
    return dest;
  }
  //----------------------------------------------------------------------------
  // This method gets an external link node with the given destination URL
  //----------------------------------------------------------------------------
  this.getNodeByDestination = function(desturl){
    for (var i in nodearray){
        var node = nodearray[i];
        if (node.getAttribute('type')=="ExternalLink"){
           var result = new Results(node);
           result.setGuider(this);
           if (result.getURL()==desturl){
              return node;
           }
        }        
    }
    return null;
  }
  //----------------------------------------------------------------------------
  // This method gets the parent of a given node
  //----------------------------------------------------------------------------
  this.getParent = function(childnode){
    var target = childnode.getAttribute('id');
    for (var i in nodearray){
        var node = nodearray[i];
        if (node.getAttribute('type')=="Question"){ //all parent nodes are Questions
           var question = new Question(node);
           question.setGuider(this);
           var answers = question.getAnswers();
           for (var j=0; j<answers.length; j++){
               var destnode = answers[j].getDestination();
               if (destnode.getID()==target){
                  return question;
               }
           }
        }
    }
    return null;        
  }

}

//Takes an XMLElement representing the node from the guider xml
function Question(node){
  
  var thisnode = node;
  var myguider = null;
  
  this.getText = function(){
    var qtnode = thisnode.getChildByName("question-text");
    return qtnode.getText();
  }
  this.getAnswers = function(){
    var answersnode = thisnode.getChildByName("answers");
    var answers = answersnode.getChildrenByName("answer");
    var retarr = new Array();
    for (var i=0; i<answers.length; i++){
        var a = new Answer(answers[i]);
        a.setGuider(myguider);  
        retarr.push(a);  
    }
    return retarr;
  }
  this.getID = function(){
    return thisnode.getAttribute('id');  
  }
  this.hasExplanation = function(){
    return (thisnode.getChildByName("explanation-text")!=null);
  }
  this.getExplanation = function(){
    var exnode = thisnode.getChildByName("explanation-text");
    return exnode.getText();
  }
  this.isQuestion     = function(){return true;}
  this.isResult       = function(){return false;}
  this.isGoogleSearch =  function(){return false;}
  this.isExternalLink =  function(){return false;}
  this.isRoot     = function(){
    if (myguider==null){
       alert("question object has no link to the guider.");
       return false;
    }
    if (this.getID()==myguider.getRootQuestion().getID()){
       return true;
    }
    return false;
  }
  this.setGuider  = function(guider){myguider = guider;};
  //parse the XML node

}

function Answer(node){
  this.SUB_NODE      = 1;
  this.GOOGLE_SEARCH = 2;
  this.EXTERNAL_LINK = 3;
  
  var thisnode = node;
  var myguider = null;
    
  this.getDestination = function(){
    var dest = null;
    var linkselem = thisnode.getChildByName('links');
    if (linkselem!=null){
       var linkelem = linkselem.getChildByName('link');
       var nodeid = linkelem.getAttribute('subsequent-node-id');
       var dest = myguider.getNode(nodeid);
    }
    if (dest!=null){
       dest.setGuider(myguider);
    }
    return dest;
  }
  
  this.getText = function(){
    var atnode = thisnode.getChildByName("answer-text");
    return atnode.getText();
  }
  this.hasExplanation = function(){
    return (thisnode.getChildByName("explanation-text")!=null);
  }
  this.getExplanation = function(){
    var exnode = thisnode.getChildByName("explanation-text");
    return exnode.getText();
  }
  this.setGuider  = function(guider){myguider = guider;};
}

function Results(node){  
  
  var thisnode = node;
  var myguider = null;
  
  this.getID = function(){
    return thisnode.getAttribute('id');  
  }
  this.getURL = function(){
    var type  = thisnode.getAttribute('type');
    var query = null;
    switch (type){
      case "GoogleSearch":
           var query = thisnode.getChildByName('query').getText();
           query = "http://www.google.com/search?hl=en&q="+query.replace(/\s/g,"+");
           break;  
      case "ExternalLink":
           var query = thisnode.getChildByName('query').getText();           
           break;  
    }
    return query;
  }
  this.isQuestion     = function(){return false;}
  this.isResult       = function(){return true;}
  this.isGoogleSearch =  function(){return (thisnode.getAttribute('type')=='GoogleSearch')}
  this.isExternalLink =  function(){return (thisnode.getAttribute('type')=='ExternalLink')}
  this.setGuider  = function(guider){myguider = guider;};
}