#Copyright 2015 Newcastle University
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import json
import traceback
from copy import deepcopy
from operator import itemgetter
import time
import calendar
import re

from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.template.loader import render_to_string
from django.core.urlresolvers import reverse
from django.db.models import Q
from django.db import transaction
from django import http
from django.shortcuts import render,redirect
from django.views import generic

import reversion

from django_tables2.config import RequestConfig

from editor.tables import EditorItemTable
from editor.models import EditorItem
import editor.models
import editor.views.generic
from editor.views.errors import forbidden
from editor.views.user import find_users
from editor.views.version import version_json
from editor.views.timeline import timeline_json
import editor.forms

from numbasobject import NumbasObject
from examparser import ParseError

class ListView(generic.ListView):
    model = EditorItem
    table_class = EditorItemTable

    def make_table(self):
        config = RequestConfig(self.request, paginate={'per_page': 10})
        results = self.table_class(self.object_list)
        config.configure(results)

        return results

    def get_context_data(self, **kwargs):
        context = super(ListView, self).get_context_data(**kwargs)
        context['results'] = self.make_table()

        return context

filter_exam = Q(exam__isnull=False)
filter_question = Q(question__isnull=False)

class SearchView(ListView):
    
    """Search exams."""
    template_name = 'editoritem/search.html'

    def get_queryset(self):

        data = deepcopy(self.request.GET)
        form = self.form = editor.forms.EditorItemSearchForm(data)
        for field in ('usage','item_types'):
            form.data.setdefault(field,form.fields[field].initial)
        form.is_valid()

        items = self.viewable_items = EditorItem.objects.filter(EditorItem.filter_can_be_viewed_by(self.request.user))

        # filter based on query
        query = self.query = form.cleaned_data.get('query')
        self.filter_query = Q()
        if query:
            words = [w for w in re.split(r'\s+',query) if w!='']
            for word in words:
                self.filter_query = self.filter_query & (Q(name__icontains=word) | Q(metadata__icontains=word) )
            print(filter_query)
            items = items.filter(self.filter_query)

        # filter based on item type
        item_types = self.item_types = form.cleaned_data.get('item_types')
        if item_types=='exams':
            items = items.filter(filter_exam)
        elif item_types=='questions':
            items = items.filter(filter_question)

        # filter based on author
        author_term = form.cleaned_data.get('author')
        if author_term:
            authors = find_users(author_term)
            self.filter_authors = Q(author__in=authors)
            items = items.filter(self.filter_authors)
        else:
            self.filter_authors = Q()

        # filter based on subject
        subjects = form.cleaned_data.get('subjects')
        if subjects and len(subjects):
            self.filter_subjects = Q(subjects__in=subjects)
            items = items.filter(self.filter_subjects)
        else:
            self.filter_subjects = Q()

        # filter based on topic
        topics = form.cleaned_data.get('topics')
        if topics and len(topics):
            self.filter_topics = Q(topics__in=topics)
            items = items.filter(self.filter_topics)
        else:
            self.filter_topics = Q()

        # filter based on usage
        usage = form.cleaned_data.get('usage')
        usage_filters = {
            "any": Q(),
            "reuse": Q(licence__can_reuse=True),
            "modify": Q(licence__can_reuse=True, licence__can_modify=True),
            "sell": Q(licence__can_reuse=True, licence__can_sell=True),
            "modify-sell": Q(licence__can_reuse=True, licence__can_modify=True, licence__can_sell=True),
        }
        if usage in usage_filters:
            self.filter_usage = usage_filters[usage]
            items = items.filter(self.filter_usage)
        else:
            self.filter_usage = Q()

        #filter based on status
        status = form.cleaned_data.get('status')
        if status and status!='any':
            self.filter_status = Q(current_stamp__status=status)
            items = items.filter(self.filter_status)
        else:
            self.filter_status = Q()

        items = items.distinct()

        return items

    def get_context_data(self, **kwargs):
        context = super(SearchView,self).get_context_data(**kwargs)
        context['form'] = self.form
        context['item_types'] = self.form.cleaned_data.get('item_types')
        context['search_query'] = self.query
        context['ability_level_field'] = zip(self.form.fields['ability_levels'].queryset,self.form['ability_levels'])

        return context

@@ -1029,16 +1029,24 @@
 import Q
+,Min,Max
 %0Afrom dj
@@ -4948,16 +4948,510 @@
        #
+ filter based on ability level%0A        ability_levels = form.cleaned_data.get('ability_levels')%0A        if ability_levels.exists():%0A            d = ability_levels.aggregate(Min('start'),Max('end'))%0A            start = d%5B'start__min'%5D%0A            end = d%5B'end__max'%5D%0A            self.filter_ability_level = Q(ability_level_start__lt=end,ability_level_end__gt=start)%0A            items = items.filter(self.filter_ability_level)%0A        else:%0A            self.filter_ability_level = Q()%0A%0A        # 
 filter b

add ability level filter to search