from django.db import models
from django.utils.translation import ugettext_lazy as _
from taggit.managers import TaggableManager
from utils import generate_uuid
import lxml.etree
#from django.core.management.validation import max_length

def Property(func):
    return property(**func()) 


class Annotation(models.Model):
    external_id = models.CharField(max_length=255, null=False, unique=True, default=generate_uuid, verbose_name=_('annotation.external_id'))
    uri = models.CharField(max_length=1024, verbose_name=_('annotation.uri'))
    tags_field = TaggableManager()
    title = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('annotation.title'))
    description = models.TextField(null=True, blank=True, verbose_name=_('annotation.description'))
    text = models.TextField(null=True, blank=True, verbose_name=_('annotation.text'))
    color = models.CharField(max_length=1024, verbose_name=_('annotation.color'))
    creator = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('creator.title'))
    contributor = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('contributor.title'))
    creation_date = models.DateTimeField(auto_now_add=True, verbose_name=_('annotation.creation_date'))
    update_date = models.DateTimeField(auto_now=True, verbose_name=_('annotation.update_date'))
    
    class Meta:
        app_label="text"
    
    @Property
    def tags(): #@NoSelf
        
        def fget(self):
            return ",".join(self.tag_list)
        
        def fset(self, value):
            values = None
            if isinstance(value, (list, tuple)):
                values = list(value)
            elif value is not None:
                values = [v.lower().strip() for v in unicode(value).split(",")]
            
            if values is not None:
                self.tags_field = ",".join(values) + ","
            else:
                self.tags_field = None

        return locals()
    
    @Property
    def tag_list(): #@NoSelf
        def fget(self):
            #return [t.name for t in Tag.objects.get_for_object(self)]
            return self.tags_field.names()
        
        return locals()
        
    
    def get_tag_list(self): 
        return self.tags_field.names()


    def __unicode__(self):
        return unicode(self.external_id) + u": " + unicode(self.title)

    def serialize(self, root_element=None):
        
        if root_element is not None:
            iri = root_element
        else :
            iri = lxml.etree.Element('iri')
            doc = lxml.etree.ElementTree(iri)
        
        
        textannotation = lxml.etree.SubElement(iri, 'text-annotation')
        id_node = lxml.etree.SubElement(textannotation, 'id')
        id_node.text = self.external_id
        uri = lxml.etree.SubElement(textannotation, 'uri')
        uri.text = self.uri
        
        if self.tags:
            tags = lxml.etree.SubElement(textannotation, 'tags')
            for t in self.get_tag_list():
                tag = lxml.etree.SubElement(tags, 'tag')
                tag.text = t
        
        content = lxml.etree.SubElement(textannotation, 'content')
        color = lxml.etree.SubElement(content, 'color')
        color.text = self.color
        description = lxml.etree.SubElement(content, 'description')
        description.text = self.description
        title = lxml.etree.SubElement(content, 'title')
        title.text = self.title
        text = lxml.etree.SubElement(content, 'text')
        text.text = self.text
        
        meta = lxml.etree.SubElement(textannotation, 'meta')
        contributor = lxml.etree.SubElement(meta, "contributor")
        contributor.text = self.contributor
        creator = lxml.etree.SubElement(meta, "creator")
        creator.text = self.creator
        creationdate = lxml.etree.SubElement(meta, "created")
        creationdate.text = str(self.creation_date)
        updatedate = lxml.etree.SubElement(meta, "modified")
        updatedate.text = str(self.update_date)

        if root_element is not None:
            return root_element
        else:        
            return doc


    @staticmethod
    def create_annotation(external_id, uri=None, tags=None, title=None, description=None, text=None, color=None, creator=None, contributor=None, creation_date=None, update_date=None):
        annotation = Annotation(external_id=external_id, uri=uri, tags=tags, title=title, description=description, text=text, color=color, creator=creator, contributor=contributor, creation_date=creation_date, update_date=update_date)
        annotation.save()
        
        return annotation

        
        
