// ===================================================================
// ParolBoxReader


var Bible20;
if (!Bible20) {
  Bible20 = {};
}
else if (typeof Bible20 != "object") {
  throw new Error("Bible20 already exists and is not an object");
}

if (!Bible20.Parol) {
  Bible20.Parol = {};
}
else if (typeof Bible20.Parol != "object") {
  throw new Error("Bible20.Parol already exists and is not an object");
}

Bible20.Parol.ParolBoxReader = function()
{
  this._NS = "http://bible2.net/service/Parol/ParolBoxList";
}

Bible20.Parol.ParolBoxReader.prototype._flatten = function(node)
{
  try {
    //TODO low HS 2009-12-31 - check ParolBoxReader._flatten implementation for handling of <em>...</em>
    // value as from file may contain "<em>...</em>"
    var s = "";
    while (node) {
      if (node.nodeType == 1) { // Node.ELEMENT_NODE not available in IE6
        var childText = node.firstChild.data;
        if (node.nodeName == "em") {
          s += "<em>" + childText + "</em>"; // surround by delimiters
        }
        else {
          s += childText; // just flatten
        }
      }
      else if (node.nodeType == 3) { // Node.TEXT_NODE not available in IE6
        s += node.data;
      }
      // else: ignore all node types except element and text
      node = node.nextSibling;
    }
    return s;
  }
  catch (e) {
    alert("ParolBoxReader._flatten: " + e);
  }
}

Bible20.Parol.ParolBoxReader.prototype._readPerson = function(aParol, entry, person, method)
{
  try {
    var Person = entry.getElementsByTagName(person)[0];
    if (Person) {
//TODO 2010-02-19 low HS - 0..n author
      aParol[method](Person.getElementsByTagName("name")[0].firstChild.data);
    }
  }
  catch (e) {
    alert("ParolBoxReader._readPerson: " + e.name + ": " + e.message);
  }
}

Bible20.Parol.ParolBoxReader.prototype._readCategories = function(target, element)
{
  try {
    var Categories = Bible20.Parol.ParolBoxReader._getChildrenByTagName(element, "category");
    //Log.debug("Bible20.Parol.ParolBoxReader._readCategories: Categories.length="+Categories.length);
    for (var i = 0; i < Categories.length; ++i) {
      var Category = Categories[i];
      var term = Category.getAttribute("term");
      if (term) {
        var value = Category.firstChild ? Category.firstChild.data : "";
        //Log.debug("ParolBoxReader._readCategories(" + term + ", " + value + ")");//TODO
        if (term == "State" || term == "TextState") {
          value = Number(value);
        }
        target.addCategory(term, value);
      }
    }
  }
  catch (e) {
    alert("ParolBoxReader._readCategories: " + e.name + ": " + e.message);
  }
}

Bible20.Parol.ParolBoxReader.prototype.readParol = function(aParol, entry)
{
  try {
    aParol.setID     (entry.getElementsByTagName("id"     )[0].firstChild.data);
    aParol.setUpdated(entry.getElementsByTagName("updated")[0].firstChild.data);

    this._readPerson(aParol, entry, "author", "setAuthor");

    // read categories, first set defaults
    aParol.addCategory("State", 100);
    aParol.addCategory("TextState", 100);
    // Notes for Parol.getNote() are read implicitly via _readCategories
    this._readCategories(aParol, entry);

    // === setup references to IL, L, SL

    var div = entry.getElementsByTagName("div")[0];
    if (div) {
      var pArr = div.getElementsByTagName("p");
      // process all div.P elements
      for (var i = 0; i < pArr.length; ++i) {
        var p = pArr[i];
        if (p.firstChild) {
          // 2009-04-07 HS: IE6 sucks (for HTML in XML at least, some may work in pure HTML):
          //   p.className                 => undefined
          //   p.attributes['class'].value => "Null oder kein Objekt"
          //   p.getAttribute("class")     => ok
          // All three work in Firefox 2!
          aParol["set" + p.getAttribute("class")].call(aParol, this._flatten(p.firstChild)); // setup reference to IL, L, SL
        }
      }
    }
    return this;
  }
  catch (e) {
    alert("ParolBoxReader.readParol: " + e.name + ": " + e.message);
  }
}

Bible20.Parol.ParolBoxReader.prototype.readEntries = function(aParolBox, xmlDoc)
{
  try {
    if (!xmlDoc) throw new Error("ParolBoxReader.read - no xmlDoc");

    var entries = xmlDoc.getElementsByTagName("entry");
    //alert("Bible20.Parol.ParolBoxReader.prototype.readFromDom: read " + entries.length + " entries");
    // var s="XXX ";
    for (var r = 0; r < entries.length; ++r) {
      var entry = entries[r];

      // PairSetDomReader.js creates new Parol with just ID set,
      // allow to find this here and fill in the other properties
      // (but no existing properties will be reset - do not use to overwrite filled Parol!)
      var ID = (entry.getElementsByTagName("id")[0].firstChild.data);
      var aParol = aParolBox.findParol(ID);
      if (aParol) {
        // be sure to reset properties if Parol is read a second time (e.g. after edit)
        aParol.clearOptional();
        this.readParol(aParol, entry);
      }
      else {
        //s += " " + (entry.getElementsByTagName("id")[0].firstChild.data);
        aParol = new Bible20.Parol.Parol();
        this.readParol(aParol, entry);
        //alert("ParolBoxReader.read: adding id " + aParol.getID());

        var aBibleRef = new Bible20.Bible.BibleRef().fromParolID(aParol.getID());
        // [BibleRef]: store BibleRef object in each Parol (e.g. for sorting), 
        aParol.setBibleRef(aBibleRef);

        // append AFTER readParol (needs ID)!
        aParolBox.append(aParol);
      }
    }
    // alert("XXX ParolBoxReader.read=>" + s);
  }
  catch (e) {
    alert("ParolBoxReader.readEntries: " + e);
  }
}

// static function
Bible20.Parol.ParolBoxReader._getChildrenByTagName = function(node, name)
{
  var res = [];
  //var s="";
  for (var Child = node && node.firstChild; Child; Child = Child.nextSibling) {
    //if (Child.nodeType == 1) s+="<"+Child.nodeName+">\n";
    if (Child.nodeType == 1 && Child.nodeName.toLowerCase() == name) {
      res.push(Child);
    }
  }
  //alert("Bible20.Parol.ParolBoxReader._getChildrenByTagName: children = "+s);
  return res;
}

// read(aParolBox, xmlDoc, adaptFunc)
// xmlDoc may be ancestor of "feed" node or "feed" node itself
// Puts data into aParolBox.
// Calls adaptFunc (if given) for each Parol.

Bible20.Parol.ParolBoxReader.prototype.read = function(aParolBox, xmlDoc, adaptFunc, bWithNamespaces)
{
  try {
    if (!xmlDoc) throw new Error("ParolBoxReader.read - no xmlDoc");

    // in Html document, tags are returned upper case => use toLowerCase()
    var feed = (xmlDoc.nodeName.toLowerCase() == "feed" && xmlDoc) || xmlDoc.getElementsByTagName("feed")[0];

    this._readCategories(aParolBox, feed);

    this.readEntries(aParolBox, xmlDoc, adaptFunc);
  }
  catch (e) {
    alert("ParolBoxReader.read: " + e.name + ": " + e.message);
  }
}

