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

from django.http import HttpResponse, Http404
from django.db.models import Q, Count
from random import randint

from models import *
from forms import *
from game import Game

import settings

try:
	DEFAULT_DIALECT = settings.DEFAULT_DIALECT
except:
	DEFAULT_DIALECT = None

class QAGame(Game):
	""" MORFAC
	"""

	test = 0

	def __init__(self, *args, **kwargs):
		self.generated_syntaxes = list()
		super(QAGame, self).__init__(*args, **kwargs)
		self.init_tags()
		
	
	def init_tags(self):
		"""
		Initialize the grammatical information.
		This information should be moved to parameters
		"""
		self.num_fields = 6
		self.syntax =('MAINV','SUBJ','HAB')
		self.qtype_verbs = set(['V-COND','V-IMPRT','V-POT', 'PRS','PRT', 'V-PRS', 'V-PRT', 'V-GER', 'V-PRF'])

		# Default tense and mood for testing
		self.tense = "Prs"
		self.mood = "Ind"
		self.gametype = "morfa"
		
		# TODO: check this in smeoahpa, possible source of error.
		# Values for pairs QPN-APN
		
		# spørsmål:       svar:
		# manne           datne
		# datne           manne
		# dïhte           dïhte
        # 
		# månnoeh dåtnoeh
		# dåtnoeh         månnoeh
		# dah guaktah     dah guaktah
        # 
		# mijjieh         dijjieh
		# dijjieh         mijjieh
		# dah                     dah
        # 
		# Noun Sg dïhte
		# Noun Pl         dah
		
		self.QAPN={	'Sg':'Sg',			# Dïhte? Dïhte.
					'Pl':'Pl',			# Dah? Dah.
					
					'Sg1':'Sg2',		# Manne? Datne.
					'Sg2':'Sg1',		# Datne? Manne.
					'Sg3':'Sg3',		# Dïhte? Dïhte.
					
					'Du1':'Du2',		# Månnoeh? Dåtnoeh.
					'Du2':'Du1',		# Dåtnoeh? Månnoeh.
					'Du3':'Du3',		# Dah guaktah? Dah guaktah.
					
					'Pl1':'Pl2',		# Mijjieh? Dijjieh.
					'Pl2':'Pl1',		# Dijjieh? Mijjieh.
					'Pl3':'Pl3'}		# Dah? Dah.
					
					

		# Values for subject-verb agreement:
		# e.g. Subject with N+Sg+Nom requires verb with Sg3.
		self.SVPN={'Sg1':'Sg1','Sg2':'Sg2','Sg3':'Sg3','Sg':'Sg3',\
				   'Pl1':'Pl1','Pl2':'Pl2','Pl3':'Pl3','Pl':'Pl3',\
				   'Du1':'Du1','Du2':'Du2','Du3':'Du3'}

		# Available values for Number
		self.PronPN=['Sg1','Sg2','Sg3','Pl1','Pl2','Pl3','Du1','Du2','Du3']
		self.PronPNBase={'Sg1':'manne','Sg2':'datne','Sg3':u'dïhte',\
						 'Pl1':'mijjieh','Pl2':'dijjieh','Pl3':'dah',\
						 'Du1':'månnoeh','Du2':'dåtnoeh','Du3':'dah guaktah'}
		self.NounPN=['Sg','Pl']
		self.NountoPronPN={'Sg':'Sg3','Pl':'Pl3'}

	def get_qword(self, qelement, tag_el):
		"""
			Note: attempting to reduce amount of queries run here, there are still some that are repeated,
				  but these should reduced once we come along to testing numbers.
		"""
		if self.settings.has_key('dialect'):
			dialect = self.settings['dialect']
		else:
			dialect = DEFAULT_DIALECT

		word=None
		if tag_el.pos=="Num" and self.settings.has_key('num_level') and str(self.settings['num_level'])=="1":
				smallnum = ["1","2","3","4","5","6","7","8","9","10"]
				word_count=Word.objects.filter(Q(presentationform__in=smallnum) & \
											   Q(wordqelement__qelement=qelement) & \
											   Q(form__tag=tag_el.id)).count()
				word=Word.objects.filter(Q(presentationform__in=smallnum) & \
										 Q(wordqelement__qelement=qelement) & \
										 Q(form__tag=tag_el.id))[randint(0,word_count-1)]
		else:
			# Dialect is commented out still because we're only getting
			# dialectical form variants, not word variants.
			possible_words = Word.objects.filter(wordqelement__qelement=qelement,
												# dialects__dialect=dialect,
												form__tag=tag_el.id)
			if possible_words.count() > 0:
				word = possible_words.order_by('?')[0]
				form_set_filter = word.form_set.filter(tag=tag_el.id)
				# filter forms by dialect
				form_set_filter_dial = form_set_filter\
											.exclude(dialects__dialect='NG')\
											.filter(dialects__dialect=dialect)
				if form_set_filter_dial.count() > 0:
					form_set_filter = form_set_filter_dial
		if word and form_set_filter.count()>0:
			form = form_set_filter[0] 
		else: return None
		# TODO: better error handling here-- this needs to point out
		# that the DB is not installing properly, but I need to check
		# first that the code doesn't depend on returning None
		# sometimes.
		# Test by raising Form.DoesNotExist? 
		word_id = word.id
		fullform = form.fullform
			
		info = { 'word' : word_id, 'tag' : tag_el.id, 'fullform' : [ fullform ], 'qelement' : qelement }
		return info
	
	# Select a word matching semtype and return full form.
	def get_words(self, qelement, tag_el=None, lemma=None, word_id=None):
		"""
		Select word from possible options in the element.
		"""
		words = []

		if self.settings.has_key('dialect'):
			dialect = self.settings['dialect']
		else:
			dialect = DEFAULT_DIALECT
		
		# If there are no information available for these elements, try to use other info.
		word = None
		form = None
				
		if lemma and tag_el:
			form_set = tag_el.form_set.exclude(dialects__dialect='NG')
			dialect_forms = form_set.filter(dialects__dialect=dialect)
			if dialect_forms.count() > 0:
				form_set = dialect_forms

			if qelement:
				if qelement.semtype:
					form_set = form_set.filter(word__semtype=qelement.semtype)
			form = form_set[0]
		else:
			if word_id and tag_el:
				word_set = Word.objects.filter(id=word_id)
				if qelement:
					if qelement.semtype:
						word_set.filter(semtype=qelement.semtype)
				word = word_set[0]
		
		if form:
			fullform = form.fullform
			info = {'word': form.word.id, 'tag': tag_el.id, 'fullform': [ fullform ]}
			words.append(info)
		elif word:
			form_list = word.form_set.exclude(dialects__dialect='NG')

			filtered = form_list.filter(dialects__dialect=dialect)
			
			if filtered.count() > 0:
				form_list = filtered

			if tag_el:
				form_list = form_list.filter(tag=tag_el)
			# We do not want to filter by dialect here, because we want
			# all forms to be accepted regardless of dialect
			if not form_list:
				if self.test: raise Http404(qelement.id + " " + tag_el.id + " " + word.id)
				return []

			fullform = form_list[0].fullform

			info = {'word': word.id, 'tag' : tag_el.id, 'fullform' : [ fullform ] }
			words.append(info)					
		else:
			if self.test: raise Http404("not word " + str(qelement.id))			
			return []
		
		return words

	def get_elements(self, question_element, identifier):
		elements = QElement.objects.filter(question=question_element, 
											identifier=identifier)
		if elements.count() > 0:
			return elements
		else:
			return None
		

	def generate_question(self, question, qtype):
		"""
		Generate question for the form.
		Only one question is generated.
		"""
		qtext=question.string
		#print "QUESTION " + str(question.id) + " " + qtext
		qwords = {}
	
		# Find out syntax elements
		qwords_list=[]
		for w in qtext.split():
			if w== "": continue
			qwords_list.append(w)

		# Handle all grammatical elements one at the time
		# 1. SUBJ-MAINV argreement
		
		if 'SUBJ' in set(qwords_list):
			qwords['SUBJ'] = {}
			
			# Select randomly an element, if there are more than one available.
			# This way there is only one subject and tag for each question.
			subj_elements=self.get_elements(question, 'SUBJ')
			
			if not subj_elements:
				return None
			subj_el = subj_elements[randint(0, len(subj_elements)-1)]
			tag_el_count = subj_el.tags.count()
			
			# If there was no tag elements, there is nothing to do.
			# Subject tag is needed for everything else. 
			if tag_el_count == 0:
				if self.test: raise Http404("0 tag count" + " " + qwords_list)
				return None
			
			tag_el = subj_el.tags.all()[randint(0, tag_el_count-1)]
			# Get number information for subject
			subjword = {}
			if tag_el.pos == "Pron":
				subjnumber = tag_el.personnumber
				pronbase = self.PronPNBase[subjnumber]
				word_el = Word.objects.filter(lemma=pronbase)[0]
				words_ = self.get_words(None, tag_el, None, word_el.id)
				try:
					info = words_[0]
				except IndexError:
					info = False
				# print subjnumber
				# print pronbase
				# print word_el
				# print info
				# print '--'
			else:
				subjnumber = tag_el.number
				info = self.get_qword(subj_el, tag_el)

			if not info:
				if self.test: raise Http404("not info " + " ".join(qwords_list))
				return None
			
			subjword = info
			subjword['number'] = subjnumber
			qwords['SUBJ'] = subjword
			# print qwords['SUBJ']

		if 'HAB' in set(qwords_list):
			
			qwords['HAB'] = {}
			
			# Select randomly an element, if there are more than one available.
			# This way there is only one habect and tag for each question.
			hab_elements = self.get_elements(question, 'HAB')
			
			if not hab_elements:
				return None
			hab_el = hab_elements[randint(0, len(hab_elements)-1)]
			tag_el_count = hab_el.tags.count()
			
			# If there was no tag elements, there is nothing to do.
			# Subject tag is needed for everything else. 
			if tag_el_count == 0:
				if self.test: raise Http404("0 tag count" + " " + qwords_list)
				return None
			
			tag_el = hab_el.tags.all()[randint(0, tag_el_count-1)]
			
			# Get number information for habect
			habword = {}
			if tag_el.pos == "Pron":
				habnumber = tag_el.personnumber
				pronbase = self.PronPNBase[habnumber]
				word_el = Word.objects.filter(lemma=pronbase)[0]
				words_ = self.get_words(None, tag_el, None, word_el.id)
				try:
					info = words_[0]
				except IndexError:
					info = False
				# print habnumber
				# print pronbase
				# print word_el
				# print info
				# print '--'
			else:
				habnumber = tag_el.number
				info = self.get_qword(hab_el, tag_el)

			if not info:
				if self.test: raise Http404("not info " + " ".join(qwords_list))
				return None
			habword = info
			habword['number'] = habnumber
			qwords['HAB'] = habword
			# print qwords['SUBJ']

		if 'MAINV' in set(qwords_list):

			qwords['MAINV'] = {}
			mainv_word = None
			
			# Select one mainverb element for question.
			mainv_elements = self.get_elements(question,'MAINV')
			if mainv_elements:
				mainv_el = mainv_elements[randint(0, len(mainv_elements)-1)]
				
				# If there is only on tag element, then there are no choices for agreement.
				tag_el_count = mainv_el.tags.count()
				if tag_el_count == 1:
					tag_el=mainv_el.tags.all()[0]
				else:
					# Subject-verb agreement
					if qwords.has_key('SUBJ') and qwords['SUBJ'].has_key('number'):
						subjnumber=qwords['SUBJ']['number']
						v_number = self.SVPN[subjnumber]

						if qtype in self.qtype_verbs or self.gametype=="qa":
							mainv_tags = mainv_el.tags.filter(Q(personnumber=v_number))
						else:
							mainv_tags = mainv_el.tags.filter(Q(personnumber=v_number) & \
															Q(tense=self.tense) & \
															Q(mood=self.mood))
					# If there is no subject element
					# then select random tag from all tags.
					else:
						mainv_tag_count = mainv_el.tags.count()
						mainv_tags = mainv_el.tags.all()
					if not mainv_tags:
						if self.test: raise Http404("not mainv_tags " + " ".join(qwords_list) + " " + question.qid)
						return None
					tag_el = mainv_tags[randint(0, mainv_tags.count()-1)]

				# Select random mainverb
				info = self.get_qword(mainv_el, tag_el)
				mainv_word = info

				if not mainv_word:
					if self.test: raise Http404("not mainv_word " + " ".join(qwords_list) + " " + question.qid)
					return None
				else:
					mainv_word['number'] = tag_el.personnumber
					qwords['MAINV'] = mainv_word

			if not mainv_word:
				if self.test: raise Http404("not mainv" + " " + " ".join(qwords_list))
				return None
				
		# 2. Other grammatical elements
		# At the moment, agreement is not taken into account
		for s in qwords_list:
			if s in set(self.syntax): continue

			tag_el=None
			word = {}
			anumber = ""			
			elements = self.get_elements(question,s)
			if elements:
				element = elements[randint(0, len(elements)-1)]
				copy_id=element.copy_id
				if copy_id:
					copy = QElement.objects.filter(id=copy_id)[0]
					copy_syntax = copy.syntax
					
					if qwords.has_key(copy_syntax):
						word = qwords[copy_syntax]

				if element.agreement:
					agr_id = element.agreement_id
					agr_el = QElement.objects.get(id=agr_id)
					agr_syntax = agr_el.identifier
					if qwords.has_key(agr_syntax):
						qword = qwords[agr_syntax]
						if qword.has_key('tag'):
							agr_tag_id = qword['tag']
							agr_tag = Tag.objects.get(id=agr_tag_id)
							if agr_tag.personnumber:
								anumber = agr_tag.personnumber
							else:
								anumber = agr_tag.number
							tag_count = element.tags.filter(Q(personnumber=anumber) | Q(number=anumber)).count()
							if tag_count>0:
								tag_el = element.tags.filter(Q(personnumber=anumber) | Q(number=anumber))[randint(0, tag_count-1)]
				if not tag_el: 
					tag_el_count = element.tags.count()
					if tag_el_count > 0:
						tag_el = element.tags.order_by('?')[0]

				if tag_el:
					# Select random word
					info = self.get_qword(element, tag_el)
					word = info					
			else:
				word = {}
				info = {'fullform' : [ s ] }
				word = info

			if not word:
				if self.test: raise Http404("not word " + "".join(qwords_list))
				return None
			qwords[s] = word

		# Return the ready qwords list.			
		return qwords

	def generate_answers_subject(self, answer, question, awords, qwords, element="SUBJ"):
		""" Can be used to generate answers for habitive, just supply
		element="HAB".

		This method also performs Question-Answer subject agreement, for
		example:

			Do _you_ like bagels?
			_I_ like bagels.

		"""
		words=[]
		word_id=""
		a_number=""
		subj_el = None
		subjword = None

		copy_syntax = ""
		# If there is subject in the question, there is generally agreement.
		subj_elements = self.get_elements(answer,element)
		if subj_elements:
			subj_el = subj_elements[0]
		

		# Check whether an answer element should be copied from the question
		# element.
		copy_id = subj_el.copy_id
		
		if copy_id:
			subj_copy = QElement.objects.filter(id=copy_id)[0]
			copy_syntax = subj_copy.syntax
			if qwords.has_key(copy_syntax):
				qword = qwords[copy_syntax]
				subjtag_id=qword['tag']
				subjtag = Tag.objects.get(id=subjtag_id)
				subjword_id=qword['word']
				if subjtag.pos=="Pron":
					subjnumber = subjtag.personnumber
				else:
					subjnumber = subjtag.number
				
				# this should only happen if there's subj person
				a_number=self.QAPN[subjnumber]
				asubjtag = subjtag.string.replace(subjnumber,a_number)
				asubjtag_el = Tag.objects.get(string=asubjtag)
				
				# If pronoun, get the correct form
				if self.PronPNBase.has_key(a_number):
					pronbase = self.PronPNBase[a_number]
					words = self.get_words(None, asubjtag_el, pronbase)
					for word in words:
						word['number'] = a_number
					
				if not words and not len(words)>0:
					words = self.get_words(subj_copy, asubjtag_el, None, subjword_id)
					words[0]['number'] = a_number

		# Check if there are elements specified for the answer subject.
		else:
			if subj_el:
				tag_el_count = subj_el.tags.count()
				word_el_count = subj_el.wordqelement_set.count()
				
				if tag_el_count > 0:
					tag_el = subj_el.tags.all().order_by('?')[0]

				if tag_el.pos=="Pron":
					a_number = tag_el.personnumber
				else:
					a_number = tag_el.number
				
				if not subjword:
					subjword = subj_el.wordqelement_set\
									.filter(word__form__tag=tag_el)\
									.order_by('?')[0].word.id

				info = { 'qelement': subj_el.id, 'word' : subjword, 'tag' : tag_el.id, 'number' : a_number }
				words.append(info)

				for word in words:
					word['number'] = a_number
		
		awords[element] = words[:]
		
		# If SUBJ is appearing in the output, this means subjword is set to none for some reason.
		# subjword is set to none because subj_el.copy_id is none
		
		return awords

	
	def generate_answers_mainv(self, answer, question, awords, qwords):

		mainv_elements = self.get_elements(answer,"MAINV")
		# print '--'
		# print question.qid
		# print mainv_elements
		mainv_word=None
		mainv_words = []
		mainv_tag = None
		mainv_tags = []
		va_number = None

		copy_syntax = ""
		# Find content elements.
		if mainv_elements:
			mainv_el = mainv_elements[0]
			if mainv_el.copy_id:
				copy_id = mainv_el.copy_id
				copy_element = QElement.objects.get(id=copy_id)
				copy_syntax = copy_element.identifier
		# It is assumed that all subjects cause the same inflection
		# for verb, so it does not matter which subject is selected.
		if awords.has_key('SUBJ') and len(awords['SUBJ'])>0:
			# mainverb number depends on the number of the subject.
			asubj = awords['SUBJ'][0]
			a_number=asubj['number']
			# print 'asubj number: ', a_number
			va_number=self.SVPN[a_number]
			# print 'va_number: ', va_number
		else:
            # No SUBJ defined, MAINV is a copy of the question MAINV
            # and needs to have Question-Answer subject change
			if qwords.has_key(copy_syntax):
				qmainv = qwords[copy_syntax]
				q_number = qmainv['number']
				if q_number:
					va_number = self.QAPN[q_number]
			else:
				# No SUBJ defined, and MAINV is defined (and not a copy from Q)
                # but MAINV still needs to have Question-Answer subject change
				if qwords.has_key('MAINV'):
					qmainv = qwords['MAINV']
					q_number = qmainv['number']
					if q_number:
						va_number = self.QAPN[q_number]
					
		# If there is no subject, then the number of the question
		# mainverb determines the number.
		mainv_fullform = False
		mainv_form = False
		mainv_word_obj = None
		if qwords.has_key(copy_syntax):

			qmainv = qwords[copy_syntax]
			mainv_word = qwords[copy_syntax]['word']

			qmainvtag_id = qmainv['tag']
			qmainvtag = Tag.objects.get(id=qmainvtag_id)
			qmainvtag_string = qmainvtag.string
			v_number = qmainvtag.personnumber
			if va_number:
				amainvtag_string = qmainvtag_string.replace(v_number,va_number)
			else:
				amainvtag_string = qmainvtag_string
				
			mainv_tag = Tag.objects.get(string=amainvtag_string)
			mainv_tags.append(mainv_tag)
			
			mainv_word_obj = Word.objects.get(id=mainv_word)
			try:
				mainv_form = mainv_word_obj.form_set.filter(tag__string=mainv_tag).order_by('?')[0]
			except IndexError:
				error_vars = ('generate_answers_mainv', 
								mainv_word_obj,
								mainv_word_obj.pk,
								mainv_tag.string,
								mainv_word_obj.form_set.all().count())
				error = "%s: Word <%s, id: %d> missing form for Tag <%s> (%d total form(s) available). \r\n" % error_vars
				# error += '\r\n'.join([form.tag.string for form in mainv_word_obj.form_set.all()])
				raise Http404(error)

			mainv_fullform = mainv_form.fullform

		# If the main verb is under question, then generate full list.
		if answer.task == "MAINV":
			mainv_words = []
			if mainv_elements:
				for mainv_el in mainv_elements:
					if mainv_el.tags.count()>0:
						if va_number:
							# print va_number
							mainv_tags = mainv_el.tags.filter(Q(personnumber=va_number))
						else:
							mainv_tags = mainv_el.tags.all()
						for t in mainv_tags:
							info = {'qelement': mainv_el.id, 
									'tag': t.id}
							if mainv_fullform and mainv_word and mainv_tag:
								info['fullform'] = [mainv_fullform]
								info['word'] = mainv_word
								info['number'] = mainv_tag.personnumber
							mainv_words.append(info)
					else:
						info = { 'qelement' : mainv_el.id, 'tag' : mainv_tag.id }
						mainv_words.append(info)

			else:
				if mainv_word:
					mainv_words.extend(self.get_words(mainv_el, mainv_tag, None, mainv_word))
					
		# Otherwise take only one element
		else:
			if mainv_elements:
				mainv_element = mainv_elements[0]
				tag_el_count = mainv_element.tags.count()
				if tag_el_count > 0:
					mainv_tags = mainv_el.tags.filter(Q(personnumber=va_number))
				for tag in mainv_tags:
					info = { 'qelement' : mainv_element.id, 'word' : mainv_word, 'tag' : tag.id }
					mainv_words.append(info)

			else:
				for tag in mainv_tags:
					info = { 'tag' : mainv_tag.id, 'word' : mainv_word }
					mainv_words.append(info)
					
		if not mainv_words and qwords.has_key("MAINV"):
			mainv_words.append(qwords["MAINV"])
		
		awords["MAINV"] = mainv_words
		
		return awords

	def generate_syntax(self, answer, question, awords, qwords, s):
		""" Sets up specific syntactic relations between question elements, 
		such as Subject-Verb agreement.
		"""
		
		if s in ["SUBJ", "MAINV", "HAB"]: return awords
		
		if not awords.has_key(s):
			awords[s] = []

		word_id=None
		
		tag_elements = []
		swords = []
		elements = self.get_elements(answer,s)

		if not elements:
			info = { 'fullform' : [ s ] }
			swords.append(info)
			awords[s] = swords
			return awords

		element = elements[0]
		if element.copy_id:
			copy_id = element.copy_id
			copy_element = QElement.objects.get(id=copy_id)
			copy_syntax = copy_element.identifier
			if qwords.has_key(copy_syntax):
				qword = qwords[copy_syntax]
				if qword.has_key('word'):
					word_id=qword['word']
				if qword.has_key('tag'):
					tag = Tag.objects.get(id=qword['tag'])
					tag_elements.append(tag)

		if element.agreement:
			agr_id = element.agreement_id
			agr_el = QElement.objects.get(id=agr_id)
			agr_syntax = agr_el.identifier
			if qwords.has_key(agr_syntax):
				qword = qwords[agr_syntax]
				if qword.has_key('tag'):
					agr_tag_id = qword['tag']
					agr_tag = Tag.objects.get(id=agr_tag_id)
					if agr_tag.personnumber:
						anumber = agr_tag.personnumber
					else:
						anumber = agr_tag.number
					tag_count = element.tags.filter(Q(personnumber=anumber) | Q(number=anumber)).count()
					if tag_count>0:
						tag_elements = element.tags.filter(Q(personnumber=anumber) | Q(number=anumber))

		# if no agreement, take all tags.
		else:
			tag_count = element.tags.count()
			if tag_count > 0:
				tag_elements = element.tags.all()
		
		# Take word forms for all tags
		info=None
		for tag_el in tag_elements:
			if not word_id:
				info = self.get_qword(element, tag_el)
			else:
				form_list = Form.objects.filter(Q(tag=tag_el.id) & Q(word=word_id))
				if form_list:
					info = { 'qelement' : element.id, 'word' : word_id, 'tag' : tag_el.id  }
			if not info:
				if self.test: raise Http404("not info " + question.id)
				return None
			swords.append(info)

		if not swords:
			if self.test: raise Http404("not swords " + str(question.id) + " " + s + str(element.id))
			return None
		awords[s] = swords

		return awords

	######### Vasta questions
	def get_question_qa(self,db_info,qtype):

		qwords = {}
		if self.settings.has_key('level'): level=int(self.settings['level'])
		else: level='1'
		
		q_count = Question.objects.filter(gametype="qa", level__lte=level).count()
		question = Question.objects.filter(gametype="qa", level__lte=level)[randint(0,q_count-1)] 
		#question = Question.objects.get(id="107")
	   
		qtype = question.qtype
		qwords = None
		qwords= self.generate_question(question, qtype)
		db_info['qwords'] = qwords

		db_info['question_id'] = question.id
		return db_info

	######## Morfa questions
	def get_question_morfa(self,db_info,qtype):
		""" This method selects a question object based on the settings form.
		"""
		qwords = {}
		
		if self.settings.has_key('pos'):
			pos=self.settings['pos']

		# Get qtype from settings.
		if not qtype:
			if pos == "N":
				qtype = self.settings['case_context']
			if pos == "V":
				qtype=self.settings['vtype_context']
			if pos == "Num":
				qtype=self.settings['num_context']
			if pos == "A":
				qtype=self.settings['adj_context']
			if pos == "Pron":
				qtype=self.settings['pron_context']

		books=None
		if self.settings.has_key('book'): books=self.settings['book']
		# TODO: Debugging. 
		# qtype = 'N-ILL'
		# MIX
		if books:
			q_count=Question.objects.filter(Q(qtype__contains=qtype) & \
											Q(gametype="morfa") & \
											(Q(source__name__in=books) | Q(source__name="all" ))).count()
		else:
			q_count=Question.objects.filter(Q(qtype__contains=qtype) & Q(gametype="morfa")).count()
		
		### Generate question. If it fails, select another one.
		max = 20
		i=0
		while not qwords and i<max:
			i = i+1
			if books:	
				question = Question.objects.filter(Q(qtype__contains=qtype) & \
												   Q(gametype="morfa") & \
												   (Q(source__name__in=books) | Q(source__name="all" )))
			else:
				question = Question.objects.filter(Q(qtype__contains=qtype) & Q(gametype="morfa"))
			if question.count() > 0:
				question = question.order_by('?')[0]
			else:
				errormsg = 'Database may not be properly loaded. No questions found for query.'
				errormsg += '\n qtype: %s' % repr(qtype)
				raise Http404(errormsg)
			qwords = None
			qwords = self.generate_question(question, qtype)

		db_info['qwords'] = qwords
		db_info['question_id'] = question.id
		return db_info,question


	########### Morfa answers
	def get_answer_morfa(self,db_info,question):
		""" This compiles the object ids for answer sentences.  There is a lot
		of code in here that is grammatically specifics, e.g., refers to SUBJ,
		HAB, MAINV, because there are special behaviors associated with these
		element names. An update to Morfa-C would probably try to find abstract
		ways to define these relationships, in the event that the software is
		used with languages where there are different syntactic relationships.

		In sme and sma, SUBJ and MAINV have specific syntactic interactions,
		agreement, etc., while HAB and MAINV have separate agreement patterns.
		This function calls others to handle these syntactic patterns.
		"""
		
		# Select answer using the id from the interface.
		# Otherwise select answer that is related to the question.
		awords = {}
		if db_info.has_key('answer_id'):
			answer=Question.objects.get(id=db_info['answer_id'])
		else:
			answer=question.answer_set.all().order_by('?')[0]

		# Generate the set of possible answers if they are not coming from the interface
		# Or if the gametype is qa.
		if db_info.has_key('answer_id') and self.settings['gametype'] == 'context':
			awords=db_info['awords']
		else:
			# Generate the set of possible answers
			# Here only the text of the first answer is considered!!
			atext=answer.string
			words_strings = set(atext.split())
			#Initialize each element identifier
			for w in atext.split():
				if w== "": continue
				info = {}
				awords[w] = info
			# Subject and main verb are special cases:
			# There is subject-verb agreement and correspondence with question elements.
			if 'SUBJ' in words_strings:
				awords = self.generate_answers_subject(answer, question, awords, db_info['qwords'])
				
			if 'HAB' in words_strings:
				awords = self.generate_answers_subject(answer, question, awords, db_info['qwords'], element="HAB")

			if 'MAINV' in words_strings:
				try:
					awords = self.generate_answers_mainv(answer, question, awords, db_info['qwords'])
				except AttributeError:
					if self.test: raise Http404("problem")
					return "error"

			# Rest of the syntax
			#if self.test: raise Http404(words_strings)
			for s in words_strings:
				awords = self.generate_syntax(answer, question, awords, db_info['qwords'], s)
				if not awords:
					if self.test: raise Http404("problem" + s)
					return "error"
				if not awords.has_key(s):
					if self.test: raise Http404("problem2" + s)
					return "error"

		db_info['answer_id'] = answer.id
		db_info['awords'] = awords
		# print db_info
#		 raise Exception(db_info)
		# print db_info['awords']
		# print question.string
		return db_info

	def get_db_info(self, db_info,qtype=None,default_qid=None):
		anslist=[]

		# If the question id is received from the interface, use that question info
		# Otherwise select random question
		if db_info.has_key('question_id'):
			question = Question.objects.get(id=db_info['question_id'])
			qwords=db_info['qwords']
		else:
			if default_qid:
				question = Question.objects.get(qid=default_qid)	  
				qwords = None
				qwords= self.generate_question(question, qtype)
				db_info['qwords'] = qwords

			# If no default information select question
			else:
				if not self.gametype == "qa":
					db_info,question = self.get_question_morfa(db_info,qtype)
				else:
					db_info = self.get_question_qa(db_info,qtype)

		# If Vasta, store and return:
		if not self.gametype == "qa":
			db_info = self.get_answer_morfa(db_info,question)

		return db_info

	def create_form(self, db_info, n, data=None):

		question = Question.objects.get(Q(id=db_info['question_id']))
		
		answer = None
		if self.settings.has_key('dialect'):
			dialect = self.settings['dialect']
		else:
			dialect = DEFAULT_DIALECT
		
		language = "nob"
		if self.settings.has_key('language'):
			language = self.settings['language']
		if not self.gametype == "qa":
			answer = Question.objects.get(Q(id=db_info['answer_id']))
			# print answer.string
			form = (ContextMorfaQuestion(question, answer, \
										 db_info['qwords'], db_info['awords'], dialect, language,\
										 db_info['userans'], db_info['correct'], data, prefix=n, user_country=self.settings["user_country"]))
		else:
			form = (VastaQuestion(question, \
								  db_info['qwords'], language, \
								  db_info['userans'], db_info['correct'], data, prefix=n, user_country=self.settings["user_country"]))
			
		#print "awords:", db_info['awords']
		#print "awords ...................."
		#print "qwords:", db_info['qwords']
		#print "qwords ...................."

		return form, None

