from django import template
from django.db.models.query import QuerySet
from django.core.paginator import Paginator, QuerySetPaginator

register = template.Library()

class PaginateNode(template.Node):
    def __init__(self, objlist_name, nr_pages, var_name="page", param_name="page"):
        self.objlist_name = objlist_name
        self.nr_pages = nr_pages
        self.var_name = var_name
        self.param_name = param_name
    
    def render(self, context):
        try:
    	    list_or_queryset = context[self.objlist_name]
        except KeyError:
            return ''
        
    	if isinstance(list_or_queryset, QuerySet):
    	    paginator = QuerySetPaginator(list_or_queryset, self.nr_pages)
    	else:
    	    paginator = Paginator(list_or_queryset, self.nr_pages)
	
    	try:
    	    page = int(context['request'].REQUEST.get(self.param_name, 1))
    	except:
    	    page = 1

    	context[self.var_name] = paginator.page(page)
        context[self.var_name+"_set"] = paginator
        # backward compatibility injections into the context
    	context[self.var_name+"_count"] = paginator.count
    	context[self.var_name+"_num_pages"] = paginator.num_pages
    	context[self.var_name+"_page_range"] = paginator.page_range
    	return ''

def paginate(parser, token):
    try:
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
    args = arg.split(None)
    var_name = "page"
    param_name = "page"
    try:
        objlist_name = args[0]
        nr_pages = args[1]
    except:
        raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0]
    if len(args)==2:
        pass
    elif len(args)==4 and args[2]=="as":
        var_name = args[3]
    elif len(args)==6 and args[4]=="using":
        var_name = args[3]
        param_name = args[5]
    else:
        raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0]
    try:
        nr_pages = int(nr_pages)
    except:
        raise template.TemplateSyntaxError, "%r tag invalid arguments" % token.contents.split()[0]
    return PaginateNode(objlist_name, nr_pages, var_name, param_name)
paginate = register.tag(paginate)