from django import template
from django.http import QueryDict

register = template.Library()

class QueryStringSetNode(template.Node):
    def __init__(self, parameter_dict):
        self.parameter_dict = parameter_dict

    def render(self, context):
        qstring = get_query_string(context)

        value_parameter_dict = {}
        for key, value in self.parameter_dict.items():
            value_parameter_dict[get_value(key,context)] = get_value(value,context)

        existing_query_dict = QueryDict(qstring).copy()
        existing_query_dict.update(value_parameter_dict)
        return existing_query_dict.urlencode()

class QueryStringDeleteNode(template.Node):
    def __init__(self, parameter_delete_list):
        self.parameter_delete_list = parameter_delete_list

    def render(self, context):
        qstring = get_query_string(context)
        existing_query_dict = QueryDict(qstring).copy()
        print existing_query_dict
        
        parameters = map(lambda key: get_value(key, context), self.parameter_delete_list)
        for parameter in parameters:
            if existing_query_dict.get(parameter):
                del existing_query_dict[parameter]
        return existing_query_dict.urlencode()

@register.tag
def set_query_parameters(parser, token):
    try:
        key_value_pairs = token.split_contents()[1:]
        key_value_dict = dict(key_value_pair.split('=') for key_value_pair in key_value_pairs)
    except ValueError:
        raise template.TemplateSyntaxError('%r tag requires arguments to be in `key=value` pairs' % token.contents.split()[0])

    print key_value_dict
    return QueryStringSetNode(key_value_dict)

@register.tag
def del_query_parameters(parser, token):
    params = token.split_contents()[1:]
    return QueryStringDeleteNode(params)


# helper methods
def get_query_string(context):
    request = context.get('request', None)
    if request is None:
        return ''
    else:
        return request.GET.urlencode()

def get_value(key, context):
    print 'get_value: %s' % key
    try:
        value = template.Variable(key)
        value = value.resolve(context)
    except template.VariableDoesNotExist:
        return key
    else:
        return value




@@ -173,32 +173,33 @@
 ):%0A        self.
+_
 parameter_dict =
@@ -227,74 +227,48 @@
 def 
-render(self, context):%0A        qstring = get_query_string(
+contextual_parameter_dict(self, 
 context)
 %0A%0A  
@@ -255,33 +255,33 @@
 t(self, context)
-%0A
+:
 %0A        value_p
@@ -326,24 +326,25 @@
 lue in self.
+_
 parameter_di
@@ -438,16 +438,128 @@
 context)
+%0A        return value_parameter_dict%0A%0A    def render(self, context):%0A        qstring = get_query_string(context)
 %0A%0A      
@@ -643,21 +643,31 @@
 .update(
-value
+self.contextual
 _paramet
@@ -673,16 +673,25 @@
 ter_dict
+(context)
 )%0A      
@@ -832,24 +832,25 @@
        self.
+_
 parameter_de
@@ -884,16 +884,191 @@
 e_list%0A%0A
+    def contextual_parameter_delete_list(self, context):%0A        parameters = map(lambda key: get_value(key, context), self._parameter_delete_list)%0A        return parameters%0A%0A
     def 
@@ -1233,32 +1233,36 @@
        %0A        
+for 
 parameters = map
@@ -1258,116 +1258,58 @@
 eter
-s = map(lambda key: get_value(key, context), self.parameter_delete_list)%0A        for parameter in parameters
+ in self.contextual_parameter_delete_list(context)
 :%0A  

Split contextual paramter setters into separate methods