from django.shortcuts import render_to_response, render
from troggle.core.models import Expedition, Person, PersonExpedition, PersonTrip, LogbookEntry, SurvexBlock
import troggle.core.models as models
import troggle.settings as settings
import django.db.models
from troggle.parsers.logbooks import LoadLogbookForExpedition
from troggle.parsers.people import GetPersonExpeditionNameLookup
from troggle.core.forms import getTripForm#, get_name, PersonForm
from  django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse
from django.template import Context, loader
import os.path
import troggle.parsers.logbooks as logbookparsers
from django.template.defaultfilters import slugify
from troggle.helper import login_required_if_public
import datetime

from django.views.generic.list import ListView
from django.utils import timezone


# Django uses Context, not RequestContext when you call render
# to_response. We always want to use RequestContext, so that
# django adds the context from settings.TEMPLATE_CONTEXT_PROCESSORS.
# This way we automatically get necessary settings variables passed
# to each template. So we use a custom method, render_response
# instead of render_to_response. Hopefully future Django releases
# will make this unnecessary.
# from troggle.alwaysUseRequestContext import render_response

import re

@django.db.models.permalink #this allows the nice get_absolute_url syntax we are using

def getNotablePersons():
    notablepersons = []
    for person in Person.objects.all():
            if person.bisnotable():
                notablepersons.append(person)
    return notablepersons		


def personindex(request):
    persons = Person.objects.all()
    # From what I can tell, "persons" seems to be the table rows, while "personss" is the table columns. - AC 16 Feb 09
    personss = [ ]
    ncols = 4
    nc = (len(persons) + ncols - 1) / ncols
    for i in range(ncols):
        personss.append(persons[i * nc: (i + 1) * nc])
    
    notablepersons = []
    for person in Person.objects.all():
            if person.bisnotable():
                notablepersons.append(person)

    return render(request,'personindex.html', {'persons': persons, 'personss':personss, 'notablepersons':notablepersons})


def expedition(request, expeditionname):
    this_expedition = Expedition.objects.get(year=int(expeditionname))
    expeditions = Expedition.objects.all()
    personexpeditiondays = [ ]
    dateditems = list(this_expedition.logbookentry_set.all()) + list(this_expedition.survexblock_set.all())
    dates = list(set([item.date for item in dateditems]))
    dates.sort()
    for personexpedition in this_expedition.personexpedition_set.all():
        prow = [ ]
        for date in dates:
            pcell = { "persontrips": PersonTrip.objects.filter(personexpedition=personexpedition, 
                                                                logbook_entry__date=date) }
            pcell["survexblocks"] = set(SurvexBlock.objects.filter(survexpersonrole__personexpedition=personexpedition, 
                                                                    date = date))
            prow.append(pcell)
        personexpeditiondays.append({"personexpedition":personexpedition, "personrow":prow})
        
    if "reload" in request.GET:
        LoadLogbookForExpedition(this_expedition)
    return render(request,'expedition.html', {'expedition': this_expedition, 'expeditions':expeditions, 'personexpeditiondays':personexpeditiondays, 'settings':settings, 'dateditems': dateditems })

def get_absolute_url(self):
    return ('expedition', (expedition.year))

class ExpeditionListView(ListView):

    model = Expedition

    def get_context_data(self, **kwargs):
        context = super(ExpeditionListView, self).get_context_data(**kwargs)
        context['now'] = timezone.now()
        return context


def person(request, first_name='', last_name='', ):
    this_person = Person.objects.get(first_name = first_name, last_name = last_name)
    
    # This is for removing the reference to the user's profile, in case they set it to the wrong person
    if request.method == 'GET':
        if request.GET.get('clear_profile')=='True':
            this_person.user=None
            this_person.save()
            return HttpResponseRedirect(reverse('profiles_select_profile'))
    
    return render(request,'person.html', {'person': this_person, })


def GetPersonChronology(personexpedition):
    res = { }
    for persontrip in personexpedition.persontrip_set.all():
        a = res.setdefault(persontrip.logbook_entry.date, { })
        a.setdefault("persontrips", [ ]).append(persontrip)

    for personrole in personexpedition.survexpersonrole_set.all():
        a = res.setdefault(personrole.survexblock.date, { })
        a.setdefault("personroles", [ ]).append(personrole.survexblock)
    
    # build up the tables
    rdates = res.keys()
    rdates.sort()
    
    
    res2 = [ ]
    for rdate in rdates:
        persontrips = res[rdate].get("persontrips", [])
        personroles = res[rdate].get("personroles", [])
        for n in range(max(len(persontrips), len(personroles))):
            res2.append(((n == 0 and rdate or "--"), (n < len(persontrips) and persontrips[n]), (n < len(personroles) and personroles[n])))
            
    return res2


def personexpedition(request, first_name='',  last_name='', year=''):
    person = Person.objects.get(first_name = first_name, last_name = last_name)
    this_expedition = Expedition.objects.get(year=year)
    personexpedition = person.personexpedition_set.get(expedition=this_expedition)
    personchronology = GetPersonChronology(personexpedition)
    return render(request,'personexpedition.html', {'personexpedition': personexpedition, 'personchronology':personchronology})


def logbookentry(request, date, slug):
    this_logbookentry = LogbookEntry.objects.filter(date=date, slug=slug)

    if len(this_logbookentry)>1:
        return render(request, 'object_list.html',{'object_list':this_logbookentry})
    else:
        this_logbookentry=this_logbookentry[0]
        return render(request, 'logbookentry.html', {'logbookentry': this_logbookentry})


def logbookSearch(request, extra):
    query_string = ''
    found_entries = None
    if ('q' in request.GET) and request.GET['q'].strip():
        query_string = request.GET['q']
    entry_query = search.get_query(query_string, ['text','title',])
    found_entries = LogbookEntry.objects.filter(entry_query)

    return render(request,'logbooksearch.html',
                          { 'query_string': query_string, 'found_entries': found_entries, })
                          #context_instance=RequestContext(request))

def personForm(request,pk):
    person=Person.objects.get(pk=pk)
    form=PersonForm(instance=person)
    return render(request,'personform.html', {'form':form,})

from settings import * 
def pathsreport(request):
    pathsdict={
    "ADMIN_MEDIA_PREFIX" : ADMIN_MEDIA_PREFIX,
    "ADMIN_MEDIA_PREFIX" : ADMIN_MEDIA_PREFIX,
    "CAVEDESCRIPTIONSX" : CAVEDESCRIPTIONS,
    "DIR_ROOT" : DIR_ROOT,
    "ENTRANCEDESCRIPTIONS" : ENTRANCEDESCRIPTIONS,
    "EXPOUSER_EMAIL" : EXPOUSER_EMAIL,
    "EXPOUSERPASS" :"<redacted>",
    "EXPOUSER" : EXPOUSER,
    "EXPOWEB" : EXPOWEB,
    "EXPOWEB_URL" : EXPOWEB_URL,
    "FILES" : FILES,
    "JSLIB_URL" : JSLIB_URL,
    "LOGFILE" : LOGFILE,
    "LOGIN_REDIRECT_URL" : LOGIN_REDIRECT_URL,
    "MEDIA_ADMIN_DIR" : MEDIA_ADMIN_DIR,
    "MEDIA_ROOT" : MEDIA_ROOT,
    "MEDIA_URL" : MEDIA_URL,
    #"PHOTOS_ROOT" : PHOTOS_ROOT,
    "PHOTOS_URL" : PHOTOS_URL,
    "PYTHON_PATH" : PYTHON_PATH,
    "REPOS_ROOT_PATH" : REPOS_ROOT_PATH,
    "ROOT_URLCONF" : ROOT_URLCONF,
    "STATIC_ROOT" : STATIC_ROOT,
    "STATIC_URL" : STATIC_URL,
    "SURVEX_DATA" : SURVEX_DATA,
    "SURVEY_SCANS" : SURVEY_SCANS,
    "SURVEYS" : SURVEYS,
    "SURVEYS_URL" : SURVEYS_URL,
    "SVX_URL" : SVX_URL,
    "TEMPLATE_DIRS" : TEMPLATE_DIRS,
    "THREEDCACHEDIR" : THREEDCACHEDIR,
    "TINY_MCE_MEDIA_ROOT" : TINY_MCE_MEDIA_ROOT,
    "TINY_MCE_MEDIA_URL" : TINY_MCE_MEDIA_URL,
    "TUNNEL_DATA" : TUNNEL_DATA,
    "URL_ROOT" : URL_ROOT
    }
    
    ncodes = len(pathsdict)

    bycodeslist = sorted(pathsdict.iteritems())
    bypathslist = sorted(pathsdict.iteritems(), key=lambda x: x[1])

    return render(request, 'pathsreport.html', { 
        "pathsdict":pathsdict, 
        "bycodeslist":bycodeslist, 
        "bypathslist":bypathslist, 
        "ncodes":ncodes})


    
def experimental(request):
    legsbyexpo = [ ]
    for expedition in Expedition.objects.all():
        survexblocks = expedition.survexblock_set.all()
        survexlegs = [ ]
        survexleglength = 0.0
        for survexblock in survexblocks:
            survexlegs.extend(survexblock.survexleg_set.all())
            survexleglength += survexblock.totalleglength
        legsbyexpo.append((expedition, {"nsurvexlegs":len(survexlegs), "survexleglength":survexleglength}))
    legsbyexpo.reverse()
            
    survexlegs = models.SurvexLeg.objects.all()
    totalsurvexlength = sum([survexleg.tape  for survexleg in survexlegs])
    return render(request, 'experimental.html', { "nsurvexlegs":len(survexlegs), "totalsurvexlength":totalsurvexlength, "legsbyexpo":legsbyexpo })

@login_required_if_public
def newLogbookEntry(request, expeditionyear, pdate = None, pslug = None):
    expedition = Expedition.objects.get(year=expeditionyear)
    PersonTripFormSet, TripForm = getTripForm(expedition)
    if pslug and pdate:
        previousdate = datetime.date(*[int(x) for x in pdate.split("-")])
        previouslbe = LogbookEntry.objects.get(slug = pslug, date = previousdate, expedition = expedition)
        assert previouslbe.filename
    if request.method == 'POST': # If the form has been submitted...
        tripForm = TripForm(request.POST) # A form bound to the POST data
        personTripFormSet = PersonTripFormSet(request.POST)
        if tripForm.is_valid() and personTripFormSet.is_valid(): # All validation rules pass
            dateStr = tripForm.cleaned_data["date"].strftime("%Y-%m-%d")
            directory = os.path.join(settings.EXPOWEB, 
                                    "years", 
                                    expedition.year, 
                                    "autologbook")
            filename = os.path.join(directory, 
                                    dateStr + "." + slugify(tripForm.cleaned_data["title"])[:50] + ".html")
            if not os.path.isdir(directory):
                os.mkdir(directory)
            if pslug and pdate:
                delLogbookEntry(previouslbe)
            f = open(filename, "w")
            template = loader.get_template('dataformat/logbookentry.html')
            context = Context({'trip': tripForm.cleaned_data, 
                               'persons': personTripFormSet.cleaned_data,
                               'date': dateStr,
                               'expeditionyear': expeditionyear})
            f.write(template.render(context))
            f.close()
            print(logbookparsers.parseAutoLogBookEntry(filename))
            return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST
    else:
        if pslug and pdate:
            if previouslbe.cave:
                tripForm = TripForm(initial={"date": previousdate,
                                             "title": previouslbe.title,
                                             "cave": previouslbe.cave.reference(),
                                             "location": None,
                                             "caveOrLocation": "cave",
                                             "html": previouslbe.text})
            else:
                tripForm = TripForm(initial={"date": previousdate,
                                             "title": previouslbe.title,
                                             "cave": None,
                                             "location": previouslbe.place,
                                             "caveOrLocation": "location",
                                             "html": previouslbe.text})
            personTripFormSet = PersonTripFormSet(initial=[{"name": get_name(py.personexpedition), 
                                                            "TU": py.time_underground, 
                                                            "author": py.is_logbook_entry_author}
                                                           for py in previouslbe.persontrip_set.all()])
        else:        
            tripForm = TripForm() # An unbound form
            personTripFormSet = PersonTripFormSet()

    return render(request, 'newlogbookentry.html', {
        'tripForm': tripForm,
        'personTripFormSet': personTripFormSet,

    })

@login_required_if_public
def deleteLogbookEntry(request, expeditionyear, date = None, slug = None):
    expedition = Expedition.objects.get(year=expeditionyear)
    previousdate = datetime.date(*[int(x) for x in date.split("-")])
    previouslbe = LogbookEntry.objects.get(slug = slug, date = previousdate, expedition = expedition)
    delLogbookEntry(previouslbe)
    return HttpResponseRedirect(reverse('expedition', args=[expedition.year])) # Redirect after POST

def delLogbookEntry(lbe):
    for pt in lbe.persontrip_set.all():
        pt.delete()
    lbe.delete()
    os.remove(lbe.filename)

def get_people(request, expeditionslug):
    exp = Expedition.objects.get(year = expeditionslug)
    return render(request,'options.html', {"items": [(pe.slug, pe.name) for pe in exp.personexpedition_set.all()]})

def get_logbook_entries(request, expeditionslug):
    exp = Expedition.objects.get(year = expeditionslug)
    return render(request,'options.html', {"items": [(le.slug, "%s - %s" % (le.date, le.title)) for le in exp.logbookentry_set.all()]})
