//---------------------------------------------------------------------------------------
// This class contains the information that is associated with each result pane
// Dependencies:
//      Paginator.js
//---------------------------------------------------------------------------------------

/*jslint forin:true */

/**
 * Constructor for the result pane object
 * @param paneId the id of this result pane
 * @param resultSortField the initial field to sort on for this pane
 * @param description the description of the pane
 * @param collections the set of collections that belong with this pane.
 */
function ResultPane(paneId, resultSortField, description, collections)
{
    // The unique identifier for this pane, that will distinguish it from other panes
    this.paneId = paneId;

    // The currently selected collection id
    this.selectedCollection = "";

    // The initial field to sort on
    this.resultSortField = resultSortField;

    // The desription associated with each pane
    this.description = description;

    // The currently viewed collection id/name pairs
    this.collections = collections;

    // The Map of result counts per collection for the container
    this.collectionCounts = null;

    // The number of displayable results
    this.displayCount = 0;
}

/**
 * The text that goes into the collection sequence object in the sort by drop down
 */
ResultPane.collectionSequenceText = "COLLECTION_SEQUENCE";

/**
 * The options for sort by when all sources are displayed
 */
ResultPane.allResultsSortBy = null;

/**
 * The options for sort by when a single source is displayed
 */
ResultPane.singleCollectionSortBy = null;

/**
 * Sets the Base class of the ResultPane
 */
ResultPane.prototype = new Paginator();

/**
 * Defines the text that will be displayed at the top of the list of sources
 */
ResultPane.allSources = "<<uninitialized>>";

/**
 * Initializes the sort-by maps that will fill in the options for the sort-by
 * select box when they change from all collections to a single collection.
 */
ResultPane.initializeSortByMaps = function()
{
    var i;
    var sel;
    if (ResultPane.allResultsSortBy === null)
    {
        ResultPane.allResultsSortBy = [];
        ResultPane.singleCollectionSortBy = [];
        sel = document.getElementById("sort_by");
        for (i = 0; i < sel.options.length; ++i)
        {
            ResultPane.allResultsSortBy[sel.options[i].value] = sel.options[i].text;
            ResultPane.singleCollectionSortBy[sel.options[i].value] = sel.options[i].text;
        }
        ResultPane.singleCollectionSortBy["COLLECTION_SEQUENCE"] = ResultPane.collectionSequenceText;
    }
};

/**
 * Sets the collection counts for this pane
 * @param collectionCounts the new value of collectionCounts
 */
ResultPane.prototype.setCollectionCounts = function(collectionCounts)
{
    if (this.collectionCounts === null || collectionCounts === null ||
        this._mapLength(collectionCounts) > this._mapLength(this.collectionCounts))
    {
        this.collectionCounts = collectionCounts;
    }
};

/**
 * Returns the length of a map object
 * @param map
 */
ResultPane.prototype._mapLength = function(map)
{
    var ret = 0;
    for (var i in map)
    {
        ret++;
    }
    return ret;
};

/**
 * Sets the selected collection used to view the data
 * @param the code of the collection to set.
 */
ResultPane.prototype.setSelectedCollection = function(collectionCode)
{
    this.selectedCollection = collectionCode;
    ResultPane.initializeSortByMaps();

    // NOw, set the sort-by options
    if (collectionCode === "")
    {
        this.resultSortField = "RANK";
        this.updateSortByOptions(ResultPane.allResultsSortBy);
    }
    else
    {
        this.updateSortByOptions(ResultPane.singleCollectionSortBy);
    }
};

/**
 * Sets the options in the sort by select box by using the give map
 * @param newOptions the map containing the sort-by options
 */
ResultPane.prototype.updateSortByOptions = function(newOptions)
{
    var sortByElements = [document.getElementById("sort_by"), document.getElementById("sort_by_bottom")];
    var option_idx;
    var ele_idx;
    var key;
    var option;
    for (ele_idx = 0; ele_idx < sortByElements.length; ++ele_idx)
    {
        sortByElements[ele_idx].options.length = 0;

        option_idx = 0;
        for (key in newOptions)
        {
            option = new Option(newOptions[key], key);
            if (option.value == this.resultSortField)
            {
                option.selected = true;
            }
            sortByElements[ele_idx].options[option_idx++] = option;
        }
    }
};

/**
 * Resets the selected collection used to view the data
 */
ResultPane.prototype.resetSelectedCollection = function()
{
    this.selectedCollection = "";
};

/**
 * Calls into the ResultListConnector to get a page of results
 * @param startPosition the position where the list of results should start from
 * @param refresh true if a new snapshot should be generated
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
ResultPane.prototype.getPageOfResults = function(startPosition, refresh, ssid, filters)
{
    ResultListConnector.getResults(
            ssid, this.paneId, refresh, startPosition, Paginator.resultsPerPage,
            filters, this.resultSortField, this.getCollectionList(), ResultList.getResultsDWRObject);
};

/**
 * Gets an array with the pane's collection codes
 */
ResultPane.prototype.getCollectionList = function()
{
    var ret = [];

    if (this.selectedCollection === "")
    {
        for (var i = 0; i < this.collections.length; ++i)
        {
            ret[i] = this.collections[i].code;
        }
    }
    else
    {
        ret[0] = this.selectedCollection;
    }

    return ret;
};

/**
 * Sets the sort-by options from the current tab
 */
ResultPane.prototype.setSortByOptions = function()
{
    var sortByElements = [document.getElementById("sort_by"), document.getElementById("sort_by_bottom")];

    for (var ele_idx = 0; ele_idx < sortByElements.length; ++ele_idx)
    {
        // Update the sort by option to reflect current pane.
        var options = sortByElements[ele_idx].options;

        for (var i = 0; i < options.length; i++)
        {
            options[i].selected = (options[i].value == this.resultSortField);
        }
    }
};

/**
 * Sets the collections in the drop down
 */
ResultPane.prototype.setLimitToOptions = function()
{
    var limitToElements = [document.getElementById("limit-to"), document.getElementById("limit-to_bottom")];

    for (var ele_idx = 0; ele_idx < limitToElements.length; ++ele_idx)
    {
        // Update the limit-to by option to reflect current pane.
        var options = limitToElements[ele_idx].options;
        options.length = 0;
        options[0] = new Option(ResultPane.allSources, "");

        var option_idx = 0;

        for (var i = 0; i < this.collections.length; i++)
        {
            if (this.hasResults(this.collections[i].code))
            {
                option_idx++;
                options[option_idx] = new Option(this.collections[i].name, this.collections[i].code);
                options[option_idx].selected = (this.collections[i].code == this.selectedCollection);
            }
        }
    }
};

/**
 * Checks to see if the collection with the given code actually has results
 * @param code the code of the collection to check
 * @return true if the collection has results, false otherwise
 */
ResultPane.prototype.hasResults = function(code)
{
    return (this.collectionCounts === null ||
            (this.collectionCounts[code] !== null && this.collectionCounts[code] > 0));
};

/**
 * Updates the resultItems displayed in the resultPane
 * @param resultContainer the results to display
 * @param paneContainer the pane into which to set the results
 */
ResultPane.prototype.update = function(resultContainer, paneContainer)
{
    var listItem;
    var clippingIcon;
    var re;
    var els;
    var i;
    var j;
    var orderedList = document.createElement("div");

    orderedList.id = 'results';

    for (i = 0; i < resultContainer.results.length; ++i)
    {
        result = resultContainer.results[i];

        listItem = document.createElement("div");
        listItem.id = "resultItem" + i;
        listItem.className = 'floatContainer result';
        orderedList.appendChild(listItem);
        listItem.innerHTML = result.html;

        clippingIcon = ClippingsManager.createClippingIcon(i, result.resultId, result.marked);
        re = new RegExp('\\bclipping\\b');
        els = listItem.getElementsByTagName('div');

        for (j = 0; j < els.length; j++)
        {
            if (re.test(els[j].className))
            {
                els[j].appendChild(clippingIcon);
            }
        }
    }

    // Remove all nodes from the pane container
    while (paneContainer.hasChildNodes())
    {
        paneContainer.removeChild(paneContainer.firstChild);
    }

    // Add the orderedList element to the paneConainer
    paneContainer.appendChild(orderedList);

    // Update the displayed options for the new results
    this.setSortByOptions();
    this.setLimitToOptions();
    this.paginate();
};

