#-*- coding: utf-8 -*-
import math

class Paginator(object):

    def __init__(self, source, page_size, page_count):
        """
        source: fnc, source function which get 2 attributes (offset, count)
            example: source = lambda o, c: range(o,o+c)
        page_size: int, yes, it is page size
        page: int, page count on chunk
        """
        self.page_count = page_count
        self.page_size = page_size
        self.source = source

    def page(self, page=1):
        """
        page: int, page number
        """

        # calculations
        chunk_size = self.page_count*self.page_size
        chunk_number = (page-1)/self.page_count
        chunk_offset = chunk_number*chunk_size

        # get objects
        result = self.source(chunk_offset, chunk_size+1)

        objects_count = len(result)

        if objects_count == 0:
            return False

        # navigation
        if objects_count == chunk_size+1:
            has_next = True
            objects_count -= 1
        else:
            has_next = False

        if chunk_number > 0:
            has_prev = True
        else:
            has_prev = False

        # define page range 
        if objects_count == chunk_size:
            left_page_number = chunk_number*self.page_count+1
            right_page_number = left_page_number+self.page_count-1

        elif objects_count < chunk_size:
            left_page_number = chunk_number*self.page_count+1
            right_page_number = left_page_number+int(math.ceil(objects_count/float(self.page_size)))-1

        pages = range(left_page_number, right_page_number+1)

        if has_next:
            has_next = pages[-1]+1
        if has_prev:
            has_prev = pages[0]-1

        # define current page objects
        if page not in pages:
            return False
        page_index = pages.index(page)
        first_object_number = page_index*self.page_size
        last_object_number = page_index*self.page_size+self.page_size
        objects = result[first_object_number:last_object_number]

        self.has_next = has_next
        self.has_prev = has_prev
        self.pages = pages

        return objects


