from os.path import join
from django import forms, template
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.core.context_processors import csrf
from django.shortcuts import get_object_or_404, render_to_response
from django.forms.formsets import all_valid
from django.utils.safestring import mark_safe
from django.contrib.admin import helpers
from django.template import Context, loader
from django.db import models, transaction
from models import Image, Tag, Size
from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode


from forms import ImageForm, ImageUploadForm

from StringIO import StringIO

class ImageAdmin(admin.ModelAdmin):
    search_fields = ('description','size__id')
    list_display = ('id','description', 'tag_text', 'get_size_description', 'get_thumbnail_tag',)
    list_filter = ('size','tags')
    
    def save_model(self, request, obj, form, change):
        obj.save()

    def add_view(self, request, form_url='', extra_context=None):
        "The 'add' admin view for this model."
        model = self.model
        opts = model._meta

        if not self.has_add_permission(request):
            raise PermissionDenied

        ModelForm = self.get_form(request)
        formsets = []
        if request.method == 'POST':
            data = request.POST.copy()
            if request.FILES.has_key('image'):
                try:
                    imgbytes = request.FILES['image'].read()
                    info = Image.newtmp(StringIO(imgbytes))
                except (KeyError, ValueError), e:
                    context = {
                        'title': _('Add %s') % force_unicode(opts.verbose_name),
                        'is_popup': request.REQUEST.has_key('_popup'),
                        'show_delete': False,
                        'media': mark_safe(self.media),
                        'errors': [str(e)],
                        #'root_path': self.admin_site.root_path,
                        'app_label': opts.app_label,
                    }
                    context.update(csrf(request))
                    return self.render_upload_form(request, context)
                else:
                    if len(info['possible_sizes']) == 1:
                        data['size'] = info['possible_sizes'][0]
                    data.update(info)
            try:
                form = ImageForm(data)
            except AssertionError, e:
                context = {
                    'title': _('Add %s') % force_unicode(opts.verbose_name),
                    'is_popup': request.REQUEST.has_key('_popup'),
                    'show_delete': False,
                    'media': mark_safe(self.media),
                    'errors': [str(e)],
                    #'root_path': self.admin_site.root_path,
                    'app_label': opts.app_label,
                }
                context.update(csrf(request))
                return self.render_upload_form(request, context)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=False)
            else:
                form_validated = False
                new_object = self.model()
            for FormSet in self.get_formsets(request):
                formset = FormSet(data=request.POST, files=request.FILES,
                                  instance=new_object,
                                  save_as_new=request.POST.has_key("_saveasnew"))
                formsets.append(formset)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, change=False)
                form.save_m2m()
                for formset in formsets:
                    self.save_formset(request, form, formset, change=False)
                
                self.log_addition(request, new_object)
                return self.response_add(request, new_object)
        else:
            context = {
                'title': _('Add %s') % force_unicode(opts.verbose_name),
                'is_popup': request.REQUEST.has_key('_popup'),
                'show_delete': False,
                'media': mark_safe(self.media),
                'errors': [],
                #'root_path': self.admin_site.root_path,
                'app_label': opts.app_label,
            }
            context.update(csrf(request))
            return self.render_upload_form(request, context)

        adminForm = helpers.AdminForm(form, [(None, {'fields': form.base_fields.keys()})], self.prepopulated_fields)
        media = self.media + adminForm.media

        inline_admin_formsets = []
        inline_instances = self.get_inline_instances(request)
        for inline, formset in zip(inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media

        context = {
            'title': _('Add %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'is_popup': request.REQUEST.has_key('_popup'),
            'show_delete': False,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            #'root_path': self.admin_site.root_path,
            'app_label': opts.app_label,
        }   
        context.update(extra_context or {})
        return self.render_change_form(request, context, add=True)
    add_view = transaction.commit_on_success(add_view)

    def render_upload_form(self, request, context, form_url='', obj=None):
        '''Most of the following is copied from the admin.'''
        opts = self.model._meta
        app_label = opts.app_label
        ordered_objects = opts.get_ordered_objects()
        context.update({
            'add': True,
            'has_add_permission': self.has_add_permission(request),
            'has_change_permission': self.has_change_permission(request, obj),
            'has_delete_permission': self.has_delete_permission(request, obj),
            'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
            'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
            'ordered_objects': ordered_objects,
            'form_url': mark_safe(form_url),
            'opts': opts,
            'content_type_id': ContentType.objects.get_for_model(self.model).id,
            'save_as': self.save_as,
            'save_on_top': self.save_on_top,
            #'root_path': self.admin_site.root_path,
            'form': ImageUploadForm(),
        })
        return render_to_response('imadj/admin_upload.html', context, context_instance=template.RequestContext(request))
    

class SizeAdmin(admin.ModelAdmin):
    list_display = ('id','width','height', 'format')
    list_filter = ('format',)
    

class TagAdmin(admin.ModelAdmin):
    search_fields = ('id','description')
    list_display = ('id', 'description',)

admin.site.register(Image, ImageAdmin)
admin.site.register(Size, SizeAdmin)
admin.site.register(Tag, TagAdmin)
