/**
 * Definition of the ResultList object that defines the methods and attributes relevant
 * to managing the result list page.
 */

/**
 * This is a reference to the single instance of the resultList object
 */
ResultList.instance = null;

// The text that will be displayed on the search popup window
ResultList.searchPopupButton1Text = "<<<uninitialized>>>";
ResultList.searchPopupButton2Text = "<<<uninitialized>>>";

// The module name that will be used in the yahoo ui history manager
ResultList.moduleName = "ResultList";

function ResultList(ssid, tabCount, currentTabIndex, refreshMode, searchId, displayMoreResultsDialog)
{
    // The globally unique ID for the current search session.
    this.ssid = ssid;

    // The id of the current search
    this.searchId = searchId;

    // The number of tabs that will be displayed
    this.tabCount = tabCount;

    // The index to the currently selected tab
    this.currentTabIndex = currentTabIndex;

    // Whether to prompt the user to refresh results or not at end of search.
    this.refreshMode = refreshMode;

    // The array of result panes that will be displayed
    this.resultPanes = [];

    // The array of cluster panes that will be displayed
    this.clusterPanes = [];

    // The most current search status object.
    this.resultListStatus = null;

    // The sum of all displayable results from all containers w/o any collection limits.
    this.displayTotal = 0;

    // The number of milliseconds to wait for getResultListStatus requests.
    this.statusTimeout = 1000;

    // The list of filters applied to the current view.
    this.filters = [];

    // The list of the panes that are currently active in each tab.  This
    // is used to display the pane when the tabs are switched.
    this.activeTabPanes = [];

    // The current number of marked results.
    this.markedCount = 0;

    this.markListUrl     = "markList.html";
    this.emailResultsUrl = "resultsEmailer.html";

    // The currently selected tab
    this.selectedTab = null;

    // The container of the currently selected tab
    this.selectedContainer = null;

    // The collectionId map that is used to hold properties of the collections.
    this.collectionIdMap = null;
    
    //the YUI search-popup-window element
    this.searchPopup = null;

    // The number of milliseconds to wait for getCollectionStatus requests.
    this.statusTimeout = 2000;

    // Set the instance
    ResultList.instance = this;

    // True if the more results dialog should be displayed when search is finished
    this.displayMoreResultsDialog = displayMoreResultsDialog;
}

/**
 * Returns the curently active result pane object
 */
ResultList.prototype.getActivePane = function()
{
    return this.activeTabPanes[this.currentTabIndex];
}

/**
 * Post constructor call to intialize AJAX calls to update the resultListStatus.
 * Should be called after all other attributes have been initialized and you
 * are ready to start actively polling for status.
 */
ResultList.prototype.init = function()
{
    this.createSearchPopup();

    this.initPage();

    // Poll the server to get the status of the search
    this.getResultListStatus(this.ssid, this.filters, 0);

    // if there is a collection status panel configured
    if (document.getElementById("collectionStatusPanel"))
    {
        CollectionStatusPanel.addListener(this);
        CollectionStatusPanel.getCollectionStatus(this.ssid, this.filters);
    }
};

/**
 * This method is call from the CollectionStatusPanel when the collection status has been successfully
 * retrieved.
 */
ResultList.prototype.collectionStatusComplete = function()
{
    if (!ResultList.instance.isSearchFinished())
    {
        setTimeout(function(){CollectionStatusPanel.getCollectionStatus(ResultList.instance.ssid, ResultList.instance.filters);}, ResultList.instance.statusTimeout);
    }
}

/**
 * Initializes the clusterPane objects by adding the resultList class as
 * a listener for events fired from the cluster pane.
 */
ResultList.prototype.initClusterPanes = function()
{
    for (var i in this.clusterPanes)
    {
        this.clusterPanes[i].addListener(this);
    }
}

/**
 * Perform any task related to a search status update.  This method will always be
 * called after the resultListStatus object has been updated via AJAX.
 */
ResultList.prototype.updateSearchStatus = function()
{
    // if there aren't any results for the active pane,
    if (this.getActivePane().displayCount == 0 &&
        this.resultListStatus.paneCounts[this.currentTabIndex] > 0)
    {
        // Get the results for the visible pane
        this.showPage(-1, true);
    }

    this.updateSearchProgress();

    this.updateResultCounts();

    this.handleSearchFinished();
};

/**
 * Setup the Page with onclick handlers for the tabs and select the appropriate
 * tab to display initially based on the resultPane value.
 */
ResultList.prototype.initPage = function()
{
    this.initClusterPanes();

    for (var i = 0; i < this.tabCount; ++i)
    {
        // Initialize the activePanes array with the top level pane
        this.activeTabPanes[i] = this.resultPanes[i];
    }

    var initTab = YAHOO.util.History.getBookmarkedState(ResultList.moduleName) || this.currentTabIndex.toString();
    YAHOO.util.History.register(ResultList.moduleName, initTab, function (state) {/* not needed */});

    YAHOO.util.History.onReady( function () {
        var initTab = YAHOO.util.History.getCurrentState(ResultList.moduleName);
        ResultList.instance.switchTabs(initTab);
    });

    YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");
}

/**
 * Sets the local resultListStatus attribute to the new value. Calls updateSearchStatus
 * to allow any additional updates to be made.  If the search is not finished, issues
 * the next AJAX request to refresh the resultListStatus.
 * @param resultListStatus the current status of the search
 */
ResultList.prototype.setResultListStatus = function(resultListStatus)
{
    this.resultListStatus = resultListStatus;

    // Update any displayed information about the search
    this.updateSearchStatus();

    if (!this.isSearchFinished())
    {
        this.getResultListStatus(this.ssid, this.filters, this.statusTimeout);
    }
};

/**
 * Returns the total filtered results as the sum of the paneCounts for each pane
 */
ResultList.prototype.getTotalFilteredResults = function()
{
    var totalFilteredResults = 0;
    for (var i in this.resultListStatus.paneCounts)
    {
        totalFilteredResults += this.resultListStatus.paneCounts[i];
    }

    return totalFilteredResults;
}

/**
 * Tests whether search is finished.
 * @return true if search is finished
 */
ResultList.prototype.isSearchFinished = function()
{
    if (this.resultListStatus == null)
    {
        return false;
    }
    else
    {
        return this.resultListStatus.searchFinished;
    }
}

/**
 * Retrieve the current state of the search using an AJAX call.
 */
ResultList.prototype.getResultListStatus = function(ssid, filters, timeout)
{
    setTimeout(function(){ResultListConnector.getResultListStatus(ssid, filters, ResultList.getResultListStatus_callback);}, timeout);
};

/**
 * Callback for the call to ResultListConnector.getResultListStatus
 * @param status the resultListStatus object
 */
ResultList.getResultListStatus_callback = function(status)
{
    ResultList.instance.setResultListStatus(status);
}

/**
 * Reload the current page at a new starting result location, and refreshing
 * the result snapshot, if needed
 * @param newStart the start position in the result list to display
 * @param refresh true if a new snapshot should be generated.
 */
ResultList.prototype.showPage = function(newStart, refresh)
{
    if (newStart == -1)
    {
        newStart = this.getActivePane().startPosition;
    }
    this.getActivePane().getPageOfResults(newStart, refresh, this.ssid, this.filters);
};

/**
 * Adds all of the outstanding results to the displayed page by first setting
 * each pane's displayCount to 0 and then refreshing the currently displayed page
 */
ResultList.prototype.addResults = function()
{
    // Loop through all of the top level panes and set their display count to 0
    // This will ensure that they will get reloaded the next time that their tab is clicked.
    for (var i = 0; i < this.tabCount; ++i)
    {
        this.resultPanes[i].displayCount = 0;
        this.resultPanes[i].resultCount  = 0;
        this.resultPanes[i].resetSelectedCollection();
        this.updateResultCounter(i);
    }

    // if the selected pane is a cluster pane, select its corresponding top level pane
    // so that the results and clusters can get updated
    if (this.getActivePane().paneId >= this.tabCount)
    {
        this.activeTabPanes[this.currentTabIndex] = this.resultPanes[this.getActivePane().paneId - this.tabCount];
    }

    // Refresh the active pane
    this.showPage(0, true);

    if (this.isSearchFinished())
    {
        // Hide the result count indicator
        document.getElementById("more-results-info").style.visibility = "hidden";
    }
}

/**
 * Display the list marked results.
 */
 ResultList.prototype.listMarks = function()
 {
    var urlBuilder = new URLBuilder(this.markListUrl);
    urlBuilder.addParam("ssid", this.ssid);
    urlBuilder.addParam("resultViewStartPosition", this.getActivePane().startPosition);
    urlBuilder.addParam("resultPane", this.currentTabIndex);
    urlBuilder.addParam("resultViewStartPosition", this.getActivePane().startPosition);
    urlBuilder.addParam("selectedCollectionId", this.getActivePane().selectedCollection);

    return setWindowLocation(urlBuilder.toString());
 };

/**
 * Changes the direction of sort from ascending to descending or vice-versa.
 */
ResultList.prototype.toggleSortOrder = function()
{
    // Set the new sortOrder
    this.getActivePane().resultOrder.descending = !this.getActivePane().resultOrder.descending;

    this.setSortOrderImage();

    this.showPage(0, false);
}

/**
 * Sets the image on the sort order button
 */
ResultList.prototype.setSortOrderImage = function()
{
    var buttonImage = getImageDir() + "/" + (this.getActivePane().resultOrder.descending ? "sort_desc.gif" : "sort_asc.gif");
    
    if (document.getElementById("toggleSortOrderImage"))
    {
        document.getElementById("toggleSortOrderImage").src = buttonImage;
    }

    if (document.getElementById("toggleSortOrderImage_bottom"))
    {
        document.getElementById("toggleSortOrderImage_bottom").src = buttonImage;
    }
}

/**
 * Reorders the results on the page by changing the ordering parameter and re-reading
 * the results.
 * @param orderBy the means in which to order the results
 */
ResultList.prototype.reorderResults = function(orderBy)
{
    // Set the ordering in the active pane and then re-get the results
    this.getActivePane().resultOrder.resultField = orderBy;
    this.showPage(0, false);
};

/**
 * Emails the current result listing.
 */
ResultList.prototype.emailResults = function()
{
    if(this.getActivePane().displayCount > 0)
    {
        var urlBuilder = new URLBuilder(this.emailResultsUrl);
        urlBuilder.addParam("ssid", this.ssid);
        urlBuilder.addParam("resultPane", this.currentTabIndex);
        urlBuilder.addParam("snapshotIndex", this.getActivePane().paneId);
        urlBuilder.addParam("resultOrder_resultField", this.getActivePane().resultOrder.resultField);
        urlBuilder.addParam("resultOrder_descending", this.getActivePane().resultOrder.descending);
        urlBuilder.addParam("collectionId", this.getActivePane().selectedCollection);

        var win = window.open(urlBuilder.toString(), null,"top=270,left=250,height=517,width=628,status=yes,toolbar=no,menubar=no,location=no,scrollbars=no,resizable=yes");
        win.focus();
    }
    else
    {
        alert("You must have results in order to send an email");
    }
};


/**
 * View results in the current snap shot only from the given collectionId
 * @param collectionId the collecion to get results for
 */
ResultList.prototype.viewCollection = function(collectionId)
{
    this.getActivePane().setSelectedCollection(collectionId);
    this.showPage(0, false);
};

//------------------------------------------------------------------------------
// Functions for paging through the list of results
//------------------------------------------------------------------------------

/**
 * Gets the page of results from the current pane starting at newStart
 */
ResultList.prototype.gotoPage = function(newStart)
{
    this.getActivePane().gotoPage(newStart, this.ssid, this.filters);
}

/**
 * Shows the previous result page
 */
ResultList.prototype.showPrevious = function()
{
    this.getActivePane().showPrevious(this.ssid, this.filters);
};

/**
 * Shows the next result page
 */
ResultList.prototype.showNext = function()
{
    this.getActivePane().showNext(this.ssid, this.filters);
};

/**
 * Shows the first page of results
 */
ResultList.prototype.showFirst = function()
{
    this.getActivePane().showFirst(this.ssid, this.filters);
};

/**
 * Shows the last page of results
 */
ResultList.prototype.showLast = function()
{
    this.getActivePane().showLast(this.ssid, this.filters);
};

/**
 * Updates the result counts when the search status is updated.
 */
ResultList.prototype.updateResultCounts = function()
{
    // Update the count for each tab with the number of results that have been found.
    for (var i = 0; i < this.tabCount; ++i)
    {
        // Update the counts on the tab label
        var resultCountEle = document.getElementById("results_count_" + i);
        if (resultCountEle != null)
        {
            var tabDisplayedCount = resultCountEle.innerHTML;
            if (this.resultPanes[i].displayCount == 0 || tabDisplayedCount == "0" || tabDisplayedCount == "")
            {
                // Update the result count element with the number of results
                this.updateResultCounter(i);
            }
        }
    }

    this.calculateDisplayTotal();

    var unseenResultCount = this.getTotalFilteredResults() - this.displayTotal;
    DWRUtil.setValue("unseenResultCount", unseenResultCount);

    var el = document.getElementById("more-results-info");

    // If there are unseen results and either we already have displayed some results
    // or the search has finished then show the link.
    if (unseenResultCount > 0 && (this.displayTotal > 0 || this.isSearchFinished()))
    {
        el.style.visibility = "visible";
    }
    else
    {
        el.style.visibility = "hidden";
    }
};

/**
 * Updates the ui widgets that show the progress of the search
 */
ResultList.prototype.updateSearchProgress = function()
{
    var bar = document.getElementById("loading-bar");

    // If there are no collections, which is usually the case for refine search,
    // hide the loading bar
    if (this.resultListStatus.totalNumberCollections == 0)
    {
        bar.style.visibility = "hidden";
        return;
    }

    DWRUtil.setValue("totalCollections", DWRUtil.toDescriptiveString(this.resultListStatus.totalNumberCollections));
    DWRUtil.setValue("totalCompleted", DWRUtil.toDescriptiveString(this.resultListStatus.completedCollections));

    var percentComplete = (this.resultListStatus.completedCollections == this.resultListStatus.totalNumberCollections) ?
                          1.0 : this.resultListStatus.completedCollections / this.resultListStatus.totalNumberCollections;

    var image = Math.round(percentComplete * 10);

    switch (image)
    {
        case 0 :
            bar.className="zero-percent";
            break;
        case 1:
            bar.className="ten-percent";
            break;
        case 2:
            bar.className="twenty-percent";
            break;
        case 3:
            bar.className="thirty-percent";
            break;
        case 4:
            bar.className="forty-percent";
            break;
        case 5:
            bar.className="fifty-percent";
            break;
        case 6:
            bar.className="sixty-percent";
            break;
        case 7:
            bar.className="seventy-percent";
            break;
        case 8:
            bar.className="eighty-percent";
            break;
        case 9:
            bar.className="ninety-percent";
            break;
        case 10:
            bar.className="one-hundred-percent";
            break;
    }

    bar.style.visibility = "";
};

/**
 * Shows and hides the filter panes (top and bottom)
 * @param visibility "hidden" or "visible"
 */
ResultList.prototype.setFilterPaneVisibility = function(visibility)
{
    if(document.getElementById('filter_results_form') != null)
    {
        document.getElementById('filter_results_form').style.visibility = visibility;
    }

    if(document.getElementById('filter_results_form_bottom') != null)
    {
        document.getElementById('filter_results_form_bottom').style.visibility = visibility;
    }
};

/**
 * Handler for the user action of clicking on one of the displayed tabs in the UI
 * @param which_tab the tab to switch to
 */
ResultList.prototype.switchTabs = function(which_tab)
{
    YAHOO.util.History.navigate(ResultList.moduleName, which_tab.toString());

    // Hide the correct cluster list for the current pane
    if (this.clusterPanes[this.currentTabIndex])
    {
        this.clusterPanes[this.currentTabIndex].hideClusters();
    }

    // Get and temporarily hide the filter panes while we calculate things.
    this.setFilterPaneVisibility("hidden");

    // Set the selected tab
    var selectedTab = document.getElementById("tab_" + which_tab);
    if (selectedTab != null)
    {
        this.setSelectedTab(selectedTab);
    }

    // Set the selected container
    this.setSelectedContainer(document.getElementById("tab_content_" + this.activeTabPanes[which_tab].paneId));

    this.currentTabIndex = which_tab;

    // Update the description for the current tab
    if (document.getElementById("tab-description") != null)
    {
        document.getElementById("tab-description").innerHTML = this.getActivePane().description;
    }

    // Update the two drop down boxes and pagination
    this.getActivePane().setSortByOptions();
    this.getActivePane().setLimitToOptions();
    this.setSortOrderImage();
    this.getActivePane().paginate();

    // If there are no results to display
    if (this.getActivePane().resultCount == 0)
    {
        // if there are no results displayed in the pane and there are results to retrieve, get them
        if (this.getActivePane().displayCount == 0 && this.resultListStatus != null && this.resultListStatus.paneCounts[this.currentTabIndex])
        {
            // Set the selected container to the retrieving results... container
            this.setSelectedContainer(document.getElementById("retrieving-results-tab-message"));

            this.showPage(0, true);
        }
        else if (this.isSearchFinished())
        {
            this.setSelectedContainer(document.getElementById("no-results-message"));
        }
        else
        {
            this.setSelectedContainer(document.getElementById("searching-tab-message"));
        }
    }
    else
    {
        // Show the filter panes
        this.setFilterPaneVisibility("visible");
    }

    // Display the cluster list for the selected tab
    if (this.clusterPanes[this.currentTabIndex])
    {
        this.clusterPanes[this.currentTabIndex].showClusters();
    }
};

/**
 * Sets the currently selected tab element and resets the previously selected
 * tab element
 * @param newSelectedTab the newly selected tab
 */
ResultList.prototype.setSelectedTab = function(newSelectedTab)
{
    if (this.selectedTab != null)
    {
        this.selectedTab.className = "";
    }

    newSelectedTab.className = "Selected";
    if (newSelectedTab.blur) { newSelectedTab.blur(); }

    this.selectedTab = newSelectedTab;
}

/**
 * Sets the currently selected container element and hides the previously selected
 * container element
 * @param newSelectedContainer the newly selected container
 */
ResultList.prototype.setSelectedContainer = function(newSelectedContainer)
{
    if (this.selectedContainer != null)
    {
        this.selectedContainer.className = "Removed";
    }

    newSelectedContainer.className = "";

    this.selectedContainer = newSelectedContainer;
}

/**
 * Handles condidtions associated with a search status of "finished".
 */
ResultList.prototype.handleSearchFinished = function()
{
    if (!this.isSearchFinished())
    {
        return;
    }

    CollectionStatusPanel.getCollectionStatus(this.ssid, this.filters);

    var unseenResultCount = this.getTotalFilteredResults() - this.displayTotal;
    DWRUtil.setValue("unseenResultCount", unseenResultCount);

    // Hide all of the auxiliary panes by setting their class to "Removed"
    var elementIds = ["searching-tab-message", "no-results-message", "empty-tab-message", "retrieving-results-tab-message"];
    for (var i = 0; i < elementIds.length; ++i)
    {
        var elem = document.getElementById(elementIds[i]);
        elem.className = "Removed";
    }

    // Show the search completed pop-up.
    if (unseenResultCount > 0 && this.refreshMode == "PROMPT" && this.displayMoreResultsDialog)
    {
        this.showSearchPopup(unseenResultCount);
    }

    // Handle cases associated with no unseen results.
    if (unseenResultCount <= 0)
    {
        if (this.displayTotal === 0)
        {
            this.setSelectedContainer(document.getElementById("no-results-message"));
        }
        else if (this.getActivePane().displayCount === 0)
        {
            this.setSelectedContainer(document.getElementById("empty-tab-message"));
        }
    }
    // Handle cases where at least one pane has some results displayed.
    else if (this.getActivePane().displayCount === 0)
    {
        this.setSelectedContainer(document.getElementById("empty-tab-message"));
    }
 };

/**
 * Creates the search complete popup
 */
ResultList.prototype.createSearchPopup = function()
{
    document.getElementById("search-popup-window").style.display = "";

    this.searchPopup =  new YAHOO.widget.Dialog(
        "search-popup-window",
        {
            width      : "330px",
            fixedcenter: true,
            visible    : false,
            modal      : true,
            //close:false,
            underlay:"shadow",
            draggable:true,
            constraintoviewport : true,
            buttons : [ { text:ResultList.searchPopupButton1Text, handler:function(){ResultList.instance.handleSearchPopup(true);}, isDefault:true },
                        { text:ResultList.searchPopupButton2Text, handler:function(){ResultList.instance.handleSearchPopup(false);} } ]
        }
    );

    this.searchPopup.render();
}


/**
 * Update and display the search popup dialog.
 * We create a "canvas" iframe just beneath so that IE 5.5 and 6 will display
 * the div correctly over select elements.
 */
ResultList.prototype.showSearchPopup = function(resultCount)
{
    var count = document.getElementById("search_popup_resultCount");
    count.innerHTML = resultCount;

    this.searchPopup.show();
    this.searchPopup.center();
}

/**
 * Method called by the results pop-up to finish the search with a final refresh
 * or not, and to set the refresh mode if needed.
 * @param refresh true if the page should be refreshed
 */
ResultList.prototype.handleSearchPopup = function(refresh)
{
    this.searchPopup.hide();
    var disablePopup = document.getElementById("show_popup").checked;
    ResultListConnector.onSearchFinishConfirmed(disablePopup);
    if (refresh)
    {
        this.addResults();
    }
};

/**
 * Callback method for ResultConnector.getResults* methods.  The return value contains
 * a resultContainer, which contains the results requested.  It then calls into the
 * appropriate resultPane's update method to display the data.
 * @param resultContainer the object that contains the new values to dsiplay in the
 * resultPane.
 */
ResultList.getResults_callback = function(resultContainer)
{
    ResultList.instance.setResults(resultContainer);
}

/**
 * The error handler method for calls to ResultListConnector.getResults
 * and ResultListConnector.getResultsForIds
 * @param message the error message to be displayed
 */
ResultList.getResults_errorHandler = function(message, info)
{
    DWRHelper.displayDWRError("ResultList.getResults_callback", message, info);
}

ResultList.setClippingsCount_errorHandler = function(message, info)
{
    DWRHelper.displayDWRError("ResultList.setClippingsCount", message, info);
}

/**
 * Processes the result container that is received from calls to getResults...
 * @param resultContainer the object that contains the new values to dsiplay in the
 * resultPane.
 */
ResultList.prototype.setResults = function(resultContainer)
{
    var paneIndex = resultContainer.paneIndex;

    // Get the result panel where the results will be stored
    var tabContentElement = document.getElementById("tab_content_" + paneIndex);

    // Get the result pane object for this index
    var resultPane = this.resultPanes[paneIndex];

    // Calculate the maximum total counts.  This is the maximum of resultContainer.totalResults and the
    // paneCounts from the resultList status
    var statusIndex = (paneIndex < this.tabCount) ? paneIndex : paneIndex - this.tabCount;
    var maxTotalCounts = Math.max(resultContainer.totalResults, this.resultListStatus.paneCounts[statusIndex]);

    // if there are currently no results displayed for this pane, generate the clusters
    // for the pane.
    if (resultPane.displayCount == 0 && maxTotalCounts > 0 && paneIndex < this.tabCount)
    {
        if (this.clusterPanes[paneIndex])
        {
            this.clusterPanes[paneIndex].getClusters(this.ssid, this.isInActiveTab(paneIndex),
                                              maxTotalCounts);
        }

        this.updateResultCounter(paneIndex, maxTotalCounts);

        // Show the filter panes
        this.setFilterPaneVisibility("visible");        
    }

    // if this is a return from a cluster, select the node in the cluster
    if (resultContainer.clusterId != null)
    {
        var clusterIndex = paneIndex - this.tabCount;
        this.clusterPanes[clusterIndex].selectNodeByClusterId(resultContainer.clusterId);
    }

    resultPane.setCollectionCounts(resultContainer.collectionCounts);

    resultPane.resultCount      = resultContainer.resultCount;
    resultPane.startPosition    = resultContainer.startPosition;
    resultPane.totalResultCount = resultContainer.totalResults;
    resultPane.displayCount     = maxTotalCounts;
    
    resultPane.update(resultContainer, tabContentElement);

    // if this pane is in the currently selected tab and it is not displayed, then show it
    if (this.isInActiveTab(paneIndex))
    {
        this.setSelectedContainer(tabContentElement);
        this.activeTabPanes[this.currentTabIndex] = resultPane;

        if (resultContainer.totalResults == 0)
        {
            this.setSelectedContainer(document.getElementById("empty-tab-message"));
        }
    }

    this.calculateDisplayTotal();
}

/**
 * Updates the result count element for the given tab with the value from the
 * paneCounts array in the resultListStatus
 * @param tabIndex the index of the tab
 */
ResultList.prototype.updateResultCounter = function(index, count)
{
    var resultCountElement = document.getElementById("results_count_" + index);
    if (resultCountElement != null)
    {
        if (typeof count == "undefined")
        {
            count = this.resultListStatus.paneCounts[index];
        }
        resultCountElement.innerHTML = count;
    }
}

/**
 * This method calculates the total number of results that can be displayed by summing
 * the results from each of the resultPanes.  If a resultPane does not have any results
 * displayed, it adds the totalResultCount.  If it does, it means that ResultList is no
 * longer updating its count, so use the displayCount for that pane.
 */
ResultList.prototype.calculateDisplayTotal = function()
{
    this.displayTotal = 0;
    for (var i = 0; i < this.tabCount; ++i)
    {
        if (this.resultPanes[i].displayCount == 0)
        {
            this.displayTotal += this.resultListStatus.paneCounts[i];
        }
        else
        {
            this.displayTotal += this.resultPanes[i].displayCount;
        }
    }
}
/**
 * Detects if the current pane is in the currently selected tab.
 * @param paneIndex the index of the pane to be checked
 * @return true if the pane is in the currently dispalyed tab
 */
ResultList.prototype.isInActiveTab = function(paneIndex)
{
    return (paneIndex == this.currentTabIndex ||
            paneIndex - this.tabCount == this.currentTabIndex);
}

/**
 * This method is called in response to the onlableclick event in the cluster tree.
 * @param cluster the cluster object associated with the clicked cluster label.
 * @param displayPaneIndex the index to the result pane in which the clusters results
 * are to be displayed.
 * @param clusterGroup the name of the group that this cluster is associated with
 */
ResultList.prototype.onClusterClicked = function(cluster, displayPaneIndex, clusterGroup)
{
    // Reset the collectionCounts
    this.resultPanes[displayPaneIndex].setCollectionCounts(null);

    // Reset the selected collection
    this.resultPanes[displayPaneIndex].resetSelectedCollection();

    ResultListConnector.getResultsForCluster(this.ssid, displayPaneIndex, clusterGroup, cluster.clusterId,
            0, Paginator.resultsPerPage, this.filters, this.resultPanes[displayPaneIndex].resultOrder,
            ResultList.getResultsDWRObject);
}

/**
 * This method is called in response to the onlableclick event in the cluster tree
 * when the user clicks on the "All Results" node in the tree.
 * @param displayPaneIndex the index to the result pane in which the clusters results
 * are normally displayed.
 */
ResultList.prototype.onAllResultsClicked = function(displayPaneIndex)
{
    var paneIndex = displayPaneIndex - this.tabCount;

    var newResultPane = this.resultPanes[paneIndex];
    this.activeTabPanes[this.currentTabIndex] = newResultPane;

    this.setSelectedContainer(document.getElementById("tab_content_" + paneIndex));

    // Update the two drop down boxes
    newResultPane.setSortByOptions();
    newResultPane.setLimitToOptions();

    newResultPane.paginate();
}

/**
 * Callback function to the ResultListConnector.getCollectionIdMap.  This method saves
 * the collectionIdMap so that the collection information is present for the resultPane object
 * to use when generating its dispaly.
 */
ResultList.getCollectionIdMap_callback = function(collectionIdMap)
{
    ResultList.instance.collectionIdMap = collectionIdMap;
}

/**
 * The object used when making calls to getResults and getResultsByIds
 */
ResultList.getResultsDWRObject = {
  callback:     ResultList.getResults_callback,
  timeout:      20000,
  errorHandler: ResultList.getResults_errorHandler
};
