# -*- coding: utf-8 -*-
from local_conf import LLL1
import importlib
oahpa_module = importlib.import_module(LLL1+'_oahpa')

from django import forms
from django.db.models import Q
from django.http import Http404
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import force_unicode
import est_oahpa.settings as settings

settings = oahpa_module.settings
switch_language_code = oahpa_module.conf.tools.switch_language_code

from models import *
#from game import *
#from est_oahpa.est_drill.game import relax
import datetime
import socket
import sys, os, subprocess
import itertools
from random import choice

# TODO: These should be accessible in the admin interface, not hardcoded.

PRONOUNS_LIST = {'Sg1':u'ma', 'Sg2':u'sa', 'Sg3':u'ta',
		  'Pl1':u'me', 'Pl2':u'te', 'Pl3':u'nad'}

# DEMONSTRATIVE_PRESENTATION plus Sg3/Pl3
PASSIVE_PRONOUNS_LIST = {'Sg1':u'ma', 'Sg2':u'sa', 'Sg3':u'ta',
                         'Pl1':u'me', 'Pl2':u'te', 'Pl3':u'nad'}


NEGATIVE_VERB_PRES = {'Sg1':'ei', 'Sg2':'ei', 'Sg3':'ei',
		  'Pl1':'ei', 'Pl2':'ei', 'Pl3':'ei'}

TENSE_PRESENTATION = {
	'Prt': u'eile',
	'Prs': u'täna',
}

RECIPROCATIVE_PRESENTATION = {
	'Du': u'guhtet',
	'Pl': u'goabbat',
}

DEMONSTRATIVE_PRESENTATION = {
	'Sg': u'okta',
	'Sg3': u'okta',
	'Pl': u'máŋga',
	'Pl3': u'máŋga',
}

POS_CHOICES = (
	('N', _('noun')),
	('V', _('verb')),
)

CASE_CHOICES = (
    ('N-GEN', _(u'Omastav (kelle? mille?)')),
    ('N-PAR', _(u'Osastav (keda? mida?)')),
    ('N-ILL', _(u'Sisseütlev (kellesse? millesse? kuhu?)')),
    ('N-INE', _(u'Seesütlev (kelles? milles? kus?)')),
    ('N-ELA', _(u'Seestütlev (kellest? millest? kust?)')),
    ('N-ALL', _(u'Alaleütlev (kellele? millele? kuhu?)')),
    ('N-ADE', _(u'Alalütlev (kellel? millel? kus?)')),
    ('N-ABL', _(u'Alaltütlev (kellelt? millelt? kust?)')),
    ('N-TRA', _(u'Saav (kelleks? milleks?)')),
    ('N-TER', _(u'Rajav (kelleni? milleni?)')),
    ('N-ESS', _(u'Olev (kellena? millena?')),
    ('N-ABESS', _(u'Ilmaütlev (kelleta? milleta?')),
    ('N-COM', _(u'Kaasaütlev (kellega? millega?)')),
)

# For now this is just a part of a test, used in game.Game.get_db_info_new
# I wanted a very general way to specify question/answers.

NOUN_QUESTION_ANSWER = {
	# gametype			question		answer
	'N-GEN': [('N+NumberN+Nom', 'N+NumberN+Gen')],
	'N-PAR': [('N+NumberN+Nom', 'N+NumberN+Par')],
	'N-ILL': [('N+NumberN+Nom', 'N+NumberN+Ill')],
	'N-INE': [('N+NumberN+Nom', 'N+NumberN+Ine')],
	'N-ELA': [('N+NumberN+Nom', 'N+NumberN+Ela')],
	'N-ADE': [('N+NumberN+Nom', 'N+NumberN+Ade')],
	'N-ABL': [('N+NumberN+Nom', 'N+NumberN+Abl')],
	'N-ALL': [('N+NumberN+Nom', 'N+NumberN+All')],
}

NOUN_FILTER_DEFINITION = ['animacy', 'declension', 'gender', 'source']

# Pers - akk, gen, ill, lok, kom
# Dem - akk, gen, ill, lok, kom
CASE_CHOICES_PRONOUN = (
	('NOMPL', _('plural')),
	('N-GEN', _('Genitive')),
    ('N-PAR', _('Partitive')),
    ('N-ILL', _('Illative')),
    ('N-INE', _('Inessive')),
    ('N-ELA', _('Elative')),
    ('N-ALL', _('Allative')),
    ('N-ADE', _('Adessive')),
    ('N-ABL', _('Ablative')),
)

# 	('N-ACC', _('accusative')),
# 	('N-ILL', _('illative')),
# 	('N-LOC', _('locative')),
# 	('N-COM', _('comitative')),
# 	('N-GEN', _('genitive')),
# 	# ('N-ESS', _('essive')),
# )

PRONOUN_QUESTION_ANSWER = {
	# gametype			question		answer
	'N-PAR': [('Pron+Subclass+NumberN+Nom', 'Pron+Subclass+NumberN+Par')],
	'N-ILL': [('Pron+Subclass+NumberN+Nom', 'Pron+Subclass+NumberN+Ill')],
#	'N-LOC': [('Pron+Subclass+NumberN+Nom', 'Pron+Subclass+NumberN+Loc')],
#	'N-COM': [('Pron+Subclass+NumberN+Nom', 'Pron+Subclass+NumberN+Com')],
	'N-GEN': [('Pron+Subclass+NumberN+Nom', 'Pron+Subclass+NumberN+Gen')],
}

PRONOUN_FILTER_DEFINITION = ['pron_type',]

# Refl - ill, lok, kom
# Recipr - ill, lok, kom
RECIP_REFL_CHOICES = (
	('N-ILL', _('illative')),
	('N-LOC', _('locative')),
	('N-COM', _('comitative')),
)

PRONOUN_SUBCLASSES = (
	('Pers', _('personal')),
	('Dem', _('demonstrative')),
	('Recipr', _('reciprocative')),
	('Refl', _('reflexive')),
	('Rel', _('relative')),
)

CASE_CONTEXT_CHOICES = (
    ('N-PAR', _('Keda? Mida?')),
    ('N-GEN-NOM', _('Kelle? Mille?')),
    ('N-ILL-ALL', _('Kuhu?')),
    ('N-INE-ADE', _('Kus?')),
    ('N-TRA', _('Kelleks? Milleks?')),
    ('N-COM', _('Kellega? Millega?')),
    #('N-ELA', _('Elative')),
    #('N-ADE', _('Adessive')),
    #('N-ABL', _('Ablative')),
    #('N-ALL', _('Allative')),
	#('N-MIX', _('mix')),
)

NOUN_TYPE_CHOICES =(
	('N-FEM-other', _(u'feminine in -a/-я')),
	('N-FEM-8', _(u'feminine in -ь')),
	('N-MASC-INANIM', _('masculine inanimate')),
	('N-MASC-ANIM', _('masculine animate')),
	('N-NEUT', _('neuter')),
	('all', _('All')),
)

#
# No inessive or essive, and no choice between nom sg. and pl, but nom sg and pl come together.
#
PRON_CONTEXT_CHOICES = (
	#('P-NOM', _('nominative')), Morfa C pronomen nominativ skal fjernes fra menyen dersom oppgavene har ingen hensikt.
    ('P-PERS', _('personal')),
    ('P-DEM', _('demonstrative')),
    ('P-RECIPR', _('reciprocative')),
    ('P-REFL', _('reflexive')),
    ('P-REL', _('relative')),
)

WORDFORM_TYPE_CHOICES = (
	('goabbat', _('goabbat/guhtet')),
	('nubbi', _('nubbi/nuppit')),
)

ADJCASE_CHOICES = (
	('NOMPL', _('plural')),
	('ATTR', _('attributive')),
	('A-GEN', _('Genitive')),
    ('A-PAR', _('Partitive')),
    ('A-ILL', _('Illative')),
    ('A-INE', _('Inessive')),
    ('A-ELA', _('Elative')),
    ('A-ADE', _('Adessive')),
    ('A-ABL', _('Ablative')),
    ('A-ALL', _('Allative')),)

ADJECTIVE_QUESTION_ANSWER = {
	# gametype			question		answer
	'NOMPL': [('A+Sg+Nom', 'A+Pl+Nom')],
	'ATTR': [('A+Sg+Nom', 'A+Attr')],
	'N-ACC': [('A+NumberA+Nom', 'A+NumberN+Acc')],
#	'N-ILL': [('A+NumberA+Nom', 'A+NumberN+Ill')],
	'N-LOC': [('A+NumberA+Nom', 'A+NumberN+Loc')],
#	'N-COM': [('A+NumberA+Nom', 'A+NumberN+Com')],
	'N-GEN': [('A+NumberA+Nom', 'A+NumberN+Gen')],
#	'N-ESS': [('A+NumberA+Nom', 'A+Ess')],
}

ADJECTIVE_FILTER_DEFINITION = ['grade', 'stem', 'source']

ADJEX_CHOICES = (
	('A-ATTR', _('attributive')), 	# A+Nom+Sg -> A+Attr
 	('A-COMP', _('comparative')),		# A+Nom+Sg -> Comp
 	('A-SUPERL', _('superlative')),	# A+Nom+Sg -> Superl

)

ADJ_CONTEXT_CHOICES = (
	('ATTRPOS', _('attributive positive')),
	('ATTRCOMP', _('attributive comparative')),
	('ATTRSUP', _('attributive superlative')),
	('PREDPOS', _('predicative positive')),
	('PREDCOMP', _('predicative comparative')),
	('PREDSUP', _('predicative superlative')),
)

GRADE_CHOICES = (
	('POS', _('positive')),
	('COMP', _('comparative')),
	('SUPERL', _('superlative')),
)

NUM_CONTEXT_CHOICES = (
	('NUM-ATTR', _('attributive')),
	('NUM-NOM-PL', _('plural')),
	('NUM-ACC', _('accusative')),
#	('NUM-ILL', _('illative')),
	('NUM-LOC', _('locative')),
#	('NUM-COM', _('comitative')),
	('COLL-NUM', _('collective')),
	('ORD-NUM', _('ordinals')),
)

NUM_BARE_CHOICES = (
	('NOMPL', _('plural')),
	('N-ACC', _('accusative')),
#	('N-ILL', _('illative')),
	('N-LOC', _('locative')),
#	('N-COM', _('comitative')),
)

NUMERAL_QUESTION_ANSWER = {
	# gametype			question		answer
#	'N-ESS': [('Num+NumberN+Nom', 'Num+Ess')],
	'N-LOC': [('Num+NumberN+Nom', 'Num+NumberN+Loc')],
#	'N-ILL': [('Num+NumberN+Nom', 'Num+NumberN+Ill')],
}

NUMERAL_FILTER_DEFINITION = ['stem', 'source']

NUM_LEVEL_CHOICES = (
	('1', _('First level')),
	('2', _('Second level')),
)

NUM_TYPE_CHOICES = (
    ('CARD', _('cardinal')),
    ('ORD', _('ordinal')),
    ('COLL', _('collective')),
)

VTYPE_CHOICES = (
	('PRS', _('present')),
	('PRT', _('past')),
#	('PRF', _('perfect')),
#	('GER', _('gerund')),
#	('COND', _('conditional')),
#	('IMPRT', _('imperative')),
#	('POT', _('potential')),
)

VERB_QUESTION_ANSWER = {
	'V-PRS': [('V+Inf', 'V+Ind+Prs+Person-Number')],
	'V-PRT': [('V+Inf', 'V+Ind+Prt+Person-Number')],
#	'PRS': [('V+Inf', 'V+Ind+Prs+Person-Number')],
#	'PRT': [('V+Inf', 'V+Ind+Prt+Person-Number')],
#	'PRF': [('V+Inf', 'V+PrfPrc')],
#	'GER': [('V+Inf', 'V+Ger')],
#	'COND': [('V+Inf', 'V+Cond+Prs+Person-Number')],
#	'IMPRT': [('V+Inf', 'V+Imprt+Person-Number')],
#	'POT': [('V+Inf', 'V+Pot+Prs+Person-Number')],
}

VERB_FILTER_DEFINITION = ['stem', 'source']

VTYPE_CONTEXT_CHOICES = (
	('V-PRS', _('present')),
	('V-PRT', _('past')),
#	('V-PRF', _('perfect')),
#	('V-GER', _('gerund')),
#	('V-COND', _('conditional')),
#	('V-IMPRT', _('imperative')),
#	('V-POT', _('potential')),
#	('V-MIX', _('mix')),
#	('TEST', _('test questions')),
 )

LEVEL_CHOICES = (
	('l1', _('Level 1')),
	('l2', _('Level 1-2')),
	('l3', _('Level 1-3')),
	('all', _('All')),
)


DERIVATION_CHOICES = (
 	('V-DER-PASS', _('passive derivation')),
 	('A-DER-V', _('adjective->verb derivation')),
)

DERIVATION_QUESTION_ANSWER = {
	'A-DER-V': [('A+Sg+Nom', 'A+Der/AV+V+Ind+Prs+Person-Number')],

}

DERIVATION_FILTER_DEFINITION = False

DERIVATION_CHOICES_CONTEXT = (
 	('A-DER-V', _('adjective->verb derivation')),
	('DER-PASSV', _('passive derivation')),
)

BOOK_CHOICES = (
    ('all', _(u'E nagu Eesti - all chapters')),
    #('E_nagu_Eesti', _('E nagu Eesti - all chapters')),
    ('1', _('E nagu Eesti - chapter 1')),
    ('2', _('E nagu Eesti - chapter 2')),
    ('3', _('E nagu Eesti - chapter 3')),
    ('4', _('E nagu Eesti - chapter 4')),
    ('5', _('E nagu Eesti - chapter 5')),
    ('6', _('E nagu Eesti - chapter 6')),
    ('7', _('E nagu Eesti - chapter 7')),
    ('8', _('E nagu Eesti - chapter 8')),
    ('9', _('E nagu Eesti - chapter 9')),
    ('10', _('E nagu Eesti - chapter 10')),
    ('11', _('E nagu Eesti - chapter 11')),
    ('12', _('E nagu Eesti - chapter 12')),
    ('13', _('E nagu Eesti - chapter 13')),
    ('14', _('E nagu Eesti - chapter 14')),
    ('15', _('E nagu Eesti - chapter 15')),
    ('16', _('E nagu Eesti - chapter 16')),
    ('17', _('E nagu Eesti - chapter 17')),
    ('18', _('E nagu Eesti - chapter 18')),
    ('19', _('E nagu Eesti - chapter 19')),
    ('20', _('E nagu Eesti - chapter 20')),
    ('21', _('E nagu Eesti - chapter 21')),
    ('22', _('E nagu Eesti - chapter 22')),
    ('23', _('E nagu Eesti - chapter 23')),
    ('24', _('E nagu Eesti - chapter 24')),
    ('25', _('E nagu Eesti - chapter 25')),
)

FREQUENCY_CHOICES = (
	('rare', _('rare')),
	('common', _('common')),
)

GEOGRAPHY_CHOICES = (
	('world', _('world')),
	('eesti', _('eesti')),
)

VASTA_LEVELS = (
	('1', _('First level')),
	('2', _('Second level')),
	('3', _('Third level')),
)

VASTAS_NR_OF_TASKWORDS = (
	('2', _('2')),
	('3', _('3')),
	('4', _('4')),
)

TRANS_CHOICES = (
        ('estrus', _('Estonian to Russian')),
        ('rusest', _('Russian to Estonian')),
	   ('esteng', _('Estonian  to English')),
	   ('engest', _('English to Estonian')),
        ('estfin', _('Estonian to Finnish')),
        ('finest', _('Finnish to Estonian')),
        ('estswe', _('Estonian to Swedish')),
        ('sweest', _('Swedish to Estonian')),
        ('estdeu', _('Estonian to German')),
        ('deuest', _('German to Estonian')),
        #('estlat', _('Estonian to Latvian')),
        #('latest', _('Latvian to Estonian')),
        #('estnob', _('Estonian to Norwegian')),
        #('nobest', _('Norwegian to Estonian')),
)

NUMLANGUAGE_CHOICES = (
	('est', _('Estonian')),
)

SEMTYPE_CHOICES = (
    ('FAMILY', _('family')),
    ('HUMAN', _('people')),
    ('ANIMAL', _('animal')),
    ('BODY', _('body')),
    ('FOOD/DRINK', _('food/drink')),
    ('CLOTHES', _('clothes')),
    ('TIME', _('time')),
    ('WEATHER', _('weather')),
    ('NATURE', _('nature')),
    ('SCHOOL/EDU', _('school/education')),
    ('HOME', _('home')),
    ('ELECTRONICS', _('electronics')),
    ('CULTURE', _('culture')),
    ('SPORT', _('sports')),
    ('WORK', _('work')),
    ('BUSINESS', _('business')),
    ('HEALTHCARE', _('health care')),
    ('all', _('all')),
)


NUM_CHOICES = (
	('10', _('0-10')),
	('20', _('0-20')),
	('100', _('0-100')),
	('1000', _('0-1000')),
#	('ALL', _('all')),
)

NUMGAME_CHOICES = (
	('string', _('String to numeral')),
	('numeral', _('Numeral to string')),
)

NUMGAME_CHOICES_PL = (
	('string', _('Strings to numerals')),
	('numeral', _('Numerals to strings')),
)

# These are not actually used in Forms, but used as a way to sneak these
# into the locale files so that the trans tag may be applied to
# form.wordclass without altering code here

VERB_CLASSES = (
	('I', _('I')),
	('II', _('II')),
	('III', _('III')),
	('IV', _('IV')),
	('V', _('V')),
	('VI', _('VI')),
	('Odd', _('Odd')),
)

KLOKKA_CHOICES = (
	('kl1', _('easy')),
	('kl2', _('medium')),
	('kl3', _('hard')),
)

DIALOGUE_CHOICES = (
	('firstmeeting', _('Firstmeeting')),
	('firstmeeting_boy', _('Firstmeeting boy')),
	('firstmeeting_girl', _('Firstmeeting girl')),
	('firstmeeting_man', _('Firstmeeting man')),
	('visit', _('Visit')),
	('grocery', _('Grocery')),
	('shopadj', _('Shopadj')),
)

#BOOK_CHOICES = tuple(
# 	[(source.name, source.name) for source in Source.objects.all()] +
# 	[('all', _('ALL'))]
#)


# Syllables are manually coded in the templates, but it's useful to get the
# translation strings here, also for the courses module logging.

SYLLABLE_VALUES = (
	('2syll', _('bisyllabic')),
	('3syll', _('trisyllabic')),
	('Csyll', _('contracted')),
)

ALL_CHOICES = [
	ADJCASE_CHOICES,
	ADJEX_CHOICES,
	ADJ_CONTEXT_CHOICES,
	BOOK_CHOICES,
	CASE_CHOICES,
	CASE_CHOICES_PRONOUN,
	CASE_CONTEXT_CHOICES,
	DIALOGUE_CHOICES,
	FREQUENCY_CHOICES,
	GEOGRAPHY_CHOICES,
	GRADE_CHOICES,
	KLOKKA_CHOICES,
	LEVEL_CHOICES,
	NUMGAME_CHOICES,
	NUMGAME_CHOICES_PL,
	NUMLANGUAGE_CHOICES,
	NUM_BARE_CHOICES,
	NUM_CHOICES,
	NUM_CONTEXT_CHOICES,
	NUM_LEVEL_CHOICES,
	NUM_TYPE_CHOICES,
	POS_CHOICES,
	PRONOUN_SUBCLASSES,
	PRON_CONTEXT_CHOICES,
	RECIP_REFL_CHOICES,
	SEMTYPE_CHOICES,
	SYLLABLE_VALUES,
	TRANS_CHOICES,
	VASTA_LEVELS,
	VASTAS_NR_OF_TASKWORDS,
	VERB_CLASSES,
	VTYPE_CHOICES,
	VTYPE_CONTEXT_CHOICES]


GAME_TYPE_DEFINITIONS = {
	'A': ADJECTIVE_QUESTION_ANSWER,
	'Der': DERIVATION_QUESTION_ANSWER,
	'N': NOUN_QUESTION_ANSWER,
	'Num': NUMERAL_QUESTION_ANSWER,
	'Pron': PRONOUN_QUESTION_ANSWER,
	'V': VERB_QUESTION_ANSWER,
}

GAME_FILTER_DEFINITIONS = {
	'A': ADJECTIVE_FILTER_DEFINITION,
	'Der': DERIVATION_FILTER_DEFINITION,
	'N': NOUN_FILTER_DEFINITION,
	'Num': NUMERAL_FILTER_DEFINITION,
	'Pron': PRONOUN_FILTER_DEFINITION,
	'V': VERB_FILTER_DEFINITION,
}

# #
#
# Form validation
#
# #


import re

from est_oahpa.settings import INFINITIVE_SUBTRACT as infinitives_sub
from est_oahpa.settings import INFINITIVE_ADD as infinitives_add
from est_oahpa.settings import INFINITIVE as infinitive

def relax(strict):
	"""Returns a list of relaxed possibilities, making changes by relax_pairs.

		Many possibilities are generated in the event that users are
		inconsistent in terms of substituting one letter but not substituting
		another, however, *all* possibilities are not generated.

		E.g., *ryøjnesjäjja is accepted for ryöjnesjæjja
				(user types ø instead of ö consistently)

				... but ...

			  *töølledh is not accepted for töölledh
				(user mixes the two in one word)

		Similarly, directionality is included. <i> is accepted for <ï>, but
		not vice versa.

		E.g.:  *ååjmedïdh is not accepted for ååjmedidh,
				... but ...
				*miele is accepted for mïele.
	"""
	from django.utils.encoding import force_unicode

	relaxed = strict
	sub_str = lambda _string, _target, _sub: _string.replace(_target, _sub)

	relax_pairs = {
		# key: value
		# value is accepted for key - have changed the order in the pairs because the key must be unique
		# For Russian: spellrelax for je vs jo, vowels with and without stress marks
		# Write the rules for Kven if any!
	   #u'а́': u'а',
	   #u'е́': u'е',
	   #u'и́': u'и',
	   #u'о́': u'о',
	   #u'у́': u'у',
	   #u'ы́': u'ы',
	   #u'э́': u'э',
	   #u'ю́': u'ю',
	   #u'я́': u'я',
	   #u'ё': u'е',
	}

	# Create an iterator. We want to generate as many possibilities as
	# possible (very fast), so more relaxed options are available.
	searches = relax_pairs.items()
	# HU: Commented out the following complex code because it was causing an infinite loop or similar. And the generation of relaxed forms works fine without it. :)
	#print "searches composed", searches
	#permutations = itertools.chain(itertools.permutations(searches))
	#print "permutations composed"
	#perms_flat = sum([list(a) for a in permutations], [])
	#print "list of permutations ",perms_flat

	# Individual possibilities
	relaxed_perms = [sub_str(relaxed, R, S) for R, S in searches]
	#print relaxed_perms

	# Possibilities applied one by one
	#for S, R in perms_flat:
	#	relaxed = sub_str(relaxed, R, S)
	#	relaxed_perms.append(relaxed)

	# Return list of unique possibilities
	relaxed_perms = list(set(relaxed_perms))
	relaxed_perms = [force_unicode(item) for item in relaxed_perms]

	return relaxed_perms

def is_correct(self, game, example=None):
	"""
	Determines if the given answer is correct (for a bound form).
	"""
	self.game = game
	self.example = example

	if not self.is_valid():
		return False

	self.userans = self.cleaned_data['answer']

	self.answer = self.userans.strip()

	if not game == "numra":
		self.answer = self.answer.rstrip('.!?,')

	self.error = "error"
	self.iscorrect = False

	if self.answer in set(self.correct_anslist) or \
			self.answer.lower() in set(self.correct_anslist) or \
			self.answer.upper() in set(self.correct_anslist):
		self.error = "correct"
		self.iscorrect = True

	# Log information about user answers.

	correctlist = u",".join([a for a in self.correct_anslist])
	self.correctlist = correctlist
	self.log_response()

def set_correct(self):
	"""
	Adds correct wordforms to the question form.
	"""
	if self.correct_ans:
		self.correct_answers = self.correct_ans[:]
		if type(self.correct_answers) == list:
			self.correct_answers = ', '.join(self.correct_answers)



def set_settings(self):
	# self.levels = {
	# 		'l1':  ['l1'],
	# 		'l2':  ['l2', 'l1'],
	# 		'l3':  ['l3', 'l2', 'l1'],
	# 		'all': ['l3', 'l2', 'l1', 'all'],
	# 	}

	# Construct arrays for level choices.

	# Commenting this out because I don't see yet why this needs to be constructed this way.
	# If it's done automatically so that more levels can be added, the code here will still need
	# to be altered... So it seems easiest to just hard-code this for now.

	# self.levels = {}
	# self.levels['all'] = []
	# for b in LEVEL_CHOICES:
	# 	if b[0] != 'all':
	# 		self.levels[b[0]] = []
	# 		self.levels['all'].append(b[0])
	#
	# 	self.levels[b[0]].append(b[0])
	#
	# self.levels['l2'].append('l1')
	# for b in ['l1', 'l2']:
	# 	self.levels['l3'].append(b)


	# Turning these into dictionary type means there's no need to iterate to
	# get the first tuple item. Also makes it easier to read. And, there are
	# no many-to-many relationships in these tuples of tuples

	self.allsem = dict(SEMTYPE_CHOICES).keys()
	self.allcase = dict(CASE_CHOICES).keys()
	self.allcase_context = dict(CASE_CONTEXT_CHOICES).keys()
	self.proncase_context = dict(PRON_CONTEXT_CHOICES).keys()
	self.allvtype_context = dict(VTYPE_CONTEXT_CHOICES).keys()
	self.alladjcase = dict(ADJCASE_CHOICES).keys()  # added by Heli
	self.allgrade = dict(GRADE_CHOICES).keys() # added by Heli
	self.alladj_context = dict(ADJ_CONTEXT_CHOICES).keys()
	self.allnum_context = dict(NUM_CONTEXT_CHOICES).keys()
	self.allnum_bare = dict(NUM_BARE_CHOICES).keys()
	self.allnum_type = dict(NUM_TYPE_CHOICES).keys() # added by Heli
	self.sources = dict(BOOK_CHOICES).keys()
	self.geography = dict(GEOGRAPHY_CHOICES).keys()
	self.frequency = dict(FREQUENCY_CHOICES).keys() # added by Heli
	self.allnoun_type = dict(NOUN_TYPE_CHOICES).keys() # added by Pavel


# comment
# DEBUG = open('/dev/ttys001', 'w')
# DEBUG = open('/dev/null', 'w')


def get_feedback(self, wordform, language):

	language = switch_language_code(language)

	feedbacks = wordform.feedback.filter(feedbacktext__language=language).order_by('feedbacktext__order')

	feedback_messages = []
	for feedback in feedbacks:
		texts = feedback.feedbacktext_set.filter(language=language).order_by('order')
		feedback_messages.extend([a.message for a in texts])

	message_list = []
	if feedback_messages:
		for text in feedback_messages:
			text = text.replace('WORDFORM', '"%s"' % wordform.word.lemma)
			message_list.append(text)

	self.feedback = ' \n '.join(list(message_list))

	### print wordform.fullform
	### print wordform.tag.string

	### print 'stem:' + wordform.word.stem
	### print 'gradation:' + wordform.word.gradation
	### print 'diphthong:' + wordform.word.diphthong
	### print 'rime:' + wordform.word.rime
	### print 'soggi:' + wordform.word.soggi
	### print 'attrsuffix:' + wordform.word.attrsuffix
	### print 'compsuffix:' + wordform.word.compsuffix


	### print self.feedback
	### print '--'
	### # NOTE: debug
	### # print wordform.id
	### # print wordform.feedback.all()
	### # print feedbacks
	### # print self.feedback
	### # print '\n'

def select_words(self, qwords, awords):
	"""
		Fetch words and tags from the database.
	"""
	from random import choice
	selected_awords = {}

	for syntax in awords.keys():
		word = None
		tag = None
		selected_awords[syntax] = {}

		# Select answer words and fullforms for interface
		if awords.has_key(syntax) and len(awords[syntax]) > 0:
			aword = choice(awords[syntax])
			if aword.has_key('tag'):
				selected_awords[syntax]['tag'] = aword['tag']
			if aword.has_key('task'):
				selected_awords[syntax]['task'] = aword['task']
			if aword.has_key('taskword'):
				selected_awords[syntax]['taskword'] = aword['taskword']
			if aword.has_key('qelement'):
				qelem = aword['qelement']
				if type(qelem) is not long:  # to exclude MorfaC
				    if qelem.task:  # words in VastaS answer frame where task="yes".
				        selected_awords[syntax]['taskword'] = qelem.task
			if aword.has_key('word') and aword['word']:
				selected_awords[syntax]['word'] = aword['word']
			else:
				if aword.has_key('qelement') and selected_awords[syntax].has_key('tag'):
					# get form_list for a given qelement

					wqelems = WordQElement.objects.filter(qelement__id=aword['qelement'])

					# Some WordQElements are associated with words that have no
					# Forms, as such we have to randomly select one until we
					# find an element with forms. This is faster than filtering
					# by annotating and Count()

					if wqelems.count() > 0:

						form_list = None
						i, max = 0, 50

						while not form_list and i < max:
							i += 1

							wqel = wqelems.order_by('?')[0]

							selected_awords[syntax]['word'] = wqel.word.id

							form_list = wqel.word.form_set.filter(
								tag__id = selected_awords[syntax]['tag']
							)

					if form_list:
						fullf = [f.fullform for f in form_list]
						selected_awords[syntax]['fullform'] = fullf[:]

				if not selected_awords[syntax].has_key('fullform'):
					if aword.has_key('fullform') and len(aword['fullform']) > 0:
						selected_awords[syntax]['fullform'] = aword['fullform'][:]

		if not selected_awords[syntax].has_key('fullform'):

			if selected_awords[syntax].has_key('word')\
				and selected_awords[syntax].has_key('tag'):

				form_list = Form.objects.filter(
								word__id=selected_awords[syntax]['word'],
								tag__id=selected_awords[syntax]['tag'],
							)

				excl = form_list.exclude(dialects__dialect='NG')

				if excl.count() > 0:
					form_list = excl

				form_list_dialects = form_list.filter(dialects__dialect=self.dialect)

				if form_list_dialects.count() > 0:
					form_list = form_list_dialects

				if form_list.count() > 0:
					fullf = []
					for f in form_list:
						fullf.append(f.fullform)
					selected_awords[syntax]['fullform'] = fullf[:]

		# make sure that there is something to print
		if not selected_awords[syntax].has_key('fullform'):
			selected_awords[syntax]['fullform'] = []
			selected_awords[syntax]['fullform'].append(syntax)
        print "selected awords: "
        print selected_awords
	return selected_awords



# #
#
# Oahpa form meta-classes
#
# #



class OahpaSettings(forms.Form):
	"""
		The metaform for game settings. Various games subclass from this form.
	"""
	set_settings = set_settings

	def clean(self):
		x = self.cleaned_data['bisyllabic']
		print 'clean: ', x
		return self.cleaned_data

	def set_default_data(self):
		self.default_data = {
					'language' : 'est',  # sme in univ_oahpa
					'syll' : ['2syll'], # syllabicity not relevant, change this
					'bisyllabic': 'on',
					'trisyllabic': False,
					'contracted': False,
					'level' : 'all',
					'lemmacount' : '2',
					'case': 'N-GEN',
					'pos' : 'N',
					'vtype' : 'PRS',
					'adjcase' : 'NOM',
					'number' : '',
					'pron_type': 'Pers',
					'proncase' : 'N-NOM', # Need a new default case here
					'grade' : '',  # was: '' 'Pos' is not a good idea beacuse it is implicit in the database.
					'case_context' : 'N-PAR',
					'vtype_context' : 'V-PRS',
					'pron_context' : 'P-PERS',
					'num_context' : 'NUM-ATTR',
					'num_level' : '1',
					'num_type' : 'CARD',  # added by Heli
					'derivation_type' : 'V-DER-PASS',
					'derivation_type_context' : 'DER-PASSV', # was V-DER
					'geography': 'world',
					'frequency' : [],
					'num_bare' : 'N-NOM', # Need a new default case here
					'adj_context' : 'ATTRPOS',
					'book' : 'all',
					'noun_type': 'N-MASC-INANIM',
					'singular_only' : True}




class OahpaQuestion(forms.Form):
	"""
		Meta form for question/answer section.
	"""
	is_correct = is_correct
	set_correct = set_correct
	get_feedback = get_feedback

	# Set answer widget. Can this JS actually be moved to templates?
	KEYDOWN = 'javascript:return process(this, event, document.gameform);'
	answer_attrs = {'size': 45} # , 'onkeydown': KEYDOWN}
	answer = forms.CharField(max_length=45, widget=forms.TextInput(attrs=answer_attrs))

	def log_response(self):
		import datetime

		today = datetime.date.today()
		# print ','.join(self.correct_anslist)

		log, c = Log.objects.get_or_create(userinput=self.answer,
											correct=','.join(self.correct_anslist),
											iscorrect=self.iscorrect,
											example=self.example,
											game=self.game,
											date=today)

	def __init__(self, *args, **kwargs):
		correct_val = False
		if 'correct_val' in kwargs:
			correct_val = kwargs.get('correct_val')
			kwargs.pop('correct_val')

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

		# set correct and error values
		if correct_val == "correct":
			self.error = "correct"

	def init_variables(self, possible, userans_val, accepted_answers, preferred=False):
		# Get lemma and feedback
		self.feedback = ""
		self.messages = []
		if preferred:
			self.correct_ans = preferred
		else:
			self.correct_ans = accepted_answers
		self.correct_answers = ""
		self.case = ""
		self.userans = userans_val
		self.correct_anslist = []
		self.fstring = ""  # facit string
		self.error = "empty"
		self.problems = "error"
		self.pron = ""
		self.pron_imp = ""
		self.PronPNBase = PRONOUNS_LIST
		self.is_relaxed = ""
		self.is_tcomm = ""
		forms = []
		relaxings = []
		if hasattr(self, 'translang'): # commented out these two lines, because otherwise relax was not working in Morfa
			if self.translang == 'est': # caused a problem in Numra, as NumQuestion does not have the attribute translang
				# Relax spellings.

				accepted_answers = [force_unicode(item) for item in accepted_answers]
				forms = sum([relax(force_unicode(item)) for item in accepted_answers], [])
                                #print "relaxed forms: ", forms
				# need to subtract legal answers and make an only relaxed list.
				relaxings = [item for item in forms if force_unicode(item) not in accepted_answers]
		if (hasattr(self, 'gametype') and self.gametype == 'leksa'): # this applies only to Leksa, was: elif
			# PI: commented out at this stage
			# # add infinitives as possible answers
			if self.word.pos in ['V', 'X']: # X: in case the verb does not have pos attribute set to "V" in the dictionary yet.
				if self.translang in infinitives_sub and infinitives_add:
				        infin_s = infinitives_sub[self.translang]
				        infin_a = infinitives_add[self.translang]
				        inf = infinitive[self.translang]
				        lemma = re.compile(infin_s)

				        infins = [lemma.sub(infin_a, force_unicode(ax)) for ax in accepted_answers]
				        infins_without_marker = [re.sub(inf, '', force_unicode(ax)) for ax in infins] # If the verbs are given with the infinitive marker in the dictionary.
				        accepted_answers = infins + infins_without_marker + accepted_answers

                #forms = accepted_answers  # This is wrong: the relaxed pairs are overwritten!

		self.correct_anslist = [force_unicode(item) for item in accepted_answers] + [force_unicode(f) for f in forms]
		#print "correct_anslist:",self.correct_anslist
		self.relaxings = relaxings

		#def generate_fields(self,answer_size, maxlength):
		#	self.fields['answer'] = forms.CharField(max_length = maxlength, \
         #                                       widget=forms.TextInput(\
          #  attrs={'size': answer_size, 'onkeydown':'javascript:return process(this, event,document.gameform);',}))  # copied from old-oahpa

# #
#
# Leksa Forms
#
# #

class LeksaSettings(OahpaSettings):
	semtype = forms.ChoiceField(initial='all', choices=SEMTYPE_CHOICES) # was: HUMAN
	transtype = forms.ChoiceField(choices=TRANS_CHOICES, widget=forms.Select)
	# For placename quizz
	#geography = forms.ChoiceField(initial='world', choices=GEOGRAPHY_CHOICES)
	#frequency = forms.MultipleChoiceField(required=False, widget=CheckboxSelectMultiple, choices=FREQUENCY_CHOICES)  # added
	#common = forms.BooleanField(required=False, initial='1')
	#rare = forms.BooleanField(required=False,initial=0)
	# sapmi = forms.BooleanField(required=False, initial='1')
	# world = forms.BooleanField(required=False,initial=0)
	# suopma = forms.BooleanField(required=False,initial=0)
	source = forms.ChoiceField(initial='all', choices=BOOK_CHOICES)
	# level = forms.ChoiceField(initial='all', choices=LEVEL_CHOICES, widget=forms.Select(attrs={'onchange':'javascript:return SetIndex(document.gameform.semtype,this.value);',}))

	default_data = {'gametype' : 'leksa', 'language' : 'et', 'dialogue' : 'GG',
			#'syll' : [],  # was: language : est
			#'bisyllabic': False,
			#'trisyllabic': False,
			#'bisyllabic': False,
			#'contracted': False,
			'source': 'all',
			'semtype' : 'all', # was: 'HUMAN',
			#'geography' : 'world',
			#'frequency' : ['common'] # added
			}


	# set default language pair from session language setting.
	def __init__(self, *args, **kwargs):
		if 'initial_transtype' in kwargs:
			initial_transtype = kwargs.pop('initial_transtype')
		else:
			initial_transtype = False

		self.set_settings()
		super(LeksaSettings, self).__init__(*args, **kwargs)

		if initial_transtype:
			self.fields['transtype'].initial = initial_transtype
			self.default_data['transtype'] = initial_transtype


class LeksaQuestion(OahpaQuestion):
	"""
	Questions for word quizz
	"""

	def __init__(self, tcomms, stat_pref, preferred, possible, transtype, word, correct, translations, question, userans_val, correct_val, *args, **kwargs):
		lemma_widget = forms.HiddenInput(attrs={'value' : word.id})
		self.translang = transtype[-3::]
		self.sourcelang = transtype[0:3]
		self.word = word
		self.gametype = 'leksa'
		kwargs['correct_val'] = correct_val
		super(LeksaQuestion, self).__init__(*args, **kwargs)

		self.tcomm = None
		if tcomms:
			if userans_val in tcomms:
				self.tcomm = True
			else:
				self.tcomm = None


		self.fields['word_id'] = forms.CharField(widget=lemma_widget, required=False)

        # If we want stress marks in Leksa then we have to use lemma_stressed instead of lemma.

		if type(word) == Word:
                    #if self.sourcelang == 'rus':
                     #   self.lemma = word.lemma_stressed  # for Russian the words will be presented with stress marks
                    #else:
                    self.lemma = word.lemma # for other languages 'lemma_stressed' does not exist
		else:
			self.lemma = word.definition

		if word.pos.upper() == 'V':
			if word.language in infinitives_sub and infinitives_add:
				infin_s = infinitives_sub[word.language]
				infin_a = infinitives_add[word.language]

				lemma = re.compile(infin_s)
				lemmax = lemma.sub(infin_a, force_unicode(self.lemma))
				self.lemma = force_unicode(lemmax)

		self.init_variables(possible=translations,
							userans_val=userans_val,
							accepted_answers=possible,
							preferred=preferred)

		self.is_correct("leksa", self.lemma)
		# set correct and error values
		if correct_val:
			if correct_val == "correct":
				self.error = "correct"
			# always accept relaxed spelling
			#if userans_val in self.relaxings:
				self.is_relaxed = "relaxed"
				self.strict = 'Strict form'
			#else:
			#	self.is_relaxed = ""

		if stat_pref:
			self.correct_ans = stat_pref

		# Displayed answer also needs infinitive marking
		# Needs to happen last because of stat_pref
		if word.pos.upper() == 'V':
			if self.translang in infinitives_sub and infinitives_add:
				infin_s = infinitives_sub[self.translang]
				infin_a = infinitives_add[self.translang]

				lemma = re.compile(infin_s)

				self.correct_ans = [lemma.sub(infin_a, force_unicode(ax)) for ax in self.correct_ans]
				self.correct_ans = [force_unicode(ax) for ax in self.correct_ans]




# #
#
# Morfa Forms
#
# #

class MorfaSettings(OahpaSettings):
	"""
		A form for the settings part of the game form, e.g., the form used to
		set case, stem and source books for quiz questions.

		This is a separate form from the one which validates questions and
		answers.

		PI: this is quite hardcoded (and it wasn't exactly
		easy finding where the N-ILL default value in
		$home/morfa/ came from, because instead of an
		exception there was a relatively unhelpful 404 error.
	"""
	case = forms.ChoiceField(initial='N-GEN', choices=CASE_CHOICES, widget=forms.Select)
	pron_type = forms.ChoiceField(initial='PERS', choices=PRONOUN_SUBCLASSES, widget=forms.Select)
	proncase = forms.ChoiceField(initial='N-NOM-PL', choices=CASE_CHOICES_PRONOUN, widget=forms.Select)
	adjcase = forms.ChoiceField(initial='ATTR', choices=ADJCASE_CHOICES, widget=forms.Select)  # was ADJEX_CHOICES
	vtype = forms.ChoiceField(initial='PRS', choices=VTYPE_CHOICES, widget=forms.Select)
	num_bare = forms.ChoiceField(initial='N-GEN', choices=NUM_BARE_CHOICES, widget=forms.Select)
	num_level = forms.ChoiceField(initial='1', choices=NUM_LEVEL_CHOICES, widget=forms.Select)
	num_type = forms.ChoiceField(initial='CARD',choices=NUM_TYPE_CHOICES, widget=forms.Select)
	derivation_type = forms.ChoiceField(initial='V-DER-PASS', choices=DERIVATION_CHOICES, widget=forms.Select)
	derivation_type_context = forms.ChoiceField(initial='DER-PASSV', choices=DERIVATION_CHOICES_CONTEXT, widget=forms.Select)
	num_context = forms.ChoiceField(initial='NUM-ATTR', choices=NUM_CONTEXT_CHOICES, widget=forms.Select)
	case_context = forms.ChoiceField(initial='N-NOM-PL', choices=CASE_CONTEXT_CHOICES, widget=forms.Select)
	adj_context = forms.ChoiceField(initial='ATTR', choices=ADJ_CONTEXT_CHOICES, widget=forms.Select)
	vtype_context = forms.ChoiceField(initial='V-PRS', choices=VTYPE_CONTEXT_CHOICES, widget=forms.Select)
	pron_context = forms.ChoiceField(initial='P-PERS', choices=PRON_CONTEXT_CHOICES, widget=forms.Select)
	wordform_type = forms.ChoiceField(initial='', choices=WORDFORM_TYPE_CHOICES, widget=forms.Select)
	book = forms.ChoiceField(initial='all', choices=BOOK_CHOICES, widget=forms.Select)
	bisyllabic = forms.BooleanField(required=False, initial=True)
	trisyllabic = forms.BooleanField(required=False, initial=False)
	contracted = forms.BooleanField(required=False, initial=False)
	grade = forms.ChoiceField(initial='POS', choices=GRADE_CHOICES, widget=forms.Select)

	# PI added
	noun_type = forms.ChoiceField(initial='N-MASC-INANIM', choices=NOUN_TYPE_CHOICES, widget=forms.Select)
	# HU added
	singular_only = forms.BooleanField(required=False, initial=True)

	def __init__(self, *args, **kwargs):
		self.set_settings()
		self.set_default_data()
		super(MorfaSettings, self).__init__(*args, **kwargs)

		# If this is set, then the form has been posted by the user otherwise
		# it hasn't
		try:
			post_data = args[0]
		except:
			post_data = False

		if post_data:
			# Gen2 and Loc2 mostly exist for masculine nouns:
			#if 'case' in post_data:
			#	if post_data['case'] in ['Par', 'Loc']:
			#	    self.settings['noun_type'] = "N-MASC-INANIM"
			#	    self.fields['noun_type'] = 'N-MASC-INANIM'
			# Use a restricted choice set for pronoun case for Refl and Recipr
			if 'pron_type' in post_data:
				if post_data['pron_type'].lower() in ['refl', 'recipr']:
					self.fields['proncase'].choices = RECIP_REFL_CHOICES




class MorfaQuestion(OahpaQuestion):
	"""
	Questions for morphology game.
	"""

	def __init__(self, word, tag, baseform, correct, accepted_answers,
					answer_presentation, translations, question, dialect, language,
					userans_val, correct_val, conneg, *args, **kwargs):

		lemma_widget = forms.HiddenInput(attrs={'value': word.id})
		tag_widget = forms.HiddenInput(attrs={'value': tag.id})
		self.translang = 'est'
		self.gametype = 'morfa'
		kwargs['correct_val'] = correct_val
		super(MorfaQuestion, self).__init__(*args, **kwargs)

		# initialize variables
		self.init_variables(possible=[],
							userans_val=userans_val,
							accepted_answers=accepted_answers)

		if tag.string.lower().find('neg') > -1:  # was 'conneg'
			if conneg:
				conneg_agr = conneg
			else:
				conneg_agr = choice(self.PronPNBase.keys())
		else:
			conneg_agr = False

		#print "conneg: ", conneg_agr
		conneg_widget = forms.HiddenInput(attrs={'value': conneg_agr})

		self.fields['word_id'] = forms.CharField(widget=lemma_widget, required=False)
		self.fields['tag_id'] = forms.CharField(widget=tag_widget, required=False)
		self.fields['conneg'] = forms.CharField(widget=conneg_widget, required=False)

		try:
			self.lemma = baseform.fullform
		except AttributeError:
			self.lemma = baseform

		# self.wordclass = word.wordclass
		# PI: seems to be only used for verbs at this point, so just commenting out
		if not self.pron:
			self.pron = False

		#print self.lemma, correct
		#print baseform.tag, correct.tag

		# Retrieve feedback information
		self.get_feedback(correct, language)

		# Take only the first translation for the tooltip
		if len(translations) > 0:
			self.translations = translations[0]

		if tag.pos == "N":
			self.case = tag.case

		if tag.pos == 'Pron':
			self.case = tag.case

		self.tag = tag.string

		if tag.pos == "V":
			if not self.pron:
				is_actionverb = Word.objects.filter(id=word.id, semtype__semtype__contains='ACTION_V')
				if tag.string.find("Neg") > -1:  # was ConNeg
					pers = conneg_agr
					if is_actionverb:
						pronoun = self.PronPNBase[pers]
					else:
						pronoun = "see"  # Verbs that cannot be used together with personal pronouns, e.g. "sadama", "kestma", "toimuma" will have the pronoun "see" (it) as subject.

					neg_verb = NEGATIVE_VERB_PRES[pers]

					self.pron = '%s %s' % (pronoun, neg_verb)

				elif tag.personnumber:
					if is_actionverb:
						pronbase = self.PronPNBase[tag.personnumber]
					else:
						pronbase = "see"  # Verbs that cannot be used together with personal pronouns, e.g. "sadama", "kestma", "toimuma" will have the pronoun "see" (it) as subject.
					pronoun = pronbase
					self.pron = pronoun

					if self.pron and tag.mood == "Imprt":
						self.pron_imp = "(" + self.pron + ")"
						self.pron = ""
					# TODO: conneg only in Prs

			# Odne 'today', ikte 'yesterday'
			if (tag.tense in ['Prs','Prt']) and (tag.mood == 'Ind'):
				time = TENSE_PRESENTATION.get(tag.tense, False)
				self.pron = ' '.join([time, self.pron])

			if ("+Der/Pass" in tag.string) and ("+V" in tag.string):
				# Odne mun ___
				# Ikte mun ___
				# Ikte dat (okta) ___

				# Choose one if not set, if set then game is in progress, and
				# do not choose another
				pers = tag.personnumber
				if not pers:
					pers = conneg_agr
				time = TENSE_PRESENTATION.get(tag.tense, False)
				pronoun = PASSIVE_PRONOUNS_LIST[pers]

				number = ''
				if pers in ['Sg3', 'Pl3']:
					number = '(%s)' % DEMONSTRATIVE_PRESENTATION.get(tag.personnumber, False)

				self.pron = ' '.join([time, pronoun, number])

			# All pres?
			if tag.string.find("Der/AV") > -1:
				self.pron = TENSE_PRESENTATION.get(tag.tense, False) + " " + self.pron

		if tag.pos == "Pron":
			# Various display alternations for pronouns.

			# Reciprocative:
			# 	guhtet guoibmámet
			# 	goabbat guoibmámet

			if tag.subclass == 'Recipr':
				if tag.possessive.find('PxDu'):
					px_no = 'Du'
				elif tag.possessive.find('PxPl'):
					px_no = 'Pl'
				pronoun = RECIPROCATIVE_PRESENTATION.get(px_no, False)
				if pronoun:
					self.pron = pronoun

			# Demonstrative:
			# 	dát okta
			# 	dát máŋga

			if tag.subclass == 'Dem':
				noun_pres = DEMONSTRATIVE_PRESENTATION.get(tag.number, False)

				if noun_pres:
					self.lemma += ' (%s)' % force_unicode(noun_pres).encode('utf-8')

		log_name = "morfa_%s" % tag.pos
		try:
			self.is_correct(log_name, self.lemma + "+" + self.tag)
		except TypeError:
			self.is_correct(log_name, self.lemma.lemma + "+" + self.tag)

		# set correct and error values
		if correct_val:
			if correct_val == "correct":
				self.error="correct"
			# relax
			#if userans_val in self.relaxings: let's make the spelling always relaxed
                self.is_relaxed = "relaxed"
                self.strict = 'Strict form'
			#else:
			#	self.is_relaxed = ""

		self.correct_ans = answer_presentation
# #
#
# Numra Forms
#
# #


class NumSettings(OahpaSettings):
	maxnum = forms.ChoiceField(initial='10', choices=NUM_CHOICES, widget=forms.RadioSelect)
	numgame = forms.ChoiceField(initial='numeral', choices=NUMGAME_CHOICES, widget=forms.RadioSelect)
	#numlanguage = forms.ChoiceField(initial='sjd', choices=NUMLANGUAGE_CHOICES, widget=forms.RadioSelect)
	# TODO: remove mandatory need to set default data, should be done through 'initial' field setting.
	default_data = {'language' : 'est', 'numlanguage' : 'est', 'dialogue' : 'GG', 'maxnum' : '10', 'numgame': 'numeral'}

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


class NumQuestion(OahpaQuestion):
	"""
	Questions for numeral quizz
	"""
	game_log_name = 'numra'

	def answer_relax(self, answer):
		""" Method for relaxing answers. Override if needed.
		"""

		return answer

	def is_correct(self, game, example=None):
		self.game = game
		self.example = example

		if not self.is_valid():
			return False

		self.userans = self.cleaned_data['answer']
		self.answer = self.userans.strip()

		self.error = "error"
		self.iscorrect = False

		correct_test = self.game_obj.check_answer(self.question_str,
													self.userans,
													self.correct_anslist)
		if correct_test:
			self.error = "correct"
			self.iscorrect = True

		self.correctlist = u",".join(list(set(self.correct_anslist)))

		self.log_response()


	def __init__(self, numeral, num_string, num_list, gametype, userans_val, correct_val, game, *args, **kwargs):
		numeral_widget = forms.HiddenInput(attrs={'value' : numeral})
		kwargs['correct_val'] = correct_val
		self.userans_val = self.userans = userans_val
		self.game_obj = game

		if 'no_eval_correct' in kwargs:
			no_eval_correct = kwargs.pop('no_eval_correct')
		else:
			no_eval_correct = False

		super(NumQuestion, self).__init__(*args, **kwargs)
		wforms = []
		self.relaxings = []
                self.gametype = gametype
                self.translang = 'est'

		# Initialize variables
		if gametype == "string":
			self.init_variables(force_unicode(numeral), userans_val, [ numeral ])
			example = num_string
			self.question_str = num_string
		else:
			self.init_variables(force_unicode(num_list[0]), userans_val, num_list)
			wforms = sum([relax(force_unicode(item)) for item in num_list], [])
			# need to subtract legal answers and make an only relaxed list.
			self.relaxings = [item for item in wforms if item not in num_list]
			example = numeral
			self.question_str = numeral

		self.correct_anslist = self.correct_anslist + [force_unicode(f) for f in wforms]

		self.fields['numeral_id'] = forms.CharField(widget=numeral_widget, required=False)

		if gametype == "string":
			self.numstring = num_string
		self.numeral = numeral

		# Correctness not evaluated here but in child class. Short fix

		if not no_eval_correct:
			self.is_correct(self.game_log_name, example)

		if correct_val:
			if correct_val == "correct":
				self.error = "correct"
			# relax
			if userans_val in self.relaxings:
				self.is_relaxed = "relaxed"
				self.strict = 'Strict form'
			else:
				self.is_relaxed = ""


# #
#
# Klokka Forms
#
# #


class KlokkaSettings(NumSettings):
	numgame = forms.ChoiceField(initial='string', choices=NUMGAME_CHOICES_PL, widget=forms.RadioSelect)
	gametype = forms.ChoiceField(initial='kl1', choices=KLOKKA_CHOICES, widget=forms.RadioSelect)
	default_data = {'language' : 'est', 'numlanguage' : 'est', 'dialogue' : 'GG', 'gametype' : 'kl1', 'numgame': 'string'}

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


class KlokkaQuestion(NumQuestion):
	"""
	Questions for numeral quizz
	"""
	game_log_name = "klokka"

	def relax_military(self, number):
		""" Change the presentation of numerals above 13 to their lower equivalents.

		"""
		military = [
			('13', '01'),
			('14', '02'),
			('15', '03'),
			('16', '04'),
			('17', '05'),
			('18', '06'),
			('19', '07'),
			('20', '08'),
			('21', '09'),
			('22', '10'),
			('23', '11'),
			('00', '12'),
		]
		military_dict = dict(military)

		options = [number]
		hh, _, mm = number.partition(':')

		try:
			switched = '%s:%s' % (military_dict[hh], mm)
			return switched
		except KeyError:
			return number

	def __init__(self, *args, **kwargs):
		present_list = kwargs.get('present_list')
		accept_list = kwargs.get('accept_list')
		kwargs.pop('present_list')
		kwargs.pop('accept_list')

		numeral = kwargs.get('numeral')
		num_string = kwargs.get('num_string')
		correct_val = kwargs.get('correct_val')
		userans_val = kwargs.get('userans_val')
		self.gametype = gametype = kwargs.get('gametype')
		prefix = kwargs.get('prefix')
		data = kwargs.get('data')


		numeral_widget = forms.HiddenInput(attrs={'value' : numeral})
		kwargs['correct_val'] = correct_val
		self.userans_val = self.userans = userans_val

		kwargs['num_list'] = present_list
		# Prevent double evaluation of correctness

		kwargs['no_eval_correct'] = True
		super(KlokkaQuestion, self).__init__(*args, **kwargs)

		wforms = []
		self.relaxings = []
		# Initialize variables
		if gametype == "string":
			self.init_variables(force_unicode(numeral), userans_val, [ numeral ])
			example = num_string

		else:
			self.init_variables(force_unicode(accept_list), userans_val, present_list)
			wforms = sum([relax(force_unicode(item)) for item in accept_list], [])
			# need to subtract legal answers and make an only relaxed list.
			self.relaxings = [item for item in wforms if item not in accept_list]
			example = numeral

		self.correct_anslist = self.correct_anslist + [force_unicode(f) for f in wforms]


		self.fields['numeral_id'] = forms.CharField(widget=numeral_widget, required=False)

		self.numstring = num_string

		# Need to change presentation of certain numerals to avoid
		if gametype == "string":
			relaxed_presentation = [self.relax_military(a) for a in self.correct_anslist[:]]
			self.correct_ans = relaxed_presentation + self.correct_anslist
			self.correct_ans = self.correct_ans[0]
		else:
			# Clear numstring to switch presentation
			self.numstring = None


		self.numeral = numeral

		self.is_correct(self.game_log_name, example)

		if correct_val:
			if correct_val == "correct":
				self.error = "correct"
			# relax
			if userans_val in self.relaxings:
				self.is_relaxed = "relaxed"
				self.strict = 'Strict form'
			elif userans_val in accept_list and userans_val not in present_list:
				self.is_relaxed = "relaxed"
				self.strict = 'Strict form'
			else:
				self.is_relaxed = ""

	def is_correct(self, game, example=None):
		self.game = game
		self.example = example

		if not self.is_valid():
			return False

		self.userans = self.cleaned_data['answer']
		self.answer = self.userans.strip()

		self.error = "error"
		self.iscorrect = False

		correct_test = self.game_obj.check_answer(self.question_str,
													self.userans,
													self.correct_anslist)
		if correct_test:
			self.error = "correct"
			self.iscorrect = True

		self.correctlist = u",".join(list(set(self.correct_anslist)))

		self.log_response()


# #
#
# Dato Forms
#
# #

class DatoSettings(KlokkaSettings):
	gametype = None # Disable gametype (easy, medium, hard)

	default_data = {'language' : 'est', 'numlanguage' : 'est', 'numgame': 'string'}


class DatoQuestion(KlokkaQuestion):

	game_log_name = "dato"

	def answer_relax(self, answer):
		""" No need to relax.
		"""

		return answer




# #
#
# MorfaC Forms
#
# #


class ContextMorfaQuestion(OahpaQuestion):
	"""
	Questions for contextual morfa
	"""

	select_words = select_words
	qtype_verbs = set(['MAINV', 'V-PRS', 'V-PRT', 'V-COND','V-IMPRT', 'TEST']) # added MAINV for liv

	def generate_fields(self,answer_size, maxlength):
		self.fields['answer'] = forms.CharField(max_length = maxlength, \
												widget=forms.TextInput(\
			attrs={'size': answer_size,}))

			# 'onkeydown':'javascript:return process(this, event,document.gameform);'

	def __init__(self, question, qanswer, \
				 qwords, awords, dialect, language, userans_val, correct_val, *args, **kwargs):
		self.init_variables("", userans_val, [])
		self.lemma = ""
		self.dialect = dialect
		self.translang = 'est'
		self.gametype = 'morfac' # not sure if this is ok

		qtype=question.qtype
		if qtype in self.qtype_verbs:
			qtype = 'PRS'

		question_widget = forms.HiddenInput(attrs={'value' : question.id})
		answer_widget = forms.HiddenInput(attrs={'value' : qanswer.id})
		atext = qanswer.string
		task = qanswer.task
		if not task:
			error_msg = u"not task: %s %s (%s)" % (atext, question.qid, question.qatype)

			raise Http404(error_msg)
		super(ContextMorfaQuestion, self).__init__(*args, **kwargs)

		answer_size = 20
		maxlength = 30

		self.generate_fields(20,30)

		self.fields['question_id'] = forms.CharField(widget=question_widget, required=False)
		self.fields['answer_id'] = forms.CharField(widget=answer_widget, required=False)

		# Select words for the the answer
		selected_awords = self.select_words(qwords, awords)

		relaxed = []
		form_list=[]

		if not selected_awords.has_key(task):
			raise Http404(task + " " + atext + " " + str(qanswer.id))
		if len(selected_awords[task]['fullform'])>0:
			for f in selected_awords[task]['fullform']:
				self.correct_anslist.append(force_unicode(f))

			accepted = sum([relax(force_unicode(item)) for item in self.correct_anslist], [])
			self.relaxings = [item for item in accepted if item not in self.correct_anslist]
			self.correct_anslist.extend(self.relaxings)
			log_w = Word.objects.get(id=selected_awords[task]['word'])
			w_str = log_w.lemma
			w_pos = log_w.pos
			t_str = Tag.objects.get(id=selected_awords[task]['tag']).string
			log_name = "contextual_morfa_" + w_pos
			log_value = '%s+%s' % (w_str, t_str)
			self.is_correct(log_name, log_value)
			self.correct_ans = self.correct_anslist[0]

		self.correct_anslist = [force_unicode(item) for item in accepted]

		self.qattrs = {}
		self.aattrs = {}
		for syntax in qwords.keys():
			qword = qwords[syntax]
			if qword.has_key('word'):
				self.qattrs['question_word_' + syntax] = qword['word']
			if qword.has_key('tag') and qword['tag']:
				self.qattrs['question_tag_' + syntax] = qword['tag']
			if qword.has_key('fullform') and qword['fullform']:
				self.qattrs['question_fullform_' + syntax] = qword['fullform'][0]

		for syntax in selected_awords.keys():
			if selected_awords[syntax].has_key('word'):
				self.aattrs['answer_word_' + syntax] = selected_awords[syntax]['word']
			if selected_awords[syntax].has_key('tag'):
				self.aattrs['answer_tag_' + syntax] = selected_awords[syntax]['tag']
			if selected_awords[syntax].has_key('taskword'):
				self.aattrs['answer_taskword_' + syntax] = selected_awords[syntax]['taskword']
			if selected_awords[syntax].has_key('fullform') and len(selected_awords[syntax]['fullform']) == 1:
				self.aattrs['answer_fullform_' + syntax] = selected_awords[syntax]['fullform'][0]

		# Forms question string and answer string out of grammatical elements and other strings.
		qstring = ""
		astring= ""

		# Format question string
		qtext = question.string
		for w in qtext.split():
			if not qwords.has_key(w):
				qstring = qstring + " " + force_unicode(w)
			else:
				if qwords[w].has_key('fullform'):
					qstring = qstring + " " + force_unicode(qwords[w]['fullform'][0])
				else:
					qstring = qstring + " " + force_unicode(w)
		qstring=qstring.replace(" -","-")
		qstring=qstring.replace(" .",".")


		try:
			answer_word = selected_awords[task]['word']
		except KeyError:
			answer_word = False
			# print 'fail: ', question.qid
			# print ' task: ', task
			self.error = 'error'
			self.lemma = 'error in answer words: ' + question.qid
			return
			# self.lemma = question.qid
		answer_tag = selected_awords[task]['tag']
		selected_awords[task]['fullform'][0] = 'Q'

		# Get lemma for contextual morfa
		# lemma is displayed as the 'task' word in parentheses after the question
		answer_word_el = Word.objects.get(id=answer_word)
		answer_tag_el = Tag.objects.get(id=answer_tag)
		self.lemma = answer_word_el.lemma
		self.tooltip_question_id = question.qid

		# Set tooltip translations
		transl = answer_word_el.translations2(language)
		# if len(transl) == 0:
			# transl = answer_word_el.translations2('nob') # Norwegian as default
		if len(transl) > 0:
			xl = transl[0]
			self.translations = xl.definition

		# if answer_word_el.pos == 'V':
		# 	self.wordclass = answer_word_el.wordclass

		# If the asked word is in Pl, generate nominal form

		if answer_tag_el.pos == "N":
			if qtype == "COLL-NUM":
				self.lemma = answer_word_el.lemma
			else:
				if answer_tag_el.number=="Sg" or answer_tag_el.case=="Ess" or answer_tag_el.case=="Nom":  #was: qtype="N-NOM-PL"
					self.lemma = answer_word_el.lemma
				else:
					nplforms = Form.objects.filter(word__pk=answer_word, tag__string='N+Pl+Nom')
					if nplforms.count() > 0:
						self.lemma = nplforms[0].fullform
					else:
						self.lemma = answer_word_el.lemma + " (plural) fix this"

		if qtype == "ORD-NUM":
			self.lemma = answer_word_el.lemma

		if answer_tag_el.pos == "Pron":
			# Hide task word for Recipr and Refl
			if qtype in ["P-REFL", "P-RECIPR", "P-REL"]:
				self.lemma = False

		# Retrieve feedback information
		try:
			answer_word_form = Form.objects.exclude(dialects__dialect='NG')\
										.filter(word__pk=answer_word,
												tag=answer_tag_el,
												dialects__dialect=self.dialect)
			answer_word_form = answer_word_form[0]
		except:
			answer_word_form = False

		if answer_word_form:
			self.get_feedback(answer_word_form, language)

		# Format answer string
		for w in atext.split():
			if w.count("(") > 0:
			  continue

			if not selected_awords.has_key(w) or not selected_awords[w].has_key('fullform'):
				astring = astring + " " + force_unicode(w)
			else:
				astring = astring + " " + force_unicode(selected_awords[w]['fullform'][0])

		# Remove leading whitespace and capitalize.
		astring = astring.lstrip()
		qstring = qstring.lstrip()
		astring = astring[0].capitalize() + astring[1:]
		qstring = qstring[0].capitalize() + qstring[1:]

		qstring = qstring + "?"
		# Add dot if the last word is not the open question.
		if astring.count("!")==0 and not astring[-1]=="Q":
			astring = astring + "."
		self.question=qstring

		# Format answer strings for context
		q_count = astring.count('Q')
		if q_count > 0:
			astrings = astring.split('Q')
			if astrings[0]:
				self.answertext1 = astrings[0]
			if astrings[1]:
				self.answertext2 = astrings[1]

		# set correct and error values
		if correct_val:
			if correct_val == "correct":
				self.error="correct"
			# relax
			if userans_val in self.relaxings:
				self.is_relaxed = "relaxed"
				self.strict = 'Strict form'
			else:
				self.is_relaxed = ""

		if answer_word == False:
			self.lemma = '%s - error: %s' % (answer_word_el.lemma, question.qid)



def vasta_is_correct(self,question,qwords,language,utterance_name=None):
    """
    Analyzes the answer and returns a message.
    """
    if not self.is_valid():
        return None, None, None

    noanalysis=False

    fstdir = settings.FST_DIRECTORY
    toolsdir = settings.TOOLS_DIRECTORY + "/preprocess"
    fst = fstdir + "/analyser-forcg-desc.hfst"
    lo = settings.HFST_LOOKUP
	#fst = fstdir + "/analyser-gt-desc.xfst" # hfst
    #lo = settings.LOOKUP_TOOL
    #lo="/Users/mslm/bin/lookup" # xfst on Heli's machine
    lookup = " | " + lo + " -q -p " + fst # hfset
    #lookup = " | " + lo + " -flags mbTT -utf8 -d " + fst # xfst
    lookup2cg = " | cut -f1-2 | " + settings.TOOLS_DIRECTORY + "/lookup2cg " # hfst
    cg3 = "/usr/local/bin/vislcg3"
    preprocess = " | " + settings.TOOLS_DIRECTORY + "/preprocess "
    #preprocess = " | /Users/mslm/main/gt/script/preprocess "
    disamb = fstdir + "/disambiguation.cg3"
    synt_funcs = fstdir + "/functions.cg3"

    vislcg3 = " | " + toolsdir + "/tagger " + toolsdir + "/addlex.lx stdin stdout | perl " + toolsdir + "/pron.pl | " + cg3 + " --grammar " + disamb + " | " + cg3 + " --grammar " + synt_funcs

    self.userans = self.cleaned_data['answer']
    answer = self.userans.rstrip()
    answer = answer.celstrip()
    answer = answer.rstrip('.!?,')

    self.error = "error"

    qtext = question
    qtext = qtext.rstrip('.!?,')

    logfile = open('vastaF_log.txt','w')
    logfile.write(lookup+"\n");
    logfile.write(lookup2cg+"\n");
    logfile.write(vislcg3+"\n");
    logfile.write(question+"\n");
    logfile.write(answer+"\n");

    """host = 'localhost'
    port = 9000  # was: 9000, TODO - add to settings.py
    size = 1024

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((host,port)) # on victorio
        sys.stdout.write('%')

        analysis = ""
        question_lookup = "echo \"" + qtext + "\"" + preprocess
        words = os.popen(question_lookup).readlines()
        for qword in words: # or qwords ?
            cohort=""
            w = qword.lstrip().rstrip()
            s.send(w)  # on victorio
            cohort = s.recv(size)

            if not cohort or cohort == w:
                cohort = w + "\n"
            if cohort=="error":
                raise Http500
            analysis = analysis + cohort

        if self.gametype=="sahka":
            analysis = analysis + "\"<^qdl_id>\"\n\t\"^sahka\" QDL " + utterance_name +"\n"
        else:
            analysis = analysis + "\"<^qst>\"\n\t\"^qst\" QDL\n"

	   #logfile.write(analysis+"\n")
        data_lookup = "echo \"" + answer.encode('utf-8') + "\"" + preprocess
        words = os.popen(data_lookup).readlines()
        analyzed=""
        for w in words:
            w=w.strip()
            s.send(w)  # on vic
            analyzed = analyzed + s.recv(size)
        s.send("q")  # on vic
        s.close()

    except socket.error:    # port 9000 not available => morph. analysis will be done by ped-sme.fst """
    # analyse words in the question
    analysis = ""
    """question_lookup = "echo \"" + qtext + "\"" + preprocess # testing without FST+CG analysis of question and answer
    words = os.popen(question_lookup).readlines()
    for qword in words: # or qwords ?
            cohort=""
            w = qword.lstrip().rstrip()
            word_lookup = "echo \"" + force_unicode(w).encode('utf-8') + "\"" + lookup + lookup2cg  # on Heli's machine
            morfanal = os.popen(word_lookup).readlines()
            for row in morfanal:
                row = row.strip()
                cohort = cohort + row + "\n" + "\t"
            if not cohort or cohort == w:
                cohort = w + "\n"
            if cohort=="error":
                raise Http500
            analysis = analysis + cohort""" #testing
    if self.gametype=="sahka":
            analysis = analysis + "\"<^qdl_id>\"\n\t\"^sahka\" QDL " + utterance_name +"\n"
    else:
            analysis = analysis + "\"<^qst>\"\n\t\"^qst\" QDL\n"
    logfile.write(analysis+"\n")

    # analyse words in the answer
    """data_lookup = "echo \"" + answer.encode('utf-8') + "\"" + preprocess
    words = os.popen(data_lookup).readlines()
    analyzed=""
    for w in words:
            w=w.strip()
            word_lookup = "echo \"" + force_unicode(w).encode('utf-8') + "\"" + lookup + lookup2cg  # on Heli's machine
            morfanal = os.popen(word_lookup).readlines()
            ans_cohort=""
            for row in morfanal:
                row = row.strip()
                ans_cohort = ans_cohort + row + "\n" + "\t"
            analyzed = analyzed + ans_cohort
   # except socket.timeout:
    #    raise Http404("Technical error, please try again later.")

    logfile.write(analyzed+"\n")
    analysis = analysis + analyzed"""
    analysis = analysis + "\"<.>\"\n\t\".\" CLB"
    analysis = analysis.rstrip()
    analysis = analysis.replace("\"","\\\"")

    ped_cg3 = "echo \"" + analysis + "\"" + vislcg3
    checked = os.popen(ped_cg3).readlines()
    logfile.close()

    wordformObj=re.compile(r'^\"<(?P<msgString>.*)>\".*$', re.U)
    messageObj=re.compile(r'^.*(?P<msgString>&(grm|err|sem)[\w-]*)\s*$', re.U)
    targetObj=re.compile(r'^.*\"(?P<targetString>[\wáÁæÆåÅáÁšŠŧŦŋŊøØđĐžZčČ-]*)\".*dia-.*$', re.U)
    # Extract the lemma
    constantObj=re.compile(r'^.*\"\<(?P<targetString>[\wáÁæÆåÅáÁšŠŧŦŋŊøØđĐžZčČ-]*)\>\".*$', re.U)
    diaObj=re.compile(r'^.*(?P<targetString>&dia-[\w]*)\s*$', re.U)

    # Each wordform may have a set of tags.
    spelling = False
    msgstrings = {}
    diastring = "jee"
    lemma=""
    for line in checked:
        line = line.strip()
	   #logfile.write(line+"\n")

        #Find the lemma first
        matchObj=constantObj.search(line)
        if matchObj:
            lemma = matchObj.expand(r'\g<targetString>')

        #The wordform
        matchObj=wordformObj.search(line)
        if matchObj:
            wordform = matchObj.expand(r'\g<msgString>')
            msgstrings[wordform] = {}

        #grammatical/semantic/other error
        matchObj=messageObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<msgString>')
            if msgstring.count("spellingerror") > 0:
                spelling = True
            msgstrings[wordform][msgstring] = 1

        #Store the baseform if tehre is dia-whatever
        matchObj=targetObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<targetString>')
            msgstrings[wordform]['dia-target'] = msgstring
            msgstrings[wordform]['dia-lemma'] = lemma

        # What is the dia-tag?
        matchObj=diaObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<targetString>')
            msgstrings[wordform][msgstring] = 1
            diastring=msgstring


    msg=[]
    dia_msg = []
    target = ""
    variable=""
    constant=""
    found=False
    #Interface language
    if not language: language = "eng"
    language = switch_language_code(language)
    #if language == "no" : language = "nob"
    #if language == "fi" : language = "fin"
    #if language == "en" : language = "eng"
    if not language in ["nob","sme","fin","eng","swe","est"]: language="eng"
    for w in msgstrings.keys():
        if found: break
        for m in msgstrings[w].keys():
            if spelling and m.count("spelling") == 0: continue
            m = m.replace("&","")
            if Feedbackmsg.objects.filter(msgid=m).count() > 0:
                msg_el = Feedbackmsg.objects.filter(msgid=m)[0]
                message = Feedbacktext.objects.filter(feedbackmsg=msg_el,language=language)[0].message
                message = message.replace("WORDFORM","\"" + unicode(w, 'utf-8') + "\"")
                msg.append(message)
                if not spelling:
                    found=True
                    break
            else:
                if m.count("dia-") == 0:
                    msg.append(m)
                    if not spelling:
                        found=True
                        break
            if m.count("dia-") > 0:
                dia_msg.append(m)
        if msgstrings[w].has_key('dia-target'):
            constant = msgstrings[w]['dia-lemma']
            variable = msgstrings[w]['dia-target']
        if msgstrings[w].has_key('dia-unknown'):
            constant = msgstrings[w]['dia-lemma']
            variable = msgstrings[w]['dia-unknown']

    #iscorrect is used only in logging
    iscorrect=False
    if not msg:
        self.error = "correct"
        iscorrect=True

    feedbackmsg=' '.join(msg)
    today=datetime.date.today()
    log = Log.objects.create(userinput=self.userans,feedback=feedbackmsg,iscorrect=iscorrect,example=question,game=self.gametype,date=today)
    log.save()

    variables = []
    variables.append(variable)
    variables.append(constant)
    return msg, dia_msg, variables


class VastaSettings(OahpaSettings):

    book = forms.ChoiceField(initial='all', choices=BOOK_CHOICES, widget=forms.Select)
    level = forms.ChoiceField(initial='1', choices=VASTA_LEVELS, widget=forms.Select)

    def __init__(self, *args, **kwargs):
        self.set_settings()
        self.set_default_data()
        self.default_data['gametype'] = 'qa'
        super(VastaSettings, self).__init__(*args, **kwargs)

class VastaQuestion(OahpaQuestion):
    """
    Questions for vasta
    """

    select_words = select_words
    vasta_is_correct = vasta_is_correct

    def __init__(self, question, qwords, language, userans_val, correct_val, *args, **kwargs):

        self.init_variables("", userans_val, [])

        question_widget = forms.HiddenInput(attrs={'value' : question.id})

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

        maxlength=50
        answer_size=50
        self.fields['answer'] = forms.CharField(max_length = maxlength, \
                                                widget=forms.TextInput(\
            attrs={'size': answer_size, 'onkeydown':'javascript:return process(this, event, document.gameform);',}))

        self.fields['question_id'] = forms.CharField(widget=question_widget, required=False)

        self.qattrs= {}
        for syntax in qwords.keys():
            qword = qwords[syntax]
            if qword.has_key('word'):
                self.qattrs['question_word_' + syntax] = qword['word']
            if qword.has_key('tag') and qword['tag']:
                self.qattrs['question_tag_' + syntax] = qword['tag']
            if qword.has_key('fullform') and qword['fullform']:
                self.qattrs['question_fullform_' + syntax] = qword['fullform'][0]

        # Forms question string and answer string out of grammatical elements and other strings.
        qstring = ""

        # Format question string
        qtext = question.string
        for w in qtext.split():
            if not qwords.has_key(w): qstring = qstring + " " + force_unicode(w)
            else:
                if qwords[w].has_key('fullform'):
                    qstring = qstring + " " + force_unicode(qwords[w]['fullform'][0])
                else:
                    qstring = qstring + " " + w
        # this is for -guovttos
        qstring=qstring.replace(" -","-");
        qstring=qstring.replace("- ","-");

        # Remove leading whitespace and capitalize.
        qstring = qstring.lstrip()
        qstring = qstring[0].capitalize() + qstring[1:]

        qstring = qstring + "?"
        self.question=qstring

        # In qagame, all words are considered as answers.
        self.gametype="vasta"
        self.messages, jee, joo  = self.vasta_is_correct(qstring.encode('utf-8'), qwords, language)

        # set correct and error values
        if correct_val == "correct":
            self.error="correct"


def sahka_is_correct(self,utterance,targets,language):
    """
    Analyzes the answer and returns a message.
    """
    if not self.is_valid():
        return False

    if not self.cleaned_data.has_key('answer'):
        return
    qwords = {}
    # Split the question to words for analaysis.

    self.messages, self.dia_messages, self.variables = self.vasta_is_correct(utterance.utterance, None, language, utterance.name)
    #self.variables = [ "Kárášjohka" ]
    #self.dia_messages = [ "dia-unknown" ]

    if not self.messages:
        self.error = "correct"

    for answer in self.dia_messages:
        answer = answer.lstrip("dia-")
        if answer == "target":
            self.target = answer


class SahkaSettings(OahpaSettings):

    #dialogue = forms.ChoiceField(initial='firstmeeting', choices=DIALOGUE_CHOICES, widget=forms.Select)

    def __init__(self, *args, **kwargs):
        self.set_settings()
        self.set_default_data()
        self.default_data['gametype'] = 'sahka'
        self.default_data['dialogue_id'] = '1'
        self.default_data['dialogue'] = 'firstmeeting'
        self.default_data['topicnumber'] = '0'
        self.default_data['image'] = 'sahka.png'
        self.default_data['wordlist'] = ''
        self.default_data['num_fields'] = '2'
        super(SahkaSettings, self).__init__(*args, **kwargs)

        # Link to grammatical explanation for each page
        self.grammarlinkssme = Grammarlinks.objects.filter(language="sme")
        self.grammarlinksno = Grammarlinks.objects.filter(language="no")

    def init_hidden(self, topicnumber, num_fields, dialogue, image, wordlist):

        # Store topicnumber as hidden input to keep track of topics.
        #print "topicnumber", topicnumber
        #print "num_fields", num_fields
        topicnumber = topicnumber
        num_fields = num_fields
        dialogue = dialogue
        image = image
        wordlist = wordlist


class SahkaQuestion(OahpaQuestion):
    """
    Sahka: Dialogue game
    """

    select_words = select_words
    sahka_is_correct = sahka_is_correct
    vasta_is_correct = vasta_is_correct

    def __init__(self, utterance, qwords, targets, global_targets, language, userans_val, correct_val, *args, **kwargs):

        self.init_variables("", userans_val, [])

        utterance_widget = forms.HiddenInput(attrs={'value' : utterance.id})

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

        if utterance.utttype == "question":
            maxlength=50
            answer_size=50
            self.fields['answer'] = forms.CharField(max_length = maxlength, \
                                                    widget=forms.TextInput(\
            attrs={'size': answer_size, 'onkeydown':'javascript:return process(this, event, document.gameform);',}))

        self.fields['utterance_id'] = forms.CharField(widget=utterance_widget, required=False)

        self.global_targets = global_targets
        #print self.global_targets
        self.utterance =""
        self.qattrs={}

        if utterance:
            self.utterance_id=utterance.id
            #self.utterance=utterance.utterance

            # Forms question string and answer string out of grammatical elements and other strings.
            qstring = ""

            # Format question string
            qtext = utterance.utterance
            for w in qtext.split():
                if not qwords.has_key(w):
                    qstring = qstring + " " + force_unicode(w)
                    self.qattrs['question_fullform_' + w] = force_unicode(w)
                else:
                    if qwords[w].has_key('fullform'):
                        qstring = qstring + " " + force_unicode(qwords[w]['fullform'][0])
                        self.qattrs['question_fullform_' + w] = qwords[w]['fullform'][0]
                    else:
                        qstring = qstring + " " + w
                        self.qattrs['question_fullform_' + w] = w

            # this is for -guovttos
            qstring=qstring.replace(" -","-");
            qstring=qstring.replace("- ","-");

            # Remove leading whitespace and capitalize.
            qstring=qstring.replace(" .",".");
            qstring=qstring.replace(" ?","?");
            qstring=qstring.replace(" !","!");

            qstring = qstring.lstrip()
            if len(qstring)>0:
                qstring = qstring[0].capitalize() + qstring[1:]

            self.utterance=qstring

        self.target=""
        self.constant=""
        self.dia_messages = ""
        self.gametype="sahka"
        self.variables = []
        self.variables.append("")
        self.variables.append("")
        self.sahka_is_correct(utterance,targets,language)
        if self.target:
            variable=""
            constant=""
            if utterance.links.filter(target=self.target).count()>0:
                variable = utterance.links.filter(target=self.target)[0].variable
                if variable:
                    self.qattrs['target_' + variable] = self.variables[0]
                    self.global_targets[variable] = { 'target' : self.variables[0] }
                constant = utterance.links.filter(target=self.target)[0].constant
                if constant:
                    self.qattrs['target_' + constant] = self.variables[1]
                    self.global_targets[constant] = { 'target' : self.variables[1] }
        for t in self.global_targets.keys():
            if not self.qattrs.has_key(t):
                self.qattrs['target_' + t] = self.global_targets[t]['target']

        #self.error="correct"
        self.errormsg = ""

        if correct_val == "correct":
            self.error="correct"

###########
## Vasta-S (Cealkka)
###########
def cealkka_is_correct(self,question,qwords,awords,language,question_id=None):  #was: question_id=None
    """
    Analyzes the answer and returns a message.
    """
    if not self.is_valid():
        return None, None, None

    noanalysis=False
    fstdir = settings.FST_DIRECTORY
    toolsdir = settings.TOOLS_DIRECTORY + "/preprocess"
    fst = fstdir + "/analyser-forcg-desc.hfst" # hfst
    #fst = fstdir + "/analyser-gt-desc.xfst" # hfst
    #lo = settings.LOOKUP_TOOL
    lo = settings.HFST_LOOKUP
    #lo="/Users/mslm/bin/lookup" # xfst on Heli's machine
    lookup = " | " + lo + " -q -p " + fst # hfst
    #lookup = " | " + lo + " -flags mbTT -utf8 -d " + fst # xfst
    lookup2cg = " | cut -f1-2 | " + settings.TOOLS_DIRECTORY + "/lookup2cg " # hfst
    cg3 = "/usr/local/bin/vislcg3"
    preprocess = settings.TOOLS_DIRECTORY + "/preprocess "
    #preprocess = " | /Users/mslm/main/gt/script/preprocess "
    disamb = settings.FST_DIRECTORY + "/disambiguation.cg3"
    synt_funcs = settings.FST_DIRECTORY + "/functions.cg3"
    oahpa_funcs = settings.FST_DIRECTORY + "/oahpa.cg3"
    corr = settings.DEV_DIRECTORY + "/corr.py"

    vislcg3 = " | " + toolsdir + "/tagger " + toolsdir + "/addlex.lx stdin stdout | perl " + toolsdir + "/pron.pl | " + cg3 + " --grammar " + disamb + " | " + cg3 + " --grammar " + synt_funcs + " | python3 " + corr + " | " + cg3 + " --prefix '&' --num-windows 1 --single-run --grammar " + oahpa_funcs

    self.userans = self.cleaned_data['answer']
    facit = self.cleaned_data['fstring']
    answer = self.userans.rstrip()
    answer = answer.lstrip()
    answer = answer.rstrip('.!?,')
    #print answer

    self.error = "error"

    qtext = question
    qtext = qtext.rstrip('.!?,')

    logfile = open('vastas_log.txt', 'w')
    """host = 'localhost'
    port = 9000  # was: 9000, TODO - add to settings.py
    size = 1024

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((host,port)) # on vic
        sys.stdout.write('%')

        analysis = ""
        data_lookup = "echo \"" + qtext + "\"" + preprocess
        words = os.popen(data_lookup).readlines()
        print question_id
        #print words
        #print qwords
        for word in words:
            w=""
            cohort=""
            #print word
            # All the words will go through morph.analyser, even if they have a tag-attribute already. We do it to avoid problems with compound words.
            w = force_unicode(word).encode('utf-8')
            w=w.lstrip().rstrip()
            s.send(w) # on victorio
            cohort = s.recv(size)
            analysis = analysis + cohort
            #logfile.write(analysis+"\n")
            #print analysis
        ### Lemmas and POS tags of task words are gathered into the variables
        ### tasklemmas and taskpos respectively. Tasklemmas and taskpos will be
        ### sent to CG together with the morph. analysed question and answer.
        tasklemmas = ""
        for aword in awords:
            #print aword
	        #logfile.write(aword)
            if aword.has_key('taskword') and aword['taskword']:
                tlemma = aword['fullform']
                tlemma = force_unicode(tlemma).encode('utf-8')
                tlemma = tlemma.strip()
                #print tlemma
		        #logfile.write(tlemma+" ")
                tasktag = Tag.objects.filter(id=aword['tag'])
                tasktagstring = tasktag[0].string
                taskpos = tasktag[0].pos
                ttag = tasktagstring.replace("+"," ")
                #print ttag
		        #logfile.write(ttag+"\n")
                s.send(tlemma)  # on vic
                word_lookup = s.recv(size)  # on vic
		        #logfile.write(word_lookup)
                ans_cohort=""
                #print rows
                rows = word_lookup.split("\n")  # on vic
                morfanal = ""
                for row in rows:
                    ans_cohort = ans_cohort + row
		              #logfile.write(row + "\n")
                    malemmas = row.split("\"")
                    if row:
			             malemma = malemmas[1]
                    malemma_without_hash = malemma.replace('#','')
                    taglist = ttag.split()
                    tag_match = 1
                    for entag in taglist:
                        if entag not in row:
                            tag_match = 0
                    if tag_match and tlemma == malemma_without_hash:  # 'Sg Nom' or 'V Inf' is not enough - exact tag sequence needed, and also need to compare the primary form to the analysed word, to resolve ambiguities
                        print malemmas
			             #logfile.write(malemma+"\n")
                        #print malemma
                        print malemma_without_hash
                        tasklemmas = tasklemmas + "\n\t\"" + malemma + "\" "+taskpos
                    morfanal = morfanal + ans_cohort  # END

        analysis = analysis + "\"<^vastas>\"\n\t\"^vastas\" QDL " + question_id + " " + tasklemmas + "\n"
        #####
        print analysis
	   #logfile.write(analysis)
        data_lookup = "echo \"" + force_unicode(answer).encode('utf-8') + "\"" + preprocess
        word = os.popen(data_lookup).readlines()
        #print word
        analyzed=""
        for c in word:
            c=c.strip()
            print c
            s.send(c) # on vic
            analyzed = analyzed + s.recv(size)

        s.send("q")  # on vic
        s.close()  # on vic


    except socket.error:"""
    analysis = ""
    """
    # analysis = force_unicode(analysis).encode('utf-8') + "\"<^vastas>\"\n\t\"^vastas\" QDL " + force_unicode(question_id).encode('utf-8') + " " + tasklemmas + "\n"
    analysis = force_unicode(analysis).encode('utf-8') + "\"<^vastas>\" \n\t\"^vastas\"  QDL \n"

    # analyse the facit
    data_lookup = "echo \"" + force_unicode(facit).encode('utf-8') + "\"" + preprocess
    word = os.popen(data_lookup).readlines()
    #print word
    analyzed_facit=""
    for c in word:
        c=c.strip()
        word_lookup = "echo \"" + force_unicode(c).encode('utf-8') + "\"" + lookup + lookup2cg  # on Heli's machine
        morfanal = os.popen(word_lookup).readlines()
        facit_cohort=""
        for row in morfanal:
                facit_cohort = facit_cohort + row
        analyzed_facit = analyzed_facit + facit_cohort

    # analyse the user's answer
    data_lookup = "echo \"" + force_unicode(answer).encode('utf-8') + "\"" + preprocess
    word = os.popen(data_lookup).readlines()
    #print word
    analyzed_answer=""
    for c in word:
        c=c.strip()
        word_lookup = "echo \"" + force_unicode(c).encode('utf-8') + "\"" + lookup + lookup2cg  # on Heli's machine
        morfanal = os.popen(word_lookup).readlines()
        ans_cohort=""
        for row in morfanal:
                ans_cohort = ans_cohort + row
        analyzed_answer = analyzed_answer + ans_cohort

    #except socket.timeout:
        #raise Http404("Technical error, please try again later.")


    analysis = analysis + "\"<?>\"\n\t\"?\" CLB \n" + analyzed_facit + "\"<.>\"\n\t\".\" CLB" + "\n\"<^vastas>\" \n\t\"^vastas\" QDL \n" + analyzed_answer
    analysis = analysis + "\"<.>\"\n\t\".\" CLB"
    analysis = analysis.rstrip()
    analysis = analysis.replace("\"","\\\"")
    print analysis """
    input_for_pipeline = force_unicode(qtext).encode('utf-8') + "?" + " ^vastas " + force_unicode(facit).encode('utf-8') + "." + " ^vastas " + force_unicode(answer).encode('utf-8') + "."
    #logfile.write(input_for_pipeline)
    ped_cg3 = "echo \"" + input_for_pipeline + "\" | " + preprocess + lookup + lookup2cg + vislcg3
    logfile.write(ped_cg3)
    process = subprocess.Popen(ped_cg3, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
    logfile.write("\n Parsed text: \n");
    checked, errors = process.communicate()
    logfile.write(checked)
    logfile.write(errors)
    #print checked

    wordformObj=re.compile(r'^\"<(?P<msgString>.*)>\".*$', re.U)
    messageObj=re.compile(r'^.*(?P<msgString>&(grm|err|sem)[\w-]*)\s*$', re.U)
    targetObj=re.compile(r'^.*\"(?P<targetString>[\wšŠžŽäÄöÖüÜõÕ-]*)\".*dia-.*$', re.U)
    # Extract the lemma
    constantObj=re.compile(r'^.*\"\<(?P<targetString>[\wšŠžŽäÄöÖüÜõÕ-]*)\>\".*$', re.U)
    diaObj=re.compile(r'^.*(?P<targetString>&dia-[\w]*)\s*$', re.U)

    # Each wordform may have a set of tags.
    spelling = False
    msgstrings = {}
    diastring = "jee"
    lemma=""
    for line in checked.split('\n'):  # was: for line in checked:
        line = line.strip()
        #logfile.write("XXXXXXXXXXX "+ line+"\n")

        #Find the lemma first
        matchObj=constantObj.search(line)
        if matchObj:
            lemma = matchObj.expand(r'\g<targetString>')


        #logfile.write("lemma: " + lemma)
        #The wordform
        matchObj=wordformObj.search(line)
        if matchObj:
            wordform = matchObj.expand(r'\g<msgString>')
            msgstrings[wordform] = {}


        #logfile.write("wordform: " + wordform)
        #grammatical/semantic/other error
        matchObj=messageObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<msgString>')
            #logfile.write("msgstring: " + msgstring)
            if msgstring.count("spellingerror") > 0:
                spelling = True
            msgstrings[wordform][msgstring] = 1

        #Store the baseform if there is dia-whatever
        matchObj=targetObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<targetString>')
            msgstrings[wordform]['dia-target'] = msgstring
            msgstrings[wordform]['dia-lemma'] = lemma

        # What is the dia-tag?
        matchObj=diaObj.search(line)
        if matchObj:
            msgstring = matchObj.expand(r'\g<targetString>')
            msgstrings[wordform][msgstring] = 1
            diastring=msgstring

    msg=[]
    dia_msg = []
    target = ""
    variable=""
    constant=""
    found=False
    #Interface language
    if not language: language = "eng"
    language = switch_language_code(language)
    #if language == "no" : language = "nob"
    #if language == "fi" : language = "fin"
    #if language == "en" : language = "eng"
    if not language in ["nob","sme","fin","eng","swe","est"]: language="eng"

    for w in msgstrings.keys():
        if found: break
        for m in msgstrings[w].keys():
            if spelling and m.count("spelling") == 0: continue
            m = m.replace("&","")
            logfile.write("message id: " + m)
            if Feedbackmsg.objects.filter(msgid=m).count() > 0:
                msg_el = Feedbackmsg.objects.filter(msgid=m)[0]
                message = Feedbacktext.objects.filter(feedbackmsg=msg_el,language=language)[0].message
                message = message.replace("WORDFORM","\"" + unicode(w,'utf-8') + "\"")
                msg.append(message)
                if not spelling:
                    found=True
                    break
            else:
                if m.count("dia-") == 0:
                    msg.append(m)
                    if not spelling:
                        found=True
                        break
            if m.count("dia-") > 0:
                dia_msg.append(m)
        if msgstrings[w].has_key('dia-target'):
            constant = msgstrings[w]['dia-lemma']
            variable = msgstrings[w]['dia-target']
        if msgstrings[w].has_key('dia-unknown'):
            constant = msgstrings[w]['dia-lemma']
            variable = msgstrings[w]['dia-unknown']

    #iscorrect is used only in logging
    iscorrect=False
    if not msg:
        self.error = "correct"
        iscorrect=True

    feedbackmsg=' '.join(msg)
    today=datetime.date.today()
    log = Log.objects.create(userinput=self.userans,feedback=feedbackmsg,iscorrect=iscorrect,\
                                       example=question,game=self.gametype,date=today)
    log.save()
    logfile.close()

    variables = []
    variables.append(variable)
    variables.append(constant)
    return msg, dia_msg, variables


class CealkkaSettings(OahpaSettings):

    book = forms.ChoiceField(initial='all', choices=BOOK_CHOICES, widget=forms.Select)
    level = forms.ChoiceField(initial='1', choices=VASTA_LEVELS, widget=forms.Select)
    lemmacount = forms.ChoiceField(initial='2', choices=VASTAS_NR_OF_TASKWORDS, widget=forms.Select)

    def __init__(self, *args, **kwargs):
        self.set_settings()
        self.set_default_data()
        self.default_data['gametype'] = 'cealkka',
        super(CealkkaSettings, self).__init__(*args, **kwargs)

class CealkkaQuestion(OahpaQuestion):
    """
    Questions for cealkka
    """

    select_words = select_words
    cealkka_is_correct = cealkka_is_correct

    def __init__(self, question, qanswer, qfacit, qwords, awords, fwords, dialect, language, userans_val, correct_val, *args, **kwargs):

        self.init_variables("", userans_val, [])
        self.dialect = dialect
        self.gametype = "cealkka"
        qtype=question.qtype
        atext = qanswer.string
        #print "answertext:", atext
        # qfacit = Question.objects.filter(question=question.id,qatype="facit")[0] # This is done in cealkka.py.
        ftext = qfacit.string
        #print "facittext", ftext

        question_widget = forms.HiddenInput(attrs={'value' : question.id})
        answer_widget = forms.HiddenInput(attrs={'value' : qanswer.id})  #was: qanswer.id
        facit_widget = forms.HiddenInput(attrs={'value' : qfacit.id})

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

        maxlength=50
        answer_size=50
        self.fields['question_id'] = forms.CharField(widget=question_widget, required=False)

        self.fields['answer_id'] = forms.CharField(widget=answer_widget, required=False)

        self.fields['facit_id'] = forms.CharField(widget=facit_widget, required=False)

        self.fields['answer'] = forms.CharField(max_length = maxlength, \
                                                widget=forms.TextInput(\
        attrs={'size': answer_size, 'onkeydown':'javascript:return process(this, event, document.gameform);',}))

        # Select words for the answer
        astring = ""
        #print "awords that come in CealkkaQuestion as parameter: "
        #print awords
        #print "facit:"
        #print fwords
        selected_awords = self.select_words(qwords, awords)

        awords = []
        for token in atext.split():	   # det här har jag (Heli) hittat på
            if token.isupper():  # added because of keyerror
                word = selected_awords[token]
                if word.has_key('fullform') and word['fullform']:
                    word['fullform'] = force_unicode(word['fullform'][0])
            else:
                word = {}
                word['fullform'] = token
                word['taskword'] = ""
            awords.append(word)
            astring=astring+" "+force_unicode(word['fullform'])

        astring = astring.lstrip()
        #print astring

        self.awords=awords

        # Select words for the facit
        if fwords:
            fstring = ""
            selected_fwords = self.select_words(awords, fwords)
            #print "selected facitwords: ", selected_fwords

            fwords = []
            for token in ftext.split():	   # det här har jag (Heli) hittat på
                if token.isupper():  # added because of keyerror
                    word = selected_fwords[token]
                    if word.has_key('fullform') and word['fullform']:
                        word['fullform'] = force_unicode(word['fullform'][0])
                else:
                    word = {}
                    word['fullform'] = token
                    word['taskword'] = ""
                fwords.append(word)
                fstring=fstring+" "+force_unicode(word['fullform'])

            fstring = fstring.lstrip()
            # print "facit string: ", fstring
            self.fstring = fstring
            self.fwords=fwords


        fstring_widget = forms.HiddenInput(attrs={'value': self.fstring})  # provar mig fram
        self.fields['fstring'] = forms.CharField(widget=fstring_widget, required=False)

        relaxed = []
        form_list=[]

        self.qattrs= {}
        self.aattrs = {}
        for syntax in qwords.keys():
            qword = qwords[syntax]
            if qword.has_key('word'):
                self.qattrs['question_word_' + syntax] = qword['word']
            if qword.has_key('tag') and qword['tag']:
                self.qattrs['question_tag_' + syntax] = qword['tag']
            if qword.has_key('fullform') and qword['fullform']:
                self.qattrs['question_fullform_' + syntax] = qword['fullform'][0]
        for syntax in selected_awords.keys():
            if selected_awords[syntax].has_key('word'):
                self.aattrs['answer_word_' + syntax] = selected_awords[syntax]['word']
            if selected_awords[syntax].has_key('tag'):
                self.aattrs['answer_tag_' + syntax] = selected_awords[syntax]['tag']
            if selected_awords[syntax].has_key('fullform') and len(selected_awords[syntax]['fullform']) == 1:
                self.aattrs['answer_fullform_' + syntax] = selected_awords[syntax]['fullform'][0]
            if selected_awords[syntax].has_key('taskword'):
                self.aattrs['answer_taskword_' + syntax] = selected_awords[syntax]['taskword']  # to track the taskword attribute
		#print question.qid
        #print self.awords
        # Forms question string and answer string out of grammatical elements and other strings.
        qstring = ""

        # Format question string
        qtext = question.string
        for w in qtext.split():
            if not qwords.has_key(w): qstring = qstring + " " + force_unicode(w)
            else:
                if qwords[w].has_key('fullform'):
                    qstring = qstring + " " + force_unicode(qwords[w]['fullform'][0])
                else:
                    qstring = qstring + " " + w
        # this is for -guovttos
        qstring=qstring.replace(" -","-");
        qstring=qstring.replace("- ","-");

        # Remove leading whitespace and capitalize.
        qstring = qstring.lstrip()
        qstring = qstring[0].capitalize() + qstring[1:]

        qstring = qstring + "?"
        self.question=qstring

        self.gametype="cealkka"
        self.messages, jee, joo  = self.cealkka_is_correct(qstring.encode('utf-8'), qwords, awords, language, question.qid)   # was astring, awords for VastaS before

        # set correct and error values
        if correct_val == "correct":
            self.error="correct"
