<?xml version="1.0" encoding="UTF-8" ?> 
<Module>

<!-- 
Copyright (C) 2007 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Author: Clay B.
-->

  <ModulePrefs title="__UP_title__ " 
  directory_title="Google Base Gadget" 
  height="300" 
  scrolling="false" 
  description="Provides a simple, configurable interface for searching Google Base data from your Google Personalized Homepage or, using a Syndicated Gadget, most any web page or blog."
  author="Clay B." 
  author_email="clay.feedback@gmail.com" 
  author_affiliation="Google Inc." 
  author_location="Mountain View, CA" 
  title_url="http://base.google.com/" 
  thumbnail="/ig/modules/basegadget-thm.png" 
  screenshot="/ig/modules/basegadget.png" />  
  
  <UserPref name="title" display_name="Title:" required="false" default_value="Items from Google Base"/> 
  <UserPref name="itemtype" display_name="Item type" required="false"/>
  <UserPref name="refinementattributes" display_name="Attribute menus (comma separated)" />
  <UserPref name="columns" display_name="Columns (comma separated)" />
  <UserPref name="basecid" display_name="Author ID" required="false" />
  <UserPref name="showimages" display_name="Show images" datatype="bool" default_value="false"/>


  <Content type="html"> 
  <![CDATA[ 
  
<style type="text/css">

BODY, TD {
    font-family:Arial, Helvetica, sans-serif; font-size:83%; margin:0px;
}

TABLE {
    margin-left: 5;
    margin-right: auto
}

.pag {border-top:1px solid #efefef; border-bottom:1px solid #dfdfdf; padding: 1px 0 1px 0;}
.rslt td {padding-left:6px; padding-right:16px;}
.pulldown_input {
  margin-top:2px;
  margin-right:3px;
  width:90px;
}

</style>

  
<script type="text/javascript">


    //* Some Constants *//

      
    var DEBUG_MODE_ON = false;
    
    var REFINEMENT_CHANGE = 0;
    var PAGE_CHANGE = 1;
    
    var FOCUS_NONE = 0;
    var FOCUS_KEYWORDS = 1;
    
    
    // Heights of divs. (The main content div's height is computed dynamically.)
    var DIV_HEIGHT_REFINEMENTS = 42;
    var DIV_HEIGHT_TABLE_HEADER = 20;
    var DIV_HEIGHT_PAGINATION = 24;
    var DIV_HEIGHT_MESSAGE = 15;
    
    // Misc display stuff
    var ROW_COLOR = "#f4f8ff";
    var MIN_ROW_HEIGHT = 36;      
    var TEXT_FIELD_SIZE = 9;
    var NUM_RANGE_FIELD_SIZE = 3;
    var MAX_ATTRIBUTES_IN_DROPDOWN = 25;
    
    // Namespaces
    var NS_ATTRIBUTE_FEED = 1;
    var NS_TOTAL_RESULTS = 2;
    var NS_ATTRIBUTE_VALUE = 3;
    
    
    var HARD_RESTRICT = false;     // If true, then all items shown must have all the columns attributes.
    var LOCATION_SEARCH_RADIUS_IN_MILES = 5;
    
    
    var THUMBNAIL_PREFIX = "http://base.googlehosted.com/base_media?size=3&q=";
    
    

    //* Global Variables *//

    // We store all the refinements here.
    var refinementsPackage = [];
    var keywordsFocus = false;

    // Reload the content after resize so things look nice.
    window.onresize = loadContent;

    // This is how we allocate table percentages to columns.
    // The 0th entry is not used, since we always have at least title. The 1st allocates 100% to title -- the 2nd 65 to title, 35 to 1st attribute.

    var columnAllocations = [[100], [100], [65,35], [50,25,25,], [40, 20, 20, 20], [40, 15, 15, 15, 15]];

  

    //*  User Preferences *//

            
    // Defined outside a function so they're all global.        
    var prefs = new _IG_Prefs(__MODULE_ID__);
    var userPrefTitle = prefs.getString("title");
    var userPrefBaseCid = prefs.getInt("basecid");
    var userPrefrowsPerPage = 5; 
    var userPrefItemType = prefs.getString("itemtype");
    var userPrefDefaultQueries = prefs.getString("defaultkeywords");    
    var userPrefAttributesCsv = prefs.getString("attributes");
    var userPrefShowKeywordsField = true;  
    var userPrefShowrefinementWidgets = true; 
    var userPrefShowColumnHeaders = true; 
    var userPrefShowLocationField = prefs.getBool("showlocationfield");    
    var userPrefShowImages = prefs.getBool("showimages");    
    var userPrefColumnsCsv = prefs.getString("columns");
    var userPrefRefinementAttributesCsv = prefs.getString("refinementattributes");

  
    // Do some processing on the preferences.
    userPrefItemType = userPrefItemType.toLowerCase();
  
  
    // Parse the refinement attributes.    
    userPrefRefinementAttributesCsv = userPrefRefinementAttributesCsv.toLowerCase();
    var rawAttrs = userPrefRefinementAttributesCsv.split(",");
    var userPrefRefinementAttributes = [];
 
    if(rawAttrs[0].length > 1) {   // if we actually have an attribute name
      for(i in rawAttrs) {
        var trimmedAttr = trim(rawAttrs[i]);
        userPrefRefinementAttributes[i] = trimmedAttr;
      }
    }
    
    // Parse the columns to display.
    userPrefColumnsCsv = userPrefColumnsCsv.toLowerCase();
    var tmp = userPrefColumnsCsv.split(",");
    var userPrefColumns = [];
    userPrefColumns[0] = "title";              // Title is always the first column.
    for(i in tmp) {
      tmptrimmed = spacesToUnderscores(trim(tmp[i]));
      if (tmptrimmed != "title" && tmptrimmed.length > 2) {
        var j = 0;
        j = parseInt(i, 10)+1;
        userPrefColumns[j] = tmptrimmed;           // trim leading and trailing spaces.
      }
    }
    
    
  
    //*  Functions *//
    
    function isRefinementAttribute(name) {
      return nameIsInArray(name, userPrefRefinementAttributes);
    }


    function isColumn(name) {
      return nameIsInArray(name, userPrefColumns);
    }
    
    
    function nameIsInArray(name, array) {
      for(var i = 0; i < array.length; i++) {
        if (array[i] == name) {
          return true;
        }
      }
      return false;
    }

      
    
    
    function initializeRefinementsPackage() {
      refinementsPackage["resultsPage"] = 1;
      refinementsPackage["keywords"] = "";
      refinementsPackage["location"] = "";    
      refinementsPackage["pricelow"] = "";
      refinementsPackage["pricehigh"] = "";
      
      for(var i = 0; i < userPrefRefinementAttributes.length; i++) {
        refinementsPackage[userPrefRefinementAttributes[i]] = "";
      }
    }
    

    function formatDate(date) {
      var tmp = date.split("T");
      var split = tmp[0].split("-");
      
      for(var i=0; i<3; i++) {
        split[i] = parseInt(split[i], 10);
      }    
      
      var formatDate = split[1] + "/" + split[2] + "/" + split[0];
      return formatDate;
    }
    
    
    function formatTime(date) {
      var tmp = date.split("T");

      tmp = tmp[1].split(".");

      tmp = tmp[0].split(":");
      
      var ampm = "am";
      if (parseInt(tmp[0],10) >= 12) {
        tmp[0] = tmp[0] - 12;
        ampm = "pm";
      }
      
      var formatTime = tmp[0] + ":" + tmp[1] + ampm;
      
      return formatTime;
    }
    
    
    function formatDateTime(date) {
      return formatDate(date) + " at " + formatTime(date);
    }
    
    
    


    //* HELPER FUNCTIONS *//

    
    // Removes leading whitespaces
    function trim(str) {
      if (!str) return "";
      return str.replace(/^\s+/, "").replace(/\s+$/, "");
    }
    
    
    // Reverses a string.
    String.prototype.reverse = function(){
      var rev = "";
      for(var i = this.length-1; i >= 0; i--){
        rev+=this.substr(i, 1);
      }
      return rev;
    }
    
    
    
    // Formats an integer to have thousands separators.
    function formattedInteger(num, separator) {
      var a = num.toString();
      a = a.reverse();

      var formatted = "";      
      
      for(var i = 0; i < a.length; i++) {
        formatted += a.charAt(i);
        if (i%3 == 2 && i > 1 && i < a.length-1) {
          formatted += separator;
        }
      }
      
      return formatted.reverse();
    }
    

    // Sentence cases (capitalizes first letter) of a string.
    function sentenceCase(string) {
      firstChar = string.substr(0,1);
      restOfString = string.substr(1);
      sentenceCasedString = firstChar.toUpperCase() + restOfString;
      return sentenceCasedString;
    }
    
    // Converts underscores (_) to spaces. Used for some attribute values.
    function underscoresToSpaces(string) {
      return string.replace("_", " ");
    }
    
    // Converts spaces to underscores (_). Used for some attribute values.
    function spacesToUnderscores(string) {
      return string.replace(" ", "_");
    }

    
    // Converts a string to a sentence cased, underscore-removed string.
    function cleanString(string) {
      return sentenceCase(underscoresToSpaces(string));
    }
    
    
    function getCurrencySymbolForString(string) {
      if (string.match("usd")) {
        return "$";
      }
      
      if (string.match("gbp")) {
        return "&#163;";
      }
    }
    
    
    function killCurrencyName(string) {
      string = string.replace(" usd", "");
      string = string.replace(" gbp", "");
      return string;
    }
    
    
    // Formats a price value string.
    function formattedPriceString(string) {
      var currencySymbol = getCurrencySymbolForString(string);    
      
      string = killCurrencyName(string);
      var tmp = string.split(".");
      
      // Left and right of the decimal point.
      var left = tmp[0];
      var right = "";
      if (tmp[1]) {
        right = tmp[1];
        if (right.length < 2) {
          right += "0";
        }
      } else {
        right = "00";
      }
      
      left = formattedInteger(left, ",");
      
      string = currencySymbol + left + "." + right;
      return string;
    }
      
      
    function rowHeight() {
      return Math.round(contentDivHeight() / rowsPerPage());
    }
    
    
    function rowsPerPage() {
      var rows = Math.floor(Math.abs(contentDivHeight() / MIN_ROW_HEIGHT));
      if (rows < 1) {
        rows = 1;
      }
      return rows;
    }
  
  
    function attributeIsSpecialCased(attributeName) {
      if (attributeName == "location") {
        return true;
      }
      
      if (attributeName == "price") {
        return true;
      }
      return false;
    }
  
    
    
    // Format and return a Google Base API query URL.
    function createFeedUrl(feedType) {
    
      // Build the query.
      var url = "http://www.google.com/base/feeds/" + feedType + "?bq=";
      url += _esc(refinementsPackage["keywords"] + " " + userPrefDefaultQueries);
      
      if (userPrefItemType) {
        url += _esc("[item type:" + userPrefItemType + "]");
      }
      
      if (refinementsPackage["location"].length > 2) {
        url += _esc("[location: @\"" + refinementsPackage["location"] + "\" %2B" + LOCATION_SEARCH_RADIUS_IN_MILES + "mi]");
        //url += "[location: \"" + refinementsPackage["location"] + "\"]";
      }
      
      
      if (refinementsPackage["pricelow"].length > 0 && refinementsPackage["pricehigh"].length > 0) {
        var low = refinementsPackage["pricelow"];
        var high = refinementsPackage["pricehigh"];
        url += _esc("[price: " + low + ".." + high + "]");
      } else if (refinementsPackage["pricelow"].length > 0) {
        var low = refinementsPackage["pricelow"];
        url += _esc("[price >= " + low + "]");
      } else if (refinementsPackage["pricehigh"].length > 0) {
        var high = refinementsPackage["pricehigh"];
        url += _esc("[price <= " + high + "]");
      } 
      
      
      // Add the customer restrict if we have one.      
      if (userPrefBaseCid) {
        url += _esc("[customer id:" + userPrefBaseCid + "]");
      }
      
      // Snippets-feed specific stuff.
      if (feedType == "snippets") {
        
        for(var i = 0; i < userPrefRefinementAttributes.length; i++) {  // We should probably do this for both.
          if (refinementsPackage[userPrefRefinementAttributes[i]]) {
            if (!attributeIsSpecialCased(userPrefRefinementAttributes[i])) {
              url += _esc("[" + userPrefRefinementAttributes[i] + ": " + refinementsPackage[userPrefRefinementAttributes[i]] + "]");
            }
          }
        }
        
        if (isColumn("price")) {
          url += "&orderby=" + _esc("price(float USD)");
          url += "&sortorder=" + _esc("ascending");
        }
        
        
        // Hard restrict on columns.
        if (HARD_RESTRICT == true) {
          for(var i = 0; i < userPrefColumns.length; i++) {
            url+= _esc("[" + userPrefColumns[i] + "]");
          }
        }
        
        url += "&max-results=" + _esc(rowsPerPage());
        url += "&start-index=" + _esc((((refinementsPackage["resultsPage"]-1)*rowsPerPage())+1));
        
      }
      
      
            
      // Attributes-feed specific stuff.
      if (feedType == "attributes") {
        url += "&max-values=" + _esc(MAX_ATTRIBUTES_IN_DROPDOWN);
      }
      
      return url;
    }
    
    
    // Return a row (tr) style.
    function divRowStyle(row) {
      if (row%2 == 0) {
        return ROW_COLOR;
      } else {
        return "#FFFFFF";
      }
    }
    
    
    
    // TODO(cwb): Dynamically compute the max title length.
    function maxTitleCharacters() {
      return 50;
    }
    
    
        
    // Formats a title link.
    function formattedTitle(entry) {
      urlNode = getNode(entry, "link");
      titleNode = getNode(entry, "title");
      var itemUrl = urlNode.getAttribute("href");
      
      var title = titleNode.firstChild.nodeValue.substr(0,maxTitleCharacters());
      
      var html = "";
      if (userPrefShowImages) {
        if (entry.getElementsByTagName("image_link")[0]) {
          var thumbLink = entry.getElementsByTagName("image_link")[0].firstChild.nodeValue;
          thumbLink = thumbLink.replace("base_image", "base_media");
          var imageLink = "<a target='_top' href=\"" + itemUrl + "\"><img src=\"" + thumbLink + "\" height=30 width=30 border=0 style=\"border: solid 1px #AAAAAA;\"></a>";
          html += imageLink;
        }
      }
      
      
      var completeTitle = "<a target='_top' href=" + itemUrl + ">" + _hesc(title) + "</a>";
      
      if (userPrefShowImages) {
        return "<table border=0 cellspacing=0 cellpadding=0><tr><td>" + html + "</td><td>&nbsp</td><td>" + completeTitle + "</td></tr></table";
      } else {
        return completeTitle;
      }
    }
    
    
    
    // Looks through payments in an entry to see if one of them is checkout. Returns true if yes; false otherwise.
    function hasCheckout(entry) {
      payments = entry.getElementsByTagName("payment");

      if (payments.length == 0 ) {
        return false;
      }
      
      for(i in payments) {
        if (payments[i].firstChild.nodeValue == "Google Checkout") {
          return true;
        }
      }
      
      return false;
    }

    
    
    // Returns a nicely formatted price, with Google Checkout cart.
    function formattedPrice(entry) {
      var html = "";
      html += formattedPriceString(entry.getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_VALUE) + "price")[0].firstChild.nodeValue);
      return _hesc(html);
    }
    
    
    // Returns a nicely formatted standard value.
    function formattedStandardValue(entry, columnName) {
      return _hesc(cleanString(entry.getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_VALUE) + columnName)[0].firstChild.nodeValue));
    }
    
    
    // Deals with the special case author attribute.
    function formattedAuthor(entry) {
      var author = entry.getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_VALUE) + "author")[0];
      return _hesc(author.getElementsByTagName("name")[0].firstChild.nodeValue);
    }
    
    function formattedPublishedDate(entry) {
      var date = entry.getElementsByTagName("published")[0].firstChild.nodeValue;
      return _hesc(formatDateTime(date));
    }
    
    function formattedDescription(entry) {
      var description = entry.getElementsByTagName("content")[0].firstChild.nodeValue;
      return _hesc(description.substr(0,30) + "...");
    }
    
    

    // This strange function is to deal with Safari not fetching the appropriate element.
    // It's like getElementById
    function getNode(entry, columnName) {
      for(i=0; i < entry.childNodes.length; i++) {
        if (entry.childNodes[i].nodeName == columnName) {
          return entry.childNodes[i];
        }
      }
      return null;
    }
    
        
    function formattedValue(entry, columnName) {
      var html = "";
      
      if (columnName == "description") {
        html += formattedDescription(entry);
      } else {        
        node = getNode(entry, columnName);
  
        if (node  || entry.getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_VALUE) + columnName)[0]) {    // If the item has attributes from columnName.
          switch(columnName) {
            case "title":  html += formattedTitle(entry); break;
            case "price":  html += formattedPrice(entry); break;
            case "author":  html += formattedAuthor(entry); break;
            case "published": html += formattedPublishedDate(entry); break;
            default:    html += formattedStandardValue(entry, columnName); break;
          }
        } else {
          html += "--";
        }
      }
      
      return html;
    }
    
    
    
    
    
    // Returns HTML for the header row of the items table.    
    function itemTableHeader() {
      var html = "";
      html += "<tr>";
            
      for(i in userPrefColumns) {
        html += "<td width=" + columnAllocations[userPrefColumns.length][i] + "%><b><nobr>" + _hesc(cleanString(userPrefColumns[i])) + "</b></nobr></td>";    // Print a prettied up column header.
      }
            
      html += "</tr>";
      return html;
    }
    
    
    // Returns HTML for a row in the items table.
    function itemTableRow(entry, row, total) {
      var html = "";
    
      if (row < total-1) {
        var height = rowHeight();
      } else {   // For the last row, we need to adjust the height to match the total to account for rounding errors.      
        var height = rowHeight() + (contentDivHeight() - (rowsPerPage() * rowHeight()));
      }
    
      html += "<div style=\"border: solid 0px #000000; overflow:hidden; padding-left: 0px; background-color:" + divRowStyle(row) + "; height:" +  height  + "px;\">";   
      
      html += "<table border=0 cellspacing=0 cellpadding=3 width=100% height=100%><tr>";
      

      
      // For each column to show.
      for(i in userPrefColumns) {
        if (userPrefColumns[i]) {
          html += "<td width=" + columnAllocations[userPrefColumns.length][i] + "%>";
          html += formattedValue(entry, userPrefColumns[i]);
          html += "</td>";
        }
      }
      
      html += "</tr></table>";
      html += "</div>";
      
      return html;
    }
    
    
      
    function testAlert() {
      alert(document.refinements.course.value);
      var thevalue = document.getElementById("course");
      alert(thevalue.value);
    }
      
      
    
    function runningInternetExplorer() {
      if (navigator.appName == "Microsoft Internet Explorer" && navigator.appVersion >= "4.0") {
        return true;
      }
      return false;
    }
      
    
    // Namespace for attributes in the attributes feed.
    function getNamespaceString(type) {
      if (!runningInternetExplorer()) {
        return "";
      }

      switch(type) {
        case NS_ATTRIBUTE_FEED:  return "gm:"; break;
        case NS_TOTAL_RESULTS:  return "openSearch:"; break;
        case NS_ATTRIBUTE_VALUE:  return "g:"; break;  // TODO: Deal with custom attributes?
        default:  return ""; break;
      }
    }

    
    
    
    // Return an array of values for a given attribute. (Can reference them straight - this function strips funky XML stuff.)
    function valuesForAttribute(entries, attributeName) {
      var values = [];      
      
      for(var i=0; i<entries.length; i++) {
        entry = entries[i].getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_FEED) + "attribute");
        if (entry[0].getAttribute("name") == attributeName) {
          valuesXml = entry[0].getElementsByTagName(getNamespaceString(NS_ATTRIBUTE_FEED) + "value");          
                    
          if (valuesXml.length > 0) {
            for(var i=0; i<valuesXml.length; i++) {
              values[i] = _hesc(valuesXml[i].firstChild.nodeValue);
            }
            return values;
          }
        }
      }
          
      return null;
    }
    
    
    
    function resetResultsPage() {
      refinementsPackage["resultsPage"] = 1;
    }
    
    function gadgetIsNotConfigured() {
      if(userPrefItemType.length < 1 && userPrefAttributesCsv.length < 1 && userPrefColumnsCsv.length < 1 && !userPrefBaseCid) {
        return 1;
      }
      return 0;
    }
    	
    
    function incrementResultsPage() {
      refinementsPackage["resultsPage"] = refinementsPackage["resultsPage"] + 1;
    }
    
    
    function decrementResultsPage() {
      if (refinementsPackage["resultsPage"] > 1) {
        refinementsPackage["resultsPage"] = refinementsPackage["resultsPage"] - 1;
      }
    }
    
    
    // Loads up the global refinementsPackage with the current set of refinements.
    function packageRefinements() {
      
      if (userPrefShowKeywordsField) {
        refinementsPackage["keywords"] = document.refinements.keywords.value;
      }
      
      if (isRefinementAttribute("location")) {
        refinementsPackage["location"] = document.refinements.location.value;
      }
      
      if (isRefinementAttribute("price")) {
        refinementsPackage["pricelow"] = document.refinements.pricelow.value;
        refinementsPackage["pricehigh"] = document.refinements.pricehigh.value;        
      }

      
      // Package up the refinement values.
      for(var i = 0; i < userPrefRefinementAttributes.length; i++) {
        var element = document.getElementById(userPrefRefinementAttributes[i]);
        if (!attributeIsSpecialCased(userPrefRefinementAttributes[i])) {

          refinementsPackage[userPrefRefinementAttributes[i]] = element.value;

        }
      }
    }
    
    
    
    function refreshResults(pageChange, wasInKeywordsField) {
      // Go to the first result only if we're not paging.
      if (!pageChange) {
        resetResultsPage(); 
      }
      
      if (userPrefShowrefinementWidgets) {
        packageRefinements(); 
      }
      loadContent();
      
      if (wasInKeywordsField) {
        keywordsFocus = true;
      } else {
        keywordsFocus = false;
      }
    }
    
    
    function contentDivHeight() {
      if (userPrefShowrefinementWidgets) {
        var refHeight = DIV_HEIGHT_REFINEMENTS;
      } else {
        var refHeight = 0;
      }
    
      if (userPrefShowColumnHeaders) {
        var headerHeight = DIV_HEIGHT_TABLE_HEADER;
      } else {
        var headerHeight = 0;
      }
      
      
      var paddingForMessage = 0;
      if(gadgetIsNotConfigured()) {
      	paddingForMessage = DIV_HEIGHT_MESSAGE;
      }
    
      return document.body.clientHeight - (refHeight + DIV_HEIGHT_PAGINATION + headerHeight + 8) - paddingForMessage - 2;
    }
    
        
    // Create a dropdown with attribute values in it.
    function refinementDropdown(entries, attributeName) {
      var values = valuesForAttribute(entries, attributeName);
      if (values) {
        values.sort();
      }
      
      var html = "";
      html += "<select onchange=\"refreshResults(REFINEMENT_CHANGE, FOCUS_NONE);\" class=pulldown_input name=\"" + attributeName + "\" id=\"" + attributeName + "\"><option value=''>any";

      if (values) {
        for(var i = 0; i < values.length; i++) {
          html += "<option ";
          if (values[i] == refinementsPackage[attributeName]) {
            html += " SELECTED ";
          }        
          html += "value=\"" + values[i] + "\">" + values[i];
        }
        html += "</select>";
      }
      
      return html;
    }
    
    
    
    
    function columnNames() {            
      var headerHtml = "";
      headerHtml += "<table width=100% border=0 cellpadding=3 cellspacing=0>";
      headerHtml += itemTableHeader();
      headerHtml += "</table>";
      _gel("header_div").innerHTML = headerHtml;
    }  
    
    
    function refinementWidgets() {
      _IG_FetchXmlContent(createFeedUrl("attributes"),
        function(response) {
          var refinementsHtml = "";
          
          // Start the page form and create the widgets at the top.
          refinementsHtml += "<form name=refinements onSubmit=\"refreshResults(REFINEMENT_CHANGE, FOCUS_NONE); return false;\"><table border=0 cellspacing=0 cellpadding=0><tr>";    
                  
          var entries = response.getElementsByTagName("entry");

          // Write each refinement widget.
          for(var i = 0; i < userPrefRefinementAttributes.length; i++) {
            refinementsHtml += "<td valign=top>" + cleanString(userPrefRefinementAttributes[i]) + "<br>";

            if (userPrefRefinementAttributes[i] == "location") {
              var theHtml = "<input type=text size=" + TEXT_FIELD_SIZE + " value=\"" + refinementsPackage["location"] + "\" name=location>&nbsp;";
              refinementsHtml += theHtml;
            } else if (userPrefRefinementAttributes[i] == "price") {            
              var theHtml = "<nobr><input type=text size=" + NUM_RANGE_FIELD_SIZE + " value=\"" + refinementsPackage["pricelow"] + "\" name=pricelow> to <input type=text size=" + NUM_RANGE_FIELD_SIZE + " value=\"" + refinementsPackage["pricehigh"] + "\" name=pricehigh>&nbsp;</nobr>";
              refinementsHtml += theHtml;
            } else {
              refinementsHtml += refinementDropdown(entries, userPrefRefinementAttributes[i]);
            }
            refinementsHtml += "&nbsp;</td>";
          }
          
          
          // Put the user's item types aside.
          userItemTypes = valuesForAttribute(entries, "item type");
          
          
          if (userPrefShowKeywordsField) {          
            refinementsHtml += "<td valign=top>Keywords<br><nobr><input type=text size=" + TEXT_FIELD_SIZE + " value=\"" + refinementsPackage["keywords"] + "\"name=keywords>";
            refinementsHtml += "<input type=button value='Go' onClick=\"refreshResults(REFINEMENT_CHANGE, FOCUS_NONE);\"></nobr>";
            refinementsHtml += "</td>";
          }
          
          refinementsHtml += "</tr></form></table>";
         
          _gel("refinements_div").innerHTML = refinementsHtml;
          
          if (keywordsFocus) {
            document.refinements.keywords.focus();
          }
        });
    }
    
    
    
    function pagination(response) {    
      var paginationHtml = "";      
      var totalResults = response.getElementsByTagName(getNamespaceString(NS_TOTAL_RESULTS) + "totalResults")[0].firstChild.nodeValue;      
      
      var startResult = ((refinementsPackage["resultsPage"]-1)*rowsPerPage()+1);
      var endResult = "";
      if (totalResults < rowsPerPage() || refinementsPackage["resultsPage"]*rowsPerPage() > totalResults) {
        endResult = totalResults;
      } else {
        endResult = (refinementsPackage["resultsPage"]*rowsPerPage());
      }
      
      if (totalResults > 0) {
        paginationHtml += "<table width=100% border=0 cellspacing=0 cellpadding=4><tr><td>";
        paginationHtml += "Results " + startResult + " - " + endResult + " of " + formattedInteger(totalResults, ",");
        paginationHtml += "</td><td align=right>&nbsp;&nbsp;&nbsp;";
        
        if (refinementsPackage["resultsPage"] > 1) {
          paginationHtml += "<a href=# onClick=\"decrementResultsPage(); refreshResults(PAGE_CHANGE, FOCUS_NONE); return false;\">&laquo; Prev</a>&nbsp;&nbsp;&nbsp;";
        }
        
        if (endResult != totalResults) {
          paginationHtml += "<a href=# onClick=\"incrementResultsPage(); refreshResults(PAGE_CHANGE, FOCUS_NONE); return false;\">Next &raquo;</a></td>";
        }
        
        if (runningInternetExplorer()) {
          paginationHtml += "<td>&nbsp;</td>";
        }
        
        paginationHtml += "</tr></table>";
        
      } else {
        paginationHtml += "<table border=0 cellspacing=0 cellpadding=4><tr><td> </td></tr></table>";
      }
      
      _gel("pagination_div").innerHTML = paginationHtml;

    }
    
    

    
    
    function loadContent() {      
      _IG_FetchXmlContent(createFeedUrl("snippets"), 
        function(response) {
        
          var contentHtml = "";
          
          if (userPrefShowColumnHeaders) {
            columnNames();
          }
          
          if (userPrefShowrefinementWidgets) {
            refinementWidgets();
          }    
        
          // Test the response.
          if (!response) {
            contentHtml = "There was a problem processing your request.";
            _gel("content_div").innerHTML = contentHtml;
            return;
          } 
          

          // Create table rows.
          var entries = response.getElementsByTagName("entry");
          
          if (entries.length == 0) {
            contentHtml += "<table width=100%><tr><td valign=top align=center width=100%><br><br><br><br><br><center>Your search did not match any items.</center><br><br>";
            
            if (DEBUG_MODE_ON) {
              contentHtml += "<br><font size=1><a href='" + createFeedUrl("snippets") + "'>[dbg: snippets url]</a></font>";
            }

            contentHtml += "</td></tr></table>";
          }
      
    
          for (var i = 0; i < entries.length; i++) {
            contentHtml += itemTableRow(entries[i], i, entries.length);
          }
          
          
          if (DEBUG_MODE_ON) {
            contentHtml += "<br><font size=1><a href='" + createFeedUrl("snippets") + "'>[dbg: snippets url]</a></font>";
            contentHtml += "<br><font size=1><a href='" + createFeedUrl("attributes") + "'>[dbg: attributes url]</a></font>";
            
            contentHtml += "&nbsp;&nbsp;<font size=1><a target=_blank href=http://www.gmodules.com/ig/creator?synd=open&url=http://www.justsomestuff.com/cwb/baselets/baselet.xml>Embed</a></font>";
          }      


          _gel("content_div").innerHTML = contentHtml;
          pagination(response);            
                
          document.getElementById("content_div").style.height = contentDivHeight();
        
          firstTimeLoad = false;
        });
    }
  

    // Create the divs for refinement widgets, content, and pagination.
    document.write("<div id=spacer_div style=\"border: solid 0px #000000; height:3px; overflow: invisible; \"><img src=a height=1></div>");    // TODO: REPLACE THIS SPACERR IMAGE
    
    if(gadgetIsNotConfigured()) { // if no item type
      document.write("<div style=\"height: " + DIV_HEIGHT_MESSAGE + "; background-color: #fff4c2; padding-left: 5px; padding-top: 3px;\"><center><font size=1>Edit settings to configure this gadget. <a target='_blank' href=http://base.google.com/support/bin/answer.py?answer=62679>Instructions</a></div>");
    }
    
    if (userPrefShowrefinementWidgets) {
      document.write("<div id=refinements_div style=\"border: solid 0px #000000; height:" + DIV_HEIGHT_REFINEMENTS + "px; overflow: invisible; \"></div>");
    }
    
    if (userPrefShowColumnHeaders) {
      document.write("<div id=header_div style=\"border: solid 0px #000000; height:" + DIV_HEIGHT_TABLE_HEADER + "px; overflow: invisible; \"></div>");    
    }
    
    document.write("<div id=content_div style=\"border: solid 0px #FF0000;  height: " + contentDivHeight() + "px; overflow: invisible; border-top: solid 1px #CCCCCC;\"></div>");
    document.write("<div id=pagination_div align=left style=\"border: solid 0px #FF0000;  height:" + DIV_HEIGHT_PAGINATION + "; padding-left: 0px; border-top: solid 1px #CCCCCC; border-bottom: solid 1px #CCCCCC;\"></div>");
    
    
    // Render the gadget.
    initializeRefinementsPackage()
    loadContent();
      
  </script>
  ]]> 
  </Content> 
</Module>
