
/**
 * The number of results to display on a page.
 */
Paginator.resultsPerPage = 10;

/**
 * Constructor for the Paginator object
 */
function Paginator()
{
    // The number of results currently being displayed (up to resultsPerPage count).
    this.resultCount = 0;

    // The total number of results excluding any collection limits.
    this.totalResultCount = 0;

    // The starting position
    this.startPosition = 0;

    // Pagination specific variables:

    // the current page that the list is on
    this.currentPage = 1;

    // The number of page links????
    this.pageLinkCount = 5;

    // The total number of pages
    this.pageCount = 1;

    // The last page
    this.lastPage = 1;
}

/**
 * Gets a new set of results starting witht the index of newStart
 * @newStart the new starting position of the results
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
Paginator.prototype.gotoPage = function(newStart, ssid, filters)
{
    if (newStart < this.totalResultCount)
    {
        this.getPageOfResults(newStart, false, ssid, filters);
    }
};

/**
 * Shows the previous page of results
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
Paginator.prototype.showPrevious = function(ssid, filters)
{
    var nextPosition = this.startPosition - Paginator.resultsPerPage;
    if (nextPosition > -1)
    {
        this.getPageOfResults(nextPosition, false, ssid, filters);
    }
};

/**
 * Shows the next page of results
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
Paginator.prototype.showNext = function(ssid, filters)
{
    var nextPosition = this.startPosition;
    if ((nextPosition + Paginator.resultsPerPage) < this.totalResultCount)
    {
        nextPosition += Paginator.resultsPerPage;
        this.getPageOfResults(nextPosition, false, ssid, filters);
    }
};

/**
 * Shows the first page of results
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
Paginator.prototype.showFirst = function(ssid, filters)
{
    if (this.startPosition >= Paginator.resultsPerPage)
    {
        this.getPageOfResults(0, false, ssid, filters);
    }
};

/**
 * Shows the last page of results
 * @param ssid the id of the search
 * @param filters the list of filters to apply to the results
 */
Paginator.prototype.showLast = function(ssid, filters)
{
    var paneCount = this.totalResultCount;
    var firstEntryOnLastPage = Math.floor(paneCount / Paginator.resultsPerPage) * Paginator.resultsPerPage;

    if ((firstEntryOnLastPage % Paginator.resultsPerPage) === 0 && firstEntryOnLastPage == paneCount)
    {
        firstEntryOnLastPage = firstEntryOnLastPage - Paginator.resultsPerPage;
    }

    if (this.startPosition < firstEntryOnLastPage)
    {
        this.getPageOfResults(firstEntryOnLastPage, false, ssid, filters);
    }
};

/**
 * Handle the updating and displaying of pagination information and
 * links for the currently displayed pane.
 */
Paginator.prototype.paginate = function()
{
    var paneCount    = this.totalResultCount;
    this.pageCount   = Math.ceil(paneCount / Paginator.resultsPerPage);
    this.currentPage = Math.ceil((this.startPosition+1) / Paginator.resultsPerPage);
    this.lastPage    = Math.ceil(paneCount / Paginator.resultsPerPage);

    var el = null;

    // Update both the top and bottom pagination, if they exist
    var suffix = ["", "_bottom"];

    for (var ele_idx = 0; ele_idx < suffix.length; ++ele_idx)
    {
        var end = suffix[ele_idx];
        if (document.getElementById('filter_results_form' + end) == null)
        {
            continue;
        }

        // If there are more then one page worth of results then
        // we need to display the page navigations links.
        if (this.pageCount > 1)
        {
            el = document.getElementById("PageLinks" + end);
            var links = el.firstChild;
            if (links != null)
            {
                el.removeChild(links);
            }
            links = document.createElement("span");

            // Disable or enable the link buttons and set their images
            if (this.currentPage == 1)
            {
                document.getElementById('FirstPageLink' + end).disabled    = true;
                document.getElementById('PreviousPageLink' + end).disabled = true;
                document.getElementById('FirstPageLinkImage' + end).src = "images/icon.first.disabled.18x20.png";
                document.getElementById('PreviousPageLinkImage' + end).src = "images/icon.previous.disabled.18x20.png";
            }
            else
            {
                document.getElementById('FirstPageLink' + end).disabled    = false;
                document.getElementById('PreviousPageLink' + end).disabled = false;
                document.getElementById('FirstPageLinkImage' + end).src = "images/icon.first.18x20.png";
                document.getElementById('PreviousPageLinkImage' + end).src = "images/icon.previous.18x20.png";
            }

            if (this.currentPage == this.lastPage)
            {
                document.getElementById('NextPageLink' + end).disabled = true;
                document.getElementById('LastPageLink' + end).disabled = true;
                document.getElementById('NextPageLinkImage' + end).src = "images/icon.next.disabled.18x20.png";
                document.getElementById('LastPageLinkImage' + end).src = "images/icon.last.disabled.18x20.png";
            }
            else
            {
                document.getElementById('NextPageLink' + end).disabled = false;
                document.getElementById('LastPageLink' + end).disabled = false;
                document.getElementById('NextPageLinkImage' + end).src = "images/icon.next.18x20.png";
                document.getElementById('LastPageLinkImage' + end).src = "images/icon.last.18x20.png";
            }


            var startPosition = this.startPosition;

            // Try to keep the current page in the middle of the page links.
            var pageOffset = Math.floor(this.pageLinkCount/2);
            var firstPage = Math.min(Math.max((this.currentPage - pageOffset),1), this.currentPage);
            var positionOffset = (this.currentPage - firstPage) * Paginator.resultsPerPage;
            var nextPosition = this.startPosition - positionOffset;

            // We want to show pageLinkCount number of links even when we are near the end of the list.
            while ( (nextPosition + (this.pageLinkCount-1) * Paginator.resultsPerPage) >= this.totalResultCount && firstPage > 1)
            {
                nextPosition -= Paginator.resultsPerPage;
                firstPage -= 1;
            }

            // display up to pageLinkCount page number links for each available page of results.
            for (var i = 0; i < Math.min(this.pageCount, this.pageLinkCount); i++)
            {
                var link = document.createElement("a");
                link.innerHTML = firstPage + i;
                if (startPosition != nextPosition)
                {
                    link.href = "javascript:goToPageFunction(" + nextPosition + ");";
                }
                else
                {
                    link.style.fontWeight = "bold";
                }
                links.appendChild(link);
                nextPosition += Paginator.resultsPerPage;
            }
            el.appendChild(links);

            el = document.getElementById("PaginatedNavigation" + end);
            el.style.visibility = "visible";
        }
        else
        {
            el = document.getElementById("PaginatedNavigation" + end);
            el.style.visibility = "hidden";
        }

        // Update the start/end and total values.
        el = document.getElementById("StartPosition" + end);
        el.innerHTML = this.resultCount > 0 ? this.startPosition + 1 : this.startPosition;

        el = document.getElementById("EndPosition" + end);
        el.innerHTML = this.startPosition + this.resultCount;

        el = document.getElementById("TotalResults" + end);
        el.innerHTML = this.totalResultCount;

        // Show the filter form element if there are any results
        if (this.totalResultCount > 0)
        {
            document.getElementById('filter_results_form' + end).style.visibility = "visible";
        }
    }
};
