from django.contrib.auth.models import User, Group
from django import forms as forms
from django.db import models

from mail.models import Domain, Account, Address
from mail.fields import LocalPartEmailField, SeparatedValuesField

class MokelBaseForm(forms.ModelForm):
    def __init__(self, groups=None, *args, **kwargs):
        super(MokelBaseForm, self).__init__(*args, **kwargs)
        self.groups = groups


class DomainForm(MokelBaseForm):
    class Meta:
        model = Domain
        fields = ('enabled')

class AccountForm(MokelBaseForm):
    class Meta:
        model = Account
        exclude = ('password', 'created_date', 'changed')

    def __init__(self, *args, **kwargs):
        super(AccountForm, self).__init__(*args, **kwargs)
        # limit admingroups only to those the user is in herself
        self.fields['admins'].queryset = \
                self.groups

    def clean(self):
        """
        validates the AccountForm

        a bit of a special case here:
         * if we have an instance but it doesn't have a primary key
           * we check wether or not there is an object in the DB with the same
             name
           * if not, all is fine, business as usual
           * if yes, we tried to create an Account with a name that is already
             in use and bail out

        this is my first endeviour into metaprogramming so forgive the pun
        """
        if isinstance(self.instance, Account):
            if self.instance.pk is None:
                try: 
                    Account.objects.get(name=self.cleaned_data['name'])
                    raise forms.ValidationError('choose another name please')
                except Account.DoesNotExist:
                    pass
        return super(AccountForm, self).clean()

class AddressForm(MokelBaseForm):
    class Meta:
        model = Address
        fields = ('address', 'enabled', 'recipients', 'account')

    def __init__(self, *args, **kwargs):
        super(AddressForm, self).__init__(*args, **kwargs)

        # limit the possible accounts to only those accounts the current user
        # has read/write access to. This also does validation correctly :)

        self.fields['account'].queryset = \
                Account.objects.filter(admins__in=self.groups)

    address = LocalPartEmailField()
    recipients = SeparatedValuesField(forms.EmailField, strip=True)
    recipients.widget = forms.Textarea()
    recipients.required = False

class DeleteForm(forms.Form):
    confirm = forms.BooleanField(required=True)
    def clean_confirm(self):
        if not self.cleaned_data['confirm']:
            raise forms.ValidationError('To delete, please check')

class RequestNewDomainForm(forms.Form):
    name = forms.CharField(required=True, max_length=255,
            label="Request new domain")

#class RequestMap(forms.Form):
#    servername = forms.CharField(required=True, max_length=255, 
#            label="Name of requesting Server")
#    public_key = forms.Textarea(required=True)

