package models

import (
	"math"
	"net/http"
	"strconv"
)

// Pagination result object.
type Pagination struct {
	Page    int
	PerPage int
	Total   int64
	Sort    string
}

// Page for Iter.
type Page struct {
	Page      int
	IsCurrent bool
}

// Load the page from form or query parameters.
func (p *Pagination) ParsePage(r *http.Request) {
	raw := r.FormValue("page")
	a, err := strconv.Atoi(raw)
	if err == nil {
		if a <= 0 {
			a = 1
		}
		p.Page = a
	} else {
		p.Page = 1
	}
}

// Iter the pages, for templates.
func (p *Pagination) Iter() []Page {
	var (
		pages = []Page{}
		total = p.Pages()
	)
	for i := 1; i <= total; i++ {
		pages = append(pages, Page{
			Page:      i,
			IsCurrent: i == p.Page,
		})
	}
	return pages
}

func (p *Pagination) Pages() int {
	return int(math.Ceil(float64(p.Total) / float64(p.PerPage)))
}

func (p *Pagination) GetOffset() int {
	return (p.Page - 1) * p.PerPage
}

func (p *Pagination) HasNext() bool {
	return p.Page < p.Pages()
}

func (p *Pagination) HasPrevious() bool {
	return p.Page > 1
}

func (p *Pagination) Next() int {
	if p.Page >= p.Pages() {
		return p.Pages()
	}
	return p.Page + 1
}

func (p *Pagination) Previous() int {
	if p.Page > 1 {
		return p.Page - 1
	}
	return 1
}
