var AJAJObj = new Object();

actASAP("addWordForm", function() { AsyncSubmit(); });
actASAP("ccWord", function() { getEl("ccWord").focus(); });
// For the next two, we can't act as soon as the relevant container exists, because we're
// not guaranteed that everything in that container has been created when the function fires.
// So we trigger when the container below exists, guaranteeing that the container we're
// interested in has been created and filled. This depends on HTML order, of course
actASAP("clues", function() { allWordLinks(); });
actASAP("balloon", function() { allClueLinks(); });

function allWordLinks() {
  if (getEl("words")) {
    var wordDiv = getEl("words");
    var links = wordDiv.getElementsByTagName("a");
    for(var i=0; i<links.length; i++) {
      links[i].onclick = function() { showClueBalloon(this); return false; };
      classAdd(links[i], "ajaxLink");
    }
  }
}

function allClueLinks() {
  if (getEl("clues")) {
    var wordDiv = getEl("clues");
    var dlChildren = ["dt", "dd"];
    for (var c=0; c<dlChildren.length; c++) {
      var dts = wordDiv.getElementsByTagName(dlChildren[c]);
      for(var i=0; i<dts.length; i++) {
        if (dts[i].childNodes.length && dts[i].childNodes[0].tagName == "A") {
          var dtLink = dts[i].childNodes[0];
          dtLink.onmouseover = function() { clueLinkMouse(this, 1); }
          dtLink.onmouseout = function() { clueLinkMouse(this, 0); }
          dtLink.onclick = function() { clueLinkClick(this); }
        }
      }
    }
  }
}

function AsyncSubmit() {
  var form=getEl("addWordForm");
  form.onsubmit = function () {
    var curPageDate = getEl("curDayField").value.split("-");
    var curClueDate = getEl("ccDate").value.split("-");
    if (parseInt(curPageDate[0], 10)==parseInt(curClueDate[0], 10) && // year,
        parseInt(curPageDate[1], 10)==parseInt(curClueDate[1], 10) && // month,
        parseInt(curPageDate[2], 10)==parseInt(curClueDate[2], 10)) { // and day must match
      // if going to a different day, go ahead and reload full page 
      var postStr = "word="+getEl("ccWord").value+"&clue="+getEl("ccClue").value+
                    "&date="+getEl("ccDate").value+"&page=enter&async=1";
      var dbWriteUrl = "http://crossword.toddstadler.com/db_write.php";
      getEl("wait").style.display = "block";
      GoAJAJ(AJAJObj, postStr, dbWriteUrl, "POST", wordAddHandler)
      return false;
    }
  }
}

function wordAddHandler() {
  getEl("ccWord").value = "";
  getEl("ccClue").value = "";
  getEl("ccWord").focus();
  if (AJAJObj.results.wordCount) { // must be >= 1 or it didn't work
    var curClueDate = getEl("ccDate").value.split("-");
    var curClueYr = parseInt(curClueDate[0], 10);
    var curClueMo = parseInt(curClueDate[1], 10);
    curClueMo = (curClueMo<10) ? "0"+curClueMo : curClueMo; // make sure of leading 0
    var curClueDy = parseInt(curClueDate[2], 10);
    curClueDy = (curClueDy<10) ? "0"+curClueDy : curClueDy; // make sure of leading 0
    var curDl = getEl("dl"+curClueYr+curClueMo+curClueDy);
    var curDtAry = curDl.getElementsByTagName("dt");
    var found = 0;
    var dtTooFar = null;
    for (var i=0; (i<curDtAry.length && !found); i++) { // loop through word/dt list
      var dtWord = curDtAry[i].firstChild.firstChild.nodeValue;
      if (dtWord > AJAJObj.results.word) { // we've gone one DT too far
        dtTooFar = curDtAry[i];
        found = 1;
      }
    }
    // insert the new clue in a new DD
    var newDd = document.createElement("dd");
    newDd.id = "dd"+AJAJObj.results.clueId;
    newDd.appendChild(newDdA = document.createElement("a"));
    newDdA.href = "edit.php?clueid="+AJAJObj.results.clueId;
    newDdA.onmouseover = function() { clueLinkMouse(this, 1); }
    newDdA.onmouseout = function() { clueLinkMouse(this, 0); }
    newDdA.onclick = function() { clueLinkClick(this); }
    newDdA.title = "Edit this word/clue pair";
    var fixedClue = AJAJObj.results.clue.replace(/\\\"/g, '"');
    newDdA.innerHTML = fixedClue.replace(/\\\'/g, "'"); // not DOM due to <i> in clues 
    curDl.insertBefore(newDd,dtTooFar);
    // insert the new word in a new DT
    var newDt = document.createElement("dt");
    newDt.id = "dt"+AJAJObj.results.clueId;
    newDt.appendChild(newDtA = document.createElement("a"));
    newDtA.onmouseover = function() { clueLinkMouse(this, 1); }
    newDtA.onmouseout = function() { clueLinkMouse(this, 0); }
    newDtA.onclick = function() { clueLinkClick(this); }
    newDtA.href = "edit.php?clueid="+AJAJObj.results.clueId;
    newDtA.title = "Edit this word/clue pair";
    newDtA.appendChild(newDtAText = document.createTextNode(AJAJObj.results.word));
    curDl.insertBefore(newDt,newDd);
    for (var i=recentClueNum; i>0; i--) { // recentClueNum set by PHP
      var iPlus = i+1;
      var newClass = (i == recentClueNum) ? "" : "recent"+iPlus;
      var oldClass = "recent"+i;
      if (getEl("dt"+recentCluesAry[i])) {
        classRemove(getEl("dt"+recentCluesAry[i]), oldClass);
        classAdd(getEl("dt"+recentCluesAry[i]), newClass);
      }
      if (getEl("dd"+recentCluesAry[i])) {
        classRemove(getEl("dd"+recentCluesAry[i]), oldClass);
        classAdd(getEl("dd"+recentCluesAry[i]), newClass);
      }
      recentCluesAry[i] = (i > 1) ? recentCluesAry[i-1] : AJAJObj.results.clueId;
    }
    classAdd(getEl("dt"+AJAJObj.results.clueId), "recent1");
    classAdd(getEl("dd"+AJAJObj.results.clueId), "recent1");
    if (AJAJObj.results.wordCount > 1) { // if our word is a multiple repeat one ...
      var newCount = AJAJObj.results.wordCount;
      var curUl;
      if (getEl("repeatList"+newCount)) {
        curUl = getEl("repeatList"+newCount); // where to insert word
      } else {  // create a new UL and insert it
        var oldDiv = null;
        for (var i=newCount-1; !oldDiv && i; i--) {
          oldDiv = getEl("repeatDiv"+i); // look backwards, counting down, until we find div
        }
        var newDiv = document.createElement("div");
        newDiv.id = "repeatDiv"+newCount;
        getEl("words").insertBefore(newDiv, oldDiv); // make the new count div
        var newDivH3;
        newDiv.appendChild(newDivH3 = document.createElement("h3"));
        newDivH3.id = "repeatHead"+newCount;
        newDivH3.appendChild(newH3Text = document.createTextNode(""+newCount+" times"));
        var newH3Span = document.createElement("span");
        newH3Span.appendChild(newH3SpanText = document.createTextNode("(0 words)"));
        newDivH3.insertBefore(newH3Span, newH3Text); // make the new H3 header
        newDiv.appendChild(curUl = document.createElement("ul"));
        curUl.id = "repeatList"+newCount;
      }
      var curLiAry = curUl.getElementsByTagName("li");
      var found = 0;
      var liTooFar = null;
      for (var i=0; (i<curLiAry.length && !found); i++) { // loop through word/li list
        var liWord = curLiAry[i].firstChild.firstChild.nodeValue;
        if (liWord > AJAJObj.results.word) { // we've gone one LI too far
          liTooFar = curLiAry[i];
          found = 1;
        }
      }
      if (newCount > 2) {  // delete the new word from the old UL where it was
        var oldWordCount = newCount-1;
        var deleteLi = getEl("word"+AJAJObj.results.wordID).parentNode;
        var deleteUl = deleteLi.parentNode;
        deleteUl.removeChild(deleteLi);
        // need to update count of n-repeat words here
        var oldCountTxt = getEl("repeatHead"+oldWordCount).firstChild.firstChild;
        var newOldCount = parseInt(oldCountTxt.nodeValue.match(/\d+/), 10) - 1;
        var countWord = (newOldCount > 1) ? "words" : "word";
        var newOldCountStr = "(" + newOldCount + " " + countWord + ")";
        var newOldCountTxt = document.createTextNode(newOldCountStr);
        oldCountTxt.parentNode.replaceChild(newOldCountTxt, oldCountTxt);
        var liAry = deleteUl.getElementsByTagName("li");
        if (liAry.length == 0) {  // just deleted the last LI in that UL
          var deleteDiv = deleteUl.parentNode;
          deleteDiv.parentNode.removeChild(deleteDiv); // get rid of that DIV
        } 
      }
      // insert the new word in the new UL
      var newLi = document.createElement("li");
      newLi.appendChild(newLiA = document.createElement("a"));
      newLiA.id = "word"+AJAJObj.results.wordID;
      newLiA.href = "word.php?wordid="+AJAJObj.results.wordID;
      newLiA.title = "Click to show all clues with answer: ";
      newLiA.title += AJAJObj.results.word.toUpperCase();
      newLiA.appendChild(newLiAText = document.createTextNode(AJAJObj.results.word));
      newLiA.onclick = function() { showClueBalloon(this); return false; };
      classAdd(newLiA, "ajaxLink");
      curUl.insertBefore(newLi,liTooFar);
      for (var i=recentRepeatNum; i>0; i--) { // recentRepeatNum set by PHP
        var iPlus = i+1;
        var newClass = (i == recentRepeatNum) ? "" : "recent"+iPlus;
        var oldClass = "recent"+i;
        classRemove(getEl("word"+recentRepeatsAry[i]), oldClass);
        classAdd(getEl("word"+recentRepeatsAry[i]), newClass);
        recentRepeatsAry[i] = (i > 1) ? recentRepeatsAry[i-1] : AJAJObj.results.wordID;
      }
      classAdd(getEl("word"+AJAJObj.results.wordID), "recent1");
      var curCountTxt = getEl("repeatHead"+newCount).firstChild.firstChild;
      var change = (i == 0) ? 1 : -1; // increase new count, decrease old one
      var newCountNum = parseInt(curCountTxt.nodeValue.match(/\d+/), 10) + change;
      var countWord = (newCountNum > 1) ? "words" : "word";
      var newCountStr = "(" + newCountNum + " " + countWord + ")";
      var newCountTxt = document.createTextNode(newCountStr);
      curCountTxt.parentNode.replaceChild(newCountTxt, curCountTxt);
    }
    getEl("wait").style.display = "none";
  }
}

function showClueBalloon(el) {
  var WordID = el.id.substr(4);
  var linkTag = getEl(el.id);
  var offsetY = 0;
  var offsetX = 0;
  for (var elem = linkTag; elem != null; elem = elem.offsetParent) {
    offsetX += elem.offsetLeft;
    offsetY += elem.offsetTop;
  }
  var wordBalloon = getEl("balloon");
  wordBalloon.style.visibility = "hidden";
  var queryStr = "wordid="+WordID+"&x="+offsetX+"&y="+offsetY;
  var getWordInfoUrl = "http://crossword.toddstadler.com/js/word2json.php";
  GoAJAJ(AJAJObj, queryStr, getWordInfoUrl, "GET", buildWordBalloon)
}

function balloonHide() {
  getEl("balloon").style.visibility = "hidden";
//  getEl("ccWord").focus();  // this doesn't work, but too lazy to look why
  return false;
}

function buildWordBalloon() {
  lnkX = AJAJObj.results.x;
  lnkY = AJAJObj.results.y;
  var h2 = getEl("balloonH2");
  while(h2.firstChild) { h2.removeChild(h2.firstChild); }
  h2.appendChild(document.createTextNode(AJAJObj.results.word));
  var dl = getEl("balloonDl");
  while(dl.firstChild) { dl.removeChild(dl.firstChild); }
  for(var i=0; i<AJAJObj.results.clues.length; i++) {
    var clueDt = document.createElement("dt");
    clueDt.appendChild(document.createTextNode(AJAJObj.results.clues[i].date));
    var clueDd = document.createElement("dd");
//    clueDd.appendChild(document.createTextNode(AJAJObj.results.clues[i].clue));
// DOM is cool, but innerHTML makes it easier to handle (e.g.) <i> tags in the clue response
    clueDd.innerHTML = AJAJObj.results.clues[i].clue;
    dl.appendChild(clueDt);
    dl.appendChild(clueDd);
  }

  var wordBalloon = getEl("balloon");
  var scrollDist = (document.documentElement && document.documentElement.scrollTop) ?
    document.documentElement.scrollTop : document.body.scrollTop;
  var windowHeight = (document.documentElement && document.documentElement.clientHeight) ?
    document.documentElement.clientHeight : document.body.clientHeight;
  var balloonBottom = lnkY+wordBalloon.clientHeight-scrollDist+5;
  var yDelta = 0;
  if (balloonBottom > windowHeight) {
    classRemove(wordBalloon, "balloonUp");
    classAdd(wordBalloon, "balloonDown");
    yDelta = 15 - wordBalloon.clientHeight;
  } else {
    classRemove(wordBalloon, "balloonDown");
    classAdd(wordBalloon, "balloonUp");
    yDelta = 15;
  }
  wordBalloon.style.top = (lnkY+yDelta)+"px";
  wordBalloon.style.left = (lnkX-270)+"px";
  wordBalloon.style.visibility = "visible";
}

function clueLinkMouse(el, over) {
  var elId = el.parentNode.id.substr(2);
  var thisDd = getEl("dd"+elId);
  var thisDt = getEl("dt"+elId);
  if (over) {
    classAdd(thisDd, "ajaxLinkHover");
    classAdd(thisDt, "ajaxLinkHover");
  } else {
    classRemove(thisDd, "ajaxLinkHover");
    classRemove(thisDt, "ajaxLinkHover");
  }
}

function clueLinkClick(el) {
  var elId = el.parentNode.id.substr(2);
  var thisDd = getEl("dd"+elId);
  var thisDt = getEl("dt"+elId);
// **************** still working on this, then? **********************
//  thisDd.firstChild.className = thisClass;
//  thisDt.firstChild.className = thisClass;
}