/**
 * Escapes the given string, so it is HTML safe.
 * @param {string} html The input HTML to escape.
 * @return {string} The escaped HTML.
 */
function escapeHtml(html) {
  var s = '' + html;
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
}

/**
 * Escapes the given URL.
 * @param {string} url The URL to escape.
 * @return {string} The escaped URL.
 */
function escapeUrl(url) {
  return url.replace(/</g, '%3C').replace(/>/g, '%3E').replace(/"/g, '%22');
}

/**
 * Strips off all HTML tags.
 * @param {string} html The input HTML.
 * @return {string} The stripped version of HTML.
 */
function stripOffHtmlTags(html) {
  var s = '' + html;
  return s.replace(/\<[^\>]+\>/g, '');
}

function isArray(obj) {
  if (obj.constructor.toString().indexOf('Array') == -1) {
    return false;
  } else {
    return true;
  }
}

function getHTMLOneEntryList(thumb, title,href, price,description) {
var indexCount = 0;
//alert(href.indexOf('.html?'));
if(href.indexOf('.html?') != -1)
{
    indexCount = href.indexOf('?');
}
else
{
    indexCount = href.length;
}
  var s = '<tr class="cse-commerce-result"><td align="center" style="padding-right:.5em;">' +
           (thumb ? '<a class="url" href="' + Left(href,indexCount) + '">' +
           '<img src="' + thumb + '" height="100" border="0" style="border:1px solid #664433;"></a>' :
           '') + '</td><td valign="top" style="padding-top:5px;"><a class="url" style="color:#43687d;font-size:13pt;font-weight:bold;" href="' + Left(href,indexCount) + '">' +
           title + '</a><br><span style="color:#666666;font-size:9pt;width:400px;">' + description + '</span><br><span style="color:#43687d;font-size:13pt;font-weight:bold;">Starts at ' + 
           '<font color="#f78d1e" style="font-size:13pt;">' + price +
           '</font></span>&nbsp;&nbsp;&nbsp;<a style="text-decoration:none;" href="' + Left(href,indexCount) + '"><span style="color:#477896;font-size:12px;font-weight:bold;">' +
           '<img style="padding-top:5px;" src="../shop/arsformqa/googlecommercesearch/images/shopnow.jpg" title="Shop Now" alt="Shop Now"/>' +
           '</span></a></td></tr>';
           
           //alert(Left(href,indexCount));
           
  return s;
}

//added by JB to format currencey
function formatCurrency(num) {
num = num.toString().replace(/\$|\,/g,'');
if(isNaN(num))
num = "0";
sign = (num == (num = Math.abs(num)));
num = Math.floor(num*100+0.50000000001);
cents = num%100;
num = Math.floor(num/100).toString();
if(cents<10)
cents = "0" + cents;
for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
num = num.substring(0,num.length-(4*i+3))+','+
num.substring(num.length-(4*i+3));
return (((sign)?'':'-') + '$' + num + '.' + cents);
}

function getHTMLOneEntryGrid(thumb, title, href, price) {
  var s = '<li class="result-grid"><div class="result-cont-grid">';
  s += thumb ? '<p class="result-image-grid"><a class="url" href="' +
       href + '"><img width="100" border="0" src="' + thumb +
       '"></a></p>' : '';

  if (title.length > 15) {
    title = title.substring(0, 12) + '...';
  }

  s += '<h3 class="result-h3-grid"><a wrap=soft href="' +
       href + '">' + title + '</a></h3><b>' + price + '</b></div>';

  return s;
}

function getPromotions(promotions) {
  // Create promotions section at the top.
  var str = '';
  if (promotions) {
      for (var i = 0, item; item = promotions.g$promotion[i]; ++i) {
      str += '<div class="cse-commerce-promotion">';
      str += '<table><tr>';
      if (item.g$image_link) {
        str += '<td class="cse-commerce-promotion-image">';
        str += '<a href="' + escapeUrl(item.g$link.$t) + '">';
        str += '<img src="' + escapeUrl(item.g$image_link.$t);
        str += '" ></img>';
        str += '</a>';
        str += '</td>';
      }
      str += '<td class="cse-commerce-promotion-title">' +
             '<strong><a href="' + escapeUrl(item.g$link.$t) + '\">' +
             stripOffHtmlTags(item.g$title.$t) + '</a></strong>';
      if (item.g$snippet) {
        str += '<br/><span>' + item.g$snippet.$t + '</span>';
      }
      str += '</div></td></tr></table></div>';
    }
  }
  return str;
}

function Right(str, n){
    if (n <= 0)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}

function Left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}

function getHTML(entries, promotions, view, gridImage, listImage) {
  var imagePrefix = 'http://www.google.com/cse/images/commerce/';
    
  if (view == 'grid') {
    if (gridImage) {
      gridImage.src = imagePrefix + 'grid_view_selected.png';
      gridImage.style.display = '';
    }
    if (listImage) {
      listImage.src = imagePrefix + 'list_view_unselected.png';
      listImage.style.display = '';
    }
  } else {
    if (gridImage) {
      gridImage.src = imagePrefix + 'grid_view_unselected.png';
      gridImage.style.display = '';
    }
    if (listImage) {
      listImage.src = imagePrefix + 'list_view_selected.png';
      listImage.style.display = '';
    }
  }

  var s = getPromotions(promotions);

  s += view == 'grid' ? '<div id="cse-main-div">' : '<table><colgroup>' +
               '<col id="cse-commerce-image">' +
               '<col id="cse-commerce-description">' +
               //'<col id="cse-commerce-price"></colgroup><tbody>';
               '</colgroup><tbody>';


  for (var i = 0, item; item = entries[i]; ++i) {
    var title = item.getTitle().getText();
    var description = item.getContent().getText();
    var href = item.getLink('alternate').getHref();
    var price = item.getAttribute('price').getValue();
    var thumb;
    
    var findSpace = '';
    if (title.length > 45)
    {
        changeTitle = Right(title,title.length - 35);
        changeTitle = changeTitle.replace(' ','<br>');
        title = Left(title,35) + changeTitle;
    }
    
//var the_char=my_car.charAt(0);

    if ('image_link' in item.getAttributes()) {
      var img_obj = item.getAttribute('image_link');
      if (isArray(img_obj)) {
        thumb = img_obj[0].getValue();
        if (thumb[7] == 0) {
          thumb = img_obj[1].getValue();
        }
        if (thumb[7] == 0) {
          thumb = img_obj[2].getValue();
        }
      } else {
        thumb = item.getAttribute('image_link').getValue();
      }
    }

    if (thumb) {
      thumb = escapeUrl(thumb);
    }

    title = title;
    decription = escapeHtml(description);
    href = escapeUrl(href);
    price = escapeHtml(price);
    //alert(price.replace('usd',''));
    price = formatCurrency(price.replace('usd',''));
    s += view == 'grid' ? getHTMLOneEntryGrid(thumb, title, href, price) :
                 getHTMLOneEntryList(thumb, title, href, price,description);
  }

  s += view == 'list' ? '</tbody></table>' : '';
  return s;
}

/*
 * Initializes Commerce Search preview code.
 *
 * Note: This script requires http://www.google.com/jsapi to be included
 * in your HTML page:
 * <script src="http://www.google.com/jsapi" type="text/javascript"></script>*/
 
 
function initializeCommerceSearch(customerId,
                                  cx,
                                  resultsPanel,
                                  unfilteredAttrsPanel,
                                  filteredAttrsPanel,
                                  country,
                                  opt_doneCallback,
                                  opt_errorHandler,
                                  opt_currency,
                                  opt_gridImage,
                                  opt_listImage) {
  google.load('gdata', '1.x');
  var baseUrlPrefix = 'http://www.google.com/base/feeds/';
  var baseService;

  // Global refinement vars.
  var sortOrder = 'match';
  var priceMatch = '';
  var currency = opt_currency ? opt_currency : 'usd';
  var currentPage = 1;
  var resultsLimit = 12;
  var queryString = '';
  var allEntries;
  var allAttrEntries;
  var viewPref = 'list';
  var allPromotions;
  var gridImage = opt_gridImage;
  var listImage = opt_listImage;
  var filtersMap = {};  // Map which maps an attribute to a filter key.
  var unfilteredAttrs = unfilteredAttrsPanel;
  var filteredAttrs = filteredAttrsPanel;
  var reqCountry = country;

  // This callback will run when the snippets feed query has complete
  // Customize based on which attributes you want to display.
  var handleSnippetsFeed = function(result) {
    var spellingSuggestions = [];
    for (var i = 0, item; item = result.feed.link[i]; ++i) {
      if (item.rel == 'http://schemas.google.com/g/2006#spellcorrection' &&
          item.title) {
        spellingSuggestions.push(item.title);
      }
    }
    if (opt_doneCallback) {
      var totalResults = result.feed.getTotalResults().getValue();
      var totalPages = Math.min(Math.ceil(totalResults / resultsLimit), 8);
      opt_doneCallback(result.feed, spellingSuggestions, currentPage,
                       totalPages);
    }

    allEntries = result.feed.entry;
    allPromotions = result.feed.g$promotions;
    var str = getHTML(allEntries, allPromotions, viewPref, gridImage,
                      listImage);
    resultsPanel.innerHTML = str;
  };

  function truncateAndAddEllipses(nChars, str) {
    if (str.length > nChars) {
      return str.substring(0, nChars - 3) + '...';
    } else {
      return str;
    }
  }

  // This callback will run when the snippets feed query has completed.
  var handleAttributesFeed = function(result) {
    var attrsFilter = '';
    var attrsUnfilter = '';
    var sums = [];
    var temp;
    
    //alert(result);
    //alert(result.feed.entry);
    
    allAttrEntries = result.feed.entry;

    // Compute the summation of the Values vector.

    for (var i = 0, item; item = allAttrEntries[i]; ++i) {
      var t = item.getAttribute();
      var attribs = t.getValues();
      sums[i] = 0;
      for (var j = 0, attrib; attrib = attribs[j]; ++j) {
        sums[i] += parseInt(attrib.getCount());
      }
    }

    // Sort by the summation computed in the previous step.
    // This is a heuristic to decide whc are the more relevant
    // attributes.
    for (var i = 0; i < sums.length; ++i) {
      for (var j = i + 1; j < sums.length; ++j) 
      {
        if (sums[j] > sums[i]) {
          temp = sums[i];
          sums[i] = sums[j];
          sums[j] = temp;
          temp = allAttrEntries[i];
          allAttrEntries[i] = allAttrEntries[j];
          allAttrEntries[j] = temp;
        }
      }
    }

    for (var i = 0, item; item = allAttrEntries[i]; ++i) {
      var t = item.getAttribute();
      var attribs = t.getValues();

      if (t.name != 'price') {
        if (filtersMap[t.name]) {
          var count = '';
          for (var j = 0, attrib; attrib = attribs[j]; ++j) {
            if (attrib.getValue() == filtersMap[t.name]) {
              count = attrib.getCount();
              break;
            }
          }

          attrsFilter += '<div><h4>By ' + t.name +
                         '</h4><div class="cse-commerce-facet">';
          attrsFilter += '<ul><li class="cseLink"><a style="color:#000000;font-size:9pt;font-weight:bold;" href="javascript:void(0)" ' +
                         'onClick="javascript:af(\'' + t.name +
                         '\', \'' + filtersMap[t.name] + '\')">' +
                         truncateAndAddEllipses(20,
                                                escapeHtml(filtersMap[t.name]));

          if (count != '') {
            attrsFilter += '(' + escapeHtml(count) + ')';
          }

          attrsFilter += '</a></li>';
          attrsFilter += '<li class="cseLink"><a style="color:#5a5a5a;font-size:9pt;" href="javascript:void(0)" ' +
                         'onClick="javascript:af(\'' + t.name +
                         '\', null)">View all</a></li>';
          attrsFilter += '</ul></div></div>';
        } else {
          attrsUnfilter += '<div id=attr' + i + '>';
          attrsUnfilter += showBuckets(i, false);
          attrsUnfilter += '</div>';
        }
      }
    }

    if (attrsFilter != '') {
      filteredAttrs.innerHTML = attrsFilter;
      filteredAttrs.style.display = '';
    } else {
      filteredAttrs.style.display = 'none';
    }

    if (attrsUnfilter != '') {
      unfilteredAttrs.innerHTML = attrsUnfilter;
      unfilteredAttrs.style.display = '';
    } else {
      unfilteredAttrs.style.display = 'none';
    }
  };

  // This function shows the buckets in an unfiltered facet. If all is set to
  // true all facets are shown with a "less" option if there are more than 5
  // facets. If all is set to false only 5 facets are shown with a "more..."
  // option.
  function showBuckets(i, all) {
  //alert(i);
  
    var entry = allAttrEntries[i];
    var attr = entry.getAttribute();
    //alert(attr.name);
    
    //if(attr.name == 'price' || attr.name == 'product type' || attr.name == 'brand' || attr.name == 'width' || attr.name == 'height' || attr.name == 'designer')
    //{
    var str = '<h4 style="font-size:10pt;">BY ' + attr.name.toUpperCase() +
              '</h4><div class="cse-commerce-facet"><ul>';
    var attribs = attr.getValues();
    var showLess = false;
    var showMore = false;

    for (var j = 0, attrib; attrib = attribs[j]; ++j) 
    {
      if (j > 5) 
      {
        if (!all) 
        {
          showMore = true;
          break;
        } 
        else 
        {
          showLess = true;
        }
      }
      var value = truncateAndAddEllipses(20,
                                         escapeHtml(attrib.getValue()));
      var count = escapeHtml(attrib.getCount());
      str += '<li class="cseLink"><a style="color:#5a5a5a;font-size:9pt;" href="javascript:void(0)" ' +
             'onClick="javascript:af(\'' + attr.name +
             '\', \'' + attrib.getValue() + '\')">' + value +
             '&nbsp;(' + count + ')</a></li>';
    }
    if (showLess) 
    {
      str += '<li class="cseLink"><a style="color:#5a5a5a;font-size:9pt;" href="javascript:void(0)" ' +
             'onClick="javascript:sb(' + i + ',false)">Less...</a></li>';
    }
    else if (showMore) 
    {
      str += '<li class="cseLink"><a style="color:#5a5a5a;font-size:9pt;" href="javascript:void(0)" ' +
             'onClick="javascript:sb(' + i + ',true)">More...</a></li>';
    }
    str += '</ul></div>';
    return str;
    //}
    //else
    //{
    //return '';
    //}
   
  }

  function showBucketsDiv(index, all) {
    var div = document.getElementById('attr' + index);
    if (div) {
      div.innerHTML = showBuckets(index, all);
    }
  }

  // This callback will run if getSnippetFeed throws any errors.
  var handleError = function(error) {
    var message = error.cause ? error.cause.statusText :
        (error.message ? error.message : error);
    if (opt_errorHandler) {
      opt_errorHandler(message);
    } else {
      alert(message);
    }
  };

  // This function is called to clear the results pane.
  function clearResults() {
    if (gridImage) {
      gridImage.style.display = 'none';
    }

    if (listImage) {
      listImage.style.display = 'none';
    }

    resultsPanel.innerHTML = '';
  }

  // Here we construct the call to Base using the GDATA API.
  // We make two requests:
  //  - One to fetch the search results
  //  - The other to get the attribute counts & buckets
  function getMyFeed(q) {
    if (q == '') {
      handleError('Empty query');
      return;
    }
    if (customerId == '') {
      handleError('Missing or invalid customer ID');
      return;
    }
    queryString = q.replace(/#/g, '%23');

    baseService = new google.gdata.gbase.GoogleBaseService('Commerce-Demo');
    var query = new google.gdata.gbase.SnippetsQuery(
        baseUrlPrefix + 'snippets');
    query.setFullTextQuery(queryString);
    var baseQuery = '[customer id:' + customerId + '][item type:products]';
    baseQuery += '[target country:' + reqCountry + '][item language:en]';

    for (var key in filtersMap) {
      if (filtersMap[key]) {
        baseQuery += '[' + key + ':' + filtersMap[key] + ']';
      }
    }

    query.setBq(baseQuery + priceMatch);
    if (sortOrder == 'match') {
      query.setOrderby('auto');
    } else if (sortOrder == 'price_low') {
      query.setOrderby('price(float ' + currency + ')');
      query.setSortorder('ascending');
    } else if (sortOrder == 'price_high') {
      query.setOrderby('price(float ' + currency + ')');
      query.setSortorder('descending');
    } else if (sortOrder == 'name') {
      query.setOrderby('title(text)');
      query.setSortorder('ascending');
    }

    query.setStartIndex((currentPage - 1) * resultsLimit + 1);
    query.setMaxResults(resultsLimit);
    query.setParam('cx', cx);
    query.setParam('content', 'promotions');

    baseService.getSnippetsFeed(query, handleSnippetsFeed, handleError);

    // Get attributes.
    var attributes = new google.gdata.gbase.AttributesQuery(baseUrlPrefix +
                                                            'attributes');
    attributes.setFullTextQuery(queryString);
    attributes.setBq(baseQuery + priceMatch);
    attributes.setParam('cx', cx);
    attributes.setParam('max-values', '20');

    baseService.getAttributesFeed(attributes, handleAttributesFeed,
                                  handleError);
  };

  // Called when we click on a price refinement.
  function priceSubmit(query, price) {
    currentPage = 1;
    if (price == 0) {
      priceMatch = '[price < 500.00 ' + currency + ']';
    } else if (price == 500) {
      priceMatch = '[price:500.0..1000.00 ' + currency + ']';
    } else if (price == 1000) {
      priceMatch = '[price:1000.0..2500.00 ' + currency + ']';
    } else if (price == 2500) {
      priceMatch = '[price:2500.0..5000.00 ' + currency + ']';
    } else if (price == 5000) {
      priceMatch = '[price >= 5000.0 ' + currency + ']';
    } else if (price == -1) {
      priceMatch = '[price >= 0 ' + currency + ']';
    }
    clearResults();
    getMyFeed(query);
  };

  // Called when we submit a new search term.
  function formSubmit(query, order) {
    currentPage = 1;

    if (order) {
      sortOrder = order;
    } else {
      sortOrder = 'match';
      priceMatch = '';
      filtersMap = {};
    }

    clearResults();
    getMyFeed(query);
  };

  // Called when we submit a new spelling correction.
  function spellSubmit(query) {
    currentPage = 1;
    clearResults();
    getMyFeed(query);
  }

  // Called when we navigate to the given page.
  function pageSubmit(page) {
    currentPage = page;
    clearResults();
    getMyFeed(queryString);
  }

  // Called when we view to change the view
  function changeView(view, resultsPanel) {
    viewPref = view;
    resultsPanel.innerHTML = getHTML(allEntries, allPromotions, view, gridImage,
                                     listImage);
  }

  // Called when a filter is applied.
  function applyFilter(query, key, value) {
    currentPage = 1;
    filtersMap[key] = value;
    clearResults();
    getMyFeed(query);
  }

  return {
    'formSubmit': formSubmit,
    'priceSubmit': priceSubmit,
    'spellSubmit': spellSubmit,
    'pageSubmit': pageSubmit,
    'changeView': changeView,
    'applyFilter': applyFilter,
    'showBucketsDiv': showBucketsDiv };
}

