/* Javascript for the publicnotes project. */

var PN = { 

/* variables:  */
bases: new Array(),

activeBase: undefined,

pointerImage: undefined,

noteWidth: "45%",

/* number of pixels away from the left-hand edge of the screen that we'll place a note */
leftMostEdge: 10,
topMostEdge: 10,

commentaryHeader: undefined,
noteNav: undefined,
mainText: undefined,
framingBlock: undefined,
allNotes: document.createElement("DIV"),

displayAllCommentary: "To read only the annotations, click here",
collapseAllCommentary: "To hide annotations and show Klein's speech, click here",

noteBorderWidth: 3,
noteBorderStyle: "solid red",

onLoad: function() {
	/* precache the pointer image. */
	PN.createPointer();
	var x = 0;
  	var n = document.getElementById("note" + x);
  	var b = document.getElementById("base" + x);
	while (n != undefined && b != undefined) {
		PN.bindBaseToNoteLink(b,n);

	/* get the next note. */
		x++;
	  	n = document.getElementById("note" + x);
  		b = document.getElementById("base" + x);
	};

  	PN.mainText = document.getElementById("maintext");
  	PN.framingBlock = document.getElementById("framing");
	PN.noteNav = document.createElement("DIV");
	PN.noteNav.className = "note-navigation";
	PN.noteNav.id = "note-navigation";

	PN.noteNav.revert = document.createElement("A");
	PN.noteNav.revert.appendChild(document.createTextNode(PN.displayAllCommentary));
        PN.noteNav.revert.href = "#note-navigation";
	PN.noteNav.revert.onclick = function() { PN.getAllNotes(PN.allNotes);
			PN.allNotes.className = "maintext";
			PN.mainText.parentNode.replaceChild(PN.allNotes, PN.mainText);
			PN.noteNav.revert.style.display = "none"; 
			PN.noteNav.collapse.style.display = "inline";
			return false; };

	PN.noteNav.collapse = document.createElement("A");
	PN.noteNav.collapse.appendChild(document.createTextNode(PN.collapseAllCommentary));
        PN.noteNav.collapse.href = "#note-navigation";
	PN.noteNav.collapse.onclick = function() { PN.collapseAllNotes();
			PN.allNotes.parentNode.replaceChild(PN.mainText, PN.allNotes);
			PN.noteNav.revert.style.display = "inline"; 
			PN.noteNav.collapse.style.display = "none"; 
			return false; };
	PN.noteNav.collapse.style.display = "none";

	PN.noteNav.appendChild(PN.noteNav.revert);
	PN.noteNav.appendChild(PN.noteNav.collapse);
	PN.framingBlock.appendChild(PN.noteNav);

	PN.commentaryHeader = document.getElementById("note-section-header");
	if (PN.commentaryHeader) {
		PN.commentaryHeader.style.display = "none";
	}
 
	window.onresize = PN.handleResize;
},


handleResize: function() {
	if (undefined != PN.activeBase) {
		var b = PN.activeBase;
		PN.baseTrigger(b);
		PN.baseTrigger(b);
	}
},

bindBaseToNoteLink: function(base, notelink) {
	var allnote = document.createElement("DIV");
	var fullnote = notelink.parentNode;
   	allnote.appendChild(fullnote);
	allnote.noteTitle = notelink;
	allnote.contents = fullnote;
	PN.wrapShadow(fullnote); 
	allnote.attribution = PN.addAttribution(fullnote, allnote.noteTitle);
	allnote.closeBox = PN.addCloseBox(fullnote, base);

	allnote.noteTitle.style.display = "none";
	allnote.className = "notewrapper";
	allnote.style.display = "none";
	base.parentNode.insertBefore(allnote, base.nextSibling);
	PN.dismissNote(allnote);
	base.assocNote = allnote;
	allnote.assocBase = base;
	base.title = "Click for notes";
	base.onclick = function() { return PN.baseTrigger(this); };
/*	base.onmouseover = function() { return PN.baseTrigger(this); }; */

/* push onto bases: */
        PN.bases[PN.bases.length] = base;
},

collapseAllNotes: function() {
  var ix = 0;

  if (PN.activeBase)
     PN.activeBase.className = "";

  if (PN.pointerImage)
     PN.pointerImage.style.display = "inline";

  while (ix < PN.bases.length) {
    var base = PN.bases[ix];
    var note = base.assocNote;
 
    note.noteTitle.style.display = "none";
    note.style.display = "none";
    note.closeBox.style.display = "inline";
    note.attribution.style.display = "block";
    base.parentNode.insertBefore(note, base.nextSibling);
    base.onclick = function() { return PN.baseTrigger(this); };

    ix++;
  }
},

getAllNotes: function(el) {
  var ix = 0;

  if (PN.activeBase)
     PN.baseTrigger(PN.activeBase);

  if (PN.pointerImage)
     PN.pointerImage.style.display = "none";

  while (ix < PN.bases.length) {
    PN.bases[ix].onclick = function() {return true;};
    var n = PN.bases[ix].assocNote;

    n.style.display = "block";
    n.style.position = "static";
    n.style.width = "100%";
    n.closeBox.style.display = "none";
    n.noteTitle.style.display = "none";
    n.attribution.style.display = "none";
    n.contents.style.border = "none";

    el.appendChild(n);
    ix++;
  }
},

addCloseBox: function(closetarget, baseobj) {
  var newimg = document.createElement("IMG");
  newimg.src = "close.png";
  newimg.alt = "Close Note";
  newimg.title = "Close Note";
  newimg.className = "closebox";
  newimg.style.cursor = "pointer";
  newimg.assocBase = baseobj;
  newimg.onclick = function() { return PN.baseTrigger(this.assocBase); };
  closetarget.insertBefore(newimg, closetarget.firstChild);
  return newimg;
},

dismissNote: function(n) {
	n.style.display = "none";
        if (n.pointer)
          n.removeChild(n.pointer);
        n.pointer = undefined;
},


displayNote: function(n) {
	var xx = PN.findPos(n.assocBase);
	n.contents.style.border = PN.noteBorderWidth + "px " + PN.noteBorderStyle;
	n.style.position = "absolute";
	n.style.width = PN.noteWidth;
	n.style.display = "block";

	var dist = 7;
	var down = 2;

/*         n.pointer = n.appendChild(PN.createDiagonalTable(2*dist + off, off)); */
	n.pointer = n.appendChild(PN.createPointer());
        n.pointer.style.position = "absolute";
	n.pointer.style.left = (n.offsetWidth/2 + n.pointer.offsetWidth) + "px";
	n.pointer.style.bottom = (PN.noteBorderWidth - n.pointer.offsetHeight) + "px";

	var l = (xx[0] - n.offsetWidth/2);
	if (l < PN.leftMostEdge)
		l = PN.leftMostEdge;
	n.style.left = l + "px";
	var t = (PN.noteBorderWidth + down + xx[1] - n.offsetHeight - n.pointer.offsetHeight);
	if (t < PN.topMostEdge)
		t = PN.topMostEdge;
	n.style.top = t + "px";

/* consider scrolling the page so that the full note is visible.
http://www.quirksmode.org/viewport/compatibility.html would be useful
for this. in particular, document.body.{scrollWidth,scrollHeight} */
	var soff = PN.getScrollOffset();
	if (soff.y > t - PN.topMostEdge)
		scrollTo(soff.x, t - PN.topMostEdge);
},

/* thanks again, PPK.  From http://www.quirksmode.org/viewport/compatibility.html  */
getScrollOffset: function() {
	var x,y;
	if (self.pageYOffset) // all except Explorer
	{ //alert("a " + self.pageYOffset);
		x = self.pageXOffset;
		y = self.pageYOffset;
	}
	else if (document.documentElement && document.documentElement.scrollTop)
	// Explorer 6 Strict
	{ //alert("b " + document.documentElement.scrollTop);
		x = document.documentElement.scrollLeft;
		y = document.documentElement.scrollTop;
	}
	else if (document.body) // all other Explorers
	{ //alert("c " + document.body.scrollTop);
		x = document.body.scrollLeft;
		y = document.body.scrollTop;
	}
	return {x: x, y: y};
},


createPointer: function(n) {
	if (PN.pointerImage == undefined) {
		PN.pointerImage = document.createElement("IMG");
		PN.pointerImage.src = "pointer.png";
		PN.pointerImage.alt = "";
		PN.pointerImage.className = "pointer";
	}
	return PN.pointerImage;
},

addAttribution: function(el, addafter) {
  var attribution = document.createElement("DIV");
  attribution.className = "attribution";
  var aimg = document.createElement("IMG");
  aimg.src = "logo-tiny.png";
  aimg.alt = "Time Out From Testing";
  aimg.title = "Time Out From Testing";
  var atxt = document.createTextNode(" responds:");
  attribution.appendChild(aimg);
  attribution.appendChild(atxt);
  var x;
  if (addafter)
    x = addafter.nextSibling;
  else 
    x = el.firstChild;
  attribution.appendChild(document.createElement("HR"));
  el.insertBefore(attribution, x);
  return attribution;
},

wrapShadow: function(el) {
  return el;
/*	for some reason, fancy PN.wrapShadow calls fail on IE6 and IE7:  */
  return PN.wrapShadowTable(el);
  return PN.wrapShadowDiv(el);
},

wrapShadowDiv: function(el) {
  var outd = document.createElement("DIV");
  outd.className = "shadow-wrap-out";
  var ind = document.createElement("DIV");
  ind.className = "shadow-wrap-in";
  outd.appendChild(ind);
  el.parentNode.insertBefore(outd, el);
  ind.appendChild(el);
  return outd;
},

wrapShadowTable: function(el) {
  var shwid = 5;
  var prefix = "";
  var par = document.createElement("TABLE");
  par.cellSpacing = "0px";
  var rowt = par.appendChild(document.createElement("TR"));
  var rowm = par.appendChild(document.createElement("TR"));
  var rowb = par.appendChild(document.createElement("TR"));

  var tl = rowt.appendChild(document.createElement("TD"));
  tl.className="shadow-tl";
  var t = rowt.appendChild(document.createElement("TD"));
  t.className="shadow-t";
  var tr = rowt.appendChild(document.createElement("TD"));
  tr.width = tr.height = shwid;
  tr.className="shadow-tr";

  var ml = rowm.appendChild(document.createElement("TD"));
  ml.width = shwid;
  ml.className="shadow-l";
  var xx = rowm.appendChild(document.createElement("TD"));
  xx.style.padding = "0px";
  xx.style.margin = "0px";
  xx.style.border = "1px solid green";
  var mr = rowm.appendChild(document.createElement("TD"));
  mr.width = shwid;
  mr.className="shadow-r";

  var bl = rowb.appendChild(document.createElement("TD"));
  bl.width = bl.height = shwid;
  bl.className="shadow-bl";
  var b = rowb.appendChild(document.createElement("TD"));
  b.height = shwid;
  b.className="shadow-b";
  var br = rowb.appendChild(document.createElement("TD"));
  br.width = br.height = shwid;
  br.className="shadow-br";

  el.parentNode.insertBefore(par, el);
  xx.appendChild(el);
  return par;
},

createDiagonalTable: function(n, topshadow) {
  var par = document.createElement("TABLE");
  par.className = "diagtable";
  par.cellPadding = "0px";
  par.cellSpacing = "0px";
  var nx = 0;
  var ny = 0;
  while (nx < n) {
    var row = par.appendChild(document.createElement("TR"));
    ny = 0;
    while (ny < nx) {
/*
      var c = row.appendChild(document.createElement("TD"));
      c.className = "diagcell"; 
*/
      ny++;
    }
    while (ny < n) {
      var c = row.appendChild(document.createElement("TD"));
      c.className = "diagcell"; 
      c.innerHTML = "&nbsp;";
      c.width = "1px";
      c.height = "1px";
      if (ny >= n - (((n - nx)/n)*topshadow + 0.9)) {
       c.className = "diagshadow";
      } 
      ny++;
    }
    nx++;
  }
  return par;
},

baseDeactivate: function(base) {
	base.className = "";
	PN.dismissNote(base.assocNote);
/*	base.onmouseover = function() { return PN.baseTrigger(this); }; */
},

baseTrigger: function(base) {
	if (base.className == "activebase") {
	/* this is already active, so we should de-activate it: */
		if (PN.activeBase) {
			PN.activeBase = undefined;
		}
		PN.baseDeactivate(base);
		return false;
	} else {
		if (PN.activeBase != undefined) {
			PN.baseDeactivate(PN.activeBase);
		};
		base.className = "activebase";
/* disable mouseover activity for the active base */
		base.onmouseover = function() { return false; };

		PN.displayNote(base.assocNote);
		PN.activeBase = base;
	}
	return false;
},

/* thanks, PPK! findPos() is from http://www.quirksmode.org/js/findpos.html */
findPos: function(obj) {
	var curtop = 0;
	var curleft = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft;
		curtop = obj.offsetTop;
		while (obj = obj.offsetParent, obj) {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return [curleft,curtop];
},

nothing: null

}
