#!/usr/bin/env python
# -*- coding: utf-8 -*-

from django import template
from django.http import request

register = template.Library()

def remove_formatting(string):
    if type(string) is str:
        for to_strip in ["'", '"', ' ']:
            string = string.strip(to_strip)
            
        for to_remove in ['\t', '\n',]:
            string = string.replace(to_remove, '')
        
    return string

@register.filter(name='proper_paginate')
def proper_paginate(paginator, current_page, neighbors=2):
    if paginator.num_pages > 2*neighbors:
        start_index = max(1, current_page-neighbors)
        end_index = min(paginator.num_pages, current_page + neighbors)
        if end_index < start_index + 2*neighbors:
            end_index = start_index + 2*neighbors
        elif start_index > end_index - 2*neighbors:
            start_index = end_index - 2*neighbors
        if start_index < 1:
            end_index -= start_index
            start_index = 1
        elif end_index > paginator.num_pages:
            start_index -= (end_index-paginator.num_pages)
            end_index = paginator.num_pages
        page_list = [f for f in range(start_index, end_index+1)]
        return page_list[:(2*neighbors + 1)]
    return paginator.page_range

@register.filter
def addstr(value, parameter):
    return str(value) + str(parameter)

class VariableNode(template.Node):
    def __init__(self, name, content=None):
        if content==None and '=' in name:
            self.content = name.split('=')[1]
            self.name = name.split('=')[0]
        else:
            self.content = content
            self.name = name
        
    def render(self, context):
        if type(self.content) is not str:
            self.content = self.content.render(context)
        try:
            self.content = template.Variable(self.content).resolve(context)
        except template.VariableDoesNotExist:
            pass
        
        self.content = remove_formatting(self.content)
        context[self.name] = self.content
        return ''

class PartialNode(template.Node):
    def __init__(self, name, block):
        self.name = remove_formatting(name)
        self.block = block
        
    def render(self, context):
        if type(self.block) is template.NodeList:
               self.block = self.block.render(context)
        
        self.block = remove_formatting(self.block)
        
        context = context.flatten()
        context['block'] = self.block
        t = template.loader.get_template('partials/%s.html' % self.name)
        return t.render(context)

@register.tag(name='set')
def set_block(parser, token):
    split = token.split_contents()
    if len(split) >= 1:
        variable_name = split[1]
    else:
        raise template.TemplateSyntaxError('%r expects a variable name' % split[0])
            
    if len(split) == 2:
        content=None
        if '=' not in variable_name:
            content = parser.parse(('end%s'%split[0],))
        parser.delete_first_token()
        return VariableNode(variable_name, content)
    else:
        return VariableNode(variable_name, split[2])

@register.tag(name='partial')
def partial(parser, token):
    split = token.split_contents()
    if len(split) >= 1:
        partial_name = split[1]
    else:
        raise template.TemplateSyntaxError('%r expects a partial name' % split[0])
    
    if len(split) == 2:
        block_tag = False
        for token in reversed(parser.tokens):
            if 'end%s'%split[0] in token.contents:
                block_tag = True
                break
                
            if split[0] in token.contents:
                break
                
        if block_tag:
            nodeList = parser.parse(('end%s'%split[0],))
            parser.delete_first_token()
        else:
            nodeList = template.NodeList()
        return PartialNode(partial_name, nodeList)
    else:
        nodeList = template.NodeList()
        for parameter in split[2:]:
            if '=' in parameter:
                nodeList.append(
                    VariableNode(name=parameter)
                )
            else:
                raise template.TemplateSyntaxError('%r expects kwargs, got args' % split[0])
        return PartialNode(partial_name, nodeList)
    