// ==UserScript==
// @name          LDS Scripture Columnizer
// @namespace     http://spig.net/
// @description   Columnize the scripture verses on scriptures.lds.org
// @include       http://scriptures.lds.org/*
// @exclude       http://scriptures.lds.org/*/*/*/*
// @exclude       http://scriptures.lds.org/*/search*
// @date          2007-10-18
// @GM_version    0.6.4
// @version       0.1.24
// ==/UserScript==

// function lifted from http://www.dustindiaz.com/getelementsbyclass
function getElementsByClass(searchClass,node,tag) {
  var classElements = new Array();
  if ( node == null )
    node = document;
  if ( tag == null )
    tag = '*';
  var els = node.getElementsByTagName(tag);
  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
}

// lifted from the greasemonkey guide
function addGlobalStyle(css) {
  var head, style;
  head = document.getElementsByTagName('head')[0];
  if (!head) { return; }
  style = document.createElement('style');
  style.type = 'text/css';
  style.innerHTML = css;
  head.appendChild(style);
}

function addTopLink(parent) {
  // append a link to the top anchor so that you can return to the top
  brTag1 = document.createElement("br");
  brTag2 = document.createElement("br");
  
  parent.appendChild(brTag1);
  parent.appendChild(brTag2);
  
  linkTag = document.createElement("a");
  linkTag.href = window.location.href + "#top";
  linkTag.innerHTML = "To Top of Page ^";
  
  parent.appendChild(linkTag);
}

function cleanHtml(html) {
  // replace tags and html entities to help get a better length calculation
  html = html.toString().replace(/<[^>]*?>/g, "");
  html = html.replace(/&[^;]*?;/g, "");
  return html;
}

// first, create new columns for the verses
cols = new Array();
cols[0] = document.createElement("div");
cols[1] = document.createElement("div");
cols[2] = document.createElement("div");
cols[0].id="col1";
cols[0].className="verseColumn";
cols[0].style.width="30%";
cols[1].id="col2";
cols[1].className="verseColumn";
cols[1].style.width="30%";
cols[1].style.marginLeft="3%";
cols[1].style.marginRight="3%";
cols[2].id="col3";
cols[2].className="verseColumn";
cols[2].style.width="30%";

// next, grab all elements that are verses and other wanted elements
// available classes: title, preface, subtitle, summary, verse, note
// it is assumed that all above fields could exist more than once
// verses is almost guaranteed to exist more than once - unless it's a really short chapter (I don't know of any)
// only get the verses and notes and then add them back on
verses = getElementsByClass("verse");
notes = getElementsByClass("note");

var parent = verses[0].parentNode;

// get the total length of all verses
totalLengthOfVerses = 0;
for (var i=0; i<verses.length; i++) {
  totalLengthOfVerses += cleanHtml(verses[i].innerHTML).length;
}

avgLengthOfVerses = cleanHtml(verses[0].innerHTML).length;
if (verses.length > 2) avgLengthOfVerses = totalLengthOfVerses / 3;
currentLength = 0;
currentColumn = 0;
for (var i=0; i<verses.length; i++) {
  html = cleanHtml(verses[i].innerHTML);
  if (currentLength + html.length <= avgLengthOfVerses) {
    currentLength += html.length;
  }
  else {
    if (i>0 && currentColumn < 2) { addTopLink(verses[i-1]); }
    currentColumn += 1;
    currentLength = html.length;
  }

  // just make sure we don't go past our expected columns
  if (currentColumn > 2) { currentColumn = 2; }

  cols[currentColumn].appendChild(verses[i]);
}

// next attach new columns and supporting elements after summary
if (parent != null) {
  // add an anchor to right above the verses columns
  linkTag = document.createElement("a");
  linkTag.name = "top";
  parent.appendChild(linkTag);
  
  // append columns
  parent.appendChild(cols[0]);
  parent.appendChild(cols[1]);
  parent.appendChild(cols[2]);
  
  // clear the bottom
  brTag = document.createElement("br");
  brTag.style.clear="both";
  parent.appendChild(brTag);

  // append the notes after so that it reappends the same objects after the verses
  for (var i=0; i<notes.length; i++) {
    parent.appendChild(notes[i]);
  }
}

// lastly, apply style to verses class
// addGlobalStyle('div.verse { width: 280px; }');
addGlobalStyle('div.verseColumn { float: left; }');
