var gInterval = null;
var gSelected = false;
var noteClassName = 'note';
var noteSelectedClassName = 'note selected';
var degradableIds = [];
var upgradableIds = [];
var exposableIds = [];
var reloadBrowsers = ['Safari'];
var noNotesFoundMessage = 'No notes found';
var noteCounterMessage = 'Note {0} of {1}';
var todayMessage = 'Today';

// Returns the number of thumbnails currently in the view
function GetThumbCount() {
  return document.getElementsByTagName("img").length;
}

function _selectNote(guid, normalClassName, selectedClassName) {
	if (!normalClassName)
		normalClassName = noteClassName;
	if (!selectedClassName)
		selectedClassName = noteSelectedClassName;
    element = document.getElementById(guid); 
    if (!element) return false;
    parentElement = element.parentNode;
    if (!parentElement) return false;
    curClassName = parentElement.className;
    while (curClassName != normalClassName && parentElement != null) {
    	parentElement = parentElement.parentNode;
    	if (parentElement && parentElement.className == normalClassName) {
    		parentNoteDiv = parentElement;
    		parentNoteDiv.className = selectedClassName;
    		return true;
    	}
    }
    return false;
}

function _unselectNote(guid) {
	return _selectNote(guid, noteSelectedClassName, noteClassName);
}

function ClearHash() {
  top.location.hash = '#all';
  return true;
}

// Selects a note, which highlights it and loads the Note frames
function PickNote(guid, setHash) {
  // StopPolling();
  if (setHash &&
      (!top.location.hash || top.location.hash.length != 37 ||
       top.location.hash != gSelected)) {
    top.location.hash = guid;
  }
  _unselectNote(gSelected);
  _selectNote(guid);
  oldGuid = gSelected;
  gSelected = guid;
  viewFrame = parent.frames['PublicView'];
  if (viewFrame) {
    if (!guid) {
      viewFrame.location.replace('about:blank');
    } else {
      url = window.location.protocol + "//" + window.location.host +
        gNoteURLPrefix + guid + gNoteURLSuffix + "#" + guid;
      if (url !== viewFrame.location.toString()) {
        try {
          viewFrame.document.execCommand('stop', false, false);
        } catch (err) { }
        try {
          viewFrame.stop();
        } catch (err) { }
        if (typeof document.all !== "undefined") { // IE
          viewFrame.location = url;
        } else {
          viewFrame.location.replace(url);
        }
      }
    }
  }
  FixSearchNav();
  FixScroll(document.getElementById("note_" + guid));        
  self.focus();
  // StartPolling();  
  return false;
}

// Moves the selection to the previous note in the list
function PickNextNote() {
  var index = 0;
  thumbs = document.getElementsByTagName('img');
  for (; index < thumbs.length - 1; ++index) {
    if (thumbs[index].getAttribute('id') == gSelected) {
      PickNote(thumbs[index + 1].getAttribute('id'), true);
      break;
    }
  }
}
    
// Moves the selection to the next note in the list
function PickPreviousNote() {
  var index = 1;
  thumbs = document.getElementsByTagName("img");
  for (; index < thumbs.length; ++index) {
    if (thumbs[index].getAttribute('id') == gSelected) {
      PickNote(thumbs[index - 1].getAttribute('id'), true);
      break;
    }
  }
}
    
// adjusts the search nav to show the correct note count, next, prev.
function FixSearchNav() {
  navFrame = parent.frames['SearchNav'];
  if (!navFrame && parent.document.getElementById('notecount')) {
  	navFrame = parent;
  }
  if (navFrame) {
    thumbs = document.getElementsByTagName("img");
    
    // figure out our current (thumb's) index
    var index = 0;
    if (gSelected != false) {
      for (index = 0; index < thumbs.length; ++index) {
        if (thumbs[index].getAttribute('id') == gSelected) {
          break;
        }
      }
    }

    var noteCountBlock = navFrame.document.getElementById('notecount');
    if (noteCountBlock) {
      if (thumbs.length <= 1) {
        navFrame.document.getElementById('notecount').innerHTML = (thumbs.length == 0) ? noNotesFoundMessage : '';
        navFrame.document.getElementById('noteprev').style.visibility = 'hidden';
        navFrame.document.getElementById('notenext').style.visibility = 'hidden';
      } else {
        noteCounterUpdated = noteCounterMessage.replace(/\{0\}/, (index + 1)).replace(/\{1\}/, gTotalNotes);
        navFrame.document.getElementById('notecount').innerHTML =
          " | " + noteCounterUpdated + " | ";
        navFrame.document.getElementById('notecount').style.visibility = "visible";
        var prev = "hidden";
        if (index > 0) {
          prev = "visible";
        }
        navFrame.document.getElementById('noteprev').style.visibility = prev;
        var next = "hidden";
        if (index < gTotalNotes - 1) {
          next = "visible";
        }
        navFrame.document.getElementById('notenext').style.visibility = next;
      }
    }
  }
}    

// If the selected note thumbnail isn't visibible in the frame region, this
// will scroll the window to make it visible
function FixScroll(element) {
  if (element) {
    scrollTop = GetScrollTop();
    frameHeight = GetFrameHeight();
    scrollBottom = scrollTop + frameHeight;
    if (scrollTop > element.offsetTop) {
      window.scrollTo(0, element.offsetTop);
    } else if (scrollBottom < element.offsetTop + element.offsetHeight) {
      window.scrollTo(0, 
        element.offsetTop + element.offsetHeight - frameHeight);
    }
  }
}

// Boilerplate code to request more thumbs from the server
function processAjax(url) {
  if (window.XMLHttpRequest) { // Non-IE browsers
    req = new XMLHttpRequest();
    req.onreadystatechange = LoadThumbsCallback;
    try {
      req.open("GET", url, true);
    } catch (e) {
      alert(e);
    }
    req.send(null);
  } else if (window.ActiveXObject) { // IE
    req = new ActiveXObject("Microsoft.XMLHTTP");
    if (req) {
      req.onreadystatechange = LoadThumbsCallback;
      req.open("GET", url, true);
      req.send();
    }
  }
  return false;
}

// Invoked when we receive an asynchronous bundle of note thumbs back
function LoadThumbsCallback() {
  if (req.readyState == 4) { // Complete
    if (req.status == 200) { // OK response
      var dateBlocksStart = document.getElementsByName("date_millis").length;
      noteList = document.getElementById('note_list');
      if (noteList) {
        var range = document.createRange();
        range.selectNode(noteList);
        var noteBlocks = range.createContextualFragment(req.responseText);
        noteList.appendChild(noteBlocks);
        updateThumbDates(dateBlocksStart);
      }
    } else {
      alert("Problem: " + req.statusText);
    }
    StartPolling();
  }
}

function updateThumbDates(startPos) {
  if (!startPos)
    startPos = 0;
  var dateBlocks = document.getElementsByName("date_millis");
  for (var d=startPos; d<dateBlocks.length; d++) {
      var millis = dateBlocks[d].innerHTML;
      var children = dateBlocks[d].parentNode.childNodes;
      if (!children || children.length == 0)
          continue;
      for (var c=0; c<children.length; c++) {
          if (!children[c].attributes)
              continue;
          if (children[c].attributes.name && children[c].attributes.name.value == 'date') {
              children[c].innerHTML = GetLocalDateTime(millis);
              break;
          }
      }
  }
}
    
// Returns the current height of the visible frame's clipping region
function GetFrameHeight() {
  if (self.innerHeight) {
    frameHeight = self.innerHeight;
  } else if (document.documentElement && 
             document.documentElement.clientHeight) {
    frameHeight = document.documentElement.clientHeight;
  } else if (document.body) {
    frameHeight = document.body.clientHeight;
  }
  return frameHeight;
}

// Returns the current offset of the top of the frame's visible clipping
// region in the overall document, in pixels
function GetScrollTop() {
  if (document.documentElement && document.documentElement.scrollTop) {
    return document.documentElement.scrollTop;
  } else if (window.pageYOffset) {
    return window.pageYOffset;
  } else if (self.pageYOffset) {
    return self.pageYOffset;
  } else {
    return document.body.scrollTop;
  }
}

// Returns the total height of this document, in pixels
function GetPageHeight() {
  return document.body.offsetHeight;
}

// This function periodically checks if we've scrolled to the bottom
// of the frame.  If we have, load more content.
// It also checks whether the user has navigated back/forward in history,
// and updates the viewed note if needed.
function UpdatePoll() {
  if (top.location.hash && top.location.hash.length == 37) {
    hashGuid = top.location.hash.substring(1);
    if (gSelected != hashGuid) {
      PickNote(hashGuid, false);
    }
  }
  thumbCount = GetThumbCount();
  if (thumbCount < gTotalNotes &&
      ((100 * GetScrollTop()) / (GetPageHeight() - GetFrameHeight())) > 50) {
     StopPolling();
     processAjax(
      'notelist.jsp?search=' + gSearch + '&offset=' + thumbCount + '&max=' +
          Math.floor(thumbCount / 2));
  }
}
    
// If we don't have all of the notes, poll to watch when the user has
// scrolled far enough to need more notes
function StartPolling() {
  StopPolling();
  gInterval = setInterval('UpdatePoll()', 200);
}

// Turns off the thumb/history polling thread
function StopPolling() {
  if (gInterval) {
    clearInterval(gInterval);
  }
}

function updateQueryString(link, qString, qValue) {	
	if (link.href && qString && qValue) {
		re = new RegExp("[?&]" + qString + "=[^&]*");
		hrefString = link.href.replace(re, "");
		if (hrefString.match(/\?/))
			uSep = "&";
		else
			uSep = "?";
		link.href = hrefString + uSep + qString + "=" + escape(qValue);
	}
}

function upgrade() {
	if (degradableIds) {
		for (i=0; i< degradableIds.length; i++) {
			changeBlockVisibility(document.getElementById(degradableIds[i]), 'visible');
		}
	}
	if (upgradableIds) {
		for (i=0; i<upgradableIds.length; i++) {
			//changeBlockVisibility(document.getElementById(upgradableIds[i]), 'hidden');
			var toRemove = document.getElementById(upgradableIds[i]);
			if (toRemove && toRemove.parentNode) {
				toRemove.parentNode.removeChild(toRemove);
			}
		}
		}
		if (exposableIds) {
			for (var i in exposableIds) {
				if(toExpose = document.getElementById(i))
					changeBlockDisplay(toExpose, exposableIds[i]);
			}
		}
}

function changeBlockVisibility(element, vis, recurse) {
	if (element) {
		element.style.visibility = vis;
		if (recurse == true && element.children) {
			for (var c=0; c<=element.children.length; c++) {
				changeBlockVisibility(element.children[c], vis, recurse);
			}
		}
	}
}

function changeBlockDisplay(element, displayType, recurse) {
	if (!displayType)
		displayType = "none";
	if (element) {
		element.style.display = displayType;
		if (recurse == true && element.children) {
			for (var c=0; c<=element.children.length; c++) {
				changeBlockDisplay(element.children[c], displayType, recurse);
			}
		}
	}
}

function CheckLocations(topUri) {
	 if (self.location==top.location) self.location=topUri;

     // On IE, we need to fix the top-level URL hashp
      if (typeof document.all !== "undefined" &&  
          self.location.hash && top.location.hash &&
          self.location.hash != top.location.hash) {
        top.location.hash = self.location.hash;
      }
}

function PrintLocalDateTime(timeMillis) {
    var dateString = GetLocalDateTime(timeMillis);
	document.write((dateString != false) ? dateString : "");
}

function GetLocalDateTime(timeMillis) {
    var dateString = "";
    var d = new Date();
    d.setTime(timeMillis);
    var today = new Date();
    if (today.getTime() - timeMillis < 86400000 && d.getDate() == today.getDate()) {
      dateString += todayMessage;
    } else {
      dateString += (d.getMonth() + 1);
      dateString += ("/");
      dateString += (d.getDate());
      dateString += ("/");
      dateString += (d.getFullYear());
    }
    dateString += (", ");
    if (d.getHours() % 12 == 0) {
      dateString += ("12");
    } else {
      dateString += (d.getHours() % 12);
    }
    dateString += (":");
    var m = d.getMinutes();
    if (m < 10)
       m = "0" + m;
    dateString += (m);
    if (d.getHours() >= 12) {
      dateString += (" PM");
    } else {
      dateString += (" AM");
    }
    return dateString;
}

function reloadFrame(frameName, force) {
    var ua = navigator.userAgent;
    if (!reloadBrowsers && !force)
        return;
    var ok=false;
    var re = "";
    for (var b=0; b<reloadBrowsers.length; b++) {
        re = new RegExp(reloadBrowsers[b]);
        if (ua.match(re)) {
            ok=true;
            break;
        }
    }
    if (!ok && !force)
        return;
    if (!frameName || !parent.frames[frameName])
        return;
    var thisHref = parent.frames[frameName].location.href;
    if (thisHref != "/") {
	    thisHref.replace(/\bts=[^&]+/, "");
	    if (thisHref.match(/\?/))
	        thisHref += "&";
	    else
	        thisHref += "?";
	    thisHref += "ts=" + new Date().getTime();
	    parent.frames[frameName].location = thisHref;
	}
}