# -*- coding: utf-8 -*-
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 hdn_oahpa.settings as settings

from hdn_oahpa.conf.tools import switch_language_code

from models import *
#from game import *
#from hdn_oahpa.hdn_drill.game import relax
import datetime
import socket
import sys, os
import itertools
from random import choice

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

PRONOUNS_LIST = {'1Sg': u'nîya', '2Sg': u'kîya', '3Sg': u'wîya',
		  '1Pl': u'nîyanân', '2Pl': u'kîyawâw', '12Pl': u'kîyânaw', '3Pl': u'wîyawâw'}

# DEMONSTRATIVE_PRESENTATION plus Sg3/Pl3
PASSIVE_PRONOUNS_LIST = {'1Sg': u'nîya', '2Sg': u'kîya', '3Sg': u'wîya',
		  '1Pl': u'nîyanân', '2Pl': u'kîyawâw', '12Pl': u'kîyânaw', '3Pl': u'wîyawâw'}


NEGATIVE_VERB_PRES = {'Sg1':'in', 'Sg2':'it', 'Sg3':'ii',
		  'Pl1':'eat', 'Pl2':'ehpet', 'Pl3':'eai'}

TENSE_PRESENTATION = {
	'Prt': u'otâkosîhk',
	'Prs': u'anohc',
}

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-PL', _('Plural')),
    ('N-LOC', _('Locative')),
    ('N-DIM', _('Diminutive')),
    #('N-PX', _('Possessive')),
)

# 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-PL': [('N+Animacy+Sg', 'N+Animacy+Pl')],
	'N-LOC': [('N+Animacy+Sg', 'N+Animacy+Loc')],
	'N-DIM': [('N+Animacy+Der/Dim+N+Animacy+Sg', 'N+Animacy+Sg')],
}

FEEDBACK_TYPE = {
	'N-PL': 'answer',
	'N-LOC': 'answer',
	'N-DIM': 'question',
}

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

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

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-PL', _('Plural')),
    ('N-LOC', _('Locative')),
    ('N-PX', _('Possessive')),
    #('N-INE', _('Inessive')),
    #('N-ELA', _('Elative')),
    #('N-ADE', _('Adessive')),
    #('N-ABL', _('Ablative')),
    #('N-ALL', _('Allative')),
#	('N-MIX', _('mix')),
)

NOUN_TYPE_CHOICES =(
	('N-IN', _('inanimate')),
	('N-AN', _('animate')),
	('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 = (
	('N-PL', _('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
	'N-PL': [('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 = (
	('N-PL', _('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')),
#	('FUT', _('future')),
#	('PRF', _('perfect')),
#	('GER', _('gerund')),
#	('COND', _('conditional')),
#	('IMPRT', _('imperative')),
#	('POT', _('potential')),
)

TRANS_ANIM_CHOICES = (
	('AI-TI', _('AI-TI')),
	# ('all', _('All')),
)

VERB_QUESTION_ANSWER = {
	'V-PRS': [('V+IA', 'V+IA+Ind+Prs+Person-Number')],
	'V-PRT': [('V+IA', 'V+IA+Ind+Prt+Person-Number')],
#	'V-FUT': [('V+IA', 'V+IA+Ind+Fut+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-FUT', _('future')),
#	('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')),
)


POSSESSIVE_CHOICES = (
	('N-PX-GROUP1', _('Kin')),
	('N-PX-GROUP2', _('Body')),
	('N-PX-GROUP3', _('All')),
)

POSSESSIVE_NUMBER_CHOICES = (
	('N-SG', _('Singular')),
#	('N-PL', _('Plural')),
)

POSSESSIVE_CHOICE_SEMTYPES = dict((
	('N-PX-GROUP1', ['KIN']), # and MORFAPOSS
	('N-PX-GROUP2', ['BODY']), # and MORFAPOSS
	('N-PX-GROUP3', ['MORFAPOSS']),
))

POSSESSIVE_GROUP1_CASE = (
	('N-2SG', _('your (Sg)')),
	('N-3SG', _('his/her')),
	#('N-4SG', _('obviative')),
)

POSSESSIVE_GROUP2_CASE = (
	('N-2SG', _('your (Sg)')),
	('N-3SG', _('his/her')),
	#('N-4SG', _('obviative')),
)

POSSESSIVE_GROUP3_CASE = (
	('N-2SG', _('your (Sg)')),
	('N-3SG', _('his/her')),
	#('N-4SG', _('obviative')),
)

#POSSESSIVE_CONTEXT_CHOICES = (
#	('PX-ACC', _('accusative')),
#	('PX-ILL', _('illative')),
#	('PX-LOC', _('locative')),
#	('PX-COM', _('comitative')),
#	('PX-GEN', _('genitive')),
#)



POSSESSIVE_QUESTION_ANSWER = {
	'N-PX-GROUP1': [('N+Animacy+Sg+Px1Sg', 'N+Animacy+Sg+Possessive')],
	'N-PX-GROUP2': [('N+Animacy+Sg+Px1Sg', 'N+Animacy+Sg+Possessive')],
	'N-PX-GROUP3': [('N+Animacy+Sg+Px1Sg', 'N+Animacy+Sg+Possessive')],
}

POSSESSIVE_FILTER_DEFINITION = ['semtype']  # Heli


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'all')),
    ('Intr1', _('Introductory 1')), 
    ('Intr2', _('Introductory 2')), 
    ('Intr3', _('Introductory 3')), 
    ('Intr4', _('Introductory 4')), 
    ('Intr1_2', _('Introductory 1-2')), 
    ('Intr1_3', _('Introductory 1-3')), 
    ('Intr1_4', _('Introductory 1-4')), 
    ('advan', _('Advanced')), 
    ('Audio', _('Audiofiles')),

)

CHAPTER_CHOICES = {
    'Intr1' : ['I1','I2','I3'],
    'Intr2' : ['I4', 'I5'],
    'Intr3' : ['I6', 'I7'],
    'Intr4' : ['I8', 'I9', 'I10', 'I11', 'I12'],
    'Intr1_2' : ['I1','I2','I3', 'I4', 'I5'],
    'Intr1_3' : ['I1','I2','I3', 'I4', 'I5', 'I6', 'I7'],
    'Intr1_4' : ['I1','I2','I3', 'I4', 'I5', 'I6', 'I7', 'I8', 'I9', 'I10', 'I11', 'I12'],
}

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

GEOGRAPHY_CHOICES = (
	('world', _('world')),
#	('sapmi', _('sapmi')), # was: sápmi, maybe characters with diacritics not allowed in drop-down menus
#	('suopma', _('suopma')),
)

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

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


TRANS_CHOICES = (
	('hdneng', _('Haida to English')),
	('enghdn', _('English to Haida')),
)

NUMLANGUAGE_CHOICES = (
	('hdn', _('Haida')),
)

SEMTYPE_CHOICES = (
    ('KINSHIP-AND-PEOPLE', _('People & Kinship')),
    ('BODYPARTS-AND-CONDITIONS', _('The Human Body')),
    ('FOOD,-DRINKS,-DINNERWARE,-AND-COOKING', _('In the Kitchen')),
    ('ANIMALS', _('Animals')),
    ('MISCELLANEOUS', _('Miscellaneous')),
    ('HOME,-CLOTHING-AND-WORK', _('Home, Clothing & Work')),
    ('NATURE-AND-WEATHER', _('Nature & Weather')),
    ('TIME,-COUNTING,-MONEY,-AND-DATES', _('Time, Counting, Money & Dates')),
    ('DESCRIPTIONS', _('descriptions')),
    ('EXPRESSIONS-AND-QUESTIONS', _('Expressions & Questions')),
	('BASIC-CONVERSATION',_('Basic Conversation')),
	('TRANSPORTATION-AND-PLACES',_('Transportation & Places')),
	('ACTIVITIES',_('Activities')),
    ('all', _('all')),
)


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

NUMGAME_CHOICES = (
	('string', _('Word to numeral')),
	('numeral', _('Numeral to word')),
)

NUMGAME_CHOICES_PL = (
	('string', _('Words to numerals')),
	('numeral', _('Numerals to words')),
)

# 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 hdn_oahpa.settings import INFINITIVE_SUBTRACT as infinitives_sub
from hdn_oahpa.settings import INFINITIVE_ADD as infinitives_add

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
		# key is accepted for value - have changed the order in the pairs because the key must be unique!
		# TODO: evaluate these key:value pairs for Plain Cree, especially the last four.
		# For sma we had two levels: 1. always accept øö äæ, 2. accept i for ï, but with a comment
		# We should consider the same for the four last ones.
	   u'ā' : u'â', # a + combining macron U+0304
	   u'ē' : u'ê', # e + combining macron U+0304
	   u'ī' : u'î', # i + combining macron U+0304
	   u'ō' : u'ô', # o + combining macron U+0304
	   u'ā' : u'â', # precombined a macron
	   u'ē' : u'ê', # precombined e macron
	   u'ī' : u'î', # precombined i macron
	   u'ō' : u'ô', # precombined o macron
	   u'â' : u'â', # a + combining circumflex accent U+0302
	   u'ê' : u'ê', # e + combining circumflex accent U+0302
	   u'î' : u'î', # i + combining circumflex accent U+0302
	   u'ô' : u'ô', # o + combining circumflex accent U+0302
	   u'a' : u'â', # Accepting short for long ???
	   u'e' : u'ê', # Accepting short for long ???
	   u'i' : u'î', # Accepting short for long ???
	   u'o' : u'ô' # Accepting short for long ???
	}

	# 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 S, R 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):
	FEEDBACK_TYPE

	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' : 'hdn',  # sme in univ_oahpa
					# 'syll' : ['2syll'], # syllabicity not relevant, change this
					# 'bisyllabic': 'on',
					# 'trisyllabic': False,
					# 'contracted': False,
					'level' : 'all',
					'lemmacount' : '2',
					'case': 'N-PL',
					'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-PL',
					'vtype_context' : 'V-PRS',
					'pron_context' : 'P-DEM',
					'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
					'possessive_type': 'N-PX-GROUP1',
					'possessive_number': 'N-SG',
					'possessive_case': "N-2SG",
					
					'geography': 'world',
					'frequency' : [],
					'num_bare' : 'N-NOM', # Need a new default case here
					'adj_context' : 'ATTRPOS',
					'book' : 'all',
					'noun_type': 'N-IN',
					'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.error = "empty"
		self.problems = "error"
		self.pron = ""
		self.pron_imp = ""
		self.object = False
		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 == 'hdn': # 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 == '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)
				        infins = [lemma.sub(infin_a, force_unicode(ax)) for ax in accepted_answers]
				        accepted_answers = infins + 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: KINSHIP-AND-PEOPLE
	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' : 'hdn', 'dialogue' : 'GG',
			#'syll' : [],
			#'bisyllabic': False,
			#'trisyllabic': False,
			#'bisyllabic': False,
			#'contracted': False,
			'source': 'all',
			'semtype' : 'all', # was: 'KINSHIP-AND-PEOPLE',
			#'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'
		self.animacy = word.animacy # Added for Haida, in order to color the animate nouns. Thanks to this assigment operation the template has access to the animacy information.
		self.trans_anim = word.trans_anim
		self.audio = word.audio # pronounciation
		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':  # There is no infinitive in Haida!
		#	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 - but NO infinitive in Haida!
		# 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-PL', 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)
	trans_anim = forms.ChoiceField(initial='AI-TI', choices=TRANS_ANIM_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)
	possessive_case = forms.ChoiceField(initial='N-2SG', choices=POSSESSIVE_GROUP1_CASE, widget=forms.Select, required=False)
	possessive_type = forms.ChoiceField(initial='N-PX-GROUP1', choices=POSSESSIVE_CHOICES, widget=forms.Select)
	possessive_number = forms.ChoiceField(initial='N-SG', choices=POSSESSIVE_NUMBER_CHOICES, 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-DEM', 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 = 'hdn'
		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('conneg') > -1:
			if conneg:
				conneg_agr = conneg
			else:
				conneg_agr = choice(self.PronPNBase.keys())
		else:
			conneg_agr = False

		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

		# hack for Diminutive which has questions presented in the form,
		# and answers in nom
		if correct.tag.string in ['N+AN+Sg', 'N+IN+Sg']:
			q_form = word.form_set.filter(tag=tag)
			if len(q_form) > 0:
				self.get_feedback(q_form[0], language)
		else:
			# 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
		self.animacy = tag.animacy # added for hdn, in order to display animate / inanimate nouns in different colors

		if tag.pos == "V":
			# TODO: figure out word object here.
			if not self.pron:
				if tag.string.find("ConNeg") > -1:
					# TODO: New choice for every refresh, fix!
					pers = conneg_agr
					pronoun = self.PronPNBase[pers]
					neg_verb = NEGATIVE_VERB_PRES[pers]

					self.pron = '%s %s' % (pronoun, neg_verb)
				elif tag.personnumber:
					pronbase = self.PronPNBase[tag.personnumber]
					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 = '(%s) %s' % (pronoun, time) #' '.join([time, pronoun])

			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 word.object:
				self.object = word.object

		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' : 'hdn', 'numlanguage' : 'hdn', '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 = 'hdn'

		# 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' : 'hdn', 'numlanguage' : 'hdn', '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' : 'hdn', 'numlanguage' : 'hdn', 'numgame': 'string'}


class DatoQuestion(KlokkaQuestion):

	game_log_name = "dato"

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

		return answer
		
# #
#
# Money Forms
#
# #

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

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


class MoneyQuestion(KlokkaQuestion):

	game_log_name = "money"

	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 hdn

	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 = 'hdn'
		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('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('eng') # 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" or qtype == "ORD-NUM":
		      if qtype == 'N-PX':
		          self.lemma = False
		      else:
			     self.lemma = answer_word_el.lemma
				
		if answer_tag_el.pos == "V":
		      self.lemma = False
		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. Filter by dialect if more
		# dialects are defined
		if set(settings.DIALECTS.keys()) != set(['main', 'NG']):
			dialect_filter = True
		else:
			dialect_filter = False

		if dialect_filter:
			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 Exception, e:
				answer_word_form = False
		else:
			try:
				answer_word_form = Form.objects.filter(word__pk=answer_word, tag=answer_tag_el,)
				# .exclude(dialects__dialect='NG')\
				# dialects__dialect=self.dialect)
				answer_word_form = answer_word_form[0]
			except Exception, e:
				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:]  # No capital letters in the beginning of a sentence in Haida
		# qstring = qstring[0].capitalize() + qstring[1:]

		# qstring = qstring + "?" # no question mark in Haida
		# 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 = "/opt/smi/sme/bin"
    #fstdir = settings.FST_DIRECTORY
    fst = fstdir + "/ped-sme.fst"
    lo = "/opt/sami/xerox/c-fsm/ix86-linux2.6-gcc3.4/bin/lookup" # on victorio
    #lo="/Users/mslm/bin/lookup" # on Heli's machine
    lookup = " | " + lo + " -flags mbTT -utf8 -d " + fst # on Heli's machine
    #lookup2cg = " | /Users/pyry/gtsvn/gt/script/lookup2cg" # on Ryan's machine
    lookup2cg = " | /usr/local/bin/lookup2cg " # on victorio
    cg3 = "/usr/local/bin/vislcg3"
    preprocess = " | /opt/sami/cg/bin/preprocess " # on victorio
    #preprocess = " | /Users/mslm/main/gt/script/preprocess "
    dis_bin = "/opt/smi/sme/bin/sme-ped.cg3" # on victorio
    #dis_bin = "../sme/src/sme-ped.cg3" # on Heli's machine TODO: add to settings.py

    vislcg3 = " | " + cg3 + " --grammar " + dis_bin + " -C UTF-8"

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

    self.error = "error"

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

    #logfile = open('/home/hdn_oahpa/hdn_oahpa/hdn_drill/vastaF_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 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
        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

        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()

    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 = "eng"
    #if language == "fi" : language = "fin"
    #if language == "en" : language = "eng"
    if not language in ["nob","sme","fin","eng","swe","hdn","fra"]: 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","\"" + w + "\"")
                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 = "/opt/smi/sme/bin"
    #fstdir = settings.FST_DIRECTORY
    fst = fstdir + "/ped-sme.fst"
    lo = "/opt/sami/xerox/c-fsm/ix86-linux2.6-gcc3.4/bin/lookup"# on victorio
    #lo="/Users/mslm/bin/lookup" # on Heli's machine
    lookup = " | " + lo + " -flags mbTT -utf8 -d " + fst # on Heli's machine
    lookup2cg = " | /usr/local/bin/lookup2cg " # on victorio
    cg3 = "/usr/local/bin/vislcg3"
    preprocess = " | /opt/sami/cg/bin/preprocess " # on victorio
    #preprocess = " | /Users/mslm/main/gt/script/preprocess " # on Heli's machine
    dis_bin = "/opt/smi/sme/bin/sme-ped.cg3" # on victorio
    #dis_bin = "/Users/mslm/main/ped/sme/src/sme-ped.cg3" # on Heli's machine TODO: add to settings.py

    vislcg3 = " | " + cg3 + " --grammar " + dis_bin + " -C UTF-8"

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

    self.error = "error"

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

    #logfile = open('/home/hdn_oahpa/hdn_oahpa/hdn_drill/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 = ""
        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()
            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:
                cohort = cohort + row
	       #print cohort
            analysis = analysis + cohort
        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")
                ans_cohort = ""
                word_lookup = "echo \"" + tlemma + "\"" + lookup + lookup2cg  # on Heli's machine
                rows = os.popen(word_lookup).readlines()
                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"
        # analyse the user's answer
        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()
            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 = analyzed + ans_cohort

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


    analysis = analysis + analyzed
    analysis = analysis + "\"<.>\"\n\t\".\" CLB"
    analysis = analysis.rstrip()
    analysis = analysis.replace("\"","\\\"")
    print analysis
    #logfile.write(analysis)
    ped_cg3 = "echo \"" + analysis + "\"" + vislcg3
    checked = os.popen(ped_cg3).readlines()
    #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áÁæÆåÅáÁšŠŧŦŋŊøØđĐž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()

        #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 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"]: 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","\"" + w + "\"")
                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 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, qwords, awords, 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 atext

        question_widget = forms.HiddenInput(attrs={'value' : question.id})
        answer_widget = forms.HiddenInput(attrs={'value' : qanswer.id})  #was: qanswer.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['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
        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

        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"
