<?php

// last edit: 28.04.2018

/*

	Класс простого пагинатора.
	Настраивается при помощи переопределения переменных класса.


	Пример использования:
		
		$paginator = new PageLines(20, '/catalog/find?page='); // всего страниц, и url, к которому пристыковывать номер страницы
		$paginator->setPage(intval($_GET['page']));            // устанавливаем активную страницу
		
		
		// далее в шаблоне просто выводим в нужном месте

		{{ $paginator }}


*/

class PageLines{

	static public $templatePage = '<a class={CSS} href="{URL}">{PAGE}</a>';        // шаблон кнопки номера страницы
	static public $templatePageBack = '<a class={CSS} href="{URL}">&lt;</a>';      // шаблон кнопки "назад"
	static public $templatePageNext = '<a class={CSS} href="{URL}">&gt;</a>';      // шаблон кнопки "далее"
	static public $templatePageFirst = '<a class={CSS} href="{URL}">&lt;&lt;</a>'; // шаблон кнопки "в начало"
	static public $templatePageLast = '<a class={CSS} href="{URL}">&gt;&gt;</a>';  // шаблон кнопки "в конец"
	static public $cssClassPage = 'page';                // класс неактивной кнопки номера страницы
	static public $cssClassPageActive = '"page act"';    // класс активной кнопки номера страницы

	public $page = 0;                       // номер текущей страницы
	public $limit_page = 5;                 // лимит отображения страниц от текущей в обе стороны
	static public $delimiter_pages = '...'; // текст, который вставлять между страницами с большим промежутком (например "-1- 2 3 4 5 ... 8 9 10 11 12")
	static public $bold_page = true;        // добавлять жирность активному номеру страницы (<b>num</b>)
	static public $w_last = true;           // формировать кнопку "в конец"
	static public $w_back = true;           // формировать кнопку "назад"
	static public $w_next = true;           // формировать кнопку "далее"
	static public $w_first = true;          // формировать кнопку "в начало"
	static public $spacePages = false;      // формировать между номерами страниц пробелы

	private $pg_count, $base;

	function __construct($page_count, $base_url){
		$this->pg_count = $page_count;
		$this->base = $base_url;
	}

	/**
	*
	*/
	function to_array(){

		$result = [];
		$page = min($this->page, $this->pg_count);
		$maxPages = min($this->page + $this->limit_page - 1, $this->pg_count);

		if($this->page > $this->limit_page + 1){
			$result[] = static::$delimiter_pages;
			$start = $this->page - $this->limit_page + 1;
		}else $start = 1;

		$finish = min($this->page + $this->limit_page+1, $this->pg_count);

		if($start < $finish)
			$result = array_merge($result, range($start, $finish));

		if($finish+1 == $this->pg_count)
			$result[] = $this->pg_count;
		elseif($finish < $this->pg_count)
			$result[] = static::$delimiter_pages;

		return $result;
	}

	private function __tmpl($template, $page){
		return str_replace(
			['{CSS}','{URL}','{PAGE}'], 
			[
				$page == $this->page+1 ? static::$cssClassPageActive : static::$cssClassPage,
				$this->base . $page,
				(static::$bold_page && $page == $this->page+1) ? "<b>$page</b>" : $page
			], $template
		);
	}

	function setPage($page){
		if($page >= $this->pg_count)
			$this->page = $this->pg_count - 1;
		elseif($page < 0) 
			$this->page = 0;
		else $this->page = $page;
	}

	function count(){
		return $this->pg_count;
	}

	/**
	*
	*/
	function __toString(){
		if($this->pg_count < 2)
			return '';//$this->__tmpl($this->templatePage, 1);

		$pages = $this->to_array();
		$pagenum = $this->page + 1;
		
		$result = [];
		if(static::$w_first && $pages[0] == static::$delimiter_pages)
			$result[] = $this->__tmpl(static::$templatePageFirst, 1);

		if(static::$w_back && $pagenum > 1)
			$result[] = $this->__tmpl(static::$templatePageBack, $pagenum- 1);
		
		if($pages[0] == static::$delimiter_pages)
			$result[] = $this->__tmpl(static::$templatePage, 1);

		foreach($pages as $page)
			if(is_numeric($page))
				$result[] = $this->__tmpl(static::$templatePage, $page);
			else $result[] = $page;

		if(end($pages) == static::$delimiter_pages)
			$result[] = $this->__tmpl(static::$templatePage, $this->pg_count);
		
		if(static::$w_next && $pagenum < $this->pg_count)
			$result[] = $this->__tmpl(static::$templatePageNext, $pagenum + 1);

		if(static::$w_last && end($pages) == static::$delimiter_pages)
			$result[] = $this->__tmpl(static::$templatePageLast, $this->pg_count);

		return implode(static::$spacePages ? ' ' : '', $result);
	}
}