// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2008
// http://flock.com
//
// This file may be used under the terms of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL

const AMAZON_LIVE_SEARCH_NAME = "Amazon";
const AMAZON_LIVE_SEARCH_CLASSID =
  Components.ID("{c3cc0113-4df3-4b49-ae86-b9014776dee6}");

const AMAZON_NAMESPACE = "http://webservices.amazon.com/AWSECommerceService/";
const AMAZON_VERSION = "2008-04-07";
const AMAZON_SEARCH_COUNT = 5;


const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
const CU = Components.utils;

CU.import("resource:///modules/FlockLiveSearchProvider.jsm");

function AmazonLiveSearch() {
  this._init();
}

AmazonLiveSearch.prototype = FlockLiveSearchProvider.generateComponent(
  AMAZON_LIVE_SEARCH_NAME,
  AMAZON_LIVE_SEARCH_CLASSID,
  AmazonLiveSearch,
  "Amazon.com"
);

AmazonLiveSearch.prototype._getResults =
function ALS__getResults(aXHR, aMaxResults) {
  var relevantCategories = [];
  var relevanceRankList = [];
  var nspace = AMAZON_NAMESPACE + AMAZON_VERSION;
  var aws = new Namespace(nspace);

  function updateRelevantCategories(aType, aIds, aIndex) {
    if (aIds) {
      var amazonIds = [];
      for each (let id in aIds) {
        amazonIds.push(id.toString());
      }
      var searchResultSet = {
        category: aType,
        amazonIds: amazonIds
      };
      updateRelevantObjCategories(searchResultSet, aIndex);
    }
  }

  // Organize object in correct order
  function updateRelevantObjCategories(aObj, aIndex) {
    if (aIndex < AMAZON_SEARCH_COUNT) {
      if (!relevantCategories[aIndex]) {
        relevantCategories[aIndex] = aObj;
      } else {
        var prevObj = relevantCategories[aIndex];
        relevantCategories[aIndex] = aObj;
        updateRelevantObjCategories(prevObj, aIndex + 1);
      }
    }
  }

  function updateRankCategoryList(aRelevanceRank, aType, aIdNodes, aIndex) {
    var r = 0;
    var rankChanged = false;
    if (aRelevanceRank == 1) {
      return rankChanged;
    }

    if (aIndex) {
      r = aIndex;
    }

    if (relevanceRankList.length < 1) {
      relevanceRankList[0] = aRelevanceRank;
      updateRelevantCategories(aType, aIdNodes, 0);
      return true;
    }

    for ( ; r < relevanceRankList.length && r < AMAZON_SEARCH_COUNT; r++) {
      if (relevanceRankList[r] > aRelevanceRank) {
        // We have to a more relevant category
        rankChanged = true;
        var previousRank = relevanceRankList[r];
        relevanceRankList[r] = aRelevanceRank;
        updateRelevantCategories(aType, aIdNodes, r);
        return updateRankCategoryList(previousRank, r);
      }

      if (!relevanceRankList[r]) {
        relevanceRankList[r] = aRelevanceRank;
        updateRelevantCategories(aType, aIdNodes, r);
        rankChanged = true;
      }
    }

    if (r >= relevanceRankList.length && r <= AMAZON_SEARCH_COUNT) {
      relevanceRankList[r] = aRelevanceRank;
      updateRelevantCategories(aType, aIdNodes, r);
      rankChanged = true;
    }
    return rankChanged;
  };

  var serializer = CC["@mozilla.org/xmlextras/xmlserializer;1"]
                   .createInstance(CI.nsIDOMSerializer);
  var xmlStr = serializer.serializeToString(aXHR.responseXML.documentElement);

  var xmlData = new XML(xmlStr);
  
  var searchIndexes = xmlData.aws::Items
                             .aws::SearchResultsMap.aws::SearchIndex;

  // Traverse the categories list
  for each (let index in searchIndexes) {
    var category = index.aws::IndexName;
    var relevanceRank = index.aws::RelevanceRank;
    var relevanceRank = parseInt(relevanceRank);

    // Organize new category into the category list
    updateRankCategoryList(relevanceRank,
                           category.toString(),
                           index.aws::ASIN);
  }

  var results = [];
  for each (let category in relevantCategories) {
    var idList = category.amazonIds;

    var id = idList[0];
    var item = xmlData.aws::Items.aws::Item.(aws::ASIN == id);

    var title = item.aws::ItemAttributes.aws::Title;
    var thumbnailUrl = item.aws::SmallImage.aws::URL;
    var url = item.aws::DetailPageURL;

    var result = { title: title.toString(), url: url.toString(),
                   category: category.category };

    if (thumbnailUrl && thumbnailUrl.length) {
      result.icon = thumbnailUrl.toString();
    }

    results.push(result);
  }

  return results;
}

var NSGetModule =
  FlockLiveSearchProvider.generateNSGetModule(AMAZON_LIVE_SEARCH_NAME,
                                              AmazonLiveSearch);
