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

from semantics.models import SemanticRole, SemanticFrame, Complement, \
                             LexicalUnit, FrameRankings, SemanticRolesDisplay, \
                             LexicalUnitExamples, SelectivePreferenceRelations, \
                             GeneralSelectivePreference, FrameOpinion, Synset

from wordnet.models import Hypernymy, Synonymy

from dictionary.models import Frame_Char_Model, Lemma, Lemma_Status, \
                              sort_arguments, sort_positions, sortatributes
from dictionary.ajax_lemma_view import user_can_modify
from django.core.exceptions import SuspiciousOperation
from django.core.urlresolvers import reverse
from django.db.models import Q

from common.decorators import render, ajax
from semantics.forms import GeneralSelPrefForm, RelationalSelPrefForm, RoleForm, SynsetSelPrefForm 
from semantics.saving import modify_frames, update_meanings
from semantics.validation import validate_schemas, validate_frames, validate_lexical_units

from semantics.phraseology_generator import lexicalisation, is_subj

from settings import MORFEUSZ2

####################################### render #####################################

@render('semantics.html')
@ajax(method='get', encode_result=False)
def ajax_semantics(request, id):
    context = {}
    lemma = Lemma.objects.get(id=id)
    context['lemma'] = lemma
    context['can_modify'] = (user_can_modify(lemma, request.user) and 
                             lemma.status.stage_of_work.sym_name == 'semantics')
    context['js_vars'] = {
        'ajax_frames': reverse('ajax_frames'),
        'ajax_schemas': reverse('ajax_schemas'),
        'ajax_units': reverse('ajax_units'),
        'ajax_roles': reverse('ajax_roles'),
        'ajax_opinions': reverse('ajax_opinions'),
        'ajax_create_frame': reverse('ajax_create_frame'),
        'ajax_create_complement': reverse('ajax_create_complement'),
        'ajax_examples': reverse('ajax_examples'),
        'ajax_update_meanings': reverse('ajax_update_meanings'),
        'ajax_modify_frames': reverse('ajax_modify_frames'),
        'ajax_synsets': reverse('ajax_synsets'),
        'ajax_relations': reverse('ajax_relations'),
        'ajax_predefined_preferences': reverse('ajax_predefined_preferences'),
        'ajax_plWN_context_lookup': reverse('ajax_plWN_context_lookup'),
        'ajax_get_mwes': reverse('ajax_get_mwes'),
        'ajax_connected': reverse('ajax_connected'),
    }
    return context

def reorder_history(frames_list):
    next_ids = set()
    for frame in frames_list:
        if frame.next is not None:
            next_ids.add(frame.next.id)
    
    first = set()
    for frame in frames_list:
        if frame.id not in next_ids:
            first.add(frame)
            
    result = []
    for frame in first:
        current = frame
        while current is not None:
            result.append(current)
            current = current.next
            
    result.reverse()
    return result


@render('frames.json')
@ajax(method='get', encode_result=False)
def ajax_frames(request, lemma_id):
    context = create_frames_context(lemma_id, request.user)
    return context

def create_frames_context(lemma_id, user):
    lemma = Lemma.objects.get(id=lemma_id)
    connected = lemma.entry_obj.rel_entries.all()

    #lexical_units = LexicalUnit.objects.filter(Q(base__startswith=lemma.entry + u' ')|Q(base__contains=u' '+lemma.entry+u' ')|Q(base__endswith=u' '+lemma.entry)|Q(base=lemma.entry)).order_by('sense')
#    lexical_units = lemma.entry_obj.meanings.order_by('sense')
    
    alternations = {}        
    frames_dict = {}
    frame_units = {}
 
    frames = lemma.entry_obj.all_frames()
        
    for frame in frames:
        alternations[frame.id] = {}
        frames_dict[frame.id] = frame
        frame_units[frame.id] = frame.lexical_units.all()
           
    type_frames = {}
    for frame_id in frame_units:
        t = tuple(frame_units[frame_id])
        if t not in type_frames:
            type_frames[t] = []
        type_frames[tuple(frame_units[frame_id])].append(frames_dict[frame_id])
    

    frames_display = []
    complement_arguments = {}
    arguments_frame_connected = {}
    
#    for t in type_frames:
#        type_frames[t] = reorder_history(type_frames[t])
 
    k = type_frames.keys()
    k.sort(key=lambda tup: len(tup))
    for t in k:
   
#    for t in type_frames:
        frame_display = {"lexical_units": [], "frames": [], "visible": False, "local": False, "locked": False}
        for lu in list(t):
            frame_display["lexical_units"].append({"id": str(lu.id), "base": lu.base, "sense": str(lu.sense)})
            lu_entry = lu.entry
            lemma_entry = lemma.entry_obj
            if (lu_entry.name, lu_entry.pos.tag) == (lemma_entry.name, lemma_entry.pos.tag):
                frame_display["visible"] = True
            
        for frame in type_frames[t]:
            frame_entry = frame.entry
            lemma_entry = lemma.entry_obj
            if (frame_entry.name, frame_entry.pos.tag) == (lemma_entry.name, lemma_entry.pos.tag):
                frame_display["local"] = True
                frame_display["visible"] = True
            else:
                min_priority = [x.priority for x in Lemma_Status.objects.all() if x.status == "(S) sprawdzone"][0] 
                if frame_entry.actual_lemma().status.priority < min_priority:
                    frame_display["locked"] = True
            
            # frame_complements = Complement.objects.filter(frame=frame)
            # frame_complements = frame.complements.all()
            lemma_role = SemanticRole.objects.get(role="Lemma")
            frame_complements = frame.complements.all().exclude(roles=lemma_role)
            lemma_argument = frame.complements.filter(roles=lemma_role)
        
            # classes and first frame/position part of identifiers
            frame_ids = [u'frame_' + str(frame.id) + '_comp_' + str(complement.id) + '_' for complement in frame_complements]

            # names of roles
            frame_roles = [{'csv_id': i, 'csv_class': c, 'argument': a} for i, c, a in zip(frame_ids, frame_ids, [[role.id for role in complement.roles.all()] for complement in frame_complements])]
            
            # rowspan for 'Argumenty:'
            # frame_preferences_rowspan = max(max([len(preference) for preference in [complement.selective_preference.all() for complement in frame_complements]] + [0]), 1)
            frame_preferences_rowspan = max(max([len(complement.selective_preference.generals.all()) + len(complement.selective_preference.synsets.all()) + len(complement.selective_preference.relations.all()) for complement in frame_complements if complement.selective_preference is not None] +[0]), 1)
            
            frame_preferences = []
            for i in range(frame_preferences_rowspan):
                row = []
                idents = []
                for frame_id, complement in zip(frame_ids, frame_complements):
                    if complement.selective_preference is not None:
                        generals = complement.selective_preference.generals.all()
                        synsets = complement.selective_preference.synsets.all()
                        relations = complement.selective_preference.relations.all()
                        synset_relations = complement.selective_preference.synset_relations.all()
                        generals_len = len(generals)
                        synsets_len = len(synsets)
                        relations_len = len(relations)
                        synset_relations_len = len(synset_relations)
                        if generals_len > i:
                            general = generals[i]
                            row.append(general.name)
                            idents.append(frame_id + 'pref_g' + str(general.id) + '_')
                        elif generals_len + synsets_len > i:
                            synset = synsets[i - generals_len]
                            # lexical_units_preference = LexicalUnit.objects.filter(synset=synset)
                            row.append(unicode(synset))
                            idents.append(frame_id + 'pref_s' + str(synset.id) + '_')
                        elif generals_len + synsets_len + relations_len > i:
                            relation = relations[i - generals_len - synsets_len]
                            row.append(relation.relation.name + '<br /> -> [' + ', '.join([r.role for r in relation.to.roles.all()]) + ']')
                            idents.append(frame_id + 'pref_r' + str(relation.id) + '_')
                        elif generals_len + synsets_len + relations_len + synset_relations_len > i:
                            relation = relations[i - generals_len - synsets_len - relations_len]
                            synset = relation.to
                            row.append(relation.relation.name + '<br /> -> [' + unicode(synset) + ']')
                            idents.append(frame_id + 'pref_R' + str(relation.id) + '_')
                        else:
                            row.append('')
                            idents.append(frame_id + 'pref_-' + str(i + 1) + '_')
                    else:
                        row.append('')
                        idents.append(frame_id + 'pref_-' + str(i + 1) + '_')
                frame_preferences.append([{'csv_id': i, 'csv_class': c, 'preference': p} for i, c, p in zip(idents, frame_ids, row)])
            
            display = {"roles": frame_roles, "preferences": frame_preferences}
            if frame.opinion is None and user.is_authenticated():
                status = u'brak'
            elif frame.opinion is None and not user.is_authenticated():
                status = u'pewna'
            else:
                status = frame.opinion.value
            if len(lemma_argument) > 0:
                csv = u'frame_' + str(frame.id) + '_comp_' + str(lemma_argument[0].id) + '_lemma_' 
                lemma_info = {"include": True, "csv_id": csv, "csv_class": csv}
                if csv not in complement_arguments:
                    complement_arguments[csv] = []
                
                for schema_position in lemma_argument[0].realizations.all():
                    schema = schema_position.frame
                    position = schema_position.position
                    argument = schema_position.argument
                    alternation = schema_position.alternation
                    realization_id = u'schema_' + str(schema.id) + u'_pos_' + str(position.id) + '_arg_' + str(argument.id) + '_' + 'alt_' + str(alternation) + '_'
                    complement_arguments[csv].append(realization_id)
                    if realization_id not in arguments_frame_connected:
                        arguments_frame_connected[realization_id] = []
                    arguments_frame_connected[realization_id].append('frame_' + str(frame.id) + '_')
                    if schema.id in alternations[frame.id]:
                        alternations[frame.id][schema.id] = max(alternations[frame.id][schema.id], alternation)
                    else:
                        alternations[frame.id][schema.id] = alternation      
            else:
                lemma_info = {"include": False}
            frame_display["frames"].append({"frame_id": str(frame.id), "colspan": str(max(len(frame_roles), 1)), "rowspan": str(frame_preferences_rowspan), "status": status, "display": display, "lemma": lemma_info})

            schemata_ids = [f.id for f in lemma.frames.all()]
            
            for complement, complement_class in zip(frame_complements, frame_ids):
                if complement_class not in complement_arguments:
                    complement_arguments[complement_class] = []
                
                for schema_position in complement.realizations.all():
                    schema = schema_position.frame
                    if schema.id in schemata_ids:
                        position = schema_position.position
                        argument = schema_position.argument
                        alternation = schema_position.alternation
                        realization_id = u'schema_' + str(schema.id) + u'_pos_' + str(position.id) + '_arg_' + str(argument.id) + '_' + 'alt_' + str(alternation) + '_'
                        complement_arguments[complement_class].append(realization_id)
                        if realization_id not in arguments_frame_connected:
                            arguments_frame_connected[realization_id] = []
                        arguments_frame_connected[realization_id].append('frame_' + str(frame.id) + '_')
                        if schema.id in alternations[frame.id]:
                            alternations[frame.id][schema.id] = max(alternations[frame.id][schema.id], alternation)
                        else:
                            alternations[frame.id][schema.id] = alternation
                            # alternations[frame.id] = {}
        
        frames_display.append(frame_display)

    # ala["ma"] = "kot"

    frames_count_local = 0
    frames_count_imported = 0
    for frame in frames_display:
        if frame['visible']:
            if frame['local']:
                frames_count_local += 1
            else:
                frames_count_imported += 1
    frames_count = str(frames_count_local) + "+" + str(frames_count_imported)
    
    context = {
               'frames_display': frames_display, 
               'connections': {'connected': complement_arguments, 'connected_reverse': arguments_frame_connected},
               'frames_count': frames_count,
               'alternations': alternations
              }

    return context


@render('connected.json')
@ajax(method='get', encode_result=False)   
def ajax_connected(request, lemma_id):
    context = create_connected_context(lemma_id, request.user)
    return context

def create_connected_context(lemma_id, user):
    lemma = Lemma.objects.get(id=lemma_id)
    connected = lemma.entry_obj.rel_entries.all()
    context = {'frames_display': [], 'connections':{'connected_reverse': [], 'connected': []}}
    
    for entry in connected:
        if entry.defined():
            lemma = entry.actual_lemma()
            frame_context = create_frames_context(lemma.id, user)
            context['frames_display'] += frame_context['frames_display']
            context['connections']['connected'] += frame_context['connections']['connected']
            context['connections']['connected_reverse'] += frame_context['connections']['connected_reverse']
        
    return context


@render('units.json')
@ajax(method='get', encode_result=False)   
def ajax_units(request, lemma_id):
    context = create_units_context(lemma_id)
    return context

def create_units_context(lemma_id):
    lemma = Lemma.objects.get(id=lemma_id)
    pos_en = lemma.entry_obj.pos.tag
    pos = 'brak'
    if pos_en == 'adj':
        pos = 'przymiotnik'
    elif pos_en == 'noun':
        pos = 'rzeczownik'
    elif pos_en == 'adv':
        pos = 'przysłówek'
    elif pos_en == 'verb':
        pos = 'czasownik'
    lexical_units = lemma.entry_obj.meanings.order_by('base', 'sense')
#    lexical_units = LexicalUnit.objects.filter(Q(base__startswith=lemma.entry + u' ', pos="czasownik")|Q(base__contains=u' '+lemma.entry+u' ', pos="czasownik")|Q(base__endswith=u' '+lemma.entry, pos="czasownik")|Q(base=lemma.entry, pos="czasownik")).order_by('base', 'sense')

    bases = set([lu.base for lu in lexical_units])
    tmp = [(lu.base, lu.sense) for lu in lexical_units]

    senses = {}
    for base in bases:
        senses[base] = max(['A'] + [chr(ord(lu.sense) + 1) for lu in lexical_units.filter(luid=-1).filter(base=base)])

    context = {
               'lexical_units': [{"id": lu.id, "luid": lu.luid, "base": lu.base, "sense": lu.sense, "pos": lu.pos, "glossa": lu.glossa, "definition": lu.definition, "location": location(lu)} for lu in lexical_units],
               'informations': {'base': lemma.entry, 'sense': senses, # TODO: 2 different free senses for with/without 'się'
                                'pos': pos}
              }
    return context
    

def location(lexical_unit):
    if lexical_unit.synset is None:
        return ""
    if lexical_unit.luid >= 0:
        return ""
    where = Synonymy.objects.filter(parent=lexical_unit.synset)
    if len(where) > 0:
        return "synonim " + unicode(where[0].child)
    where = Hypernymy.objects.filter(parent=lexical_unit.synset)
    if len(where) > 0:
        return "hiponim " + unicode(where[0].child)
    return "nieznana lokacja w Słowosieci"

@ajax(method='get')   
def ajax_predefined_preferences(request):
    predefined = []
    for preference in GeneralSelectivePreference.objects.order_by('name'):
        if preference.members:
            members = [member.name for member in preference.members.generals.order_by('name')]
            members.extend([unicode(synset) for synset in preference.members.synsets.all()])
            content = u'%s: (%s)' % (preference.name, ', '.join(members))
        else:
            content = u'%s' % (preference.name)
        predefined.append({"id": preference.id, "content": content})

    context = {
               'predefined': predefined,
              }

    return context

@render('synsets.json')
@ajax(method='get', encode_result=False)   
def ajax_synsets(request, base, pos):
    
    if pos == '_':
        lexical_units = LexicalUnit.objects.filter(base=base).order_by('pos', 'base', 'sense')
    else:
        lexical_units = LexicalUnit.objects.filter(base=base, pos=pos).order_by('pos', 'base', 'sense')
    
    synsets = []
    for representative in lexical_units:
        synset = [{"id": lu.id, "luid": lu.luid, "base": lu.base, "sense": lu.sense, "pos": lu.pos, "glossa": lu.definition} for lu in LexicalUnit.objects.filter(synset=representative.synset)]
        synsets.append({"id": representative.synset.id, "content": synset})

    context = {
               'synsets': synsets,
              }

    return context

@render('relations.json')
@ajax(method='get', encode_result=False)   
def ajax_relations(request):
    
    relations = [{"id": relation.id, "content": relation.name} for relation in SelectivePreferenceRelations.objects.all()]

    context = {
               'relations': relations,
              }

    return context

@render('opinions.json')  
@ajax(method='get', encode_result=False)
def ajax_opinions(request):
    
    opinions = [{"id": opinion.short, "name": opinion.value} for opinion in FrameOpinion.objects.all().order_by('priority')]
    
    context = {
               'opinions': opinions,
              }

    return context

def NoneisNone(o):
    if o is None:
        return 'None'
    else:
        return o

@render('roles.json')  
@ajax(method='get', encode_result=False)
def ajax_roles(request):       
    roles_display = []
    maxrow = SemanticRolesDisplay.objects.all().order_by('-row')[0].row
    for i in range(1, maxrow):
        row = []
        cells = SemanticRolesDisplay.objects.filter(row=i).order_by('column')
        for cell in cells:
            roles = [{"id": r.id, "rolename": r.role, "color": NoneisNone(r.color), "gradient": NoneisNone(r.gradient)} for r in cell.roles.all().order_by('id')]
            row.append({"caption": NoneisNone(cell.caption), 
                        "rowspan": cell.rowspan, 
                        "colspan": cell.colspan, 
                        "roles": roles})
        roles_display.append(row)

    roles_short = roles_display[:]
     
    row = []
    cells = SemanticRolesDisplay.objects.filter(row=maxrow).order_by('column')
    for cell in cells:
        roles = [{"id": r.id, "rolename": r.role, "color": NoneisNone(r.color), "gradient": NoneisNone(r.gradient)} for r in cell.roles.all().order_by('id')]
        row.append({"caption": NoneisNone(cell.caption), 
                    "rowspan": cell.rowspan, 
                    "colspan": cell.colspan, 
                    "roles": roles})
    roles_display.append(row)

    roles_full = roles_display


    context = {
               'roles_display': roles_short,
               'roles_full': roles_full
              }

    return context


@render('schemas.json')   
@ajax(method='get', encode_result=False)
def ajax_schemas(request, lemma_id):

    lemma = Lemma.objects.get(id=lemma_id).entry_obj.actual_lemma()
    
    schemas_all = lemma.frames.all()
    
    characteristics = {}
    characteristics_ids = []
    schemas_by_characteristic = {}
    for schema in schemas_all:
        chars = schema.characteristics.all()
        char_types = [c.type for c in chars]
        l = [(Frame_Char_Model.objects.get(model_name=c.type).priority, c) for c in chars]
        l.sort()
        _, chars = zip(*l)
        chars = list(chars)
        characteristic_id = tuple([char.id for char in chars])
        if characteristic_id not in characteristics:
            characteristics_ids.append(characteristic_id)
            values = [char.value.value for char in chars]
            if values[0]:
                characteristics[characteristic_id] = "%s (%s)" % (values[0], ','.join(values[1:]))
            else:
                characteristics[characteristic_id] = "(%s)" % (','.join(values[1:]))
            schemas_by_characteristic[characteristic_id] = []
        schemas_by_characteristic[characteristic_id].append(schema)
    
    lexical_units = lemma.entry_obj.meanings.all()

    schemas_display = []
    schema_unit_rank = {}
    for characteristic_id in characteristics_ids:
        schema_display = {"characteristic_id": '_'.join([str(i) for i in characteristic_id]), "characteristic_display": characteristics[characteristic_id], "schemas": []}
        schemas = schemas_by_characteristic[characteristic_id]
        
        for schema in schemas: # row by row display for schema tables
            ordered_positions = sort_positions(schema.positions.all())
            # classes and first frame/position part of identifiers
            schema_ids = [u'schema_' + str(schema.id) + '_pos_' + str(position.id) + '_' for position in ordered_positions]

            # names of categories (along with class names
            schema_categories = zip(schema_ids, [','.join([category.category for category in position.ordered_categories()]) for position in ordered_positions])
            
            # value of rowspan for 'Argumenty:' header
            schema_arguments_rowspan = max(max([position.arguments.count() for position in ordered_positions] + [0]), 1)
            
            display = {"categories": [{"csv_id": c, "csv_class": c, "argument": a} for c, a in schema_categories], "arguments": []}
            for i in range(schema_arguments_rowspan):
            
                row = []
                idents = []
                for schema_id, position in zip(schema_ids, ordered_positions):
                    if position.arguments.count() > i:
                        ordered_arguments = sort_arguments(position.arguments.all())
                        row.append((unicode(ordered_arguments[i]), ordered_arguments[i]))
                        idents.append(schema_id + 'arg_' + str(ordered_arguments[i].id) + '_')
                    else: # this category has fewer posible argument realizations
                        row.append(('', None))
                        idents.append(schema_id + 'arg_-' + str(i + 1) + '_')
                # identifier, class, argument
                arg =  []
                #ma["ala"] = kot
                for i, c, a, p in zip(idents, schema_ids, row, ordered_positions):
                    astr, aobj = a
                    if aobj is not None and aobj.is_phraseologic():
                        tmp = lexicalisation(aobj, is_subj(p.categories.all()), lemma.entry_obj.name, ('neg' in characteristics[characteristic_id]))
                        lex, vrb = tmp
                    else:
                        lex, vrb = ([], [])
                    arg.append({"csv_id": i, "csv_class": c, "argument": astr, "lex": lex, "vrb": vrb})
                display["arguments"].append(arg)
            
            schema_display["schemas"].append({"schema_id": str(schema.id), "grade": lemma.get_schema_opinion(schema), "colspan": str(max(len(schema_categories), 1)), "rowspan": str(schema_arguments_rowspan), "display": display, "phraseologic": schema.phraseologic})
            
            ranks = FrameRankings.objects.filter(frame=schema)
            for rank in ranks:
                if rank.lexical_unit.id not in schema_unit_rank:
                    schema_unit_rank[rank.lexical_unit.id] = {}
                schema_unit_rank[rank.lexical_unit.id]["schema_" + str(schema.id) + "_"] = str(rank.rank)
        
        schemas_display.append(schema_display)
    
    
    context = {
               'lemma': lemma, 
               'schemas_display': schemas_display,
               'ranks': schema_unit_rank
              }

    return context
  
@render('examples.json')   
@ajax(method='get', encode_result=False)
def ajax_examples(request, lemma_id):

    lemma = Lemma.objects.get(id=lemma_id).entry_obj.actual_lemma()
    nkjp_examples = lemma.nkjp_examples.all()
    lexical_units = lemma.entry_obj.meanings.all()
    
    lexical_units_ids = [lu.id for lu in lexical_units]
    
    examples_linked = []
    
    for nkjp_example in nkjp_examples:
        
        linked = LexicalUnitExamples.objects.filter(example=nkjp_example)
        meanings = []
        
        for link in linked:
            if link.lexical_unit.id in lexical_units_ids:
                meanings.append(link.lexical_unit.id)
        
        all_argselection = nkjp_example.arguments.all()
        arguments = []
        for argselection in all_argselection:
            pos = argselection.position.id
            args = argselection.arguments.all()
            for arg in args:
                arguments.append({'id': 'schema_' + str(nkjp_example.frame.id) + '_pos_' + str(pos) + '_arg_' + str(arg.id) + '_'})
        
        examples_linked.append({'schema': 'schema_' + str(nkjp_example.frame.id) + '_', 'arguments': arguments, 'id': nkjp_example.id, 'sentence': nkjp_example.sentence, 'source': nkjp_example.source.source, 'opinion': nkjp_example.opinion.opinion, 'meanings': meanings})
    
    
    context = {
                'examples': examples_linked
              }

    return context

  
@ajax(method='get', encode_result=False)  
def ajax_create_frame(request, lexical_units):
    #lexical_unit_id_list = request.GET.get('lexical_units', '')
    lexical_unit_id_list = lexical_units
    lexical_units_ids = [int(id) for id in lexical_unit_id_list.split(',')]
    lexical_units = []
    for lexical_unit_id in lexical_units_ids:
        lexical_units.append(LexicalUnit.objects.get(id=lexical_unit_id))
    unit_bases = [lexical_unit.base for lexical_unit in lexical_units]
    base = unit_bases[0].split(' ')[0]
    for unit_base in unit_bases:
        if unit_base != base and unit_base != base + u' się':
             raise SuspiciousOperation
    frame = SemanticFrame()
    frame.save()
    for lexical_unit in lexical_units:
        frame.lexical_units.add(lexical_unit)
    lemma = Lemma.objects.get(entry=lexical_unit.base, old=False)
    return ajax_frames(request, lemma.id)

@ajax(method='get', encode_result=False)
def ajax_create_complement(request, lemma_id, frame, roles):
    #lemma_id = int(request.GET.get('lemma_id', ''))
    lemma = Lemma.objects.get(id=lemma_id, old=False)
    frame_id = frame
    #frame_id = int(request.GET.get('frame', ''))
    frame = SemanticFrame.objects.get(id=frame_id)
    #role_id_list = request.GET.get('roles', '')
    role_id_list = roles
    role_ids = [int(id) for id in role_id_list.split(',')]
    roles = []
    for role_id in role_ids:
        roles.append(SemanticRole.objects.get(id=role_id))
    complement = Complement(frame=frame)
    complement.save()
    for role in roles:
        complement.roles.add(role)
    return ajax_frames(request, lemma.id)
    
@ajax(method='post', encode_result=True)
def ajax_update_meanings(request, operations, lemma_id):
    update_meanings(lemma_id, operations)
    units_context = create_units_context(lemma_id)
    return units_context
    
@ajax(method='post', encode_result=True)
def ajax_modify_frames(request, operations, lemma_id):
    if not request.user.is_authenticated():
        return 'user logged out'
    modify_frames(lemma_id, operations, request.user)
    frames_context = create_frames_context(lemma_id, request.user)
    return frames_context
        
@ajax(method='get', encode_result=True)         
def ajax_plWN_context_lookup(request, term):
    results = []
    term = unicode(term)
    if len(term) > 0:
        obj_results = LexicalUnit.objects.filter(base__startswith=term)
        results = get_ordered_lexical_units_bases(obj_results)
    return {'result': results}

def get_ordered_lexical_units_bases(lexical_units_query):
    last_unit_base = ''
    lexical_unit_bases = []
    ordered_lexical_units = lexical_units_query.order_by('base')
    for lexical_unit in ordered_lexical_units:
        if lexical_unit.base != last_unit_base:
            lexical_unit_bases.append(lexical_unit.base)
        last_unit_base = lexical_unit.base
    return lexical_unit_bases

@ajax(method='get', encode_result=True)         
def synset_context_lookup(request, term):
    results = []
    term = unicode(term)
    if len(term) > 0:
        obj_results = LexicalUnit.objects.filter(base__startswith=term)
        results = get_ordered_lexical_units(obj_results)
    return {'result': results}

def get_ordered_lexical_units(lexical_units_query):
    ordered_lexical_units = lexical_units_query.order_by('base', 'sense')
    return [unicode(lu) for lu in ordered_lexical_units]

@ajax(method='get')
def validate_semantics(request, lemma_id, new_status_id):
    error_msg = ''
    if Lemma.objects.get(id=lemma_id).old:
        error_msg = u'Odśwież hasło, widoczna wersja nie jest aktualna.'
    else:
        try:
            status = Lemma_Status.objects.get(id=new_status_id)
        except Lemma_Status.DoesNotExist:
            status = None
        if status and status.check_semantics:
            error_msg = validate_frames(lemma_id)
            if not error_msg:
                error_msg = validate_lexical_units(lemma_id)
            if not error_msg:
                error_msg = validate_schemas(lemma_id)
    return {'error_message': error_msg}

@render('sem_arg_form.html')
@ajax(method='get', encode_result=False)
def sem_arg_form(request):
    form = RoleForm()
    return {'form': form}

@render('general_preference_form.html')
@ajax(method='get', encode_result=False)
def general_preference_form(request):
    form = GeneralSelPrefForm()
    return {'form': form}

@render('synset_preference_form.html')
@ajax(method='get', encode_result=False)
def synset_preference_form(request):
    form = SynsetSelPrefForm()
    return {'form': form}

@render('relational_preference_form.html')
@ajax(method='get', encode_result=False)
def relational_preference_form(request):
    form = RelationalSelPrefForm()
    return {'form': form}

@ajax(method='post', encode_result=True)         
def ajax_get_mwes(request, options):
    results = []
    bases = sorted(list(set(options)))
    for term in bases:
        term = unicode(term)
        if len(term) > 0:
            obj_results = LexicalUnit.objects.filter(base=term)
            if len(obj_results) > 0:
                sense = chr(ord(max([chr(ord('A') - 1)] + [str(lu.sense) for lu in obj_results])) + 1)
                for lu in obj_results:
                    results.append({'base': lu.base, 'sense': str(lu.sense), 'id': lu.id, 'luid': lu.luid, 'sid': lu.synset.id})
            else:
                sense = 'A'    
            # dla tworzenia nowej jednostki
            results.append({'base': term, 'sense': sense, 'id': '', 'luid': -1, 'sid': ''})
    return {'mwes': results}
