/*
geoquiz_handler.js
Author: Larry Ching
Date Created: Feb 22, 2006
Geography quiz. Local data in geoquiz.xml retrieved by ContentLoader()
Requires: geoquiz_dbcom.js, ContentLoader.js and geoquiz_googlemap.js .
*/
/*
History:
Mar 11, 2007 - Incorporate calls to map functions in geoquiz_googlemap.js .
April 17, 2007 - Fixes for Internet Explorer - onclick event handling.

*/

var countries_shuffled = new Array();
var modulo_indexes = new Array();

function makeRandomArray(){
  var countryArray = net.geoquiz_xmlDoc.getElementsByTagName("Country");
  var categoryArray = net.geoquiz_xmlDoc.getElementsByTagName("Category");
  var countries_len = countryArray.length;
  var categories_len = categoryArray.length;
  
  countries_shuffled.length = countries_len;
  modulo_indexes.length = categories_len;
  
  for (i=0;i<categories_len; i++) {
    modulo_indexes[i] = 0;
  }
  
  var countries_serial = new Array(countries_len);
  
  for (i=0;i<countries_len; i++) {
    countries_serial[i] = i;
  }
  
  var shrinklength = countries_len;
  for (i=0;i<(countries_len - 1); i++) {
    countries_shuffled[i] = countries_serial.splice(Math.floor(shrinklength * Math.random()),1);
    shrinklength-- ;
  }
  countries_shuffled[countries_len - 1] = countries_serial[0];
}

function xmlLoaded(){
  // Initializtion of buttons, category list values and country value
  net.geoquiz_xmlDoc = this.req.responseXML; // Added to "net" object to make it accessible to functions
  net.countrystring = "" ; // Storage for country value
  
  makeRandomArray();
  
  // The code for the next three buttons was placed in separate functions to
  // facilitate adding more functionality to the buttons in the future.
  initAnswerButton();
  initCheckButton();
  initHintButton();
  
  hideElement("catanswer");
  hideElement("hintcheck");
  // hideElement("statusdata");
  fillCategoryList();
  showWorldMap();
}

function fillCategoryList(){
  // Fill div categorylist with category choices
  // categoryArray contains all the xml doc nodes that have tag "Category"
  var categoryArray = net.geoquiz_xmlDoc.getElementsByTagName("Category");
  var divCategorylist = document.getElementById("categorylist");
  var newradiobutton = null;
  var onclickstr = "";
  var cattype = "";
  for(i=0; i < categoryArray.length; i++){
    // workaround for IE input type=radio problem
    // http://cf-bill.blogspot.com/2006/03/another-ie-gotcha-dynamiclly-created.html
    cattype = categoryArray[i].getAttribute("type") ;
    onclickstr = 'showQuestion(\"' + cattype + '\")' ;
    try { 
      // For IE
      newradiobutton = document.createElement("<input type='radio' name='category' value='" + cattype + "' onclick='" + onclickstr + "' />"); 
    }
    catch(err) { 
      // Other browsers
      newradiobutton = document.createElement("input");
      newradiobutton.setAttribute("type","radio");
      newradiobutton.setAttribute("name","category");
      newradiobutton.setAttribute("value",cattype);
      newradiobutton.setAttribute("onclick", onclickstr);
    }

    newradiobutton.setAttribute("id","category" + i);
    divCategorylist.appendChild(newradiobutton);
    divCategorylist.appendChild(document.createTextNode(categoryArray[i].getAttribute("type")));
  }
  divCategorylist.appendChild(document.createElement("br"));
}

function changeCountry(){
  // Used to initalize or change the country 
  // Choose random country from XML list and show 
  // countryArray contains all the nodes that have tag "Country"
  // NOTE: For Part II - Add deselecting of category list, clearing Answer field when
  // country is changed.
  // Changed 26 Feb 2007 to change the value of net.countrystring .
  var countryArray = net.geoquiz_xmlDoc.getElementsByTagName("Country");
  var categoryArray = net.geoquiz_xmlDoc.getElementsByTagName("Category");
  var countries_len = countryArray.length;
  var categories_len = categoryArray.length;
  var checkedindex = findCheckedRadioIndex("category", categories_len);
  
  var newcountry = countryArray[countries_shuffled[modulo_indexes[checkedindex]]];
  
  var newcountrystring = newcountry.firstChild.data;
  if (newcountry.getAttribute("prefix")) {
    newcountrystring = newcountry.getAttribute("prefix") + " " + newcountrystring;
  }
    net.countrystring = newcountrystring ;
    updateMap(countries_shuffled[modulo_indexes[checkedindex]]);
    modulo_indexes[checkedindex] = (modulo_indexes[checkedindex] + 1)%countries_len;
}

function findCheckedRadio(idprefix, num_of_radio){
  // Tests radio objects with a common id format to see which one is checked.
  // Returns the category (value) string from the checked object.
  var checked_value = "";
  var one_radio_obj = null;
  for (var i=0; (i < num_of_radio)&&(checked_value == ""); i++) {
    one_radio_obj = document.getElementById(idprefix + i);
    if (one_radio_obj.checked) {
      checked_value = one_radio_obj.value;
    }
  }
  
  return checked_value;
  
}

function findCheckedRadioIndex(idprefix, num_of_radio){
  // Tests radio objects with a common id format to see which one is checked.
  // Returns the index of the checked object.
  var checked_index = -1;
  var one_radio_obj = null;
  for (var i=0; (i < num_of_radio)&&(checked_index == -1); i++) {
    one_radio_obj = document.getElementById(idprefix + i);
    if (one_radio_obj.checked) {
      checked_index = i;
    }
  }
  
  return checked_index;
  
}

function showQuestion(thecategory){
  //alert("In showQuestion. thecategory == " + thecategory);
  // retrieves the question for the category chosen
  // Modified 26 Feb 2007: Uses net.countrystring
  var local_category = "";
  if(thecategory.length <= 0){
    local_category = window.event.srcElement.value; // might be IE
  }else{
    local_category = thecategory;
  }
  changeCountry();
  var categoryArray = net.geoquiz_xmlDoc.getElementsByTagName("Category");
  hideElement("catanswer");
  hideElement("hintcheck");
  getQuestion(categoryArray,local_category);
}

function getQuestion(categoryArray,thecategory){
  // Gets question from XML object.
  // Modified 26 Feb 2007 to use net.countrystring
    var questionTag = null;
     
    for (var i=0; (i < categoryArray.length)&&(questionTag == null); i++) {
      if (categoryArray[i].getAttribute("type") == thecategory) {
        questionTag = categoryArray[i].getElementsByTagName("Question");
        var questiontext = questionTag[0].firstChild.data;
        questiontext = questiontext.replace("XXX",net.countrystring) ;
        document.getElementById("catquestion").firstChild.data = "Question: " + questiontext;
        queryTag = categoryArray[i].getElementsByTagName("Query");
        var querystring = queryTag[0].firstChild.data;
        var trimcountrystring = net.countrystring.replace("the ","");
        querystring = querystring.replace("XXX",trimcountrystring);
        makeAndSendQuery(querystring);
       }
    }
}

// The callback function for the ContentLoader object, which was created in makeAndSendQuery(). 
// It parses the sqlquery reply into the string formats required for the Answer(s) and Hint fields, 
// and writes the strings to the display.
// Note: "this" refers to the ContentLoader object, which has the attribute "req.responseText".
// Modified Feb. 15, 2007 to (sorta) handle responseXML == null.
function writeAnswerHint(){
  var divTag = document.getElementById("catanswer");
  var answerstring = "";
  var sqlquery_Resp = this.req.responseXML;
  if(sqlquery_Resp){ // Valid responseXML
    var itemtags = sqlquery_Resp.getElementsByTagName("item");
    answerstring = itemtags[0].firstChild.data;
    for(var i=1; i < itemtags.length; i++) {
      if(i == (itemtags.length - 1)) {
        answerstring += " or " + itemtags[i].firstChild.data;
      }else{
        answerstring += ", " + itemtags[i].firstChild.data;
      }
    }
  }else{ // Probably responseText is valid instead
    // responseXML is now working, will not be developed further.
    sqlquery_Resp = this.req.responseText;
    answerstring = sqlquery_Resp;
  }
  if (answerstring.indexOf(" or ") > 0) {
    divTag.firstChild.data = "Answers: " + answerstring;
  }else{
    divTag.firstChild.data = "Answer: " + answerstring;
  }
  // Erase any old answers
  document.getElementById("inputyouranswer").value = "";
}

function showHint(){
  // onlick handler of the Hint button.
  makeHint();
  showElement('hintcheck');
}

function makeHint(){
  // Creates a hint by replacing certain letters with a * .
  // Future versions would have fancier character replacement, and choosing a few
  // answers out of a string of multiple answers.
  var hintstring = document.getElementById("catanswer").firstChild.data ;
  var hintcheckobj = document.getElementById('hintcheck');
  hintstring = hintstring.replace(/Answer:|Answers:/,"");
  hintstring = hintstring.replace(/[aeiou]/gi,"*");
  hintstring = hintstring.replace(" *r "," or ");
  hintcheckobj.firstChild.data = "Hint: " + hintstring;
}

function checkAnswer(){
  // Examine user's answer for correctness and reports accordingly.
  // Future versions would need much more sophisticated string matching/testing.
  var fullanswer = document.getElementById("catanswer").firstChild.data;
  var youranswer = document.getElementById("inputyouranswer").value;
  if (youranswer.length > 0) {
    if (isTheAnswer(youranswer, fullanswer)){
      // Answer is right
      document.getElementById('hintcheck').firstChild.data = youranswer + " is right!";
      showElement("catanswer");
      var thecategory = findCheckedRadio("category", 4);
      if ((thecategory == "Capital City")||(thecategory == "Big Cities")) {
        showMarker(youranswer);
      }
    }else{
    // Wrong
      document.getElementById('hintcheck').firstChild.data = "Sorry, " + youranswer + " is wrong.";
    }
  } else { // no user answer
    document.getElementById('hintcheck').firstChild.data = "Please enter your answer first.";
  }
  showElement("hintcheck");
}

function isTheAnswer(testanswer, realanswer){
  testanswer = testanswer.toLowerCase() ;
  realanswer = realanswer.toLowerCase() ;
  realanswer = realanswer.replace(/answer: |answers: /,"");
  if ( realanswer.indexOf(testanswer) < 0 ) {
    return false;
  }else{
    // teststring exists in realstring, but still may be wrong answer
    if (realanswer.indexOf(" or ") > 0) {
      // More than a single answer. Find matching string
      var matchloc = realanswer.indexOf(testanswer);
      var ending = realanswer.indexOf(",",matchloc);
      if (ending < 0) ending = realanswer.indexOf(" or ",matchloc);
      if (ending < 0) ending = realanswer.length;
      realanswer = realanswer.slice(matchloc,ending);
    }
    if(testanswer.length == realanswer.length){
      return true;
    }else{
      return false;
    }
  }
}

function initAnswerButton() {
  var answerbutton = document.getElementById("showanswer");
  answerbutton.onclick = function() { showElement('catanswer'); } ;
}

function initHintButton() {
  var hintbutton = document.getElementById("hint");
  hintbutton.onclick = showHint;
}

function initCheckButton() {
  var checkbutton = document.getElementById("checknoshow");
  checkbutton.onclick = checkAnswer;
}

function showElement(id_string){
  document.getElementById(id_string).style.visibility = "visible";
}

function hideElement(id_string){
  document.getElementById(id_string).style.visibility = "hidden";
}

window.onload=function(){
  var geoquiz_contentLoader = new net.ContentLoader("geoquizmap.xml", xmlLoaded);
}


