<?php

/**
 * Pagination class
 *
 * this class contain the methods that Will Be Used For Pagination
 *
 *
 * LICENSE: Open source
 *
 * @category   general
 * @package    core system
 * @subpackage parent
 * @copyright  coderg
 * @license    http://coderg.com
 * @version    .01
 * @link       http://coderg.com
 * @since      2018
 */
class Pagination {

    //TABLE NAME HERE
    private $tableName;
    // How many adjacent pages should be shown on each side?
    private $adjacents;
    // GET NUM OF DATA FROM TABLE
    private $dataCount;
    // controller name and action to add page number after it like controller/action/4
    private $targetpage;
    //how many items to show per page
    private $limit;
    //TARGET PAGE NUMBER FROM URL
    private $page;
    // The recorde that will start to get data
    private $start;
    //previous page is page - 1
    private $prev;
    //next page is page + 1
    private $next;
    //pagesCount is = total pages / items per page, rounded up.
    private $pagesCount;
    //last page minus 1
    private $lastPageMinus1;
    // SET CONDITION LIKE (WHERE `catid` =1 AND `type` =0 ORDER BY ID DESC)
    private $condition;
    // the Output pages Numbers Like 1|2|3
    private $pagination = "";
    // Model Object Like instructorModel
    private $modelObject;
    private $segment;
    private $sqlQuery;

    /**
     *  __construct
     *
     *  preparing Properties for Pagination
     * @param     (none)
     * @return  (none)
     *
     */
    public function __construct() {
        global $paginationConfig;
        $this->segment = $paginationConfig['segment'];
        $this->modelObject = new $paginationConfig['modelName']();
        // set table Name
        $this->tableName = $this->modelObject->getTableName();
        // set limit (how many recourd per page)
        $this->limit = $paginationConfig['limit'];
        // set controller concatenated with / and action
        $this->targetpage = $this->set_targetpage();
        // set Condition
        $this->condition = $paginationConfig['condition'];
        //set sqlquery
        $this->sqlQuery = $paginationConfig['sqlQuery'];
		//set adjacents
        $this->adjacents = $paginationConfig['adjacents'];
        // get row count
        $this->dataCount = $this->modelObject->get_data_number($this->condition,$this->sqlQuery);
        // get page from url
        $this->page = $this->set_page();
        // first item to display on this page if no page var is given, set start to 0
        $this->start = $this->set_start();
        // set the Page For previous Button
        $this->prev = $this->page - 1;
        // set the Page For Next Button
        $this->next = $this->page + 1;
        // get the number of pages
        $this->pagesCount = ceil($this->dataCount / $this->limit);
        //last page minus 1
        $this->lastPageMinus1 = $this->pagesCount - 1;
    }

    /**
     *  set_page
     *
     *  GET Target Page Number From Url & If No Page Set It To 1
     * @param     (none)
     * @return  (number) The Page Number From Url If Founded Or Set It Equal 1
     */
    private function set_page() {
        $route = new Route();

        $pageNumber = $route->getSegment($this->segment);
        if ($pageNumber == false) {
            return 1;
        } else {
            return $pageNumber;
        }
    }

    /**
     *  set_targetPage
     *
     *  GET controller And Action From Url
     * @param     (none)
     * @return  (string) The controller concatenated wwith / and action
     */
    private function set_targetPage() {
        $route = new Route();
        if($route->checkAdminPath())
        {
            $controller = $route->getSegment(1);
            $action = $route->getSegment(2); 
            $paramArray = array_slice($route->getParameters(), 0, $this->segment - 3);
            $paramString = implode('/', $paramArray);
            if ($paramString == null) {
                $result = BASE_URL . ADMIN_FOLDER . "/" . $controller . "/" . $action;
            } else {
                $result = BASE_URL . ADMIN_FOLDER . "/" .$controller . "/" . $action . '/' . $paramString;
            }
        }else{
            $controller = $route->getSegment(0);
            $action = $route->getSegment(1);
            $paramArray = array_slice($route->getParameters(), 0, $this->segment - 2);
            $paramString = implode('/', $paramArray);
            if ($paramString == null) {
                $result = BASE_URL . $controller . "/" . $action;
            } else {
                $result = BASE_URL . $controller . "/" . $action . '/' . $paramString;
            }
        }
        
        
        return $result;
    }

    /**
     *  set_start
     *
     *  first item to display on this page if no page var is given, set start to 0
     *   0 -> Will Be The First Recorde In Table
     * @param     (none)
     * @return  (number) first item to display on this page
     */
    private function set_start() {
        //first item to display on this page if no page var is given, set start to 0
        return ($this->page) ? ($this->page - 1) * ($this->limit) : 0;
    }

    /**
     *  get_pagination
     *
     *  preparing My pagination Links Like 1|2|3|4
     * @param     (none)
     * @return  (string)  My pagination Links Like 1|2|3|4
     */
    public function get_pagination_links() {
        if ($this->pagesCount > 1) {
            $this->pagination .= "<div class=\"pagination\">";
            //previous button
            if ($this->page > 1)
                $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$this->prev\">&laquo; Previous</a>";
            else
                $this->pagination.= "<span class=\"disabled\">&laquo; Previous</span>";

            //pages
            if ($this->pagesCount < 7 + ($this->adjacents * 2)) { //not enough pages to bother breaking it up
                for ($counter = 1; $counter <= $this->pagesCount; $counter++) {
                    if ($counter == $this->page)
                        $this->pagination.= "<span class=\"current\">$counter</span>";
                    else
                        $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$counter\">$counter</a>";
                }
            }
            elseif ($this->pagesCount > 5 + ($this->adjacents * 2)) { //enough pages to hide some
                //close to beginning; only hide later pages
                if ($this->page < 1 + ($this->adjacents * 2)) {
                    for ($counter = 1; $counter < 4 + ($this->adjacents * 2); $counter++) {
                        if ($counter == $this->page)
                            $this->pagination.= "<span class=\"current\">$counter</span>";
                        else
                            $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$counter\">$counter</a>";
                    }
                    $this->pagination.= "...";
                    $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$this->lastPageMinus1\">$this->lastPageMinus1</a>";
                    $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$this->pagesCount\">$this->pagesCount</a>";
                }
                //in middle; hide some front and some back
                elseif ($this->pagesCount - ($this->adjacents * 2) > $this->page && $this->page > ($this->adjacents * 2)) {
                    $this->pagination.= "<a class='pagination' href=\"$this->targetpage/1\">1</a>";
                    $this->pagination.= "<a class='pagination' href=\"$this->targetpage/2\">2</a>";
                    $this->pagination.= "...";
                    for ($counter = $this->page - $this->adjacents; $counter <= $this->page + $this->adjacents; $counter++) {
                        if ($counter == $this->page)
                            $this->pagination.= "<span class=\"current\">$counter</span>";
                        else
                            $this->pagination.= "<a href=\"$this->targetpage/$counter\">$counter</a>";
                    }
                    $this->pagination.= "...";
                    $this->pagination.= "<a href=\"$this->targetpage/$this->lastPageMinus1\">$this->lastPageMinus1</a>";
                    $this->pagination.= "<a href=\"$this->targetpage/$this->pagesCount\">$this->pagesCount</b></a>";
                }
                //close to end; only hide early pages
                else {
                    $this->pagination.= "<a href=\"$this->targetpage/1\">1</a>";
                    $this->pagination.= "<a href=\"$this->targetpage/2\">2</a>";
                    $this->pagination.= "...";
                    for ($counter = $this->pagesCount - (2 + ($this->adjacents * 2)); $counter <= $this->pagesCount; $counter++) {
                        if ($counter == $this->page)
                            $this->pagination.= "<span class=\"current\">$counter</span>";
                        else
                            $this->pagination.= "<a href=\"$this->targetpage/$counter\">$counter</a>";
                    }
                }
            }

            //next button
            if ($this->page < $counter - 1)
                $this->pagination.= "<a class='pagination' href=\"$this->targetpage/$this->next\">Next &raquo;</a>";
            else
                $this->pagination.= "<span class=\"disabled\">Next &raquo;</span>";
            $this->pagination.= "</div>\n";
        }
        return $this->pagination;
    }

    /**
     *  get_data
     *
     *  get Data From Table Based On Condition
     * @param     (none)
     * @return  (array)  If Found Any Data , NULL otherwise
     */
    public function get_data() {
        if(empty($this->sqlQuery))
        {
            return $this->modelObject->retrieveAllData($this->condition . " LIMIT ?,? ", array($this->start, $this->limit));
        }else{
           return $this->modelObject->retrieveDataByQuery($this->sqlQuery. " LIMIT ?,? ", array($this->start, $this->limit)); 
        }
    }

}

?>