"""
To make page links like below:

Prev 1 ... 23 24 25 26 27 ...221 Next

Use like this , "bbs_posting_list" is the name of url 

{% page_link "bbs_posting_list" page pages %}

page_link.html:

{% load zsp_tags %}

{% if prev %}<a href="{% url url_name prev %}">Prev</a>{% endif %}

{% for i in page_numbers %}

    {% if forloop.first %}
        {% ifnotequal 1 i %}<a href="{% url url_name 1 %}">1</a>{% endifnotequal %}
        {% if omit_first %}...{% endif %}
    {% endif %}
    
    {% ifequal i page %}
        <a class="now">{{ i }}</a>
    {% else %}
        <a href="{% url url_name i %}">{{ i }}</a>
    {% endifequal %}
    
    {% if forloop.last %}
        {% if omit_last %}...{% endif %}
        {% ifnotequal pages i %}<a href="{% url url_name pages %}">{{ pages }}</a>{% endifnotequal %}
    {% endif %}
    
{% endfor %}

{% if next %}<a href="{% url url_name next %}">Next</a>{% endif %}

"""

from django import template

register = template.Library()

@register.inclusion_tag('page_link.html')
def page_link(url_name,page,pages,adjacent_pages=2):
    page_numbers=[n for n in \
                    range(page - adjacent_pages,page + adjacent_pages + 1) \
                    if n > 0 and n <= pages
                    ]
    try:
        [1,2].index(page_numbers[0])
        omit_first=False
    except ValueError:
        omit_first=True
        
    try:
        [pages-1,pages].index(page_numbers[-1])
        omit_last=False
    except ValueError:
        omit_last=True

    return {
    "url_name":url_name,
    "pages":pages,"page":page,"page_numbers":page_numbers,
    'omit_first':omit_first,'omit_last':omit_last,
    "prev":page!=1,"next":page!=pages
    }



"Default tags used by the template system, available to all templates."

from django.template import Node, NodeList, Template, Context, resolve_variable
from django.core.urlresolvers import reverse
from django.conf import settings


class URLNode(Node):
    def __init__(self, view_name, args, kwargs):
        self.view_name = view_name
        self.args = args
        self.kwargs = kwargs

    def render(self, context):
        from django.core.urlresolvers import reverse, NoReverseMatch
        args = [arg.resolve(context) for arg in self.args]
        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) for k, v in self.kwargs.items()])


        def _reverse(url_name):
            return reverse(url_name,args=args, kwargs=kwargs)

        try:
            return _reverse(self.view_name)
        except NoReverseMatch:
            try:
                project_name = settings.SETTINGS_MODULE.split('.')[0]
                return _reverse(project_name + '.' + self.view_name)
            except NoReverseMatch:
                url_name = context.get(self.view_name,'')
                if url_name:
                    try:
                            return _reverse(url_name)
                    except NoReverseMatch:
                        try:
                            return _reverse(project_name + '.' + url_name)
                        except NoReverseMatch:
                            return ''
            return ''
            
def url(parser, token):
    """
    Returns an absolute URL matching given view with its parameters.

    This is a way to define links that aren't tied to a particular URL configuration::

        {% url path.to.some_view arg1,arg2,name1=value1 %}

    The first argument is a path to a view. It can be an absolute python path
    or just ``app_name.view_name`` without the project name if the view is
    located inside the project.  Other arguments are comma-separated values
    that will be filled in place of positional and keyword arguments in the
    URL. All arguments for the URL should be present.

    For example if you have a view ``app_name.client`` taking client's id and
    the corresponding line in a URLconf looks like this::

        ('^client/(\d+)/$', 'app_name.client')

    and this app's URLconf is included into the project's URLconf under some
    path::

        ('^clients/', include('project_name.app_name.urls'))

    then in a template you can create a link for a certain client like this::

        {% url app_name.client client.id %}

    The URL will look like ``/clients/client/123/``.
    """
    bits = token.contents.split(' ', 2)
    if len(bits) < 2:
        raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0]
    args = []
    kwargs = {}
    if len(bits) > 2:
        for arg in bits[2].split(','):
            if '=' in arg:
                k, v = arg.split('=', 1)
                k = k.strip()
                kwargs[k] = parser.compile_filter(v)
            else:
                args.append(parser.compile_filter(arg))
    return URLNode(bits[1], args, kwargs)
url = register.tag(url)
