function dispReviewContent()
{
  var fd=document.getElementById('featurediv');
  var theContent='<table border=0 cellspacing=0 cellpadding=10 width="100%"><tr>';
  var addedContent=false;
  if (reviewHtml.length>0)
  {
    theContent+='<td class="abouttext" valign="top">';
    theContent+=reviewHtml+'</td>\n';
    addedContent=true;
  }
  if (!addedContent)
    theContent+='<td class="abouttext">Unable to display review information</td>\n';
  theContent+='</tr></table>\n';
  fd.innerHTML=theContent;
  window.location.hash='featurediv';
  return;
}

var reviewsPerPage=10;
var startReview=0;

function dispReviews(diffTab)
{
  if (!initReviews)
  {
    reviewHtml='Getting reviews... please wait';
    dispReviewContent();
    doReviewRequest(0,reviewsPerPage);
  }
  if (initReviews)
  {
    dispReviewContent();
    return;
  }
}

function doReviewRequest(startInd,revCount)
{
  startReview=startInd;
  reviewRequester.performRequest('GET','/customer/getRatingsReviews.jsp?subcatid='+useSubcatId+'&startreview='+startInd+'&count='+revCount+'&rnd='+Math.random(),true,null);
  return;
}

function showMoreReview(n)
{
  var reviewMore=document.getElementById('reviewmore'+n);
  var reviewLess=document.getElementById('reviewless'+n);
  var reviewCont=document.getElementById('reviewcont'+n);
  if (!reviewMore||!reviewLess)
    return;
  var ratingsCont=document.getElementById('ratingscont'+n);
  reviewMore.style.display='none';
  reviewLess.style.display='inline';
  if (reviewCont)
    reviewCont.style.display='inline';
  if (ratingsCont)
    ratingsCont.style.display='block';
  return;
}

function showLessReview(n)
{
  var reviewMore=document.getElementById('reviewmore'+n);
  var reviewLess=document.getElementById('reviewless'+n);
  var reviewCont=document.getElementById('reviewcont'+n);
  if (!reviewMore||!reviewLess)
    return;
  var ratingsCont=document.getElementById('ratingscont'+n);
  reviewMore.style.display='inline';
  reviewLess.style.display='none';
  if (reviewCont)
    reviewCont.style.display='none';
  if (ratingsCont)
    ratingsCont.style.display='none';
  return;
}

function getDataByTagName(curNode,childNodeName)
{
  var childNodes=curNode.getElementsByTagName(childNodeName);
  if (!childNodes)
    return '';
  if (childNodes.length<=0)
    return '';
  var childNodeData=childNodes.item(0).firstChild;
  if (!childNodeData)
    return '';
  childNodeData=childNodeData.data;
  if (!childNodeData)
    return '';
  return childNodeData;
}

function setReviewsPerPage(num)
{
  if(!isNaN(parseInt(num)))
    reviewsPerPage = parseInt(num);
}

function reviewRequestHandler(txt,xml)
{
readReviews:
  try
  {
    if (!xml)
    {
      reviewErrorHandler(null);
      return;
    }
    var allReviews=xml.getElementsByTagName('ALLREVIEWS');
    if (!allReviews||(allReviews.length==0))
    {
      reviewErrorHandler(null);
      return;
    }
    allReviews=allReviews.item(0);
    var totalReviewCount=makeNum(getDataByTagName(allReviews,'TOTALCOUNT'));
    allReviews=allReviews.getElementsByTagName('REVIEW');
    var numReviews=allReviews.length;
    initReviews=true;
    if (numReviews==0)
    {
      reviewHtml='There are no reviews for this product.';
      break readReviews;
    }
    reviewHtml='<table border=0 cellspacing=0 cellpadding=0 class="abouttext" width="100%">\n';
    reviewHtml+='<tr><td colspan=3>';
    if (numReviews==totalReviewCount)
    {
      reviewHtml+='Displaying '+numReviews;
      if (numReviews==1)
        reviewHtml+=' review';
      else
        reviewHtml+=' reviews';
    }
    else
    {
      reviewHtml+='Page:';
      var pageNum=0;
      for (var i=0;i<totalReviewCount;i+=reviewsPerPage)
      {
        pageNum++;
        if ((startReview>=i)&&(startReview<(i+reviewsPerPage)))
          reviewHtml+=' '+pageNum;
        else
          reviewHtml+=' <a href="javascript:doReviewRequest('+i+','+reviewsPerPage+')">'+pageNum+'</a>';
      }
    }
    reviewHtml+='</td></tr>\n';
    var curReview,firstName,lastName,fullName,city,reviewContent,reviewTitle,handicap,frequencyOfPlay,reviewDate;
    var allRatings,curRating,ratingName,ratingValue,ratingStyle;
    var fullStars,useHalfStar,emptyStars;
    var reviewContentSplit;
    for (var i=0;i<numReviews;i++)
    {
      curReview=allReviews.item(i);
      firstName=getDataByTagName(curReview,'FIRSTNAME');
      lastName=getDataByTagName(curReview,'LASTNAME');
      city=getDataByTagName(curReview,'CITY');
      reviewTitle=getDataByTagName(curReview,'REVIEWTITLE');
      reviewContent=getDataByTagName(curReview,'POSTEDREVIEW');
      handicap=getDataByTagName(curReview,'HANDICAP');
      frequencyOfPlay=getDataByTagName(curReview,'FREQUENCY_OF_PLAY');
      reviewDate=getDataByTagName(curReview,'REVIEW_DATE');
      reviewHtml+='<tr><td colspan=3><hr></td></tr>\n';
      reviewHtml+='<tr><td valign="top" class="smalltext" width=80>';
      allRatings=curReview.getElementsByTagName('RATING');
      reviewContent=addBreaks(reviewContent);
      reviewContentSplit=getReviewContentSplit(reviewContent);

      if (allRatings&&(allRatings.length>0))
      {
        var ratingItems=new Array();
        var numRatingItems=0;
        for (var j=0;j<numRatingTypes;j++)
        {
          ratingName=ratingTypeNames[j];
          for (var k=0;k<allRatings.length;k++)
          {
            curRating=allRatings.item(k);
            if (ratingName==getDataByTagName(curRating,'RATING_NAME'))
            {
              ratingItems[numRatingItems++]=curRating;
              break;
            }
          }
        }
        for (var j=0;j<numRatingItems;j++)
        {
          curRating=ratingItems[j];
          if (j>0)
            reviewHtml+='<br>\n';
          if (j==1)
          {
            if (reviewContentSplit<=0)
              reviewHtml+='<span id="reviewmore'+i+'"><a href="#" onClick="showMoreReview('+i+');return false" style="color:black; font-weight:bold">(More)</a></span>';
            reviewHtml+='<div id="ratingscont'+i+'" style="display:none">';
          }
          ratingName=getDataByTagName(curRating,'RATING_NAME');
          ratingValue=makeNum2(getDataByTagName(curRating,'RATING_VALUE'));
          ratingStyle=getDataByTagName(curRating,'RATING_STYLE');
          if (ratingStyle=='stars')
          {
            reviewHtml+='<b>'+ratingName+'</b><br>\n';
            fullStars=Math.floor(ratingValue);
            useHalfStar=((ratingValue-fullStars)>=0.50);
            emptyStars=5-fullStars;
            if (useHalfStar)
              emptyStars--;
            for (var k=0;k<fullStars;k++)
              reviewHtml+='<img src="/images/reviews/'+ppc_prefix+'star_full.gif" width=14 height=13>';
            if (useHalfStar)
              reviewHtml+='<img src="/images/reviews/'+ppc_prefix+'star_half.gif" width=14 height=13>';
            for (var k=0;k<emptyStars;k++)
              reviewHtml+='<img src="/images/reviews/'+ppc_prefix+'star_empty.gif" width=14 height=13>';
          }
          else
            reviewHtml+='<b>'+ratingName+':</b> '+ratingValue;
        }
        if (numRatingItems>1)
        {
          reviewHtml+='</div>\n';
          if (reviewContentSplit<=0)
            reviewHtml+='<span id="reviewless'+i+'" style="display:none"><a href="#" onClick="showLessReview('+i+');return false" style="color:black; font-weight:bold">(Less)</a></span>';
        }
      }
      fullName=firstName;
      if (lastName.length>0)
        fullName+=' '+lastName;
      reviewHtml+='</td><td width=5>&nbsp;</td><td valign="top">';
      if (reviewTitle=='')
        reviewTitle='Review by '+fullName;
      reviewHtml+='<span style="float: left"><b>'+reviewTitle+'</b></span>';
      if (reviewDate!='')
        reviewHtml+='<span style="float: right">'+reviewDate+'</span>';
      reviewHtml+='<br>\n';
      reviewHtml+='<font color="blue">'+fullName+' from '+city+'</font>';
      if (handicap.length>0)
        reviewHtml+=' - Handicap: <font color="blue">'+handicap+'</font>';
      if (frequencyOfPlay.length>0)
        reviewHtml+=' - Frequency of play: <font color="blue">'+frequencyOfPlay+'</font>';
      reviewHtml+='<br><br>'

      if (reviewContentSplit>0)
      {
        reviewHtml+=reviewContent.substring(0,reviewContentSplit);
        reviewHtml+='<span id="reviewmore'+i+'" style="color:black; font-weight:bold">...<a href="#" onClick="showMoreReview('+i+');return false" style="color:black; font-weight:bold">(More)</a></span>';
        reviewHtml+='<span id="reviewcont'+i+'" style="display:none">';
        reviewHtml+=reviewContent.substring(reviewContentSplit);
        reviewHtml+='</span>\n';
        reviewHtml+='<span id="reviewless'+i+'" style="display:none"><br><a href="#" onClick="showLessReview('+i+');return false" style="color:black; font-weight:bold">(Less)</a></span>';
      }
      else
        reviewHtml+=reviewContent;
      reviewHtml+='</td></tr>\n';
    }
    reviewHtml+='</table>\n';
  }
  catch(e)
  {  alert('There was an error displaying the reviews');  }
  dispReviewContent();
  return;
}

function isWordPart(c)
{
  return ((c>='a')&&(c<='z'))||((c>='A')&&(c<='Z'))||((c>='0')&&(c<='9'));
}

var REVIEW_PREVIEW_CHARS=150;
var REVIEW_PREVIEW_FUDGE=20;
var REVIEW_PREVIEW_LINES=2;

function getReviewContentSplit(reviewContent)
{
  var reviewContentLen=reviewContent.length;
  var lastBreak=-1;
  var breakCount=0;
  while (lastBreak<REVIEW_PREVIEW_CHARS)
  {
    lastBreak=reviewContent.indexOf('<br>',lastBreak+1);
    if (lastBreak<0)
      break;
    breakCount++;
    if (breakCount==REVIEW_PREVIEW_LINES)
    {
      // Decide split early if many small lines
      if (lastBreak<(REVIEW_PREVIEW_CHARS+REVIEW_PREVIEW_FUDGE))
        return lastBreak;
      break;
    }
  }

  // Check if it even needs to be split
  if (reviewContentLen<(REVIEW_PREVIEW_CHARS+REVIEW_PREVIEW_FUDGE))
    return -1;

  // Look for a break in the window. If one is found, split there. The -4 is to catch a break that is partially before the window
  var reviewContentSplit=reviewContent.indexOf('<br>',REVIEW_PREVIEW_CHARS-REVIEW_PREVIEW_FUDGE-4);
  // If the break was in the window, use it
  if ((reviewContentSplit>=0)&&(reviewContentSplit<(REVIEW_PREVIEW_CHARS+REVIEW_PREVIEW_FUDGE)))
    return reviewContentSplit;

  var curPos=0;
  // Moving outwards from the window's center, look for a transition from word character to non-word character
  for (var j=0;j<REVIEW_PREVIEW_FUDGE;j++)
  {
    curPos=REVIEW_PREVIEW_CHARS+j;
    if ((curPos<reviewContentLen)&&isWordPart(reviewContent.charAt(curPos-1))&&!isWordPart(reviewContent.charAt(curPos)))
      return curPos;
    curPos=REVIEW_PREVIEW_CHARS-j;
    if ((curPos>0)&&isWordPart(reviewContent.charAt(curPos-1))&&!isWordPart(reviewContent.charAt(curPos)))
      return curPos;
  }
  // Just split it down the center of the window
  return REVIEW_PREVIEW_CHARS;
}

function addBreaks(s)
{
  if (!s)
    return '';
  var ind=0,indadj;
  while (ind<s.length)
  {
    ind=s.indexOf('\n',ind);
    if (ind<0)
      return s;
    indadj=((ind>0)&&(s.charAt(ind-1)=='\r'))?1:0;
    s=s.substring(0,ind-indadj)+'<br>'+s.substring(ind-indadj,s.length);
    ind+=5+indadj;
  }
  return s;
}

function reviewTimeoutHandler()
{
  if (initReviews)
  {
    alert('There was an error contacting the server. Please try again shortly.');
    return;
  }
  reviewHtml='There was an error contacting the server. Click <a href="javascript:dispReviews(true)">here</a> to try again.';
  dispReviewContent();
  return;
}

function reviewErrorHandler(status)
{
  if (initReviews)
  {
    alert('The server returned an error code. Please try again shortly.');
    return;
  }
  reviewHtml='The server returned an error code. Click <a href="javascript:dispReviews(true)">here</a> to try again.';
  dispReviewContent();
  return;
}

function reviewReentrantHandler()
{  return;  }

function reviewSeriousError()
{
  alert('Due to a browser compatibility problem, I can not talk to the server to get customer reviews.');
  return;
}

var initReviews=false;
var reviewHtml='';
var ratingsHtml='';

var reviewRequester=new BGRequest('reviewRequester');
reviewRequester.normalHandler=reviewRequestHandler;
reviewRequester.timeoutHandler=reviewTimeoutHandler;
reviewRequester.errorHandler=reviewErrorHandler;
reviewRequester.reentrantHandler=reviewReentrantHandler;
reviewRequester.noXMLHttpHandler=reviewSeriousError;
reviewRequester.timeoutInterval=20000;

