from django.shortcuts import render_to_response
from django import http
from django import newforms as forms
from django.template import RequestContext, Context, loader
from django.core import validators
from django.conf import settings
from ghestalt.app.utils import bad_or_missing
from ghestalt.app.models import UserProfile
from ghestalt.i18n.utils import i18n_site_base
from django.contrib.auth import logout, login, authenticate
from django.contrib.auth.models import User
from django.core.mail import send_mail
from django.contrib.auth.decorators import login_required
from django.utils import translation
N_ = lambda x: x

class AccountForm(forms.Form):
    email = forms.EmailField(label=_('E-mail address'))
    password = forms.CharField(label=_('Password'),widget=forms.PasswordInput)
    password2 = forms.CharField(label=_('Password (again)'),widget=forms.PasswordInput)
    first_name = forms.CharField(label=_('First name'),max_length=30)
    last_name = forms.CharField(label=_('Last name'),max_length=30)
    user_name = forms.CharField(label=_('Account username'),max_length=30)
    location = forms.CharField(label=_('Location'),max_length=30, required=False)
    otro_lang = forms.ChoiceField(label=_('Language'),choices=settings.LANGUAGES, required=False)
    otro_first_name = forms.CharField(label=_('First name in language'),max_length=30, required=False)
    otro_last_name = forms.CharField(label=_('Last name in language'),max_length=30, required=False)
    def clean_email(self):
        if User.objects.filter(email=self.clean_data.get('email')).count() > 0:
            raise forms.ValidationError(u'That email address already exists.')
        return self.clean_data.get('email')
    def clean_location(self):
        raw = self.clean_data.get('location')
        if raw=='':
            return raw
        raw2 = map(unicode.upper,map(unicode.strip,raw.split(',')))
        if len(raw2) != 2:
            raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
        if raw2[0][-1] in 'NS':
            if raw2[0][0]=='-':
                raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
            if raw2[0][-1]=='S':
                raw2[0] = '-'+raw2[0][:-1]
            if raw2[0][-1]=='N':
                raw2[0] = raw2[0][:-1]
        if raw2[1][-1] in 'EW':
            if raw2[1][0]=='-':
                raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
            if raw2[1][-1]=='W':
                raw2[1] = '-'+raw2[1][:-1]
            if raw2[1][-1]=='E':
                raw2[1] = raw2[1][:-1]
        try:
            long,lat = (float(raw2[0]),float(raw2[1]))
        except ValueError:
            raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
        return '%f,%f' % (long,lat)
    def clean_user_name(self):
        if User.objects.filter(username=self.clean_data.get('user_name')).count() > 0:
            raise forms.ValidationError(u'That username already exists.')
        return self.clean_data.get('user_name')
    def clean(self):
        if self.clean_data.get('password') and self.clean_data.get('password2') and self.clean_data['password'] != self.clean_data['password2']:
            raise forms.ValidationError(u'Please make sure your passwords match.')
        return self.clean_data
    
def create(request):
    if request.POST:
        form = AccountForm(request.POST)
        if form.is_valid():
            user_name = form.clean_data.get('user_name')
            password = form.clean_data.get('password')
            email = form.clean_data.get('email')
            first_name = form.clean_data.get('first_name')
            last_name = form.clean_data.get('last_name')
            location = form.clean_data.get('location')
            otro_lang = form.clean_data.get('otro_lang')
            otro_first_name = form.clean_data.get('otro_first_name')
            otro_last_name = form.clean_data.get('otro_last_name')
            u = User.objects.create_user(user_name, email, password)
            u.first_name = first_name
            u.last_name = last_name
            u.save()
            userprofile = UserProfile(first_name=first_name, last_name=last_name, email=email, role="User", user=u, location=location,otro_lang=otro_lang, otro_last_name=otro_last_name, otro_first_name=otro_first_name)
            userprofile.save()
            t = loader.get_template('email/welcome.txt')
            c = Context({
                'first_name': form.clean_data.get('first_name'),
                'last_name' : form.clean_data.get('last_name'),  
                'user_name': form.clean_data.get('user_name') })
            site_email = settings.SITE_EMAIL
            subject = _("Welcome to %s" % (settings.SITE_NAME))
            site_base = i18n_site_base(request)
            c['login_url'] = "%s%s/accounts/login" % (settings.SITE_DOMAIN, site_base)
            user = authenticate(username=form.clean_data.get('user_name'), password=form.clean_data.get('password'))
            login(request, user)
            userprofile = UserProfile.objects.get(user=user.id)
            request.session['userID'] = userprofile.id
            if userprofile.otro_lang != settings.LANGUAGE_CODE[:2]:
                request.session['otro_lang'] = userprofile.otro_lang
                try:
                    if request.session['other_lang']: pass
                except KeyError:
                    request.session['other_lang'] = userprofile.otro_lang
            if settings.ENABLE_MAIL:
                try:
                    send_mail(subject, t.render(c), site_email,
                             [email], fail_silently=False)
                except:
                    return bad_or_missing(request,'Problems sending mail.')
            return http.HttpResponseRedirect('%s/accounts/thankyou' % (site_base))
    else:
        form = AccountForm()
    return render_to_response('account_create_form.html', {'form': form},
                                RequestContext(request))
##
class EditAccountForm(forms.Form):
    first_name = forms.CharField(label=N_('First name'),max_length=30,translate=True)
    last_name = forms.CharField(label=N_('Last name'),max_length=30,translate=True)
    location = forms.CharField(label=N_('Location'),max_length=30,required=False,translate=True)
    otro_lang = forms.ChoiceField(label=N_('Language'),choices=settings.LANGUAGES,required=False,translate=True)
    otro_first_name = forms.CharField(label=N_('First name in language'),max_length=30,required=False,translate=True)
    otro_last_name = forms.CharField(label=N_('Last name in language'),max_length=30,required=False,translate=True)
    def clean_location(self):
        raw = self.clean_data.get('location')
        if raw=='':
            return raw
        raw2 = map(unicode.upper,map(unicode.strip,raw.split(',')))
        if len(raw2) != 2:
            raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
        if raw2[0][-1] in 'NS':
            if raw2[0][0]=='-':
                raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
            if raw2[0][-1]=='S':
                raw2[0] = '-'+raw2[0][:-1]
            if raw2[0][-1]=='N':
                raw2[0] = raw2[0][:-1]
        if raw2[1][-1] in 'EW':
            if raw2[1][0]=='-':
                raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
            if raw2[1][-1]=='W':
                raw2[1] = '-'+raw2[1][:-1]
            if raw2[1][-1]=='E':
                raw2[1] = raw2[1][:-1]
        try:
            long,lat = (float(raw2[0]),float(raw2[1]))
        except ValueError:
            raise forms.ValidationError(_(u'Cannot parse location. Format is lat,long.'))
        return '%f,%f' % (long,lat)
    def clean(self):
        return self.clean_data
    
def edit(request):
    if request.POST:
        form = EditAccountForm(request.POST)
        if form.is_valid():
            first_name = form.clean_data.get('first_name')
            last_name = form.clean_data.get('last_name')
            otro_lang = form.clean_data.get('otro_lang')
            otro_first_name = form.clean_data.get('otro_first_name')
            otro_last_name = form.clean_data.get('otro_last_name')
            location = form.clean_data.get('location')
            u = User.objects.get(id=request.user.id)
            userprofile = UserProfile.objects.get(user=u.id)
            u.first_name = first_name
            u.last_name = last_name
            u.save()
            userprofile.first_name=first_name
            userprofile.last_name=last_name
            userprofile.role="User"
            userprofile.user=u
            userprofile.location=location
            userprofile.otro_lang=otro_lang
            userprofile.otro_last_name=otro_last_name
            userprofile.otro_first_name=otro_first_name
            userprofile.save()
            if userprofile.otro_lang != settings.LANGUAGE_CODE[:2]:
                request.session['otro_lang'] = userprofile.otro_lang
                try:
                    if request.session['other_lang']: pass
                except KeyError:
                    request.session['other_lang'] = userprofile.otro_lang
            site_base = i18n_site_base(request)
            return http.HttpResponseRedirect('%s/accounts/info/' % (site_base))
    else:
        userprofile = UserProfile.objects.get(user=request.user.id)
        user = User.objects.get(id=request.user.id)
        d = userprofile.__dict__
        d.update(user.__dict__)
        form = EditAccountForm(d)
    return render_to_response('account_edit_form.html', {'form': form},
                                RequestContext(request))
edit = login_required(edit)

def info(request):
    try:
        user_data = UserProfile.objects.get(user=request.user.id)
    except:
        #This case happens if a user is created in admin but does not have account info
        return bad_or_missing(request, 'The person you are logged in as, does not have an account.  Please create one.')
    return render_to_response('account.html', {'user_data': user_data},
                              RequestContext(request))
info = login_required(info)

def site_logout(request):
    logout(request)
    site_base = i18n_site_base(request)
    return http.HttpResponseRedirect('%s/' % (site_base))
