import os, posixpath

from django.db import models
from django import forms
from django.core import validators

from rlextra.utils import pdf2jpeg
from rldjango.common.validators import isValidPdfFile, formatFileSize

# Monkeypatch to tell Django which SQL datatype to use.  If we ever use a
# different DBMS, we'll have to do this for the relevant backend!
from django.db.backends.mysql import creation
creation.DATA_TYPES['PdfField'] = 'varchar(100)'


class PdfUploadField(forms.FileUploadField):
    "A FileUploadField that raises CriticalValidationError if the uploaded file doesn't go through PageCatcher."

    def __init__(self, *args, **kwargs):
        forms.FileUploadField.__init__(self, *args, **kwargs)
        self.validator_list.insert(0, self.validate)

    def validate(self, field_data, all_data):
        try:
            isValidPdfFile(field_data, all_data)
        except validators.ValidationError, e:
            raise validators.CriticalValidationError, e.messages


class PdfThumbnailsField(forms.HiddenField):

    def render(self, data):
        from django.utils.html import escape
        from django.conf import settings
        parts = []
        parts.append(forms.HiddenField.render(self, data))
        pdfFilename = os.path.join(settings.MEDIA_ROOT, data)
        st = os.stat(pdfFilename)
        parts.append('<p class="help">%s</p>' % formatFileSize(st.st_size))
        if data:
            try:
                srcs = getPdfThumbnailUrls(pdfFilename)
            except ValueError:
                parts.append('<p class="help">Could not create thumbnail image for this PDF file.</p>'
                             '<!--%s-->' % exc)
            else:
                LIMIT = 4
                if len(srcs) > LIMIT:
                    parts.append('<p class="help">(only showing first %d pages)</p>' % LIMIT)
                for (i, src) in enumerate(srcs[:LIMIT]):
                    parts.append('<img style="border: 1px solid" src="%s" alt="thumbnail page %d"/>' % (escape(src), i+1))
                
        return '\n'.join(parts)


class PdfField(models.FileField):

    def get_manipulator_field_objs(self):
        return [PdfUploadField, PdfThumbnailsField]


def getPdfThumbnailUrls(filename):
    """Raises ValueError if ghostscript fails to generate all the thumbnails."""
    from django.conf import settings
    # these filenames are not unique, but I guess it doesn't matter until we start caching these thumbnails
    jpegs = pdf2jpeg.pdf2jpeg(filename, scale=0.2, outDir=settings.OUTDIR)
    return [posixpath.join(settings.OUTDIR_HTTP, os.path.basename(jpeg)) for jpeg in jpegs]
