from daisyproducer.documents.external import DaisyPipeline
from daisyproducer.documents.models import Document, Version, Attachment
from daisyproducer.documents.versionHelper import XMLContent
from django import forms
from django.db import models
from django.core.files.base import ContentFile
from django.forms import ModelForm
from django.forms.util import ErrorList
from django.utils.translation import ugettext_lazy as _

class PartialVersionForm(ModelForm):

    def getcontentMetaData(self):
        return self._contentMetaData

    def setcontentMetaData(self, value):
        self._contentMetaData = value

    contentMetaData = property(getcontentMetaData, setcontentMetaData)

    def clean_content(self):
        data = self.files['content']
        # make sure the content has mime type of 'text/xml'
        if data.content_type != 'text/xml':
            raise forms.ValidationError(
                "The mime type of the uploaded file must be 'text/xml'")
        # FIXME: test the mime-type with python-magic
        # make sure the uploaded version is valid xml
        exitMessage = DaisyPipeline.validate(data.temporary_file_path())
        if exitMessage:
            raise forms.ValidationError(
                "The uploaded file is not a valid DTBook XML document: %s" % 
                ' '.join(exitMessage))            
        # make sure the meta data of the uploaded version corresponds
        # to the meta data in the document
        xmlContent = XMLContent()
        errorList = xmlContent.validateContentMetaData(
            data.temporary_file_path(), **self.contentMetaData)
        if errorList:
            raise forms.ValidationError(
                # FIXME: find a way to sanely display all error
                # messages from the errorList, not just the first one
                "The meta data '%s' in the uploaded file does not correspond to the value in the document: '%s' instead of '%s'" % errorList[0])
            
        return data

    class Meta:
        model = Version
        fields = ('comment', 'content',)

class PartialAttachmentForm(ModelForm):

    @property
    def content_type(self):
        return self.files['content'].content_type

    # make sure the content has mime type as defined in the Attachment class
    def clean_content(self):
        data = self.files['content']
        choices = tuple([choice[0] for choice in Attachment.MIME_TYPE_CHOICES])
        if data.content_type not in choices:
            raise forms.ValidationError(
                "The mime type of the uploaded file must be in %s" % 
                ', '.join(choices))
        return data

    class Meta:
        model = Attachment
        fields = ('comment', 'content',)


class PartialDocumentForm(ModelForm):

    def limitChoicesToValidStates(self, document):
        nextValidStateChoices = [(state.id, state.name) for state in document.state.next_states.all()]
        self.fields['state'].choices = nextValidStateChoices

    class Meta:
        model = Document
        fields = ('state',)
    
class OCRForm(forms.Form):
    data = forms.FileField(
        label = _("Data from scan"), 
        help_text = _("The image files that resulted from the scan"))


class MarkupForm(forms.Form):
    data = forms.CharField(
        widget=forms.Textarea(
            attrs={
                'class' : "wiki-edit",
                'cols' : "60",
                'rows' : "24"}))
    comment = forms.CharField(
        widget=forms.TextInput(attrs={'size':'60'}))

    def save(self, document):
        # create a new version with the new content
        contentString = self.cleaned_data['data']
        content = ContentFile(contentString.encode("utf-8"))
        version = Version.objects.create(
            comment = self.cleaned_data['comment'],
            document = document)
        version.content.save("updated_version.xml", content)


class SBSFormForm(forms.Form):
    BRAILLE_CONTRACTION_GRADE_CHOICES = (
        ('0', _('Grade 0')),
        ('1', _('Grade 1')),
        ('2', _('Grade 2')),
        )
    contraction = forms.TypedChoiceField(BRAILLE_CONTRACTION_GRADE_CHOICES, 
        label=_("Contraction"), coerce=int)

@@ -4074,120 +4074,848 @@
    c
-ontraction = forms.TypedChoiceField(BRAILLE_CONTRACTION_GRADE_CHOICES, %0A        label=_(%22Contraction%22), coerce=int)
+ells_per_line = forms.IntegerField(label=_(%22Cells per Line%22), initial=40, min_value=1, max_value=255)%0A    lines_per_page = forms.IntegerField(label=_(%22Lines per Page%22), initial=28, min_value=1, max_value=255)%0A    contraction = forms.TypedChoiceField(%0A        label=_(%22Contraction%22), %0A        choices=BRAILLE_CONTRACTION_GRADE_CHOICES, %0A        coerce=int)%0A    hyphenation = forms.BooleanField(label=_(%22Hyphenation%22), required=False)%0A    generate_toc = forms.BooleanField(label=_(%22Generate a table of contents%22), required=False)%0A    show_original_page_numbers = forms.BooleanField(label=_(%22Show original page numbers%22), required=False)%0A    enable_capitalization = forms.BooleanField(label=_(%22Enable Capitalization%22), required=False)%0A    detailed_accented_characters = forms.BooleanField(label=_(%22Detailed Accented Characters%22), required=False)%0A
 %0A

Add attributes to sbsform form analogous to liblouis