// Legacy

function dispSpecs()
{
  ppTabs.changeTabByName('Specifications');
  return;
}

/* ****************************** ProductPageTabs ****************************** */

function ProductPageTabs(jsName, idPrefix, imgSrcPrefix, imgSrcPrefixHighlighted, comparisonData, tabs, comparisonState)
{
  this.jsName = jsName;
  this.idPrefix = idPrefix;
  this.imgSrcPrefix = imgSrcPrefix;
  this.imgSrcPrefixHighlighted = imgSrcPrefixHighlighted;
  this.comparisonData = comparisonData;
  this.tabs = tabs;
  for (var i = 0; i < this.tabs.length; i++)
    this.tabs[i].parentObj = this;
  this.currentTab = null;

  this.hasInitialComparisonState = false;
  if (comparisonState != null)
  {
    if (!comparisonState.isComparisonState)
      comparisonState = ComparisonState.prototype.createComparisonStateFromString(this.comparisonData, comparisonState);
    this.hasInitialComparisonState = (comparisonState != null);
  }
  this.comparisonState = this.hasInitialComparisonState ? comparisonState : ComparisonState.prototype.getBlankState(this.comparisonData);
}

ProductPageTabs.prototype.getTab = function(tabId)
{
  for (var i = 0; i < this.tabs.length; i++)
    if (this.tabs[i].tabId == tabId)
      return this.tabs[i];
  return null;
}

ProductPageTabs.prototype.getTabByName = function(tabName)
{
  for (var i = 0; i < this.tabs.length; i++)
    if (this.tabs[i].tabName == tabName)
      return this.tabs[i];
  return null;
}

ProductPageTabs.prototype.getCurrentTabId = function()
{
  if (this.currentTab == null)
    return 0;
  return this.currentTab.tabId;
}

ProductPageTabs.prototype.changeTabByName = function(tabName)
{
  var newTab = this.getTabByName(tabName);
  if (newTab == null)
    return;
  this.changeTab(newTab.tabId);
  return;
}

ProductPageTabs.prototype.changeTab = function(newTabId)
{
  var newTab = this.getTab(newTabId);
  if (newTab == null)
    return;

  if (this.currentTab == newTab)
    return;

  var oldTab = this.currentTab;
  if (oldTab != null)
  {
    if (!oldTab.preDeselect())
      return;
    document.getElementById(this.idPrefix + 'Cell' + oldTab.tabId).className = this.idPrefix + 'NotSelected';
    document.getElementById(this.idPrefix + 'Cell' + oldTab.tabId + 'A').className = this.idPrefix + 'NotSelectedA';
    document.images[this.idPrefix + 'Image' + oldTab.tabId + 'Left'].src = this.imgSrcPrefix + 'left.gif';
    document.images[this.idPrefix + 'Image' + oldTab.tabId + 'Right'].src = this.imgSrcPrefix + 'right.gif';
    oldTab.postDeselect();
  }
  
  this.currentTab = newTab;

  newTab.preSelect();
  
  this.updateContent(newTab.getContent());

  document.getElementById(this.idPrefix + 'Cell' + newTab.tabId).className = this.idPrefix + 'Selected';
  document.getElementById(this.idPrefix + 'Cell' + newTab.tabId + 'A').className = this.idPrefix + 'SelectedA';
  document.images[this.idPrefix + 'Image' + newTab.tabId + 'Left'].src = this.imgSrcPrefixHighlighted + 'left.gif';
  document.images[this.idPrefix + 'Image' + newTab.tabId + 'Right'].src = this.imgSrcPrefixHighlighted + 'right.gif';

  newTab.postSelect();

  return;
}

ProductPageTabs.prototype.createHtml = function()
{
  var t = '<a name="' + this.idPrefix + 'TableAnchor"></a>\n' +
          '<table width="930" border="0" cellpadding="0" cellspacing="0" class="abouttext">\n' +
          '  <tr>\n' +
          '    <td height=26 class="' + this.idPrefix + 'Spacer" width=20><img src="/images/spacer.gif" width="20" height=1 border=0></td>\n';
  for (var i = 0; i < this.tabs.length; i++)
  {
    var curTab = this.tabs[i];
    t += '    <td height=26 class="' + this.idPrefix + 'BlankSpacer" width=6><img id="' + this.idPrefix + 'Image' + curTab.tabId + 'Left" src="' + this.imgSrcPrefix + 'left.gif" width=6 height=26></td>\n' +
         '    <td height=26 class="' + this.idPrefix + 'NotSelected" id="' + this.idPrefix + 'Cell' + curTab.tabId + '"><a class="' + this.idPrefix + 'NotSelectedA" id="' + this.idPrefix + 'Cell' + curTab.tabId + 'A" href="javascript:' + this.jsName + '.changeTab(' + curTab.tabId + ')"><b>' + curTab.tabName + '</b></a></td>\n' +
         '    <td height=26 class="' + this.idPrefix + 'BlankSpacer" width=14><img id="' + this.idPrefix + 'Image' + curTab.tabId + 'Right" src="' + this.imgSrcPrefix + 'right.gif" width=14 height=26></td>\n';
  }
  
  t += '    <td height=26 class="' + this.idPrefix + 'Spacer" width="950"><img src="/images/spacer.gif" height=1 border=0></td>\n' +
       '  </tr>\n' +
       '  <tr>\n' +
       '    <td colspan=' + (this.tabs.length * 3 + 2) + ' width="950" class="' + this.idPrefix + 'FeatureContent">\n' +
       '      <br>\n' +
       '      <div id="' + this.idPrefix + 'FeatureDiv"></div>\n';
  for (var i = 0; i < this.tabs.length; i++)
  {
    var curTab = this.tabs[i];
    var extraHtml = curTab.getExtraHtml();
    if (extraHtml != null)
      t += extraHtml;
  }
  t += '    </td>\n' +
       '  </tr>\n' +
       '</table>\n';
  return t;
}

ProductPageTabs.prototype.updateContent = function(newContent)
{
  var fd = document.getElementById(this.idPrefix + 'FeatureDiv');
  fd.innerHTML = newContent;
  return;
}

ProductPageTabs.prototype.initHtml = function()
{
  document.getElementById(this.idPrefix + 'TabsDiv').innerHTML = this.createHtml();
  return;
}

ProductPageTabs.prototype.gotoTable = function()
{
  try
  {
    window.location.hash = this.idPrefix + 'TableAnchor';
  }
  catch (e)
  {  }
  return;
}

/* ****************************** ProductPageTab ****************************** */

function ProductPageTab(tabId, tabName)
{
  this.tabId = tabId;
  this.tabName = tabName;
}

ProductPageTab.prototype.refreshContent = function()
{
  this.parentObj.updateContent(this.getContent());
}

ProductPageTab.prototype.getJSName = function()
{
  return this.parentObj.jsName + '.getTab(' + this.tabId + ')';
}

ProductPageTab.prototype.getSubcatObj = function()
{
  return this.parentObj.subcatObj;
}

ProductPageTab.prototype.preSelect = function() {  return;  }
ProductPageTab.prototype.postSelect = function() {  return;  }
ProductPageTab.prototype.preDeselect = function() {  return true;  }
ProductPageTab.prototype.postDeselect = function() {  return;  }
ProductPageTab.prototype.getExtraHtml = function() {  return null;  }

/* ****************************** HighlightsTab ****************************** */

function HighlightsTab(highlightsHtml, productName)
{
  ProductPageTab.call(this, 1, 'Highlights');
  this.highlightsHtml = highlightsHtml;
  this.productName = productName;
}

HighlightsTab.prototype = new ProductPageTab();
HighlightsTab.prototype.constructor = HighlightsTab;

HighlightsTab.prototype.getContent = function()
{
  return '<table border=0 cellspacing=0 cellpadding=0 width="100%" class="abouttext">' +
         '  <tr bgcolor="1B456B">' +
         '    <td style="padding-left: 12px; padding-right: 12px" width="100%"><font face="Arial, Helvetica, sans-serif" size="2" color="#FFFFFF"><b>PRODUCT DESCRIPTION:</b></font></td>' +
         '  </tr>' +
         '  <tr bgcolor="#D7D7D7">' +
         '    <td style="padding-left: 12px; padding-right: 12px" width="100%"><font face="Arial, Helvetica, sans-serif" size="2" color="#1B456B"><b>' + this.productName + '</b></font></td>' +
         '  </tr>' +
         '  <tr bgcolor="#FFFFFF">' +
         '    <td style="padding: 12px" width="100%">' + this.highlightsHtml + '</td>' +
         '  </tr>' +
         '</table>';
}

/* ****************************** SpecificationsTab ****************************** */

function SpecificationsTab()
{
  ProductPageTab.call(this, 2, 'Specifications');
}

SpecificationsTab.prototype = new ProductPageTab();
SpecificationsTab.prototype.constructor = SpecificationsTab;

SpecificationsTab.prototype.getContent = function()
{
  var comparisonData = this.parentObj.comparisonData;
  var comparisonState = this.parentObj.comparisonState;
  var t = '<table border=0 cellspacing=0 cellpadding=0 width="100%" class="abouttext">' +
          '  <tr bgcolor="#1B456B">' +
          '    <td colspan=2 class="' + this.parentObj.idPrefix + 'SpecContent"><font size="2" face="Arial, Helvetica, sans-serif" color="#FFFFFF"><b>SPECIFICATIONS</b></font></td>' +
          '  </tr>';

  var primarySubcat = comparisonData.getPrimarySubcat();
  
  var numRows = 0;
  if (primarySubcat.hasDisambiguations() && (primarySubcat.specData.getNumDisambiguations() > 1))
    t += this.getRowHTML(numRows++, '<b>Select:</b>', this.getDisambiguationSel());
  
  var specData = comparisonState.getPrimarySpecData();

  var priceDisplayValue = specData.getPriceDisplay();

  if (primarySubcat.topTag.length > 0)
    priceDisplayValue += '<br><b><font color="red">' + primarySubcat.topTag + '</font></b>';
  
  if (priceDisplayValue.length > 0)
    t += this.getRowHTML(numRows++, 'Our Price', priceDisplayValue);

  var srpDisplayValue = specData.getSRPDisplay();
  if (srpDisplayValue.length > 0)
    t += this.getRowHTML(numRows++, 'Suggested Retail', srpDisplayValue);

  for (var i = 0; i < comparisonData.getNumFields(); i++)
  {
    var field = comparisonData.getFieldByIndex(i);
    var fieldValue = specData.getSpecDataByFieldFiltered(field);
    if (!fieldValue)
      continue;
    t += this.getRowHTML(numRows++, field.getDisplayName(), fieldValue);
  }
  
  if (primarySubcat.modelList.length > 0)
    t += this.getRowHTML(numRows++, 'Models', primarySubcat.modelList);
  t += '</table>\n';
  return t;
}

SpecificationsTab.prototype.getDisambiguationSel = function()
{
  var primarySubcat = this.parentObj.comparisonData.getPrimarySubcat();
  var t = '<select class="productform" name="' + this.parentObj.idPrefix + 'SpecDisambigSel" size="1" onChange="' + this.getJSName() + '.changeSpecSelection(this)">\n';
  for (var i = 0; i < primarySubcat.specData.getNumDisambiguations(); i++)
  {
    t += '<option value="' + i + '"';
    if (this.parentObj.comparisonState.primaryDisambiguationIndex == i)
      t += ' SELECTED';
    t += '>' + primarySubcat.specData.getDisambiguationDisplayName(i) + '</option>\n';
  }
  t += '</select>';
  return t;
}

SpecificationsTab.prototype.changeSpecSelection = function(s)
{
  var si = s.selectedIndex;
  if ((si >= 0) && (si != this.parentObj.comparisonState.primaryDisambiguationIndex))
  {
    this.parentObj.comparisonState.primaryDisambiguationIndex = si;
    this.refreshContent();
  }
  return;
}


SpecificationsTab.prototype.getRowBgColor = function(curRow)
{
  return ((curRow & 1) == 0) ? '#FFFFFF' : '#D7D7D7';
}

SpecificationsTab.prototype.getLeftHTML = function(theBgColor, leftHTML)
{
  return '<td width=132 style="padding-left: 40px; padding-top:3px; padding-bottom: 3px" valign="top" bgcolor="' + theBgColor + '"><font size="2" face="Arial, Helvetica, sans-serif">' + leftHTML + '</font></td>';
}

SpecificationsTab.prototype.getRightHTML = function(theBgColor, rightHTML)
{
  return '<td class="' + this.parentObj.idPrefix + 'GreyLeft" valign="top" bgcolor="' + theBgColor + '">' + rightHTML + '</td>';
}

SpecificationsTab.prototype.getRowHTML = function(curRow, leftHTML, rightHTML)
{
  var theBgColor = this.getRowBgColor(curRow);
  return '<tr>' + this.getLeftHTML(theBgColor, leftHTML) + this.getRightHTML(theBgColor, rightHTML) + '</tr>\n';
}

/* ****************************** AccessoriesTab ****************************** */

function AccessoriesTab(accessoriesHtml)
{
  ProductPageTab.call(this, 3, 'Accessories');
  this.accessoriesHtml = accessoriesHtml;
}

AccessoriesTab.prototype = new ProductPageTab();
AccessoriesTab.prototype.constructor = AccessoriesTab;

AccessoriesTab.prototype.getContent = function()
{
  return this.accessoriesHtml;
}

/* ****************************** ComparisonTab ****************************** */

function ComparisonTab()
{
  ProductPageTab.call(this, 4, 'Click&nbsp;To&nbsp;Compare');
  this.maxProductsToCompareWith = 3;
  this.maxProductsPerPage = 6;
  this.areaWidth = 620;
  this.columnWidthTrim = 25;
}

ComparisonTab.prototype = new ProductPageTab();
ComparisonTab.prototype.constructor = ComparisonTab;

ComparisonTab.prototype.getContent = function()
{
  var comparisonData = this.parentObj.comparisonData;
  var comparisonState = this.parentObj.comparisonState;
  var idPrefix = this.parentObj.idPrefix;
  var numSubcatsCompared = comparisonState.getNumSubcats();
  var numCols = numSubcatsCompared + 2;
  var reachedMaxSubcats = (numSubcatsCompared >= this.maxProductsToCompareWith);
  if (!reachedMaxSubcats)
    numCols++;
  var colWidth = Math.floor((this.areaWidth / numCols) - this.columnWidthTrim);
  var primarySubcat = comparisonData.getPrimarySubcat();

  var dispFields = [];
  for (var i = 0; i < comparisonData.fieldData.length; i++)
  {
    var curField = comparisonData.fieldData[i];
    for (var j = -1; j < numSubcatsCompared; j++)
    {
      var curSubcat = (j < 0) ? primarySubcat : comparisonState.getComparisonSubcat(j);
      if (curSubcat.hasField(curField))
      {
        dispFields.push(curField);
        break;
      }
    }
  }
  
  var dispModelList = false;
  for (var i = -1; i < numSubcatsCompared; i++)
  {
    var curSubcat = (i < 0) ? primarySubcat : comparisonState.getComparisonSubcat(i);
    if (curSubcat.modelList.length > 0)
    {
      dispModelList = true;
      break;
    }
  }
  var numDispFields = dispFields.length + (dispModelList ? 1 : 0);

  var curRow = 0;
  var t = '<table border=0 cellspacing=0 cellpadding=0 width=950 class="abouttext">\n' + 
          '  <tr bgcolor="#1B456B">\n' +
          '    <td colspan=' + (numCols + 1) + ' class="' + idPrefix + 'SpecContent"><font size="2" face="Arial, Helvetica, sans-serif" color="#FFFFFF"><b>COMPARISON</b></font></td>\n' +
          '  </tr>\n' +
          '  <tr>\n' +
          this.getLeftCell(curRow, 'Model');
  for (var i = -1; i < numSubcatsCompared; i++)
  {
    var curSubcat = (i < 0) ? primarySubcat : comparisonState.getComparisonSubcat(i);
    t += this.getRegularCell(curRow, colWidth, i, this.getModelHTML((i < 0), curSubcat, (i < 0) ? comparisonState.primaryDisambiguationIndex : comparisonState.disambiguationIndexList[i]));
  }
  if (!reachedMaxSubcats)
    t += '<td rowspan=' + (numDispFields + 3) + ' valign="top" width="' + colWidth + '" class="' + idPrefix + ((numSubcatsCompared > 0) ? 'GreyLeft' : 'BlankLeft') + '"><span id="' + idPrefix + 'FeatureCompareDiv">' + this.getComparePageHTML() + '</span></td>\n';
  t += '</tr>\n';
  curRow++;
  
  t += this.createRowHTML(curRow++, colWidth, comparisonState, 'Our Price', function(curSubcat, curSpecData) {
      var cellContent = curSpecData.getPriceDisplay();
      if (curSubcat.topTag.length > 0)
        cellContent += '<br><b><font color="red">' + curSubcat.topTag + '</font></b>';
      if (cellContent.length == 0)
        cellContent = '&nbsp;';
      return cellContent;
    }
  );

  t += this.createRowHTML(curRow++, colWidth, comparisonState, 'Suggested Retail', function(curSubcat, curSpecData) {
      var srpDisplay = curSpecData.getSRPDisplay();
      if (srpDisplay.length == 0)
        srpDisplay = '&nbsp;';
      return srpDisplay;
    }
  );

  for (var i = 0; i < dispFields.length; i++)
  {
    var curField = dispFields[i];
    t += this.createRowHTML(curRow++, colWidth, comparisonState, curField.getDisplayName(), function(curSubcat, curSpecData) {
        var fieldValue = curSpecData.getSpecDataByField(curField);
        if ((fieldValue == null) || (fieldValue.length == 0))
          fieldValue = 'N/A';
        return fieldValue;
      }
    );
  }

  if (dispModelList)
  {
    t += this.createRowHTML(curRow++, colWidth, comparisonState, 'Models', function(curSubcat, curSpecData) {
        var cellContent = curSubcat.modelList;
        if (cellContent.length == 0)
          cellContent = 'N/A';
        return cellContent;
      }
    );
  }
  
  t += '</table>\n';
  return t;
}

ComparisonTab.prototype.createRowHTML = function(curRow, colWidth, comparisonState, leftCellContent, cellContentFunction)
{
  var t = '  <tr>\n' + this.getLeftCell(curRow, leftCellContent);
  for (var i = -1; i < comparisonState.getNumSubcats(); i++)
  {
    var curSubcat = (i < 0) ? comparisonState.getPrimarySubcat() : comparisonState.getComparisonSubcat(i);
    var curSpecData = (i < 0) ? comparisonState.getPrimarySpecData() : comparisonState.getComparisonSpecData(i);
    var cellContent = cellContentFunction(curSubcat, curSpecData);
    t += this.getRegularCell(curRow, colWidth, i, cellContent);
  }
  t += '  </tr>\n';
  return t;
}

ComparisonTab.prototype.getRowBgColor = function(curRow)
{
  return ((curRow & 1) == 0) ? '#FFFFFF' : '#D7D7D7';
}

ComparisonTab.prototype.getLeftCell = function(curRow, cellContent)
{
  return '<td class="' + this.parentObj.idPrefix + 'BlankLeft" valign="top" width="130" bgcolor="' + this.getRowBgColor(curRow) + '"><font size="2" face="Arial, Helvetica, sans-serif"><b>' + cellContent + '</b></font></td>\n';
}

ComparisonTab.prototype.getRegularCell = function(curRow, colWidth, curSubcatIndex, cellContent)
{
  var curStyle = (curSubcatIndex < 0) ? 'ThisSubcatCol' : ((curSubcatIndex == 0) ? 'BlankLeft' : 'GreyLeft');
  return '<td class="' + this.parentObj.idPrefix + curStyle + '" align="left" valign="top" width="' + colWidth + '" bgcolor="' + this.getRowBgColor(curRow) + '">' + cellContent + '</td>\n';
}

ComparisonTab.prototype.changeSpecSelection = function(s, subcatId)
{
  var si = s.selectedIndex;
  if (si < 0)
    return;
  if (this.parentObj.comparisonState.setDisambiguationIndex(subcatId, si))
    this.refreshContent();
  return;
}

ComparisonTab.prototype.compareChangePageIndex = function(newPageIndex)
{
  var fcd = document.getElementById(this.parentObj.idPrefix + 'FeatureCompareDiv');
  if (fcd)
  {
    this.parentObj.comparisonState.curPageIndex = newPageIndex;
    fcd.innerHTML = this.getComparePageHTML();
  }
  return;
}

ComparisonTab.prototype.getComparePageHTML = function()
{
  var subcatsList = this.parentObj.comparisonState.getLimitedSubcatList();
  var numPages = Math.floor((subcatsList.length + this.maxProductsPerPage - 1) / this.maxProductsPerPage);

  var comparisonState = this.parentObj.comparisonState;
  if ((comparisonState.curPageIndex < 0) || (comparisonState.curPageIndex >= numPages))
    comparisonState.curPageIndex = 0;

  // See what comparison options are available
  var mfrNameList = comparisonState.getMfrNameListToDisplay(subcatsList);
  var subcatClassList = comparisonState.getSubcatClassListToDisplay(subcatsList);
  var priceIndexList = comparisonState.getPriceIndexListToDisplay(subcatsList);
  var shouldDisplayOnSale = comparisonState.shouldDisplayOnSale(subcatsList);
  var hasLists = (mfrNameList != null) || (subcatClassList != null) || (priceIndexList != null);

  var priceRangeData = comparisonState.getPriceRangeData();
  var showProducts = comparisonState.hasSelections() || !hasLists;

  var idPrefix = this.parentObj.idPrefix;
  var thisTabJS = this.getJSName();
  var t = '';
  if (comparisonState.hasSelections())
  {
    t += '<a href="javascript:' + thisTabJS + '.comparisonPageBack()" style="color: blue">Go Back</a>' +
         ' &nbsp; &nbsp; <a href="javascript:' + thisTabJS + '.comparisonPageStartOver()" style="color: blue">Start Over</a><br><br>\n';
  }
  else
  {
    if (showProducts)
      t += '<br>Please select a product to compare<br>\n';
    else
      t += '<br>Please make a selection to compare<br>\n';
  }
  if (hasLists)
  {
    t += '<form name="' + idPrefix + 'CompareProdForm" style="margin: 0px">\n' +
         '<table border=0 style="padding-left: 0px; padding-right: 3px; padding-top: 0px; padding-bottom: 10px" class="abouttext">\n';
    if (subcatClassList != null)
    {
      t += this.createSelectListRow('Category:', 'CompareCategorySel', 'compareCategorySelect', 0, subcatClassList.length,
                                    function(index) {  return subcatClassList[index].classId;  },
                                    function(index) {  return subcatClassList[index].getDisplayName();  });
    }
    if (priceIndexList != null)
    {
      t += this.createSelectListRow('Price:', 'ComparePriceSel', 'comparePriceSelect', shouldDisplayOnSale ? -1 : 0, priceIndexList.length,
                                    function(index) {  return ((index < 0) ? -1 : priceIndexList[index]);  },
                                    function(index) {  return ((index < 0) ? 'On Sale' : priceRangeData.getRangeDisplayName(priceIndexList[index]));  });
    }
    if (mfrNameList != null)
    {
      t += this.createSelectListRow('Brand:', 'CompareMfrSel', 'compareMfrSelect', 0, mfrNameList.length,
                                    function(index) {  return mfrNameList[index];  },
                                    function(index) {  return mfrNameList[index];  });
    }
    t += '</table>\n' +
         '</form>\n';
  }

  if (showProducts)
  {
    var pageLinks = this.getPageLinksHTML(comparisonState.curPageIndex, numPages);
    if (pageLinks.length > 0)
      t += pageLinks + '<br>\n';
  
    var startIndex = comparisonState.curPageIndex * this.maxProductsPerPage;
    var endIndex = startIndex + this.maxProductsPerPage;
    if (endIndex > subcatsList.length)
      endIndex = subcatsList.length;
    t += '<table border=0 cellspacing=0 cellpadding=3 class="abouttext">\n';
    for (var i = startIndex; i < endIndex; i++)
    {
      var curSubcat = subcatsList[i];
      t += '<tr><td><img src="' + curSubcat.thumbImageUrl + '" onError="' + thisTabJS + '.thumbImageComingSoon(this)" border=0></td>' +
           '<td><a href="javascript:' + thisTabJS + '.compareAddSubcat(' + curSubcat.subcatId + ')" style="color: blue">' + curSubcat.subcatName + '</a></td></tr>\n';
    }
    t += '</table><br><br>\n';
    if (pageLinks.length > 0)
      t += pageLinks;
  }
  return t;
}

ComparisonTab.prototype.createSelectListRow = function(rowTitle, selectListName, jsFunctionName, startIndex, endIndex, optionValueFunction, optionTextFunction)
{
  var t = '<tr><td>' + rowTitle + '</td><td><select name="' + this.parentObj.idPrefix + selectListName + '" size="1" onChange="' + this.getJSName() + '.' + jsFunctionName + '(this)">\n' +
           '<option value="">Select...</option>\n';
  for (var i = startIndex; i < endIndex; i++)
    t += '<option value="' + optionValueFunction(i) + '">' + optionTextFunction(i) + '</option>\n';
  t += '</select></td></tr>\n';
  return t;
}

ComparisonTab.prototype.getPageLinksHTML = function(curPageIndex, numPages)
{
  if (numPages < 2)
    return '';
  var t = '';
  for (var i = 0; i < numPages; i++)
  {
    if (i > 0)
      t += '&nbsp;';
    if (i != curPageIndex)
      t += '<a href="javascript:' + this.getJSName() + '.compareChangePageIndex(' + i + ')" style="color: blue">';
    t += (i + 1);
    if (i != curPageIndex)
      t += '</a>';
  }
  return t;
}

ComparisonTab.prototype.getModelHTML = function(isPrimary, subcatSpecs, curDisambiguationIndex)
{
  var t = '';
  if (!isPrimary)
  {
    t += '<a id="' + this.parentObj.idPrefix + 'CmpAnchor' + subcatSpecs.subcatId + '" href="/customer/category/product.jsp?SUBCATEGORY_ID=' + subcatSpecs.subcatId;
    var comparisonStateString = this.parentObj.comparisonState.getStateString(subcatSpecs.subcatId);
    if ((comparisonStateString != null) && (comparisonStateString.length > 0))
      t += '&cmpState=' + escape(comparisonStateString);
    t += '">';
  }
  t += '<img src="' + subcatSpecs.thumbImageUrl + '" onError="' + this.getJSName() + '.thumbImageComingSoon(this)" border=0><br>' +
       '<font color="black">' + subcatSpecs.subcatName + '</font>';
  if (!isPrimary)
    t += '</a>';
  if (subcatSpecs.hasDisambiguations() && (subcatSpecs.specData.getNumDisambiguations() > 1))
    t += ' ' + this.getDisambiguationSel(subcatSpecs, curDisambiguationIndex);
  if (!isPrimary)
    t += '<br><a href="javascript:' + this.getJSName() + '.compareRemoveSubcat(' + subcatSpecs.subcatId + ')"><font face="Arial, Helvetica, sans-serif" size="1" color="#0000ff">Remove</font></a>';
  return t;
}

ComparisonTab.prototype.compareAddSubcat = function(subcatId)
{
  var comparisonState = this.parentObj.comparisonState;
  if (comparisonState.getNumSubcats() >= this.maxProductsToCompareWith)
    return;
  if (comparisonState.addSubcatId(subcatId))
    this.refreshContent();
  return;
}

ComparisonTab.prototype.compareRemoveSubcat = function(subcatId)
{
  if (this.parentObj.comparisonState.removeSubcatId(subcatId))
    this.refreshContent();
  return;
}

ComparisonTab.prototype.compareCategorySelect = function(s)
{
  var si = s.selectedIndex;
  if (si < 0)
    return;
  if (this.parentObj.comparisonState.stateChangeLimitClassId(parseInt(s.options[si].value)))
  {
    this.parentObj.comparisonState.resetPageIndex();
    this.refreshContent();
  }
  return;
}

ComparisonTab.prototype.compareMfrSelect = function(s)
{
  var si = s.selectedIndex;
  if (si < 0)
    return;
  if (this.parentObj.comparisonState.stateChangeLimitMfr(s.options[si].value))
  {
    this.parentObj.comparisonState.resetPageIndex();
    this.refreshContent();
  }
  return;
}

ComparisonTab.prototype.comparePriceSelect = function(s)
{
  var si = s.selectedIndex;
  if (si < 0)
    return;
  var comparisonState = this.parentObj.comparisonState;
  var priceRangeData = comparisonState.getPriceRangeData();
  if (priceRangeData == null)
    return;
  var rangeIndex = parseInt(s.options[si].value);
  var doRefresh;
  if (rangeIndex < 0)
    doRefresh = comparisonState.stateChangeLimitPriceOnSale();
  else
  {
    var priceSel = priceRangeData.getSelection(rangeIndex);
    if (priceSel == null)
      return;
    doRefresh = comparisonState.stateChangeLimitPrice(priceSel);
  }
  if (doRefresh)
  {
    this.parentObj.comparisonState.resetPageIndex();
    this.refreshContent();
  }
  return;
}

ComparisonTab.prototype.comparisonPageBack = function()
{
  if (this.parentObj.comparisonState.popStack())
  {
    this.parentObj.comparisonState.resetPageIndex();
    this.refreshContent();
  }
  return;
}

ComparisonTab.prototype.comparisonPageStartOver = function()
{
  if (this.parentObj.comparisonState.clearStack())
  {
    this.parentObj.comparisonState.resetPageIndex();
    this.refreshContent();
  }
  return;
}

ComparisonTab.prototype.getDisambiguationSel = function(subcatSpecs, curDisambiguationIndex)
{
  var t = '<select class="productform" name="' + this.parentObj.idPrefix + 'CmpDisambigSel" size="1" onChange="' + this.getJSName() + '.changeSpecSelection(this, ' + subcatSpecs.subcatId + ')">\n';
  for (var i = 0; i < subcatSpecs.specData.getNumDisambiguations(); i++)
  {
    t += '<option value="' + i + '"';
    if (curDisambiguationIndex == i)
      t += ' SELECTED';
    t += '>' + subcatSpecs.specData.getDisambiguationDisplayName(i) + '</option>\n';
  }
  t += '</select>';
  return t;
}

ComparisonTab.prototype.thumbImageComingSoon = function(img)
{
  if (img.src.indexOf('/images/products/coming-soon-icon.jpg') < 0)
    img.src = '/images/products/coming-soon-icon.jpg';
  return;
}

/* ****************************** ReviewsTab ****************************** */

function ReviewsTab(reviewsPerPage)
{
  ProductPageTab.call(this, 5, 'Reviews');
  this.reviewsPerPage = reviewsPerPage;
  this.reviewHtml = '';
  this.reviewRequester = null;
  this.requestedPageIndex = 0;

  this.REVIEW_PREVIEW_CHARS = 150;
  this.REVIEW_PREVIEW_FUDGE = 20;
  this.REVIEW_PREVIEW_LINES = 2;
}

ReviewsTab.prototype = new ProductPageTab();
ReviewsTab.prototype.constructor = ReviewsTab;

ReviewsTab.prototype.initRequester = function()
{
  var thisTab = this;
  this.reviewRequester = new BGRequest(this.getJSName() + '.reviewRequester');
  this.reviewRequester.timeoutInterval = 20000;
  this.reviewRequester.normalHandler = function(txt, xml) {  ReviewsTab.prototype.handleReviewRequest.call(thisTab, txt, xml);  }
  this.reviewRequester.timeoutHandler = function() {  ReviewsTab.prototype.timeoutHandler.call(thisTab);  }
  this.reviewRequester.errorHandler = function() {  ReviewsTab.prototype.errorHandler.call(thisTab);  }
  this.reviewRequester.reentrantHandler = function() {  ReviewsTab.prototype.reentrantHandler.call(thisTab);  }
  this.reviewRequester.noXMLHttpHandler = function() {  ReviewsTab.prototype.noXMLHttpHandler.call(thisTab);  }
}

ReviewsTab.prototype.wrapReviewContent = function()
{
  var t = '<table border=0 cellspacing=0 cellpadding=10 width="100%"><tr>';
  if (this.reviewHtml.length > 0)
    t += '<td class="abouttext" valign="top">' + this.reviewHtml + '</td>\n';
  else
    t += '<td class="abouttext">Unable to display review information</td>\n';
  t += '</tr></table>\n';
  return t;
}


ReviewsTab.prototype.getContent = function()
{
  if (this.reviewRequester == null)
  {
    this.reviewHtml = 'Getting reviews... please wait';
    this.requestReviews(this.requestedPageIndex);
  }
  return this.wrapReviewContent();
}

ReviewsTab.prototype.requestReviews = function(pageIndex)
{
  if (this.reviewRequester == null)
    this.initRequester();
  if (this.reviewRequester.rqStarted > 0)
    return;
  this.requestedPageIndex = pageIndex;
  this.reviewRequester.performRequest('GET', '/customer/getRatingsReviews.jsp?subcatid=' + this.parentObj.comparisonData.primarySubcatId + '&startreview=' + (pageIndex * this.reviewsPerPage) + '&count=' + this.reviewsPerPage + '&rnd=' + Math.random(), true, null);
  return;
}

ReviewsTab.prototype.handleReviewRequest = function(txt, xml)
{
readReviews:
  try
  {
    if (!xml)
    {
      this.reviewErrorHandler(null);
      return;
    }
    var allReviews = xml.getElementsByTagName('ALLREVIEWS');
    if (!allReviews || (allReviews.length==0))
    {
      this.reviewErrorHandler(null);
      return;
    }
    allReviews = allReviews.item(0);
    var totalReviewCount = parseInt(getDataByTagName(allReviews, 'TOTALCOUNT'));
    allReviews = allReviews.getElementsByTagName('REVIEW');
    var numReviews = allReviews.length;
    if (numReviews == 0)
    {
      this.reviewHtml = 'There are no reviews for this product.';
      break readReviews;
    }
    var t = '<table border=0 cellspacing=0 cellpadding=0 class="abouttext" width="100%">\n' +
            '<tr><td colspan=3>';
    if (numReviews == totalReviewCount)
    {
      t += 'Displaying ' + numReviews;
      if (numReviews == 1)
        t += ' review';
      else
        t += ' reviews';
    }
    else
    {
      t += 'Page:';
      var numPages = Math.floor((totalReviewCount + this.reviewsPerPage - 1) / this.reviewsPerPage);
      for (var i = 0; i < numPages; i++)
      {
        if (i == this.requestedPageIndex)
          t += ' ' + (i + 1);
        else
          t += ' <a href="javascript:' + this.getJSName() + '.requestReviews(' + i + ')">' + (i + 1) + '</a>';
      }
    }
    t += '</td></tr>\n';

    var idPrefix = this.parentObj.idPrefix;
    var fullStars, useHalfStar, emptyStars;
    for (var i = 0; i < numReviews; i++)
    {
      var curReview = allReviews.item(i);
      var firstName = getDataByTagName(curReview, 'FIRSTNAME');
      var lastName = getDataByTagName(curReview, 'LASTNAME');
      var city = getDataByTagName(curReview, 'CITY');
      var reviewTitle = getDataByTagName(curReview, 'REVIEWTITLE');
      var reviewContent = getDataByTagName(curReview, 'POSTEDREVIEW');
      var handicap = getDataByTagName(curReview, 'HANDICAP');
      var frequencyOfPlay = getDataByTagName(curReview, 'FREQUENCY_OF_PLAY');
      var reviewDate = getDataByTagName(curReview, 'REVIEW_DATE');
      t += '<tr><td colspan=3><hr></td></tr>\n';
      t += '<tr><td valign="top" class="smalltext" width=80>';
      var allRatings = curReview.getElementsByTagName('RATING');
      var reviewContent = this.addBreaks(reviewContent);
      var reviewContentSplit = this.getReviewContentSplit(reviewContent);

      if (allRatings && (allRatings.length > 0))
      {
        var ratingItems = [];
        
        var subcatObj = this.getSubcatObj();
        for (var j = 0; j < subcatObj.ratingNames.length; j++)
        {
          var ratingName = subcatObj.ratingNames[j];
          for (var k = 0; k < allRatings.length; k++)
          {
            var curRating = allRatings.item(k);
            if (ratingName == getDataByTagName(curRating, 'RATING_NAME'))
            {
              ratingItems.push(curRating);
              break;
            }
          }
        }
        for (var j = 0; j < ratingItems.length;j++)
        {
          var curRating = ratingItems[j];
          if (j > 0)
            t += '<br>\n';
          if (j == 1)
          {
            if (reviewContentSplit <= 0)
              t += '<span id="' + idPrefix + 'ReviewMore' + i + '"><a href="javascript:' + this.getJSName() + '.showMoreReview(' + i + ')" style="color:black; font-weight:bold">(More)</a></span>';
            t += '<div id="' + idPrefix + 'RatingsCont' + i + '" style="display:none">';
          }
          var ratingName = getDataByTagName(curRating, 'RATING_NAME');
          var ratingValue = parseFloat(getDataByTagName(curRating, 'RATING_VALUE'));
          var ratingStyle = getDataByTagName(curRating, 'RATING_STYLE');
          if (ratingStyle == 'stars')
          {
            t += '<b>' + ratingName + '</b><br>\n';
            var fullStars = Math.floor(ratingValue);
            var useHalfStar = ((ratingValue - fullStars) >= 0.50);
            var emptyStars = 5 - fullStars;
            if (useHalfStar)
              emptyStars--;
            for (var k = 0; k < fullStars; k++)
              t += '<img src="/images/reviews/star_full.gif" width=14 height=13>';
            if (useHalfStar)
              t += '<img src="/images/reviews/star_half.gif" width=14 height=13>';
            for (var k = 0; k < emptyStars; k++)
              t += '<img src="/images/reviews/star_empty.gif" width=14 height=13>';
          }
          else
            t += '<b>' + ratingName + ':</b> ' + ratingValue;
        }
        if (ratingItems.length > 1)
        {
          t += '</div>\n';
          if (reviewContentSplit <= 0)
            t += '<span id="' + idPrefix + 'ReviewLess' + i + '" style="display:none"><a href="javascript:' + this.getJSName() + '.showLessReview(' + i + ')" style="color:black; font-weight:bold">(Less)</a></span>';
        }
      }
      fullName = firstName;
      if (lastName.length > 0)
        fullName += ' ' + lastName;
      t += '</td><td width=5>&nbsp;</td><td valign="top">';
      if (reviewTitle == '')
        reviewTitle = 'Review by ' + fullName;
      t += '<span style="float: left"><b>' + reviewTitle + '</b></span>';
      if (reviewDate != '')
        t += '<span style="float: right">' + reviewDate + '</span>';
      t += '<br>\n';
      t += '<font color="blue">' + fullName + ' from ' + city + '</font>';
      if ((handicap.length > 0) && (handicap != 'N/A'))
        t += ' - Handicap: <font color="blue">' + handicap + '</font>';
      if (frequencyOfPlay.length > 0)
        t += ' - Frequency of play: <font color="blue">' + frequencyOfPlay + '</font>';
      t += '<br><br>'

      if (reviewContentSplit > 0)
      {
        t += reviewContent.substring(0, reviewContentSplit) +
            '<span id="' + idPrefix + 'ReviewMore' + i + '" style="color:black; font-weight:bold">...<a href="javascript:' + this.getJSName() + '.showMoreReview(' + i + ')" style="color:black; font-weight:bold">(More)</a></span>' +
            '<span id="' + idPrefix + 'ReviewCont' + i + '" style="display:none">' +
            reviewContent.substring(reviewContentSplit) +
            '</span>\n' +
            '<span id="' + idPrefix + 'ReviewLess' + i + '" style="display:none"><br><a href="javascript:' + this.getJSName() + '.showLessReview(' + i + ')" style="color:black; font-weight:bold">(Less)</a></span>';
      }
      else
        t += reviewContent;
      t += '</td></tr>\n';
    }
    t += '</table>\n';
    this.reviewHtml = t;
  }
  catch(e)
  {
    this.lastError = e;
    this.reviewHtml = 'There was an error displaying the reviews';
  }
  if (this.parentObj.currentTab == this)
    this.refreshContent();
  return;
}

ReviewsTab.prototype.showMoreReview = function(n)
{
  var idPrefix = this.parentObj.idPrefix;
  var reviewMore = document.getElementById(idPrefix + 'ReviewMore' + n);
  var reviewLess = document.getElementById(idPrefix + 'ReviewLess' + n);
  var reviewCont = document.getElementById(idPrefix + 'ReviewCont' + n);
  if (!reviewMore || !reviewLess)
    return;
  var ratingsCont = document.getElementById(idPrefix + 'RatingsCont' + n);
  reviewMore.style.display = 'none';
  reviewLess.style.display = 'inline';
  if (reviewCont)
    reviewCont.style.display = 'inline';
  if (ratingsCont)
    ratingsCont.style.display = 'block';
  return;
}

ReviewsTab.prototype.showLessReview = function(n)
{
  var idPrefix = this.parentObj.idPrefix;
  var reviewMore = document.getElementById(idPrefix + 'ReviewMore' + n);
  var reviewLess = document.getElementById(idPrefix + 'ReviewLess' + n);
  var reviewCont = document.getElementById(idPrefix + 'ReviewCont' + n);
  if (!reviewMore || !reviewLess)
    return;
  var ratingsCont = document.getElementById(idPrefix + 'RatingsCont' + n);
  reviewMore.style.display = 'inline';
  reviewLess.style.display = 'none';
  if (reviewCont)
    reviewCont.style.display = 'none';
  if (ratingsCont)
    ratingsCont.style.display = 'none';
  return;
}

ReviewsTab.prototype.isWordPart = function(c)
{
  return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
}

ReviewsTab.prototype.getReviewContentSplit = function(reviewContent)
{
  var reviewContentLen = reviewContent.length;
  var lastBreak = -1;
  var breakCount = 0;
  while (lastBreak < this.REVIEW_PREVIEW_CHARS)
  {
    lastBreak = reviewContent.indexOf('<br>', lastBreak + 1);
    if (lastBreak < 0)
      break;
    breakCount++;
    if (breakCount == this.REVIEW_PREVIEW_LINES)
    {
      // Decide split early if many small lines
      if (lastBreak < (this.REVIEW_PREVIEW_CHARS + this.REVIEW_PREVIEW_FUDGE))
        return lastBreak;
      break;
    }
  }

  // Check if it even needs to be split
  if (reviewContentLen < (this.REVIEW_PREVIEW_CHARS + this.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>', this.REVIEW_PREVIEW_CHARS - this.REVIEW_PREVIEW_FUDGE - 4);
  // If the break was in the window, use it
  if ((reviewContentSplit >= 0) && (reviewContentSplit < (this.REVIEW_PREVIEW_CHARS + this.REVIEW_PREVIEW_FUDGE)))
    return reviewContentSplit;

  // Moving outwards from the window's center, look for a transition from word character to non-word character
  for (var i = 0; i < this.REVIEW_PREVIEW_FUDGE; i++)
  {
    var curPos = this.REVIEW_PREVIEW_CHARS + i;
    if ((curPos < reviewContentLen) && this.isWordPart(reviewContent.charAt(curPos - 1)) && !this.isWordPart(reviewContent.charAt(curPos)))
      return curPos;
    curPos = this.REVIEW_PREVIEW_CHARS - i;
    if ((curPos > 0) && this.isWordPart(reviewContent.charAt(curPos - 1)) && !this.isWordPart(reviewContent.charAt(curPos)))
      return curPos;
  }
  // Just split it down the center of the window
  return this.REVIEW_PREVIEW_CHARS;
}

ReviewsTab.prototype.addBreaks = function(s)
{
  if (!s)
    return '';
  var index = 0;
  while (index < s.length)
  {
    index = s.indexOf('\n', index);
    if (index < 0)
      return s;
    var indexAdjust = ((index > 0) && (s.charAt(index - 1) == '\r')) ? 1 : 0;
    s = s.substring(0, index - indexAdjust) + '<br>' + s.substring(index - indexAdjust, s.length);
    index += 5 + indexAdjust;
  }
  return s;
}

/* ****************************** CustomizationTab ****************************** */

function CustomizationTab(customProductData, curCustomProductId, xmlPage, flashFile, flashFileOld, customProductWidth, customProductHeight)
{
  ProductPageTab.call(this, 6, 'Customize');
  this.customProductData = customProductData;
  this.curCustomProductId = curCustomProductId;
  this.xmlPage = xmlPage;
  this.flashFile = flashFile;
  this.flashFileOld = flashFileOld;
  this.customProductWidth = customProductWidth;
  this.customProductHeight = customProductHeight;
  this.customTabVisited = false;
}

CustomizationTab.prototype = new ProductPageTab();
CustomizationTab.prototype.constructor = CustomizationTab;

CustomizationTab.prototype.getContent = function()
{
  if (this.customProductData.length <= 2)
    return '';
  var t = '<div style="padding-bottom: 5px">';
  for (var i = 0; i < this.customProductData.length; i += 2)
  {
    if (i > 0)
      t += ' - ';
    if (this.curCustomProductId != this.customProductData[i])
      t += '<a href="javascript:' + this.getJSName() + '.switchCustomProduct(' + (i >>> 1) + ')">';
    else
      t += '<b>';
    t += this.customProductData[i + 1];
    if (this.curCustomProductId != this.customProductData[i])
      t += '</a>';
    else
      t += '</b>';
  }
  t += '</div>';
  return t;
}

CustomizationTab.prototype.preDeselect = function()
{
  var custDiv = document.getElementById(this.parentObj.idPrefix + 'CustomizationDiv');
  if (custDiv)
  {
    custDiv.style.visibility = 'hidden';
    var custPlaceholder = document.getElementById(this.parentObj.idPrefix + 'CustomizationPlaceholder');
    if (custPlaceholder)
      custPlaceholder.style.display='none';
  }
  return true;
}

CustomizationTab.prototype.postSelect = function()
{
  var custDiv = document.getElementById(this.parentObj.idPrefix + 'CustomizationDiv');
  if (custDiv)
  {
    var custPlaceholder = document.getElementById(this.parentObj.idPrefix + 'CustomizationPlaceholder');
    custPlaceholder.style.display = '';
    custPlaceholder.style.minWidth = this.customProductWidth;
    custPlaceholder.style.minHeight = this.customProductHeight + 5;
    custPlaceholder.style.width = this.customProductWidth;
    custPlaceholder.style.height = this.customProductHeight + 5;
    calcXY(custPlaceholder);
    custDiv.style.top = custPlaceholder.calcy;
    custDiv.style.left = custPlaceholder.calcx+2;
    custDiv.style.visibility = 'visible';
  }
  if (!this.customTabVisited)
    this.writeCustomProductDiv();
  return;
}

CustomizationTab.prototype.getExtraHtml = function()
{
  return '<div id="' + this.parentObj.idPrefix + 'CustomizationPlaceholder" style="display:none"></div>' +
         '<div id="' + this.parentObj.idPrefix + 'CustomizationDiv" style="visibility: hidden; position: absolute"></div>';
}

CustomizationTab.prototype.switchCustomProduct = function(customProductIndex)
{
  var newCustomProductId = this.customProductData[customProductIndex << 1];
  if (newCustomProductId != this.curCustomProductId)
  {
    this.curCustomProductId = newCustomProductId;
    this.refreshContent();
    this.writeCustomProductDiv();
  }
  return;
}

CustomizationTab.prototype.writeCustomProductDiv = function()
{
  var idPrefix = this.parentObj.idPrefix;
  var custDiv = document.getElementById(idPrefix + 'CustomizationDiv');
  var curCustomXmlPage = this.xmlPage;
  var ccFileName = (flashVersion < 8) ? this.flashFileOld : this.flashFile;
  var customFlashVer = 10;
  
  custDiv.innerHTML = '<div id="' + idPrefix + 'TempCustDiv"></div><div id="' + idPrefix + 'TempCustDiv2"></div>';
  var custDiv2 = document.getElementById(idPrefix + 'TempCustDiv2');
  this.customTabVisited = true;
  AC_FL_RunContent_div(idPrefix + 'TempCustDiv',
    'allowScriptAccess', 'sameDomain',
    'movie', ccFileName + '?version=' + customFlashVer,
    'FlashVars', 'css_file=/script/customProduct.css&xml_file=' + this.xmlPage + '%3FcustomProductId=' + this.curCustomProductId + '%26rcpid=' + this.parentObj.subcatObj.rcpid,
    'quality', 'high',
    'bgcolor', '#ffffff',
    'wmode', 'window',
    'swliveconnect', 'true',
    'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0',
    'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
    'width', '' + this.customProductWidth,
    'height', '' + this.customProductHeight,
    'id', idPrefix + 'CustomProduct',
    'name', idPrefix + 'CustomProduct',
    'src', ccFileName + '?version=' + customFlashVer);
  // A div cannot be entirely a script tag in IE ... so we add a nonbreakable space...
  custDiv2.innerHTML = '&nbsp;<scr' + 'ipt event=FSCommand(command,args) for=' + idPrefix + 'CustomProduct>\n' + idPrefix + 'CustomProduct_DoFSCommand(command,args) <' + '/scr' + 'ipt>';
  return;
}

CustomizationTab.prototype.receiveFSCommand = function(command, args)
{
  floatCart.addCustomProductToCart(this.curCustomProductId, this.parentObj.subcatObj.rcpid, args, false);
  return;
}
