	
///////////////////////////////////////////////////////////////////////////////
// BEGIN: JavaScript to show/hide post content 
///////////////////////////////////////////////////////////////////////////////
	
// define the hide style
if (document.getElementById)
{
  document.write("<style type=\"text/css\">");
  document.write(".hidepostcontent { display:none; }");
  document.write("</style>");
}
	
///////////////////////////////////////////////////////////////////////////////
// important constants
///////////////////////////////////////////////////////////////////////////////
	
// these determine the position at which to cut off display when
// hiding post content.
//
// minLen      the minimum number of characters (including HTML
//             syntax) in the post body that will be visible (i.e.
//             the cutoff - point will be after minLen characters)
//
// minHide     the minimum number of characters (including HTML
//             syntax) in the post body after the cutoff point
//
// maxShow     break at this number of characters regardless

// If the total number of characters in the post body is less than
// minLen + minHide, then there will be no automatic hiding of content
// for that post.
var minLen = 250;
var minHide = 50;
var maxShow = 300;
	
// display text for show / hide links in the page
var showMoreTxt = "show more<img border=0 src=pics/arrow_downblue.gif align=absmiddle>";
var showLessTxt = "show less<img border=0 src=pics/arrow_upblue.gif align=absmiddle>";
	
///////////////////////////////////////////////////////////////////////////////
// general utility functions
///////////////////////////////////////////////////////////////////////////////
	
// concat a string several times
function addStrRepeat(str, count)
{
  var src = "";
  for (var i = 0; i < count; i++)
  {
    src += str;
  }
  return src;
}
	
// add an indexOf function to the Array class (this does inefficient
// linear search, but for the task at hand it should be sufficient)
if (!Array.prototype.indexOf)
{
  function Array_indexOf(x)
  {
    for (var i = 0; i < this.length; i++)
    {
      if (this[i] == x)
      {
        return i;
      }
    }
    return -1;
  }
  Array.prototype.indexOf = Array_indexOf;
}
	
///////////////////////////////////////////////////////////////////////////////
// functions to manipulate the post body
///////////////////////////////////////////////////////////////////////////////
	
// generate the html code that enables user to switch show / hide mode
function writeToggleStr(postid, bShowContent)
{
  var postURL = "#" + postid.substr(4);
  var prefStr = "&nbsp;<a class=\"showhidelink\" href=\"";
  prefStr += postURL; 
  prefStr += "\" onclick=javascript:toggleVisible('" + postid + "',";
  var expandStr = prefStr + "true);>" + showMoreTxt + "</a>";
  var collapseStr = prefStr + "false);>" + showLessTxt + "</a>";
	
  whichpost = document.getElementById(postid);
  children = whichpost.childNodes;
  for (var i = 0; i < children.length; i++)
  {
    if (children[i].tagName == "DIV" && children[i].className == "showhidestring")
    {
      children[i].innerHTML = bShowContent ? collapseStr : expandStr;
      //break;
    }
    if (children[i].tagName == "DIV" && children[i].className == "showhidetoggle")
    {
   		children[i].innerHTML = "&nbsp;<a href=\"\" onclick=\"toggleVisible('"+postid+"'); return false;\">"+showLessTxt+"</a>";
    	if (bShowContent) {
      		children[i].style.visibility = "visible";
      		children[i].style.position = 'relative';
    	} else {
      		children[i].style.visibility = "hidden"; 
      		children[i].style.position = 'absolute'; 
    	}
      //break;
    }
  }
}
	
// generate the div containing the post text
function getPostBody(postid)
{
  var postBody = null;
  whichpost = document.getElementById(postid);
  children = whichpost.childNodes;
  for (var i = 0; i < children.length; i++)
  {
    if (children[i].tagName == "DIV" && children[i].className == "showhideposttext")
    {
      postBody = children[i];
      break;
    }
  }
  return postBody;
}
	
// display the code to enable toggling show/hide in a post
function displayToggle(postid)
{
  if (document.getElementById)
  {
    if (limitDisplay(postid))
    {
      writeToggleStr(postid, false);
    }
  } 
}
	
// add the ellipsis and if specified, the hide tag
function addHideStr(postBody, breakPos)
{
  if (breakPos[0] == -1)
  {
    return false;
  }
	
  var postStr = postBody.innerHTML;
  var dispStr = postStr.substr(0, breakPos[0]);
  var hideStr = postStr.substr(breakPos[0]);
	

  var newStr = dispStr;
  
  // breakPos[4] is an array of the tag names that were open in the first part (showing) part of the text
  // breakPos[5] is an array of the same tag names and any parameters (everything between < and >
  // add terminating tags for any open tags (breakPos[4]) to text before break and same starting tags (breakPos[5]) at start of hidden section
  if (breakPos[4].length > 0) {
  	for (var ic=breakPos[4].length-1;ic>=0;ic--) {
  		newStr += "</" + breakPos[4][ic] + ">";
  		hideStr = "<" + breakPos[5][ic] + ">" + hideStr;
  	}
  }
  
  if (breakPos[3])
  {
    newStr += "<div class=\"hidepostcontent\">";
    //newStr += addStrRepeat("<p>", breakPos[1]);
    //newStr += addStrRepeat("<br>", breakPos[2]);
    newStr += hideStr + "</div>";
  }
  else
  {
    newStr += hideStr;
  }
	
  postBody.innerHTML = newStr;
  return true;
}
	
// find the position in the post body where to cutoff text -- it
// returns an array called breakPos with four elements
//   breakPos[0] -- cutoff position (-1 indicates no cutoff)
//   breakPos[1] -- number of open <p> tags
//   breakPos[2] -- number of open <br> tags
//   breakPos[3] -- flag to indicate whether to add the 'hide content'
//                  div (false means the user might have manually
//                  inserted one, and so we shouldn't be adding
//                  another)
function findBreakPos(postBody)
{
  var breakPos = new Array(-1, 0, 0, false, 0); // break, #p, #br, bAddHideStr, tagsList
	
  var postStr = postBody.innerHTML;
  var lowPostStr = postStr.toLowerCase();
  var posHidden = lowPostStr.indexOf("hidepostcontent");
  if (posHidden != -1)
  {
    posHidden = lowPostStr.substr(0, posHidden).lastIndexOf("<div");
  }
  if (posHidden != -1)
  {
    breakPos[0] = posHidden;
//  alert('R1 breakpt='+breakPos[0]+'  openPs='+breakPos[1]+'  openBs='+breakPos[2]+'  Flag='+breakPos[3]);
    return breakPos;
  }
	
  var totLen = lowPostStr.length;
  if (totLen <  minLenTemp + minHide)
  {
//  alert('R2 breakpt='+breakPos[0]+'  openPs='+breakPos[1]+'  openBs='+breakPos[2]+'  Flag='+breakPos[3]);
    return breakPos;
  }
	
  breakPos[3] = true; // add the hide tag
  breakPos[0] = 0;
	
  var tagsList = new Array();
  var tagsTextList = new Array();
  var minLenTemp = minLen;
  
  // scan the text until we find a tag that exists beyond the required break point (minLenTemp), IF..
  // there are no open tags:
  // example: in this example, even if the minLenTemp is say, 500, we won't find a break because the SPAN tag
  // is wrapping the entire text (need a way to accomodate this probably- for now)
  // <span>this is sample text. <br>... another 2000 characters </span>
  
//  while (breakPos[0] <  minLenTemp || tagsList.length != 0)
  while (breakPos[0] <  minLenTemp)
  {
    var curStr = lowPostStr.substr(breakPos[0]);

    // find the next tag
    var tagPos = curStr.indexOf("<");
    
    if (tagPos == -1)
    {
    	if (curStr.length > maxShow)
    	{
		    breakPos[0] =  maxShow;
    	}
		break;
    }
	
    // look at the first character within the tag
    var remStr = curStr.substr(tagPos + 1);
    
    // find the end of the tag & accomodate spaces within the tag = objective is to find what tag it is
    var endTagPos = remStr.indexOf(">");
    // save the entire tag contents - tag name plus any parameters - will use these to precede the hidden text area
    tagText = remStr.substr(0,endTagPos);
    
    var closeTagPos = remStr.indexOf("/>");
    var spacePos = remStr.indexOf(" ");
    var namePos = spacePos != -1 && spacePos < endTagPos ? spacePos : endTagPos;
    if (closeTagPos == endTagPos - 1 && namePos == endTagPos)
    {
      namePos--;
    }
    
    // found the tag name
    var tagName = remStr.substr(0, namePos);
    var bTagEnd = tagName.indexOf("/") == 0;
    if (bTagEnd)
    {
      tagName = tagName.substr(1);
    }
    
    // if we found a BR or P, then assume we found 75 more characters (guesstimate as to how many chars are in typical line)
    if (tagName == "p" || tagName == "br")
		minLenTemp -= 75;
		
	// if this tag occurs beyond the required split point, then set the break point and exit
    if (breakPos[0] + tagPos >  minLenTemp && tagsList.length == 0 &&
        (tagName == "p" || tagName == "br"))
    {
      breakPos[0] += tagPos;
      break;
    }
	
    // otherwise, increment the breakpo
    breakPos[0] += tagPos + endTagPos + 2;
	
    if (closeTagPos == endTagPos - 1)
    {
      continue;
    }
	
    if (tagName == "p")
    {
      breakPos[1] += bTagEnd ? -1 : 1;
    }
    else if (tagName == "br")
    {
      breakPos[2] += bTagEnd ? -1 : 1;
    }
    else if (bTagEnd)
    {
      ind = tagsList.indexOf(tagName);
      if (ind != -1)
      {
        tagsList.splice(ind, 1);
        tagsTextList.splice(ind, 1);
      }
    }
    else
    {
      tagsList.push(tagName);
      tagsTextList.push(tagText);
    }
  }
	
  // if the last tag found was found before the required break point, then return -1 (show the entire string)
  if (breakPos[0] < minLenTemp || totLen - breakPos[0] < minHide)
  {
    breakPos[0] = -1;
  }
   // tack on the list of open tags - back at the caller, a closing tag for each one will be added at the break point
  breakPos[4] = tagsList;
  breakPos[5] = tagsTextList;
  
//  alert('R3 breakpt='+breakPos[0]+'  openPs='+breakPos[1]+'  openBs='+breakPos[2]+'  Flag='+breakPos[3]);
   return breakPos;
}
	
// hide text starting at the appropriate place
	
function limitDisplay(postid)
	
{
  var postBody = getPostBody(postid);
  if (postBody)
  {
    return addHideStr(postBody, findBreakPos(postBody));
  }
  return false;
}
	
// switch between show and hide mode
function swapStyles(divBody)
{
  var children = divBody.childNodes;
  var hideshow;
  for (var i = 0; i < children.length; i++)
  {
    if (children[i].tagName == "DIV")
    {
      if (children[i].className == "hidepostcontent")
      {
        children[i].className = "showpostcontent";
        hideshow = true;
      }
      else if (children[i].className == "showpostcontent")
      {
        children[i].className = "hidepostcontent";
        hideshow = false;
      }
    }
  }
  return hideshow;
}
	
// main function to change show/hide mode
function toggleVisible(postid, bShowContent)
{
  var postBody = getPostBody(postid);
  if (postBody)
  {
//    swapStyles(postBody);
    bShowContent = swapStyles(postBody);
    writeToggleStr(postid, bShowContent);
  }
}
	
////////////////////////////////////cc///////////////////////////////////////////
// END: JavaScript to show/hide post content 
///////////////////////////////////////////////////////////////////////////////

