// ===================================================================
// BibleChapterView
// $Id: BibleChapterView.js 3648 2009-06-13 18:13:04Z helmut $

// BibleChapterView(element)
// - element must have attribute "id"
function BibleChapterView(element, headingElement, aModel)
{
  try {
    if (!element) throw("BibleChapterView(): missing parameter 'element'");
    var orig = element;
    if (typeof element == "string") element = document.getElementById(element);
    if (!element) throw("BibleChapterView(): missing element '" + orig + "' in document");
    this.element = element;
    this.headingElement = headingElement ? document.getElementById(headingElement) : null;
    this._Model = aModel;
  }
  catch (e) {
    Log.error("BibleChapterView: " + e);
  }
}


BibleChapterView.prototype =
{
  _maxSecond2Show: 10,

  toString: function()
  {
    return "BibleChapterView(" + this.element.id + ")";
  },

  _makeID: function(i)
  {
    // use e.g. "_v1" as anchor for verse 1, plus prefix that identifies the view
    return this.element.id + "_" + i;
  },

  _computeVerse: function(chapterNumber, verseNumber)
  {
    try {
    }
    catch (e) {
      Log.error("BibleChapterView._showVerse: " + e);
    }
  },

  _computeParolLinks: function(PAIRS4VERSE)
  {
    try {
      if (!PAIRS4VERSE || !PAIRS4VERSE.length) return "";
      // PAIRS4VERSE may contain duplicate second Parol, i.e. Pairs P1, P2 with P1.getSecond() == P2.getSecond()!

      // pre-process data (pre-computed rates)
      var SECONDQUAL2TUPLE = {};
      for (var i = 0, nPairs = PAIRS4VERSE.length; i < nPairs; ++i) {
        var aPair = PAIRS4VERSE[i];
        var rate = aPair.getYes() - aPair.getNo();
        if (rate <= 0) { continue; }
        var secondQual = aPair.getSecond();
        var ExistingTuple = SECONDQUAL2TUPLE[secondQual];
        if (!ExistingTuple || ExistingTuple[0] < rate) {
          // add new or better pair
          if (!aPair._secondBibleRef) {
            // [BibleRef]
            // if ParolText for this Parol has not yet been read
            // (e.g. Query.Init reads 400 first Parol only),
            // then compute the BibleRef locally for the pair
            aPair._secondBibleRef = new Bible20.Bible.BibleRef().fromParolID(secondQual);
          }
          SECONDQUAL2TUPLE[secondQual] = [rate, secondQual, aPair._secondBibleRef];
        }
      }

      // collect into array
      var SECOND = [];
      for (var S in SECONDQUAL2TUPLE) {
        SECOND.push(SECONDQUAL2TUPLE[S]);
      }

      // 1. sort pairs by descending rate
      SECOND.sort(
          function(a, b) {
            var rate = b[0] - a[0];
            // in case _secondBibleRef is not set: call to PairSet.updateParolCache is missing in BibleStudioModel
            return rate ? rate : a[2].compareTo(b[2]);
          });
    
      // 2. take only the best pairs
      SECOND = SECOND.slice(0, this._maxSecond2Show);
    
      // 3. sort rest by bible reference
      SECOND.sort(
          function(a, b) {
            return a[2].compareTo(b[2]);
          });
    
      // compute links to associated second verses
      var sParolLinks = "";
      var SpaceReplace = /\s/g;
      var QuoteReplace = /\'/g;
      var aParolBox = this._Model.getParolBox();
      for (var i = 0, nSecond = SECOND.length; i < nSecond; ++i) {
        var Tuple = SECOND[i];
        var secondQual = Tuple[1];
        var A = Bible20.Bible.BibleRef.splitParolID(secondQual);
        if (A) {
          if (sParolLinks) {
            sParolLinks += "; ";
          }
          var onclick = "document._Controller.showBibleTextForParolQual(\"" + secondQual + "\"); return false;";
          var aSecondParol = aParolBox.findParol(secondQual);
          // assume there are no <> and & in getLOneLine() result
          var sSecond = aSecondParol ? aSecondParol.getLOneLine().replace(QuoteReplace, "&#38;") : "";
          sParolLinks += "<a href='#' onclick='" + onclick + "' title='" + sSecond + "'>"
            + this._BibleRefFormatter.FormatShort(A[0], A[1], A[2], A[3]).replace(SpaceReplace, "&nbsp;")
            + "</a>";
        }
      }
      return sParolLinks;
    }
    catch (e) {
      alert("BibleChapterView._computeParolLinks: " + e);
    }
  },

  _computeParolInfo: function(aParol)
  {
    try {
      var Info = this._ParolFormatter.getInfo(aParol);
      if (!Info) return "";
  
      var sParolInfo = "<img src='images/" + Info[1] 
      var ref = aParol.getSL();
      if (Info[3]) {
        ref += " (" + Info[3] + ")";
      }
      var onclick = "document._Controller.showParol(\"" + aParol.getID() + "\"); return false;";
      return "<img src='images/" + Info[1] 
        + "' alt='' title='" + Info[2] + " " + ref + " anzeigen' onclick='" + onclick + "'/>";
    }
    catch (e) {
      alert("BibleChapterView._computeParolInfo: " + e);
    }
  },

  _show: function(aChapter, book, chapter)
  {
    try {
      // remember chapter
      this._BibleRef = new Bible20.Bible.BibleRef(book, chapter);
      if (!this._ParolFormatter) {
        this._ParolFormatter = new ParolFormatter(this._Model);
      }
      if (!this._BibleRefFormatter) {
        this._BibleRefFormatter = new Bible20.Bible.BibleRefFormatter();
      }

      var aParolBox = this._Model.getParolBox();
      var aPairSet  = this._Model.getPairSet();

      // provide ALL PAIRS!
      var SecondPerFirst = aPairSet.findSecondPerFirst();

      // initialize arrays of verses
      var VERSES = aChapter.getVerses();
      var vlen = VERSES.length;
      var PAROLINFO = new Array(VERSES.length); // 1-based
      var PAIRS     = new Array(VERSES.length); // 1-based
      for (var v1 = 1; v1 <= vlen; ++v1) {
        PAROLINFO[v1] = "";
        PAIRS[v1]     = [];
      }
      // provide all Parol of the chapter
//TODO 2010-02-13 HS low - handle multiple bibles with different bible references per parol
      var ParolArr = aParolBox.findChapterParols("Schlachter2000", book, chapter);

      // process all Parol of the chapter (fill arrays per verses)
      for (var p = 0, plen = ParolArr.length; p < plen; ++p) {
        var aParol = ParolArr[p];
        var id = aParol.getID();
        var A = Bible20.Bible.BibleRef.splitParolID(id);
        if (!A) continue;

        //alert("mapping id="+id);
        var startVerseNumber = A[2];
        var endVerseNumber = A[3] || startVerseNumber;

        // remember pairs (only for start verse of Parol)
        var SECOND = SecondPerFirst[id];
        if (SECOND) {
          PAIRS[startVerseNumber] = PAIRS[startVerseNumber].concat(SECOND);
        }

        // compute PAROLINFO (per verse)
        for (var v = startVerseNumber; v <= endVerseNumber; ++v) {
          PAROLINFO[v] += this._computeParolInfo(aParol);
        }
      }

      // process heading
      if (this.headingElement) {
        this.headingElement.innerHTML = this._BibleRefFormatter.Format(book, chapter);
      }

      // finally concat strings of all verses
      var res = "";
      res += "<table>";
      for (var i = 1; i <= vlen; ++i) {
        var text = aChapter.getVerse(i).getText();
        if (!text) continue; // be defensive about missing verses

        // start of <tr>
        res += "<tr id='" + this._makeID(i) + "'>";
        var sParolLinks = this._computeParolLinks(PAIRS[i]);
        res += "<td>" + PAROLINFO[i] + "</td>"
          + "<td class='VerseNumber'>" + i + "</td>"
          + "<td class='VerseText'>" + text + "</td>"
          + "<td class='VerseSecondLinks'>" + sParolLinks + "</td>"
          + "</tr>";
      }
      res += "</table>";

      // --- show text (even empty chapter) ---
      // avoid overwrite of text written in showText()!
      if (res) {
        this.element.innerHTML = res;
        this._SelectedVerses = null;
      }
    }
    catch (e) {
      Log.error("BibleChapterView._show: " + e);
    }
  },

  showText: function(text)
  {
    try {
      this.element.innerHTML = text;
      this._SelectedVerses = null;
    }
    catch (e) {
      Log.error("BibleChapterView.showText: " + e);
    }
  },

  update: function(book, chapter, aChapter)
  {
    try {
      this._show(aChapter || Bible20.Bible.Chapter.NULL, book, chapter);
    }
    catch (e) {
      Log.error("BibleChapterView.update: " + e);
    }
  },

  getBibleRef: function()
  {
    return this._BibleRef;
  },

  // selectVerse:
  // if bScrollIntoView is not null, it must be true (= scroll to top) or false (= scroll to bottom),
  // and P.scrollIntoView(bScrollIntoView) is called
  selectVerse: function(verseNumberStart, verseNumberEnd, bScrollIntoView)
  {
    try {
      if (this._BibleRef) {
        this._BibleRef = new Bible20.Bible.BibleRef(
          this._BibleRef.getBook(),
          this._BibleRef.getChapterNumber(),
          verseNumberStart,
          verseNumberEnd);
      }

      if (!verseNumberEnd) verseNumberEnd = verseNumberStart;
      if (this._SelectedVerses) {
        for (var i = 0, len = this._SelectedVerses.length; i < len; ++i) {
          this._SelectedVerses[i].className = "nonSelectedVerse";
        }
      }
      this._SelectedVerses = [];
      var bFirst = true;
      for (var v = verseNumberStart; v <= verseNumberEnd; ++v) {
        var P = document.getElementById(this._makeID(v));
        if (P) {
          this._SelectedVerses.push(P);
          P.className = "selectedVerse";
          if (bFirst) {
            if (bScrollIntoView != null) {
              P.scrollIntoView(bScrollIntoView);
            }
            bFirst = false;
          }
        }
      }
    }
    catch (e) {
      Log.error("BibleChapterView.selectVerse: " + e);
    }
  },

  // === Fonts ===

  getFontSize: function()
  {
    return this.element.style.fontSize;
  },

  getFontFamily: function()
  {
    return this.element.style.fontFamily;
  },

  setFontSize: function(size)
  {
    // size may be empty!
    this.element.style.fontSize = size;
  },

  setFontFamily: function(family)
  {
    this.element.style.fontFamily = family;
  },

  // === Direction ===

  setLang: function(lang)
  {
    // TODO low HS 2009-12-31 - support RTL languages in BibleChapterView
    //    var lang = this.EditModel.getLang();
    // 2008-11-05 HS: "fa" stated in
    // https://developer.mozilla.org/En/Making_Sure_Your_Theme_Works_with_RTL_Locales
    var dir = (lang == "he" || lang == "ar" || lang == "fa") ? "rtl" : "ltr";
    this.element.style.direction = dir;
  }
}

