from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.db.models import Q
from django.forms.util import ErrorList
from django.http import HttpResponse, Http404, HttpResponseRedirect, \
    HttpResponseForbidden, HttpResponseServerError, HttpResponseBadRequest
from django.shortcuts import render_to_response, get_object_or_404, \
    get_list_or_404
from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.html import escape
from django.utils.translation import ugettext as _, ungettext
from httplib import CONFLICT
from ldt.core.models import Owner
from ldt.text.utils import boolean_convert
from lxml import etree
from lxml.html import fromstring, fragment_fromstring
from ldt.text.models import *
from string import Template
from urllib2 import urlparse
from utils import *
import StringIO
import base64
import cgi
import django.core.urlresolvers
import ldt.auth as ldt_auth
import ldt.utils.path as ldt_utils_path
import logging
import lucene
import tempfile
import uuid


## Filters the annotation depending on the request parameters
## Returns an xml containing the resulting annotations
def filter_annotation(request, uri=None, filter=None, limit=None, creator=None):
    annotlist = None
    query = Q()    
    
    if request.GET.get('uri'):
        query &= Q(uri=request.GET.get('uri'))
    if request.GET.get('creator'):
        query &= Q(creator=request.GET.get('creator'))
    if request.GET.get('filter') and len(request.GET.get('filter')) > 0:
        query &= Q(text__icontains=request.GET.get('filter'))

    annotlist = Annotation.objects.filter(query)
    
    if request.GET.get('limit'):
        nb = request.GET.get('limit')
        #offset = request.GET.get('limit')[1]
        annotlist = annotlist[:nb]

    #create xml
    iri = lxml.etree.Element('iri')
    doc = lxml.etree.ElementTree(iri)
    
    for annot in annotlist:
        textannotation = lxml.etree.SubElement(iri, 'text-annotation')
        id = lxml.etree.SubElement(textannotation,'id')
        id.text = annot.external_id
        uri = lxml.etree.SubElement(textannotation,'uri')
        uri.text = annot.uri
        
        if annot.tags:
            if type(annot.tags) is unicode:
                annot.tags = eval(annot.tags)
            tags = lxml.etree.SubElement(textannotation,'tags')
            ltags = normalize_tags(annot.tags)
            for t in ltags:
                tag = lxml.etree.SubElement(tags, 'tag')
                tag.text = t
            
        content = lxml.etree.SubElement(textannotation,'content')
        color = lxml.etree.SubElement(content,'color')
        color.text = annot.color
        description = lxml.etree.SubElement(content,'description')
        description.text = annot.description
        title = lxml.etree.SubElement(content,'title')
        title.text = annot.title
        text = lxml.etree.SubElement(content,'text')
        text.text = annot.text
        
        meta = lxml.etree.SubElement(textannotation,'meta')
        contributor = lxml.etree.SubElement(meta, "contributor")
        contributor.text = annot.contributor
        creator = lxml.etree.SubElement(meta, "contributor")
        creator.text = annot.creator
        creationdate = lxml.etree.SubElement(meta, "created")
        creationdate.text = str(annot.creation_date)
        updatedate = lxml.etree.SubElement(meta, "modified")
        updatedate.text = str(annot.update_date)
        
    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8")


## Creates an annotation from a urlencoded xml content
## Returns an xml-structured annotation
#@login_required
def create_annotation(request, content):
    cont = base64.urlsafe_b64decode(str(request.POST["content"]))
    doc = lxml.etree.fromstring(cont)
    
    id = unicode(doc.xpath("/iri/text-annotation/id/text()")[0])
    if id is None:
        id = generate_uuid()
        
    uri = unicode(doc.xpath("/iri/text-annotation/uri/text()")[0])
    ltags = []
    for tag in doc.xpath("/iri/text-annotation/tags/tag/text()"):
        ltags.append(unicode(tag))
    tags=normalize_tags(ltags)
    
    title = unicode(doc.xpath("/iri/text-annotation/content/title/text()")[0])
    desc = unicode(doc.xpath("/iri/text-annotation/content/description/text()")[0])
    text = unicode(doc.xpath("/iri/text-annotation/content/text/text()")[0])
    color = unicode(doc.xpath("/iri/text-annotation/content/color/text()")[0])
    
    creator = unicode(doc.xpath("/iri/text-annotation/meta/creator/text()")[0])
    contributor = unicode(doc.xpath("/iri/text-annotation/meta/contributor/text()")[0])
    creation_date = unicode(doc.xpath("/iri/text-annotation/meta/created/text()")[0])
    update_date = unicode(doc.xpath("/iri/text-annotation/meta/modified/text()")[0])
    
    try:
        annotation = Annotation.create_annotation(external_id=id, uri=uri, tags=tags, title=title, description=desc, text=text, color=color, creator=creator, contributor=contributor, creation_date=creation_date, update_date=update_date)
        annotation.save()
        return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8")
        #return doc
    except IntegrityError:
    #except Annotation.IntegrityError:
        #print 'This id is already used! Please choose another one!'
        return HttpResponse(status=409)
    
    
    
## Gets an annotation (from its id)
## Returns the xml-structured annotation
def get_annotation(request, id):
    try:
        annot = Annotation.objects.get(external_id=request.GET.get('id',''))
    except:
    #except Annotation.DoesNotExist:
        raise Http404
    iri = lxml.etree.Element('iri')
    doc = lxml.etree.ElementTree(iri)
    
    textannotation = lxml.etree.SubElement(iri, 'text-annotation')
    id = lxml.etree.SubElement(textannotation,'id')
    id.text = annot.external_id
    uri = lxml.etree.SubElement(textannotation,'uri')
    uri.text = annot.uri
    
    if annot.tags:
        if type(annot.tags) is unicode:
            annot.tags = eval(annot.tags)
        tags = lxml.etree.SubElement(textannotation,'tags')
        ltags = normalize_tags(annot.tags)
        for t in ltags:
            tag = lxml.etree.SubElement(tags, 'tag')
            tag.text = t
    
    content = lxml.etree.SubElement(textannotation,'content')
    color = lxml.etree.SubElement(content,'color')
    color.text = annot.color
    description = lxml.etree.SubElement(content,'description')
    description.text = annot.description
    title = lxml.etree.SubElement(content,'title')
    title.text = annot.title
    text = lxml.etree.SubElement(content,'text')
    text.text = annot.text
    
    meta = lxml.etree.SubElement(textannotation,'meta')
    contributor = lxml.etree.SubElement(meta, "contributor")
    contributor.text = annot.contributor
    creator = lxml.etree.SubElement(meta, "creator")
    creator.text = annot.creator
    creationdate = lxml.etree.SubElement(meta, "created")
    creationdate.text = str(annot.creation_date)
    updatedate = lxml.etree.SubElement(meta, "modified")
    updatedate.text = str(annot.update_date)

    #return doc
    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8")


## Deletes an annotation (from its id)
## Returns an empty xml-structured annotation
#@login_required
def delete_annotation(request, id):
    try:
        annot = Annotation.objects.get(external_id=request.POST["id"])
        annot.delete()
    #except Annotation.DoesNotExist:
    except:
        raise Http404
    
    doc=create_empty_annotation()
    #return doc
    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8")


## Updates the content of an annotation
## Returns the xml-structured updated annotation
#@login_required
def update_annotation(request, content, id):
    try:
        annot = Annotation.objects.get(external_id=request.POST["id"])
    #except Annotation.DoesNotExist:
    except:
        raise Http404
    
    cont = base64.urlsafe_b64decode(str(request.POST["content"]))
    doc = lxml.etree.fromstring(cont)
    
    uri = doc.xpath("/iri/text-annotation/uri/text()")
    if uri != [] and annot.uri != uri[0]:
        annot.uri = unicode(uri[0])
    
    tags = []
    for tag in doc.xpath("/iri/text-annotation/tags/tag"):
        tags.append(unicode(tag.text))
    if annot.tags is not None:
        if type(annot.tags) is unicode:
            annot.tags = eval(annot.tags)
        tags += annot.tags
    tags = normalize_tags(tags)
    annot.tags=tags
    
    title = doc.xpath("/iri/text-annotation/content/title/text()")
    if title != [] and annot.title != title[0]:
        annot.title = unicode(title[0])
    desc = doc.xpath("/iri/text-annotation/content/description/text()")
    if desc != [] and annot.description != desc[0]:
        annot.description = unicode(desc[0])
    text = doc.xpath("/iri/text-annotation/content/text/text()")
    if text != [] and annot.text != text[0]:
        annot.text = unicode(text[0])
    color = doc.xpath("/iri/text-annotation/content/color/text()")
    if color != [] and annot.color != color[0]:
        annot.color = unicode(color[0])
    
    contributor = doc.xpath("/iri/text-annotation/meta/contributor/text()")
    if contributor != [] and annot.contributor != contributor[0]:
        annot.contributor = unicode(contributor[0])
    update_date = doc.xpath("/iri/text-annotation/meta/modified/text()")
    if update_date != [] and annot.update_date != update_date[0]:
        annot.update_date = unicode(update_date[0])

    annot.save()
    
    return get_annotation(id)
    
