<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Code Igniter
 *
 * An open source application development framework for PHP 4.3.2 or newer
 *
 * @package		CodeIgniter
 * @author		Rick Ellis
 * @copyright	Copyright (c) 2006, pMachine, Inc.
 * @license		http://www.codeignitor.com/user_guide/license.html 
 * @link		http://www.codeigniter.com
 * @since		Version 1.0
 * @filesource
 */
 
// ------------------------------------------------------------------------

/**
 * Pagination Class
 *
 * @package		CodeIgniter
 * @subpackage	Libraries
 * @category	Pagination
 * @author		Rick Ellis
 * @link		http://www.codeigniter.com/user_guide/libraries/pagination.html
 */
class CI_Pagination {

	var $base_url			= ''; // The page we are linking to
	var $total_rows  		= ''; // Total number of items (database results)
	var $per_page     		= 10; // Max number of items you want shown per page
	var $num_links    		=  2; // Number of "digit" links to show before/after the currently viewed page
	var $cur_page     		=  0; // The current page being viewed
	var $first_link   		= '&lsaquo; First';
	var $next_link			= '&gt;';
	var $prev_link			= '&lt;';
	var $last_link    		= 'Last &rsaquo;';
	var $uri_segment		= 3;
	var $full_tag_open		= '';
	var $full_tag_close		= '';
	var $first_tag_open		= '';
	var $first_tag_close	= '&nbsp;';
	var $last_tag_open		= '&nbsp;';
	var $last_tag_close		= '';
	var $cur_tag_open		= '&nbsp;<b>';
	var $cur_tag_close		= '</b>';
	var $next_tag_open		= '&nbsp;';
	var $next_tag_close		= '&nbsp;';
	var $prev_tag_open		= '&nbsp;';
	var $prev_tag_close		= '';
	var $num_tag_open		= '&nbsp;';
	var $num_tag_close		= '';

	/**
	 * Constructor
	 *
	 * @access	public
	 * @param	array	initialization parameters
	 */
    function CI_Pagination($params = array())
    {    
		if (count($params) > 0)
		{
			$this->initialize($params);		
		}
		
		log_message('debug', "Pagination Class Initialized");
    }
	
	// --------------------------------------------------------------------
	
	/**
	 * Initialize Preferences
	 *
	 * @access	public
	 * @param	array	initialization parameters
	 * @return	void
	 */
    function initialize($params = array())
    {    
		if (count($params) > 0)
		{
			foreach ($params as $key => $val)
			{
				if (isset($this->$key))
				{
					$this->$key = $val;
				}
			}		
		}
    }
	
	// --------------------------------------------------------------------
	
	/**
	 * Generate the pagination links
	 *
	 * @access	public
	 * @return	string
	 */	
    function create_links()
    {  
		// If our item count or per-page total is zero there is no need to continue.
        if ($this->total_rows == 0 OR $this->per_page == 0)
        {
           return '';
    	}
    	
		// Calculate the total number of pages
        $num_pages = intval($this->total_rows / $this->per_page);
        
		// Use modulus to see if our division has a remainder.If so, add one to our page number.
        if ($this->total_rows % $this->per_page) 
        {
            $num_pages++;
        }
 
		// Is there only one page? Hm... nothing more to do here then. 
        if ($num_pages == 1)
        {
            return '';
        }
        
		// Determine the current page number.		
		$obj =& get_instance();	
		if ($obj->uri->segment($this->uri_segment) != 0)
		{
			$this->cur_page = $obj->uri->segment($this->uri_segment);
		}
		
		if ( ! ctype_digit($this->cur_page))
		{
			$this->cur_page = 0;
		}
		
		$uri_page_number = $this->cur_page;
		$this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
   
		// Calculate the start and end numbers. These determine
		// which number to start and end the digit links with
        $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
        $end   = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
        
		// Add a trailing slash to the base URL if needed
		$this->base_url = preg_replace("/(.+?)\/*$/", "\\1/",  $this->base_url);
		
  		// And here we go...
        $output = '';
 
		// Render the "First" link
        if  ($this->cur_page > $this->num_links)
        {
            $output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
        }
 
		// Render the "previous" link
        if  (($this->cur_page - $this->num_links) >= 0)
        {
        	$i = $uri_page_number - $this->per_page;  
        	if ($i == 0) $i = '';
            $output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
        }
        
		// Write the digit links
        for ($loop = $start -1; $loop <= $end; $loop++) 
        {
			$i = ($loop * $this->per_page) - $this->per_page;
					
			if ($i >= 0)
			{
				if ($this->cur_page == $loop)
				{
					$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
				}
				else
				{
					$n = ($i == 0) ? '' : $i;
					$output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
				}
			}
        } 

		// Render the "next" link
        if ($this->cur_page < $num_pages)
        {  
            $output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close;        
        }

		// Render the "Last" link
        if (($this->cur_page + $this->num_links) < $num_pages)
        {
            $i = (($num_pages * $this->per_page) - $this->per_page);
            $output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close;
        }
    
		// Kill double slashes.  Note: Sometimes we can end up with a double slash 
		// in the penultimate link so we'll kill all double shashes.
		$output = preg_replace("#([^:])//+#", "\\1/", $output);  

		// Add the wrapper HTML if exists
		$output = $this->full_tag_open.$output.$this->full_tag_close;
		
		return $output;		
    }
}
// END Pagination Class
?>