# -*- coding: utf-8 -*-

from django import forms
from django.forms.models import formset_factory
from django.utils.translation import ugettext as _

from models import Word, Tag, Form
from django.db.models import Q, Count

from courses.models import UserGrade

from django.http import Http404
	
# # #
# #
# # Some global choices
# #
# # # 

# from xml_settings import *

# # #
# #
# # Settings form classes
# #
# # # 

class GameSettings(forms.Form):
	""" Provides some generalized methods to MorfaSettings and LeksaSettings.

		General idea is that the game will call one of the following:
				MorfaS, MorfaV, MorfaAdj, MorfaNum
				LeksaSettings

		MorfaSettings is broken up into subclasses in order to keep things
		easier to debug.

		MorfaSettings has several methods, but no form fields. Form fields
		are on the subforms.

		GameSettings.__init__()
			GameSettings.set_defaults()
				MorfaSettings
					MorfaS
						makeQuery
					getInitialData
		
		Returns initial data to the views, which produce a formset of 5
		Question classes. Question classes are populated by the formset
		using data from MorfaSettings.getInitialData.
	"""
	question_count = 5

	def __init__(self, *args, **kwargs):
		if 'preset_fields' in kwargs:
			preset_fields = kwargs['preset_fields']
			kwargs.pop('preset_fields')
		else:
			preset_fields = False

		super(GameSettings, self).__init__(*args, **kwargs)

		if preset_fields:
			for fname, field in preset_fields.items():
				self.fields[fname] = field

		self.set_defaults()

	def clean(self):
		cleaned_data = self.cleaned_data
		self.makeQuery()
		return cleaned_data
	
	def set_defaults(self):
		""" Set default options on form (in event that it hasn't been requested 
			yet.
		"""
		self.initial_data = dict([(name, unicode(field.initial)) 
									for name, field in self.fields.items()])
		self.makeQuery()
		return




# TODO: make custom validators/fields? re django.core.validators
# http://docs.djangoproject.com/en/dev/ref/forms/validation/

# # #
# # 
# #  Question classes
# #
# # #

class Question(forms.Form):
	""" Question meta-class. Some methods will be moved in here which end up 
		being common across question-types.

		For now this Question class works mostly unadulterated on LeksaQuestion
		and MorfaQuestion.

		Question.__init__()

		Validation process:
			Follows Django documentation, with custom versions of following:
				clean_answers
				clean
			Additional customization is in LeksaQuestion/MorfaQuestions' 
			check_answer methods.
			
			When the form is validated, it runs clean_answers, and then
			clean. The clean method then calls check_answer() which
			does the actual answer checking, producing validation errors.
	
	"""
	# Shortcut
	hide = {'widget': forms.HiddenInput()}
	
	# Set up fields
	lemma = forms.CharField(max_length=50, **hide)
	pronoun = forms.CharField(max_length=8, required=False, **hide)
	userans = forms.CharField(max_length=50, required=False)
	word_id = forms.IntegerField(**hide)
	correct = forms.NullBooleanField(required=False, **hide)
	answers = forms.CharField(max_length=250, required=False, **hide)

	class Errors:
		""" Global question error responses.
		"""
		try_again = _(u'Try again!')
		empty_answers = _(u'No possible answers.')
		blank_user_answer = _(u'No answer given.')
	
	def __init__(self, *args, **kwargs):
		# Make compatible with old form names
		if kwargs.has_key('initial'):
			kwargs['initial']['word_id'] = kwargs['initial']['id']
			kwargs['initial']['answers'] = ', '.join(kwargs['initial']['translations'])
			
			# Keep the lemma available in templates.
			self.lemma_value = kwargs['initial']['lemma']
			if 'pronoun' in kwargs['initial']:
				self.pronoun_string = kwargs['initial']['pronoun']
			else:
				pass
				
		super(Question, self).__init__(*args, **kwargs)
	
	def clean_answers(self):
		""" This method cleans answers from database, and will run before .clean()
		
			Here we try to cut off limits in Leksa entries, e.g.:
				tremenninger (innbyrdes) -> tremenninger

			For Morfa, this isn't necessary, as MorfaSettings.getInitialData 
			supplies only lemmas matching tags: ['girjjis']
		"""
		
		answers = self.cleaned_data.get("answers").split(', ')
		answers = [a.strip() for a in answers if a.strip()]
		
		# Remove parentheticals
		answers = [a.partition('(')[0].strip() for a in answers]
		
		if len(answers) == 0:
			raise forms.ValidationError(self.Errors.empty_answers)
		
		return answers

	def clean(self):
		""" Prepare form data and raise validation errors. Validation errors 
			are raised if the user provides a wrong answer.
			
			Leksa and Morfa are essentially the same, since .GetInitialData()
			supplies the correct answers.
			
			This method depends on results from .clean_answers(), which runs
			first.			
		"""
		cleaned_data = self.cleaned_data
		
		user_answer = cleaned_data.get("userans")
		answers = cleaned_data.get("answers")
				
		# Making sure that the lemma and answers always show up in the form.
		self.lemma_value = cleaned_data['lemma']
		if 'pronoun' in cleaned_data:
			self.pronoun_string = cleaned_data['pronoun']
		else:
			self.pronoun_string = ''
		
		try:
			self.answer_list = ', '.join(answers)
		except TypeError:
			print answers
			if type(answers) != list:
				raise Http404('Answers missing from one of the questions...?')
		self.answer_list_as_list = answers

		# Always return cleaned data.
		self.check_answer()
		return cleaned_data


