# coding: utf-8

# django imports
from django import template
from django.utils.encoding import smart_unicode
from django.utils.safestring import mark_safe
from django.utils.http import urlencode

# filebrowser imports
from filebrowser.settings import SELECT_FORMATS

register = template.Library()


@register.inclusion_tag('filebrowser/include/_response.html', takes_context=True)
def query_string(context, add=None, remove=None):
    """
    Allows the addition and removal of query string parameters.
    
    _response.html is just {{ response }}
    
    Usage:
    http://www.url.com/{% query_string "param_to_add=value, param_to_add=value" "param_to_remove, params_to_remove" %}
    http://www.url.com/{% query_string "" "filter" %}filter={{new_filter}}
    http://www.url.com/{% query_string "sort=value" "sort" %}
    """
    
    # Written as an inclusion tag to simplify getting the context.
    add = string_to_dict(add)
    remove = string_to_list(remove)
    params = context['query'].copy()
    response = get_query_string(params, add, remove)
    return {'response': response }


def query_helper(query, add=None, remove=None):
    """
    Helper Function for use within views.
    """
    
    add = string_to_dict(add)
    remove = string_to_list(remove)
    params = query.copy()
    return get_query_string(params, add, remove)


def get_query_string(p, new_params=None, remove=None):
    """
    Add and remove query parameters. From `django.contrib.admin`.
    """
    
    if new_params is None: new_params = {}
    if remove is None: remove = []
    for r in remove:
        for k in p.keys():
            if k.startswith(r):
                del p[k]
    for k, v in new_params.items():
        if v is None:
            if k in p:
                del p[k]
        else:
            p[k] = v
    return '?%s' % urlencode(p)


def string_to_dict(string):
    """
    Usage:
        {{ url|thumbnail:"width=10,height=20" }}
        {{ url|thumbnail:"width=10" }}
        {{ url|thumbnail:"height=20" }}
    """
    
    kwargs = {}
    if string:
        string = str(string)
        if ',' not in string:
            # ensure at least one ','
            string += ','
        for arg in string.split(','):
            arg = arg.strip()
            if arg == '': continue
            kw, val = arg.split('=', 1)
            kwargs[kw] = val
    return kwargs


def string_to_list(string):
    """
    Usage:
        {{ url|thumbnail:"width,height" }}
    """
    
    args = []
    if string:
        string = str(string)
        if ',' not in string:
            # ensure at least one ','
            string += ','
        for arg in string.split(','):
            arg = arg.strip()
            if arg == '': continue
            args.append(arg)
    return args


class SelectableNode(template.Node):
    def __init__(self, filetype, format):
        self.filetype = template.Variable(filetype)
        self.format = template.Variable(format)
    
    def render(self, context):
        try:
            filetype = self.filetype.resolve(context)
        except template.VariableDoesNotExist:
            filetype = ''
        try:
            format = self.format.resolve(context)
        except template.VariableDoesNotExist:
            format = ''
        if filetype and format and filetype in SELECT_FORMATS[format]:
            selectable = True
        elif filetype and format and filetype not in SELECT_FORMATS[format]:
            selectable = False
        else:
            selectable = True
        context['selectable'] = selectable
        return ''


def selectable(parser, token):
    
    try:
        tag, filetype, format = token.split_contents()
    except:
        raise TemplateSyntaxError, "%s tag requires 2 arguments" % token.contents.split()[0]
        
    return SelectableNode(filetype, format)
    
register.tag(selectable)

@@ -152,48 +152,8 @@
 safe
-%0Afrom django.utils.http import urlencode
 %0A%0A# 
@@ -1579,24 +1579,25 @@
             
+#
 if k.startsw
@@ -1604,16 +1604,39 @@
 ith(r):%0A
+            if k == r:%0A
         
@@ -1703,40 +1703,28 @@
  if 
-v is None:%0A            if k in p
+k in p and v is None
 :%0A  
@@ -1725,36 +1725,32 @@
 ne:%0A            
-    
 del p%5Bk%5D%0A       
@@ -1744,33 +1744,47 @@
  p%5Bk%5D%0A        el
-s
+if v is not Non
 e:%0A            p
@@ -1806,27 +1806,95 @@
 urn 
-'?%25s' %25 urlencode(p
+mark_safe('?' + '&'.join(%5Bu'%25s=%25s' %25 (k, v) for k, v in p.items()%5D).replace(' ', '%2520')
 )%0A%0A%0A

Revert "urlencode query_string tag"