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

"""Web presentation DataGroup, UserGroupPerm classes"""

from django import template
#from django import http
from django.shortcuts import render_to_response
#    , redirect, get_object_or_404get_list_or_404, HttpResponse
from django.utils.translation import ugettext as _
#from django.utils.decorators import method_decorator
#from django.views.decorators.cache import cache_control
#from django.views.decorators.cache import never_cache
#from django.views.decorators.csrf import csrf_protect
from django.contrib.auth.decorators import login_required

from django import forms
from django.contrib.admin import widgets
from django.contrib import messages
#from django.db import transaction
#from django.db.models import Q
#import datetime

from .views import general_context, class_by_name # , classes_desktop
from .dataviews import datalist_create # use_obj_read,


#-------------------------------------------------------------------------------
class AdvSearchForm(forms.Form):
    """Dynamic Search form for a advanced searching"""


    chfields = [('nofields', '----'), ('created_by', 'created_by'),
                ('classname', 'classname'), ('name', 'name'),
                ('description', 'description')]
    chtypes = [('notypes', '----'), ('equals', 'is equal to'),
               ('notequals', 'is not equal to')]

    negate = forms.BooleanField(label="Not", required=False)
    fields = forms.ChoiceField(label="Search", choices=chfields,
                               required=False)
    types = forms.ChoiceField(label="Condition", choices=chtypes,
                              required=False)
    seach_text = forms.CharField(label="Search Text", max_length=90,
                                 required=False)
    and_cond = forms.BooleanField(label="And", required=False)
    or_cond = forms.BooleanField(label="Or", required=False)

    def __init__(self, linecount, *args, **kwargs):

        super(AdvSearchForm, self).__init__(*args, **kwargs)

        for ind in range(1, linecount):
            self.fields['negate_%d' % ind] = forms.BooleanField(label="Not",
                                                                required=False)
            self.fields['fields_%d' % ind] = forms.ChoiceField(label="Search",
                                        choices=self.chfields, required=False)
            self.fields['types_%d' % ind] = forms.ChoiceField(
                            label="Condition", choices=self.chtypes,
                                                            required=False)
            self.fields['seach_text_%d' % ind] = forms.CharField(
                            label="Search Text", max_length=90, required=False)
            self.fields['and_cond_%d' % ind] = forms.BooleanField(label="And",
                                                            required=False)
            self.fields['or_cond_%d' % ind] = forms.BooleanField(label="Or",
                                                            required=False)

#-------------------------------------------------------------------------------
@login_required
#@cache_control(must_revalidate=True, max_age=3600)
#@csrf_protect
def advsearch(request, linecount=1):
    """Advanced Search Form and search context rendering"""

    lcount = int(linecount)
    if request.POST.has_key('cmd-add') and \
               request.POST['cmd-add'] == 'Add another boolean chart':
        lcount += 1
        form = AdvSearchForm(lcount) # data={'fields':'classname'}
    else:
        form = AdvSearchForm(0)

    #group by 6 elements
    fllist = []
    cnt = 0
    elemlist = []
    for field in form:
        cnt += 1
        elemlist.append(field)
        if cnt == 6:
            cnt = 0
            fllist.append(elemlist)
            elemlist = []
    if elemlist:
        fllist.append(elemlist)

    context_dict = general_context(request, 'Advanced Search',
                                   'Advanced Search Data')
    context_dict.update({'linecount': str(lcount)})
    context_dict.update({'form': form})
    context_dict.update({'fllist': fllist})
    return render_to_response('advsearch_form.html', context_dict,
                              template.RequestContext(request))

#-------------------------------------------------------------------------------
class BaseSearchForm(forms.Form):
    """General search form"""


    created_on_from = forms.DateTimeField(
                            label="Created date from (YYYY-MM-DD hh:mm:ss)",
                            required=False,
                            widget=widgets.AdminSplitDateTime)
    created_on_to = forms.DateTimeField(
                                label="Created date to (YYYY-MM-DD hh:mm:ss)",
                                required=False,
                                widget=widgets.AdminSplitDateTime)
    data_type_list = [(elem.classname, elem.classname) for elem in
                            class_by_name('ClassDeskTop').objects.all()]
    #TODO: classname not in (['Classes', 'LinkType', 'DeskTop',
    #                            'UserGroupPerm', 'DataGroup'])
    classname = forms.ChoiceField(label="Type of Data", choices=data_type_list,
                                  required=False)
    #TODO: ? form validation: created_on_to should be later created_on_from

#-------------------------------------------------------------------------------
@login_required
#@cache_control(must_revalidate=True, max_age=3600)
#@csrf_protect
def search(request):
    """Simple Search Form and search context rendering"""

    dt_list = []
    mform = ''
    kwargs = {}

    if request.method == 'GET':
        form = BaseSearchForm(request.GET)
        #show data form if 'Details' button was pressed before
        if (len(request.GET) > 7 and request.GET.has_key('classname') and
              request.GET['classname'] and request.GET['classname'] != 'Base'):
            mform = forms.models.modelform_factory(
                                     class_by_name(request.GET['classname']))()

        if form.is_valid():
            if (request.GET.has_key('add-details') and
                                request.GET['add-details'] == u'Details' and
                                form.cleaned_data['classname'] != 'Base'):
                mform = forms.models.modelform_factory(
                               class_by_name(form.cleaned_data['classname']))()

            if (request.GET.has_key('search') and
                    request.GET['search'] == 'Search'):
                #fill search parameters dictionary from base serch form
                for elem in form.cleaned_data.iteritems():
                    if elem[0] == 'created_on_from' and elem[1]:
                        kwargs.update({
                                   'created_on__gte':  elem[1]
                                 })
                    elif elem[0] == 'created_on_to' and elem[1]:
                        kwargs.update({
                                   'created_on__lte':  elem[1]
                                 })
                    elif elem[0] == 'classname' and  elem[1] != 'Base':
                        kwargs.update({
                                   'classname':  elem[1]
                                  })
                if mform:
                    for elem in mform.fields.keys():
                        #class name and form are not appropriate to each other
                        if  not elem in request.GET.keys():
                            messages.add_message(request, messages.WARNING,
                                _(u"To find all available for you %s data "
                                  u"click on 'Search' button."
                                  u"To add search parameters for %s data click"
                                  u" on 'Details' button.") % (
                                            form.cleaned_data['classname'],
                                            form.cleaned_data['classname']))
                            mform = ''
                            kwargs = {}
                            break
                        if request.GET.has_key(elem) and request.GET[elem]:
                            #fill search parameters dictionary from form by type
                            if elem == 'name' or elem == 'description':
                                kwargs.update({elem +
                                        '__icontains': request.GET[elem]})
                            else:
                                kwargs.update({elem: request.GET[elem]})
                if kwargs:
                    model = class_by_name('Base')
                    if kwargs.has_key('classname'):
                        model = class_by_name(kwargs['classname'])
                    baselist = model.objects.filter(**kwargs).exclude(
                                            classname__in=['Classes',
                                                           'DataGroup',
                                                           'UserGroupPerm'])
                    dt_list = datalist_create(request, baselist)
                    if not dt_list:
                        messages.add_message(request, messages.INFO,
                                             _('Result list is empty'))
    else:
        form = BaseSearchForm()

    context_dict = general_context(request, 'Search', 'Search Data')
    context_dict.update({'form': form, 'mform': mform, 'data_list': dt_list})

    return render_to_response('search_form.html', context_dict,
                              template.RequestContext(request))
