<?php
/**
 * A class for rendering html pagination menus.
 */
class view_widget_pagination
{
    ////////////////////////////////////////////////////////////////////////////
    // Construct and destruct functions.

    ////////////////////////////////////////////////////////////////////////////
    // Overload functions.

    ////////////////////////////////////////////////////////////////////////////
    // Interface functions.

    /**
     * Renders an html pagination menu.
     * 
     * @param string $base The base url.
     * @param integer $item The total number of items.
     * @param integer (optional) $cursor The selected page.
     * @param integer (optional) $per_page The number of items per page.
     * @param integer (optional) $padding The number of links on both end of the
     * cursor.
     * @param string (optional) $caption The caption.
     * @throws invalidargumentexception If the $item, $cursor, $per_page or
     * $padding parameter is not numeric.
     * @return string The rendered menu.
     */
    public static function render($base, $item, $cursor = 1, $per_page = 20, $padding = 5, $caption = 'item(s)')
    {
        $i = 1;
        
        foreach (array('item', 'cursor', 'per_page', 'padding') as $k)
        {
            $i++;
            
            if (!is_numeric($$k))
            {
                throw new invalidargumentexception('Argument ' . $i . ' passed to ' . __CLASS__ . '::' . __FUNCTION__ . '() must be numeric, ' . gettype($$k) . ' given.');
            }
        }
        
        $page = ceil($item / $per_page);
        $page_low = 0;
        $page_high = 0;
        $listing_low = 0;
        $listing_high = 0;
        $pagination = array();
        
        if ($item)
        {
            if ($cursor > $page)
            {
                $cursor = $page;
            }
            
            $page_low = $cursor - $padding;
            
            if ($page_low < 1)
            {
                $page_low = 1;
            }
            
            $page_high = $cursor + $padding;
            
            if ($page_high > $page)
            {
                $page_high = $page;
            }
            
            $listing_low = (($cursor - 1) * $per_page) + 1;
            $listing_high = $listing_low + $per_page - 1;
            
            if ($listing_high > $item)
            {
                $listing_high = $item;
            }
            
            $pagination[] = '<li class="caption">' . htmlspecialchars($listing_low . '-' . $listing_high . ' of ' . $item . ' ' . $caption) . '.</li>';
            
            if ($cursor > 1)
            {
                $pagination[] = '<li><a href="' . ($base . ($cursor - 1)) . '" class="previous">Previous page</a></li>';
            }
            
            for ($i = $page_low; $i <= $page_high; $i++)
            {
                $pagination[] = '<li' . (($i == $cursor) ? ' class="current"' : '') . '><a href="' . ($base . $i) . '">' . htmlspecialchars($i) . '</a></li>';
            }
            
            if ($cursor < $page)
            {
                $pagination[] = '<li><a href="' . ($base . ($cursor + 1)) . '" class="next">Next page</a></li>';
            }
        }
        else
        {
            $pagination[] = '<li class="caption">0 ' . htmlspecialchars($caption) . '</li>';
        }
        
        return '<ul>' . implode($pagination) . '</ul>';
    }

    ////////////////////////////////////////////////////////////////////////////
    // Internal functions.
}
