# -*- coding: utf-8 -*-
from math import ceil
from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage

class CouchPaginator(Paginator):
    """Allows pagination  of couchdb-python ViewResult objects. """
    def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True, pages_view=None):
        self.per_page = per_page
        self._object_list = object_list
        self.orphans = orphans
        self.allow_empty_first_page = allow_empty_first_page
        self._pages_view = pages_view
        self._num_pages = None
      
    def page(self, number):
        "Returns a Page object for the given 1-based page number."
        self._number = self.validate_number(number)
        skip = self._number * self.per_page - self.per_page
        ### FIXME it would be nice to be compatible with django
        ### and allow [from:to] syntax
        self._object_list.options['count'] = self.per_page + 1
        self._object_list.options['skip'] = skip    
        return Page(self.object_list, self._number, self)    
    
    @property
    def _count(self):
        """Implementation specific object count (overall)"""
        if self._pages_view:
            if isinstance(self._pages_view, int):
                count = self._pages_view
            else:
                count = self._pages_view.rows[0].get("value", None)
        else:
            count = None
        return count
    
    @property
    def object_list(self):
        """Returns a list of results or raises EmptyPage"""
        if self._object_list:
            return list(self._object_list)[:self.per_page]
        else:
            raise EmptyPage('That page contains no results')
            
            
class SimpleCouchPaginator(CouchPaginator):
    """Allows very simple page by page pagination with CouchDB ViewResults
        use SimpleCouchPaginator only if you don't have the absolute object count.
        If you have it CouchPaginator would be fine.
    """
    
    def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True):
        self.per_page = per_page
        self._object_list = object_list
        self.orphans = orphans
        self.allow_empty_first_page = allow_empty_first_page
        self._num_pages = None
        return super(SimpleCouchPaginator, self).__init__(object_list, per_page,
                        orphans=orphans, allow_empty_first_page=allow_empty_first_page)
    
    def validate_number(self, number):
        "Validates the given 1-based page number."
        try:
            number = int(number)
        except ValueError:
            raise PageNotAnInteger('That page number is not an integer')
        if number < 1:
            raise EmptyPage('That page number is less than 1')
        return number
    
    def _get_count(self):
        return False
    
    @property
    def num_pages(self):
        return False
        
    @property
    def object_count(self):
        return len(list(self._object_list))

    @property
    def next(self):
        if self.has_next:
            return self._number + 1
        else:
            return None

    @property
    def previous(self):
        if self.has_previous:
            return self._number - 1
        else:
            return None

    @property
    def has_next(self):
        return self.object_count > self.per_page

    @property
    def has_previous(self):
        return self._number > 1