"""
"""
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate
from django.contrib.sites.models import Site
from django.conf import settings
from django.template import RequestContext, Context, loader
from django.utils.encoding import force_unicode, smart_str
from django.core import validators
from django import newforms
from pycon.restructuredtext.forms import ReSTField
from pycon.core import safe_utf8_encode
from models import *

INCLUDE_POSTER_FIELDS = ['title','summary','description']

def filter_poster_fields(f):
    if f.name not in INCLUDE_POSTER_FIELDS:
        return None
    if f.name == 'title':
        ff = f.formfield()
        ff.widget.attrs['size'] = u'85'
        return ff
    if f.name == 'summary':
        ff = f.formfield()
        ff.widget.attrs['cols'] = 85
        return ff
    if f.name == 'description':
        return ReSTField(include_error=True, require_title=False,
                         rows=30, cols=85, aclass="monospace")
    return f.formfield()

_PosterForm = newforms.form_for_model(
    Poster, formfield_callback=filter_poster_fields)


class PosterForm(_PosterForm):
    def __init__(self, request, poster=None, post=None, *args, **kwdargs):
        self.poster = poster
        self.user = request.user
        self.request = request
        if post is None and request.POST:
            post = request.POST
        initial = {}
        if poster is not None:
            initial.update(vars(poster))
        if 'initial' in kwdargs:
            initial.update(kwdargs['initial'])
        kwdargs['initial'] = initial
        super(PosterForm, self).__init__(post, *args, **kwdargs)
    def clean_title(self):
        value = self.cleaned_data['title']
        if self.poster is not None:
            if value == self.poster.title: return value
        try: Poster.objects.get(title__exact=value)
        except Poster.DoesNotExist: return value
        raise newforms.ValidationError('There is already a ' +
            Poster._meta.verbose_name + ' with a title of "' + value +'".')
    def save(self):
        if self.poster is not None:
            res = newforms.save_instance(self, self.poster,
                                         fail_message='edit')
            return res
        ## new poster
        poster = super(PosterForm, self).save(commit=False)
        poster.author = self.user
        poster.save()

        emails = []
        t = loader.get_template("poster/email/submit_poster.txt")
        c = {
            'mailto': poster.author,
            'email': poster.author.email,
            'poster': poster
        }
        message = t.render(RequestContext(self.request, c))
        emails.append({
            'subject': settings.CONFERENCE_NAME + ' Poster Submission',
            'body': message,
            'from_email': settings.POSTER_FROM_EMAIL,
            'replyto_email': settings.POSTER_REPLYTO_EMAIL,
            'to': [poster.author.email]})
        t = loader.get_template("poster/email/review_poster.txt")
        managers = Group.objects.get(name='PosterManagers').user_set.all()
        for manager in managers:
            c = {
                'mailto': manager,
                'email': manager.email,
                'poster': poster
            }
            message = t.render(RequestContext(self.request, c))
            emails.append({
                'subject': settings.CONFERENCE_NAME +
                           ' New Poster Submission',
                'body': message,
                'from_email': settings.POSTER_FROM_EMAIL,
                'replyto_email': settings.POSTER_REPLYTO_EMAIL,
                'to': [manager.email,]})
        from pycon.core import mail
        #print emails # because dev does not have sendmail enabled.
        mail.send_mass_mail(emails)
        return poster


INCLUDE_ATTACHMENT_FIELDS = ['file', 'comment']

def filter_attachment_fields(f):
    if f.name not in INCLUDE_ATTACHMENT_FIELDS:
        return None
    return f.formfield()

_AttachmentForm = newforms.form_for_model(
    AttachedFile, formfield_callback=filter_attachment_fields)

class AttachmentForm(_AttachmentForm):
    def __init__(self, poster, request):
        self.poster = poster
        self.request = request
        self.user = request.user
        post = None
        if request.POST:
            post = request.POST
        files = None
        if request.FILES:
            files = request.FILES
        super(AttachmentForm, self).__init__(post, files=files)
    def save(self):
        attachment = super(AttachmentForm, self).save(commit=False)
        attachment.poster = self.poster
        attachment.submitter = self.user
        attachment.save()

        emails = []
        t = loader.get_template("poster/email/attachment.txt")

        sendto = [self.poster.author,]
        managers = Group.objects.get(name='PosterManagers').user_set.all()
        sendto.extend(managers)

        for user in sendto:
            c = {
                'mailto': user,
                'email': user.email,
                'attachment': attachment,
                'poster': attachment.poster
            }
            message = t.render(RequestContext(self.request, c))
            subject = settings.CONFERENCE_NAME
            subject += ' New Poster Attachment ('
            subject += smart_str(attachment.poster)
            subject += ')'
            emails.append({
                'subject': subject,
                'body': message,
                'from_email': settings.POSTER_FROM_EMAIL,
                'replyto_email': settings.POSTER_REPLYTO_EMAIL,
                'to': [user.email]})
        from pycon.core import mail
        mail.send_mass_mail(emails)
        return attachment


INCLUDE_COMMENT_FIELDS = ['comment',]

def filter_comment_fields(f):
    if f.name not in INCLUDE_COMMENT_FIELDS:
        return None
    if f.name == 'comment':
        return ReSTField(include_error=True, require_title=False,
                         rows=30, cols=85, aclass="monospace")
    return f.formfield()

_CommentForm = newforms.form_for_model(
    Comment, formfield_callback=filter_comment_fields)

class CommentForm(_CommentForm):
    def __init__(self, poster, request):
        self.poster = poster
        self.request = request
        self.user = request.user
        post = None
        if request.POST:
            post = request.POST
        super(CommentForm, self).__init__(post)
    def save(self):
        comment = super(CommentForm, self).save(commit=False)
        comment.poster = self.poster
        comment.commenter = self.user
        comment.save()

        emails = []
        t = loader.get_template("poster/email/comment.txt")

        sendto = [self.poster.author,]
        managers = Group.objects.get(name='PosterManagers').user_set.all()
        sendto.extend(managers)

        for user in sendto:
            c = {
                'mailto': user,
                'email': user.email,
                'comment': comment,
                'poster': comment.poster
            }
            message = t.render(RequestContext(self.request, c))
            subject = settings.CONFERENCE_NAME
            subject += ' New Poster Comment ('
            subject += smart_str(comment.poster)
            subject += ')'
            emails.append({
                'subject': subject,
                'body': message,
                'from_email': settings.POSTER_FROM_EMAIL,
                'replyto_email': settings.POSTER_REPLYTO_EMAIL,
                'to': [user.email,]})
        from pycon.core import mail
        mail.send_mass_mail(emails)
        return comment


class StatusForm(newforms.Form):
    status = newforms.ChoiceField(required=True, choices=POSTER_STATUS_CHOICES)
    def __init__(self, poster, post=None):
        self.poster = poster
        super(StatusForm, self).__init__(post, initial={'status': poster.status},
                                         prefix=u'%d'%poster.id)
    def save(self):
        new_status = self['status'].data
        if new_status == self.poster.status:
            return 0
        self.poster.status = new_status
        self.poster.save()
        return 1
    def __unicode__(self):
        return unicode(self['status'])
