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

#Copyright (c) 2012, Bartłomiej Nitoń
#All rights reserved.

#Redistribution and use in source and binary forms, with or without modification, are permitted provided 
#that the following conditions are met:

#    Redistributions of source code must retain the above copyright notice, this list of conditions and 
#    the following disclaimer.
#    Redistributions in binary form must reproduce the above copyright notice, this list of conditions 
#    and the following disclaimer in the documentation and/or other materials provided with the distribution.

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED 
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.

import math
import codecs
import re
import os.path
from django.utils.encoding import smart_str
from django.utils.simplejson import dumps as json_encode, loads as json_decode
from django.contrib.auth.models import User, Group
from dictionary.models import Vocabulary, Lemma, Lemma_Status, Frame_Opinion, \
                              Frame_Opinion_Value, Frame, NKJP_Example, NKJP_ArgSelection, \
                              NKJP_Source, NKJP_Opinion, Position, \
                              PositionCategory, Argument, Argument_Model, \
                              Atribute_Value, Old_Frame_Property, Configuration, \
                              Atribute, Frame_Characteristic, Frame_Char_Model, \
                              Frame_Char_Value, Message, Change, \
                              VocabularyFormat
from dictionary.forms import AddPositionForm, AddArgumentForm, AtributeChoiceForm, \
                             AtributeTextForm, FrameForm, Pos_Cat_Form, ManageVocabPermForm, \
                             AddNkjpExampleForm, MessageForm, SortForm, FilterForm, \
                             SimilarLemmasOldForm, SimilarLemmasNewForm, ChangeUserFunctionForm
from common.decorators import render, ajax, AjaxError
from django.core import serializers

# w celu generowania i pobierania plikow
from django.http import HttpResponse
from settings import PROJECT_PATH

from subprocess import call
from tempfile import mkdtemp, mkstemp
from django.template.loader import render_to_string

# czasowniki podobne
from django.db.models import Q
import operator
from django.db.models import Max, Count

from django.core.validators import email_re
from accounts.models import UserSettings

from ajax_jqgrid import JqGridAjax

def reverse(string):
  return string[::-1]

######### nkjp example modification #####################

@ajax(method='post')
def get_nkjp_dict_ids(request, source_str, opinion_str):  
    
  source_obj = NKJP_Source.objects.get(source=source_str)
  opinion_obj = NKJP_Opinion.objects.get(opinion=opinion_str)

  return {'source_id' : source_obj.pk,
          'opinion_id': opinion_obj.pk} 

def user_can_confirm(user, example):
  can_confirm = False
  approvers_count = Configuration.objects.get(selected_conf=True).example_approvers_num
  if(example.source.confirmation_required and example.approvers.count() < approvers_count 
     and user.has_perm('dictionary.confirm_example')):
    try:
      example.approvers.get(username=user.username)
    except:
      can_confirm = True  
    
  return can_confirm

@ajax(method='post')
def can_confirm_example(request, example_id):     
    
  if example_id < 0:
    return {'can_confirm': False}

  example = NKJP_Example.objects.get(id=example_id)
  can_confirm = user_can_confirm(request.user, example)

  return {'can_confirm': can_confirm}

@ajax(method='post')
def confirm_nkjp_example(request, example_id): 
     
  example = NKJP_Example.objects.get(id=example_id)
  example.approvers.add(request.user) 
  approvers_count = Configuration.objects.get(selected_conf=True).example_approvers_num
  
  if example.approvers.count() >= approvers_count:
    example.approved = True
    example.save()
 
  return {}

#####################################################


def prepareFrameTable(frame):
  max_arguments = 0
  number_of_positions = len(frame.positions.all())
  positions_list = frame.positions.all()
  rows = []
  rows.append([frame])
  rows.append([])
  for position in positions_list:
    #appending categories row
    rows[1].append(position)
    if max_arguments < len(position.arguments.all()):
      max_arguments = len(position.arguments.all())
  
  # appending table headers spans
  rows.append([])
  rows[2].append(number_of_positions) # colspan
  rows[2].append(max_arguments)       # rowspan
    
  #appending arguments rows
  arg_number = 0
  for row_number in range(3, max_arguments+3):
    rows.append([])
    for position in positions_list:
      try:
        rows[row_number].append(position.arguments.all()[arg_number])
      except IndexError: 
        rows[row_number].append('None')
    arg_number = arg_number + 1
    
  return rows 

def frameObjToSerializableDict(lemma, frame):
  frame_opinions_tab = lemma.frame_opinions.filter(frame__text_rep=frame.text_rep)
  frame_opinion = ''
  if frame_opinions_tab:
    frame_opinion = frame_opinions_tab[0].value.value
  
  frame_dict = { 'id'             : frame.id,
                 'text_rep'       : frame.text_rep,
                 'characteristics': [],
                 'positions'      : [],
                 'opinion'        : frame_opinion,
                 'error'          : False}
  
  sorted_pos_dict = sortPositions(frame.positions.all())
  
  for position in sorted_pos_dict:     
    categories_str_tab = []
    for category in position['position'].categories.all():
      categories_str_tab.append(category.category)
    categories_str_tab = sortPosCatsAsStrTab(categories_str_tab)
    
    position_dict = {'id'        : position['position'].id,
                     'text_rep'  : position['position'].text_rep,
                     'categories': categories_str_tab,
                     'arguments' : [],
                     'error'     : False}

    for argument in position['arguments']:
      argument_dict = { 'id'      : argument.id,
                        'text_rep': argument.text_rep,
                        'type'    : argument.type,
                        'error'   : False}  
      position_dict['arguments'].append(argument_dict)
      
    frame_dict['positions'].append(position_dict)
  
  frame_char_objs = sortFrameChars(frame.characteristics.all())
  for char in frame_char_objs:
    frame_dict['characteristics'].append(char.value.value) 
    
  return frame_dict

def nkjpExamplesObjToJs(nkjp_examples, user):    
  example_dict_list = []
 # example_id = 0;
  for example in nkjp_examples:
    frame = example.frame;
    frame_table_id = 'frame_'+str(frame.id)+'_'
    arguments_ids = []
    for argument_selections in example.arguments.all():
      position = argument_selections.position
      pos_table_id = 'pos_'+str(position.id)+'_'
      for argument in argument_selections.arguments.all():
        arguments_ids.append(frame_table_id+pos_table_id+'arg_'+str(argument.id)+'_')

    confirmed = True
    approvers_count = Configuration.objects.get(selected_conf=True).example_approvers_num
    if example.source.confirmation_required and example.approvers.count() < approvers_count:
      try:
        example.approvers.get(username=user.username)
      except:
        confirmed = False  
    
    sentence = example.sentence.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"")
    comment = example.comment.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"")
        
    example_dict = { 'example_id'    : example.id,
                     'frame_id'      : frame_table_id,
                     'arguments_ids' : arguments_ids,
                     'sentence'      : sentence,
                     'source'        : example.source.source,
                     'opinion'       : example.opinion.opinion,
                     'comment'       : comment,
                     'confirmed'     : confirmed} 
    example_dict_list.append(example_dict)
    
  return example_dict_list

def nkjpLemmaExamplesObjToJs(nkjp_examples, user):
  example_dict_list = []
  for example in nkjp_examples:   
    confirmed = True
    approvers_count = Configuration.objects.get(selected_conf=True).example_approvers_num
    if example.source.confirmation_required and example.approvers.count() < approvers_count:
      try:
        example.approvers.get(username=user.username)
      except:
        confirmed = False  
    
    sentence = example.sentence.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"")
    comment = example.comment.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"")
    
    example_dict = { 'example_id'    : example.id,
                     'frame_id'      : '',
                     'arguments_ids' : [],
                     'sentence'      : sentence,
                     'source'        : example.source.source,
                     'opinion'       : example.opinion.opinion,
                     'comment'       : comment,
                     'confirmed'     : confirmed} 
    example_dict_list.append(example_dict)
    
  return example_dict_list
   
@render('old_frames.html')
@ajax(method='get', encode_result=False)
def get_old_frames(request, id):

  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']
    
  selected_lemma = Lemma.objects.get(id=id)
  old_frames = selected_lemma.old_frames
  
  reflexed_frames = []
  nreflexed_frames = []
  
  for frame in old_frames.all():
    if frame.reflex:
      reflexed_frames.append(frame)
    else:
      nreflexed_frames.append(frame)
  
  return {'reflexed_frames'  : reflexed_frames,
          'nreflexed_frames' : nreflexed_frames,
          'lemma_entry'      : selected_lemma.entry}


# czy wybrany uzytkownik moze edytowac dane haslo
def user_can_modify(lemma_obj, req_user):
  try:
    lemma_obj.vocabulary.editors.get(username=req_user.username)
    edit_vocabulary = True
  except:
    edit_vocabulary = False
    
  if ((lemma_obj.owner == req_user or req_user.has_perm('dictionary.change_all_lemmas')) and 
      ( not lemma_obj.status.status == u'gotowe' or req_user.has_perm('dictionary.change_all_lemmas')) 
      and (not lemma_obj.status.status == u'sprawdzone' or req_user.has_perm('dictionary.change_all_lemmas'))  # zmodyfikowano, aby sprawdzone hasla tez dalo sie modyfikowac 
      and edit_vocabulary): 
    return True
  
  return False

@render('lemma_preview.html')
@ajax(method='get', encode_result=False)
def get_lemma_preview(request, id, main_lemma_id):

  selected_lemma = Lemma.objects.get(id=id)  
  new_frames = selected_lemma.frames.order_by('text_rep')
  
  serialized_frames = []
  for frame in new_frames:
    serialized_frames.append(frameObjToSerializableDict(selected_lemma, frame))
  json_frames = json_encode(serialized_frames)
  
  frame_char_models = Frame_Char_Model.objects.order_by('priority')
  frame_char_prior_model_vals = frame_char_models[0].frame_char_values.all()
  
  frame_char_list = []
  for frame_char_val in frame_char_prior_model_vals:
    frame_char_list.append(frame_char_val.value)
    
  json_frame_char_list = json_encode(frame_char_list)
  
  # konwertowanie przykladow na zrozumiale przez java sript
  nkjp_examples = selected_lemma.nkjp_examples.all()
  nkjp_examples_js = nkjpExamplesObjToJs(nkjp_examples, request.user)
  
  json_nkjp_examples = json_encode(nkjp_examples_js)
  
  similarLemmasNewForm = SimilarLemmasNewForm(statuses=Lemma_Status.objects.order_by('priority'))
  
  similarLemmasOldForm = SimilarLemmasOldForm()

  return {'serialized_frames': json_frames,
          'frame_char_list': json_frame_char_list,
          'nkjp_examples': json_nkjp_examples,
          'selected_lemma': selected_lemma,
          'similarLemmasNewForm': similarLemmasNewForm,
          'similarLemmasOldForm': similarLemmasOldForm}

@render('new_frames.html')
@ajax(method='get', encode_result=False)
def get_new_frames(request, id):
    
  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']

  selected_lemma = Lemma.objects.get(id=id)  
  new_frames = selected_lemma.frames.order_by('text_rep')
   
# sprawdz czy uzytkownik jest wlascicielem wybranego hasla
  can_modify = user_can_modify(selected_lemma, request.user)
  
  serialized_frames = []
  for frame in new_frames:
    serialized_frames.append(frameObjToSerializableDict(selected_lemma, frame))
  json_frames = json_encode(serialized_frames)

  # pobieranie wartosci aspektu
  aspect_model = Frame_Char_Model.objects.get(model_name=u'ASPEKT')
  aspect_vals_objs = aspect_model.frame_char_values.order_by('-priority')
  
  aspect_str_list = []
  for aspect_val in aspect_vals_objs:
    aspect_str_list.append(aspect_val.value)
    
  json_aspect_str = json_encode(aspect_str_list)
  
  # pobieranie wartosci zwrotnosci
  reflex_model = Frame_Char_Model.objects.get(model_name=u'ZWROTNOŚĆ')
  reflex_vals_objs = reflex_model.frame_char_values.order_by('-priority')
  
  reflex_str_list = []
  for reflex_val in reflex_vals_objs:
    reflex_str_list.append(reflex_val.value)
    
  json_reflex_str = json_encode(reflex_str_list)
  
  # konwertowanie przykladow na zrozumiale przez java sript
  nkjp_examples = selected_lemma.nkjp_examples.order_by('source__priority', 'opinion__priority')
  nkjp_examples_js = nkjpExamplesObjToJs(nkjp_examples, request.user)
  
  json_nkjp_examples = json_encode(nkjp_examples_js)
  
  add_nkjp_form = AddNkjpExampleForm()
  
  lemma_nkjp_examples = selected_lemma.lemma_nkjp_examples.order_by('source__priority', 'opinion__priority')
  lemma_nkjp_examples_js = nkjpLemmaExamplesObjToJs(lemma_nkjp_examples, request.user)
  json_lemma_nkjp_examples = json_encode(lemma_nkjp_examples_js)

  return {'serialized_frames': json_frames,
          'aspect_val_list': json_aspect_str,
          'reflex_val_list': json_reflex_str,
          'add_nkjp_form': add_nkjp_form,
          'nkjp_examples': json_nkjp_examples,
          'can_modify': can_modify,
          'selected_lemma': selected_lemma,
          'lemma_nkjp_examples': json_lemma_nkjp_examples,}
  
  
@ajax(method='get', encode_result=True)
def get_ctrl_preview(request, id):
  change_obj = Change.objects.get(id=id)
  frames = change_obj.entry.frames.all()
  
  serialized_frames = []
  for frame in frames:
    serialized_frames.append(frameObjToSerializableDict(change_obj.entry, frame))

  return {'serialized_frames': serialized_frames}

@render('lemma_examples.html')
@ajax(method='get', encode_result=False)
def get_lemma_examples(request, id):
  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']
    
  selected_lemma = Lemma.objects.get(id=id)  
  lemma_nkjp_examples = selected_lemma.lemma_nkjp_examples.order_by('source__priority', 'opinion__priority')
  
  lemma_nkjp_examples_js = nkjpLemmaExamplesObjToJs(lemma_nkjp_examples, request.user)
  
  # sprawdz czy uzytkownik jest wlascicielem wybranego hasla
  can_modify = user_can_modify(selected_lemma, request.user)
  
  json_lemma_nkjp_examples = json_encode(lemma_nkjp_examples_js)

  add_nkjp_form = AddNkjpExampleForm()

  return {'add_nkjp_form': add_nkjp_form,
          'lemma_nkjp_examples': json_lemma_nkjp_examples,
          'can_modify': can_modify}

############################ lemma notes ###############################33
 
@render('lemma_notes.html')
@ajax(method='get', encode_result=False)
def get_lemma_notes(request, id):
  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']
    request.session['lemma_from_note_id'] = ''
    
  selected_lemma = Lemma.objects.get(id=id)
  add_note_form = MessageForm()
  
  messages = selected_lemma.messages.filter(private=False).order_by('-time')
  private_messages = selected_lemma.messages.filter(sender=request.user, private=True).order_by('-time')

  return {'add_note_form': add_note_form,
          'messages': messages,
          'private_messages': private_messages}
  

@ajax(method='post')
def get_lemma_note(request, message_id):
  message_obj = Message.objects.get(id=message_id)
      
  return {'private'      : message_obj.private,
          'topic'        : message_obj.topic,
          'message_text' : message_obj.message_text}

@ajax(method='post')
def lemma_notes_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)

  if not (form_dict['topic'] and form_dict['message_text']):
    raise AjaxError('required fields not selected')

  selected_lemma = Lemma.objects.get(id=form_dict['lemma_id'])

  Message(topic=form_dict['topic'], message_text=form_dict['message_text'],
                        sender=request.user, lemma=selected_lemma, private=form_dict['private']
                        ).save()
      
  return {'id'   : selected_lemma.id,
          'entry': selected_lemma.entry}
  
@ajax(method='post')
def lemma_notes_modify(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)

  if not (form_dict['topic'] and form_dict['message_text']):
    raise AjaxError('required fields not selected')

  selected_lemma = Lemma.objects.get(id=form_dict['lemma_id'])
  
  message_obj = Message.objects.get(id=form_dict['message_id'])
  if not message_obj.private:
    raise AjaxError('not private')
  
  message_obj.topic = form_dict['topic']
  message_obj.message_text = form_dict['message_text']
  message_obj.private = form_dict['private']
  message_obj.save()
      
  return {'id'   : selected_lemma.id,
          'entry': selected_lemma.entry}
  

@render('note_text.html')
@ajax(method='get', encode_result=False)
def get_note_text(request, id):
  message_obj = Message.objects.get(id=id)
  message_obj.new = False
  message_obj.save()

  return {'message_text': message_obj.message_text} 


@ajax(method='post')
def remove_note(request, message_id):  
    
  message_obj = Message.objects.get(id=message_id)
    
  if message_obj.sender != request.user or not message_obj.private:
    raise AjaxError('can not remove')

  message_obj.delete()

  return {} 

@ajax(method='post')
def get_lemma_from_note(request, message_id):  
  message_obj = Message.objects.get(id=message_id)
  request.session['lemma_from_note_entry'] = message_obj.lemma.entry
  request.session['lemma_from_note_id'] = message_obj.lemma.id
  new_notes_count = request.user.user_settings.new_notes_number()

  return {'new_notes_count': new_notes_count} 

@ajax(method='post')
def note_session_clear(request):  
  request.session['lemma_from_note_entry'] = ''
  request.session['lemma_from_note_id'] = ''

  return {} 

@ajax(method='post')
def note_session_get(request):  

  return {'lemma_from_note_entry': request.session['lemma_from_note_entry'],
          'lemma_from_note_id'   : request.session['lemma_from_note_id']} 

####################################### end lemma notes ######################################3

@render('lemma_status.html')
@ajax(method='get', encode_result=False)
def get_lemma_status(request, id):
  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']   
  selected_lemma = Lemma.objects.get(id=id)  
  
  show_reserve_button = False
  show_resign_button = False
  show_ready_button = False
  show_nready_button = False
  show_confirm_button = False
  show_nconfirm_button = False
  
  if not selected_lemma.owner:
    show_reserve_button = True
    
  if selected_lemma.owner == request.user or request.user.has_perm('dictionary.confirm_lemma'):
    if selected_lemma.status.status == u'do obróbki':
      show_reserve_button = True
    elif selected_lemma.status.status == u'w obróbce':
      show_resign_button = True
      show_ready_button = True
    elif selected_lemma.status.status == u'gotowe':
      show_nready_button = True
      
  if request.user.has_perm('dictionary.confirm_lemma') and selected_lemma.status.status == u'gotowe':
    show_confirm_button = True
  elif request.user.has_perm('dictionary.confirm_lemma') and selected_lemma.status.status == u'sprawdzone':
    show_nconfirm_button = True

  return {'lemma': selected_lemma,
          'show_reserve_button' : show_reserve_button,
          'show_resign_button'  : show_resign_button,
          'show_ready_button'   : show_ready_button,
          'show_nready_button'   : show_nready_button,
          'show_confirm_button' : show_confirm_button,
          'show_nconfirm_button' : show_nconfirm_button}
  

##################################################
def get_napprv_examples(lemma):
  nApprovedExamples = lemma.nkjp_examples.filter(source__confirmation_required=True, approved=False) 
  return nApprovedExamples
  

@ajax(method='post')
def lemma_status_change(request, change_type, lemma_id):
  lemma_obj = Lemma.objects.get(id=lemma_id)  
  # sprawdza czy uzytkonik moze modyfikowac hasla w danym slowniku
  try:
    lemma_obj.vocabulary.editors.get(username=request.user.username)
    edit_vocabulary = True
  except:
    edit_vocabulary = False
  changed = False
  
  if (change_type == 'reserve' and lemma_obj.status.status == u'do obróbki' 
      and request.user.has_perm('dictionary.change_lemmas') and edit_vocabulary):
    status_obj = Lemma_Status.objects.get(status=u'w obróbce')
    lemma_obj.status = status_obj
    lemma_obj.owner = request.user
    changed = True
    lemma_obj.save()
  elif change_type == 'resign':
    status_obj = Lemma_Status.objects.get(status=u'do obróbki')
    lemma_obj.status = status_obj
    lemma_obj.owner = None
    changed = True
    lemma_obj.save()
  elif change_type == 'ready':
    status_obj = Lemma_Status.objects.get(status=u'gotowe')
    lemma_obj.status = status_obj
    changed = True
    lemma_obj.save()  
  elif change_type == 'nready':
    status_obj = Lemma_Status.objects.get(status=u'w obróbce')
    lemma_obj.status = status_obj
    changed = True
    lemma_obj.save()  
  elif change_type == 'confirm':
    status_obj = Lemma_Status.objects.get(status=u'sprawdzone')
    lemma_obj.status = status_obj
    changed = True
    lemma_obj.save() 
  elif change_type == 'nconfirm':
    status_obj = Lemma_Status.objects.get(status=u'w obróbce')
    lemma_obj.status = status_obj
    changed = True
    lemma_obj.save() 
         
  return {'entry'   : lemma_obj.entry,
          'lemma_id': lemma_obj.id,
          'changed' : changed}


@ajax(method='post')
def restore_lemma(request, change_id, lemma_id):
  old_object = Lemma.objects.get(id=lemma_id)
  old_object.old = True
  old_object.save();
  
  new_actual_lemma = Change.objects.get(id=change_id).entry
  new_actual_lemma.old = False
  new_actual_lemma.owner = old_object.owner
  new_actual_lemma.save()

  # tworzenie zmiany do systemu kontroli zmian
  lemma_change = Change(user=request.user, entry=old_object, act_owner=old_object.owner)
  lemma_change.save()
  
  # przepisywanie starych wersji dla kontroli zmian i dodanie nowej
  # najpier nalezy z przywrcanego hasla odpiac stare wpisy
#new_actual_lemma.old_versions.clear() # to ostatnim razem bylo wlaczone
  for version in old_object.old_versions.all():
    new_actual_lemma.old_versions.add(version)
  new_actual_lemma.old_versions.add(lemma_change)
  
  # przepisywanie wiadomosci, wiadomosci powinny pozostawac bez zmian
  for message in old_object.messages.all():
    new_actual_lemma.messages.add(message)
           
  return {'id' : new_actual_lemma.id,
          'entry': new_actual_lemma.entry}
  

@render('change_ctrl.html')
@ajax(method='get', encode_result=False)
def get_change_ctrl(request, id):
    
  if request.session['lemma_from_note_id']:
    id = request.session['lemma_from_note_id']
    
  selected_lemma = Lemma.objects.get(id=id)  
  old_versions = selected_lemma.old_versions.order_by('-time')
  # sprawdz czy uzytkownik jest wlascicielem wybranego hasla
  can_modify = user_can_modify(selected_lemma, request.user)
  
  return {'old_versions': old_versions,
          'can_modify': can_modify}

def getFrequentPositions(lead_number):
  freq_positions_tab = []
  max_pos_length = 0;
  for position in Position.objects.all():
    if len(position.text_rep) > max_pos_length:
      max_pos_length = len(position.text_rep)
    if len(freq_positions_tab) <= lead_number:
      freq_positions_tab.append(position)
    else:
      numberOfFrames = len(position.frames.all())
      if numberOfFrames > len(freq_positions_tab[len(freq_positions_tab)-1].frames.all()):
        freq_positions_tab.pop();
        for pos in freq_positions_tab[:]:
          if freq_positions_tab.index(pos) == lead_number-1:
            freq_positions_tab.append(position)
            break
          elif len(pos.frames.all()) < numberOfFrames:
            freq_positions_tab.insert(freq_positions_tab.index(pos), position)
            break
        
  return  {'positions': freq_positions_tab,
           'max_pos_length': max_pos_length}


@render('position_form.html')
@ajax(method='get', encode_result=False)
def position_form(request):#, id, frames):
  freq_pos_objs = request.session['frequent_positions']
  freq_pos_str_tup = [(None, u'----------')]
  for pos in freq_pos_objs['positions']:
    freq_pos_str_tup.append((pos, pos.text_rep));
  
  form = AddPositionForm(freq_pos=freq_pos_str_tup, pos_length=freq_pos_objs['max_pos_length'])   
  return {'form': form}


@render('pos_cat_form.html')
@ajax(method='get', encode_result=False)
def pos_cat_form(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  category_obj = None
  control_obj = None
  for cat in form_dict['categories']:
    pos_cat_obj = PositionCategory.objects.get(category=cat)
    if pos_cat_obj.control:
      control_obj = pos_cat_obj
    elif not pos_cat_obj.control:
      category_obj = pos_cat_obj
    
  form = Pos_Cat_Form(category_val=category_obj, control_val=control_obj)   
  return {'form': form}

@render('sort_form.html')
@ajax(method='get', encode_result=False)
def sort_form(request):
  if request.session['lemma_preview']:
    sort_rules = request.session['sort_rules_lemma_preview']
  else:
    sort_rules = request.session['sort_rules']
  
  form = SortForm(id_order_choice=sort_rules['id']['sort_order'], id_priority_choice=sort_rules['id']['priority'], 
                  entry_order_choice=sort_rules['entry']['sort_order'], entry_priority_choice=sort_rules['entry']['priority'],
                  owner_order_choice=sort_rules['owner']['sort_order'], owner_priority_choice=sort_rules['owner']['priority'],
                  vocabulary_order_choice=sort_rules['vocabulary']['sort_order'], vocabulary_priority_choice=sort_rules['vocabulary']['priority'],
                  status_order_choice=sort_rules['status']['sort_order'], status_priority_choice=sort_rules['status']['priority'])
  return {'form': form} 

 
@ajax(method='post')
def sort_form_submit(request, form_data):
  sort_dict = dict((x['name'], x['value']) for x in form_data)
  
  if not (sort_dict['id']['priority'] or sort_dict['entry']['priority'] or
          sort_dict['owner']['priority'] or sort_dict['vocabulary']['priority'] or
          sort_dict['status']['priority']):
    raise AjaxError('none priority selected')

  sort_rules = {'id' : sort_dict['id'],
                'entry': sort_dict['entry'],
                'owner': sort_dict['owner'],
                'vocabulary': sort_dict['vocabulary'],
                'status': sort_dict['status']}
  
  if request.session['lemma_preview']:
    request.session['sort_rules_lemma_preview'] = sort_rules
    request.session['sorted_column_lemma_preview'] = ''
  else:
    request.session['sort_rules'] = sort_rules
    request.session['sorted_column'] = ''
  
  ordered_sort_rules = order_sort_rules(sort_rules)
      
  return {'column': ordered_sort_rules[0]['name'],
          'sort_order': ordered_sort_rules[0]['rules']['sort_order']}

@ajax(method='post')  
def get_sort_order(request):
  order = ''
  main_field = ''
  if request.session['lemma_preview']:
    if request.session['sorted_column_lemma_preview']:
      order = request.session['sorted_column_lemma_preview']['order']
      main_field = request.session['sorted_column_lemma_preview']['name']
    else:
      ordered_sort_rules = order_sort_rules(request.session['sort_rules_lemma_preview'])
      order = ordered_sort_rules[0]['rules']['sort_order']
      main_field = ordered_sort_rules[0]['name']
  else:   
    if request.session['sorted_column']:
      order = request.session['sorted_column']['order']
      main_field = request.session['sorted_column']['name']
    else:
      ordered_sort_rules = order_sort_rules(request.session['sort_rules'])
      order = ordered_sort_rules[0]['rules']['sort_order']
      main_field = ordered_sort_rules[0]['name']
      
  return {'order': order,
          'main_field': main_field}


@render('filter_form.html')
@ajax(method='get', encode_result=False)
def filter_form(request):  
  if request.session['lemma_preview']:
    filter_rules = request.session['filter_rules_lemma_preview']
  else:    
    filter_rules = request.session['filter_rules']
    
  can_confirm_example = False
  if request.user.has_perm('dictionary.confirm_example') or request.user.is_superuser:
    can_confirm_example = True
    
  form = FilterForm(User.objects.filter(Q(groups__permissions__codename='change_lemmas') |
                    Q(is_superuser=True)).distinct(), 
                    request.user.visible_vocabularies.all(), 
                    Lemma_Status.objects.all(), sel_user=filter_rules['owner'], 
                    sel_vocabulary=filter_rules['vocabulary'], 
                    sel_status=filter_rules['status'], sel_old_property=filter_rules['old_frames_property'],
                    sel_has_argument=filter_rules['argument'], sel_has_position=filter_rules['position'],
                    can_confirm_example = can_confirm_example,
                    sel_example_source=filter_rules['example_source'],
                    sel_approver=filter_rules['approver'],
                    sel_sender=filter_rules['sender'])
  
  return {'form': form} 

@ajax(method='post')
def filter_form_submit(request, form_data):
  filter_dict = dict((x['name'], x['value']) for x in form_data)

  if filter_dict['owner']:
    owner_obj = User.objects.get(id=filter_dict['owner'])
  else:
    owner_obj = None
    
  if filter_dict['vocabulary']:
    vocabulary_obj = Vocabulary.objects.get(name=filter_dict['vocabulary'])
  else:
    vocabulary_obj = None
    
  if filter_dict['status']:
    status_obj = Lemma_Status.objects.get(id=filter_dict['status'])
  else:
    status_obj = None
    
  if filter_dict['example_source']:
    nkjp_source_obj = NKJP_Source.objects.get(id=filter_dict['example_source'])
  else:
    nkjp_source_obj = None
    
  if filter_dict['approver']:
    approver_obj = User.objects.get(id=filter_dict['approver'])
  else:
    approver_obj = None
    
  if filter_dict['has_old_frames_property']:
    old_frames_prop_obj = Old_Frame_Property.objects.get(id=filter_dict['has_old_frames_property'])
  else:
    old_frames_prop_obj = None
    
  if filter_dict['has_argument']:
    try:
      argument_obj = Argument.objects.get(text_rep=filter_dict['has_argument'])
    except Argument.DoesNotExist:
      argument_obj = None
  else:
    argument_obj = None
    
  if filter_dict['has_message_from']:
    try:
      sender_obj = User.objects.get(pk=filter_dict['has_message_from'])
    except User.DoesNotExist:
      sender_obj = None
  else:
    sender_obj = None
    
  if filter_dict['has_position']:
    position_objs = Position.objects.filter(text_rep=filter_dict['has_position']).order_by('id')
    if not position_objs:
      position_obj = None
    else:
      position_obj = position_objs[0]
  else:
    position_obj = None

  if request.session['lemma_preview']:
    request.session['filter_rules_lemma_preview'] = {'owner'              : owner_obj,
                                                     'vocabulary'         : vocabulary_obj,
                                                     'status'             : status_obj,
                                                     'example_source'     : nkjp_source_obj,
                                                     'approver'           : approver_obj,
                                                     'old_frames_property': old_frames_prop_obj,
                                                     'argument'           : argument_obj,
                                                     'position'           : position_obj,
                                                     'sender'             : sender_obj}    
  else:
    request.session['filter_rules'] = {'owner'              : owner_obj,
                                       'vocabulary'         : vocabulary_obj,
                                       'status'             : status_obj,
                                       'example_source'     : nkjp_source_obj,
                                       'approver'           : approver_obj,
                                       'old_frames_property': old_frames_prop_obj,
                                       'argument'           : argument_obj,
                                       'position'           : position_obj,
                                       'sender'             : sender_obj}
      
  return {}

@ajax(method='post')
def save_columns(request, col_model, col_names, remap):
  request.session['colModel'] = col_model
  request.session['colNames'] = col_names
  request.session['remap'] = remap
  return {}

@ajax(method='post')
def sort_column(request, colName, sortOrder):
  if request.session['lemma_preview']:
    request.session['sorted_column_lemma_preview'] = {'name': colName,
                                                      'order': sortOrder}
  else:
    request.session['sorted_column'] = {'name': colName,
                                        'order': sortOrder}

  return {}

# posiada hardocy
@render('frame_form.html')
@ajax(method='get', encode_result=False)
def frame_form(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)

  aspect_values = Frame_Char_Model.objects.get(model_name=u'ASPEKT').frame_char_values.order_by('priority')
  reflex_values = Frame_Char_Model.objects.get(model_name=u'ZWROTNOŚĆ').frame_char_values.exclude(value=u'_').order_by('priority')
  curr_aspect_val = ''
  curr_reflex_val = ''
  
  for aspect_value in aspect_values:
    for frame_char in form_dict['characteristics']:
      if aspect_value.value == frame_char:
        curr_aspect_val = aspect_value
        break
    
  for reflex_value in reflex_values:
    if reflex_value.value == form_dict['characteristics'][1]:
      curr_reflex_val = reflex_value
      break
    
  if form_dict['opinion']: 
    frame_opinion = Frame_Opinion_Value.objects.get(value=form_dict['opinion'])
  else:
    frame_opinion = form_dict['opinion']
  
  form = FrameForm(aspect_values=aspect_values, reflex_values=reflex_values,
                   aspect_val=curr_aspect_val, reflex_val=curr_reflex_val,
                   frame_opinion_val=frame_opinion)

  return {'form': form}


@ajax(method='get', encode_result=True)         
def position_lookup(request, term):
    results = []
    
    if len(term) > 0:
    	model_results = Position.objects.filter(frames__lemmas__old=False, text_rep__icontains=term).distinct()
        results = [ (x.__unicode__(), x.id) for x in model_results ]

    return {'result': results}

@ajax(method='get', encode_result=True)         
def argument_lookup(request, term):
    results = []
    
    if len(term) > 0:
    	model_results = Argument.objects.filter(positions__frames__lemmas__old=False, text_rep__icontains=term).distinct()
        results = [ (x.__unicode__(), x.pk) for x in model_results ]

    return {'result': results}

@ajax(method='post')
def add_position(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  result = {}

  # wybrano dwie pozycje, nalezy wybrac tylko jedna
  if form_dict['filtered_positions'] and form_dict['frequent_positions'] != 'None':
    raise AjaxError('not proper selection')
  # wybrano gotowa pozycje
  elif form_dict['frequent_positions'] != 'None' or form_dict['filtered_positions']:
    if form_dict['frequent_positions'] != 'None':
        pos_obj = Position.objects.filter(text_rep=form_dict['frequent_positions']).order_by('id')[0]
    elif form_dict['filtered_positions']:
      pos_objs = Position.objects.filter(text_rep=form_dict['filtered_positions'])
      pos_obj = pos_objs[0]
      if len(pos_objs) == 0:
        raise AjaxError('wrong position representation')
   
    json_serializer = serializers.get_serializer("json")()
    categories_str = json_serializer.serialize(pos_obj.categories.all(), ensure_ascii=False)
    arguments_str = json_serializer.serialize(pos_obj.arguments.all(), ensure_ascii=False)
      
    result = {"id": pos_obj.id,
              "text_rep": pos_obj.text_rep,
              "categories": categories_str,
              "arguments": arguments_str}
  else: # nie wybrano nic, dodawana jest pusta pozycja
    result = {"id": -1,
              "text_rep": '',
              "categories": '[]',
              "arguments": '[]'}
  
  return result

@ajax(method='post')
def argument_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  result = {}
  
  # sprawdz czy wypelniono wszystkie pola formularza
  if not form_dict['arg_model_name']:
    raise AjaxError('empty fields error')
  for atr_value in form_dict['atr_values']:
    if not atr_value:
      raise AjaxError('empty fields error')

  # znajdz model dodawanego argumentu
  atribute_objs = []
  arg_model_obj = Argument_Model.objects.get(arg_model_name=form_dict['arg_model_name'])
  atribute_models = arg_model_obj.atribute_models.order_by('priority')
  for i in range(len(atribute_models)):
    if atribute_models[i].text_atribute and not arg_model_obj.has_realizations:
      atr_value = u"\'" + form_dict['atr_values'][i] +"\'"
      try:
        atr_val_obj = Atribute_Value.objects.get(value=atr_value)
      except:
        atr_val_obj = Atribute_Value(value=atr_value, priority=1000)
        atr_val_obj.save()

      try:
        atr_obj = Atribute.objects.get(type=atribute_models[i].atr_model_name, atribute_value=atr_val_obj)
      except Atribute.DoesNotExist:
        atr_obj = Atribute(type=atribute_models[i].atr_model_name, atribute_value=atr_val_obj)
        atr_obj.save() 
      atribute_objs.append(atr_obj)
      
    else:
      atr_val_init = atribute_models[i].atribute_values.get(pk=form_dict['atr_values'][i])
      try:
        atr_obj = Atribute.objects.get(type=atribute_models[i].atr_model_name, atribute_value=atr_val_init)
      except Atribute.DoesNotExist:
        atr_obj = Atribute(type=atribute_models[i].atr_model_name, atribute_value=atr_val_init)
        atr_obj.save() 
      atribute_objs.append(atr_obj)
  
  atr_str_tab = []
  for atr_obj in atribute_objs:
    atr_str_tab.append(atr_obj.atribute_value.value)

  arg_text_rep = ''
  if len(atr_str_tab) == 0:
    arg_text_rep = '%s' % (form_dict['arg_model_name'])
  else: 
    arg_text_rep = '%s(%s)' % (form_dict['arg_model_name'], ','.join(atr_str_tab))
  
  try:
    arg_obj = Argument.objects.get(text_rep=arg_text_rep)
  except Argument.DoesNotExist:
    arg_obj = Argument(type=form_dict['arg_model_name'], text_rep=arg_text_rep)
    arg_obj.save()
    for atr_obj in atribute_objs:
      arg_obj.atributes.add(atr_obj)
      
  result = {'id': arg_obj.id,
            'text_rep': arg_obj.text_rep,
            'type': arg_obj.type}
  
  return result


def sortByPriority(list):
  ret_list = []
  for elem in list:
    index = len(ret_list)
    for ret_elem in ret_list:
      if (ret_elem.priority>elem.priority):
        index = ret_list.index(ret_elem)
      elif(ret_list.index(ret_elem)==len(ret_list)):
        index = len(ret_list)
    ret_list.insert(index, elem)   
  return ret_list     
    
def sortArguments(list):
  ret_list = []
  typed_list = []
  models = Argument_Model.objects.all().order_by('priority')
  for model in models:
    typed_list.append([])
    for elem in list:
      if(elem.type == model.arg_model_name):
        typed_list[len(typed_list)-1].append(elem.text_rep) 
  for ls in typed_list:
    ls.sort()  
  for ls in typed_list:
    for text_rp in ls:
      for elem in list:
        if(elem.text_rep == text_rp):
          ret_list.append(elem)
          break     
  return ret_list   

# wyszukuje ramke o najwyzszym priorytecie
# pomija rozdzileanie kategorii
def getHighestPriorFrame(positions_dict_list, row_idx):
  arguments = []

  for position in positions_dict_list:
    if(row_idx < len(position['arguments'])):
      arguments.append(position['arguments'][row_idx])
      
  sorted_args = sortArguments(arguments) 
  same_args = 0
  
  for arg in sorted_args:
    if arg == sorted_args[0]:
      same_args = same_args + 1
      
  if same_args > 1:
    same_args_dict_list = []
    for position_dict in positions_dict_list:
      if position_dict['arguments'][row_idx] == sorted_args[0]:
        same_args_dict_list.append(position_dict)
    
    # sprawdz czy wszystkie pozycje nie sa takie same
    positionsSame = True
    for same_arg_pos in same_args_dict_list: 
      if len(same_arg_pos['arguments']) > row_idx+1:
        positionsSame = False 
    if positionsSame:
      return same_args_dict_list[0]
    else:  
      return getHighestPriorFrame(same_args_dict_list, row_idx+1)
   
  for position_dict in positions_dict_list:
    if len(position_dict['arguments']) <= row_idx:
      return position_dict
    elif position_dict['arguments'][row_idx]==sorted_args[0]: 
      return position_dict
  
def sortPositions(positions):
  ret_list = []
  pos_dict_list = []

  # sortowanie argumentow na pozycjach
  for position in positions:
    sortedArguments = sortArguments(position.arguments.all())
    position_dict = {"position": position,
                     "arguments": sortedArguments}
    pos_dict_list.append(position_dict)
      
  # sortowanie pozycji wedlug kategorii
  sorted_pos_cats = PositionCategory.objects.order_by("priority")
  pos_to_sort = []
  
  for pos_cat in sorted_pos_cats:
    same_cat_positions = []
    first_pos_arg_list = []
    for position in pos_dict_list:
      if len(position['position'].categories.all()) > 0:
        first_prior_cat = position["position"].categories.order_by("priority")[0]
        if first_prior_cat == pos_cat:
          same_cat_positions.append(position)
    
    while len(same_cat_positions) != 0:
      highestPriorFrame = getHighestPriorFrame(same_cat_positions, 0)
      ret_list.append(highestPriorFrame)
      same_cat_positions.remove(highestPriorFrame)

  blanc_cat_positions = []  
  for position in pos_dict_list:
    if len(position["position"].categories.all()) == 0:
      blanc_cat_positions.append(position)
      
  while len(blanc_cat_positions) != 0:
    highestPriorFrame = getHighestPriorFrame(blanc_cat_positions, 0)
    ret_list.append(highestPriorFrame)
    blanc_cat_positions.remove(highestPriorFrame)
    
  return ret_list

@render('argument_form.html')
@ajax(method='get', encode_result=False)
def argument_form(request, form_data):#, id, frames):  
  type_form = AddArgumentForm()
  atr_value_forms = []
  has_realizations = False

  if form_data: # zaznaczono wartosci
    form_dict = dict((x['name'], x['value']) for x in form_data)
    
    # prezentowanie formularza na podstawie reprezentacji teksowej argumentu
    if form_dict['arg_text_rep']:
      arg_obj = Argument.objects.get(text_rep=form_dict['arg_text_rep'])
      
      type_form = AddArgumentForm(value=arg_obj.type)
      arg_model = Argument_Model.objects.get(arg_model_name=arg_obj.type)
      atribute_models = arg_model.atribute_models.order_by('priority')  
      has_realizations = arg_model.has_realizations
      
      for atribute_model in atribute_models:
        atribute_obj = arg_obj.atributes.get(type=atribute_model.atr_model_name)
        if atribute_model.text_atribute:
          if has_realizations:
            atr_value_forms.append(AtributeChoiceForm(values=atribute_model.atribute_values.order_by('value'), 
                                 label=atribute_model.atr_model_name, value=atribute_obj.atribute_value))
          else:
            atr_value_forms.append(AtributeTextForm(label=atribute_model.atr_model_name, value=atribute_obj.atribute_value.value.replace("\'", ''))) 
        else:
          atr_value_forms.append(AtributeChoiceForm(values=atribute_model.atribute_values.order_by('priority'), 
                                 label=atribute_model.atr_model_name, value=atribute_obj.atribute_value))
            
    elif form_dict['arg_model_name']:
      arg_model = Argument_Model.objects.get(arg_model_name=form_dict["arg_model_name"])
      has_realizations = arg_model.has_realizations
      atr_models = arg_model.atribute_models.order_by('priority')
      type_form = AddArgumentForm(value=form_dict["arg_model_name"])
    
      for i in range(len(atr_models)):
        if not atr_models[i].text_atribute:
          if i < len(form_dict['atr_values']):
            atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                    label=atr_models[i].atr_model_name, value=form_dict['atr_values'][i]))
          else:
            atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                    label=atr_models[i].atr_model_name))
     
        else:
          if i < len(form_dict['atr_values']):
            if has_realizations:
              try:
                atr_value = atr_models[i].atribute_values.get(value=form_dict['atr_values'][i])
                atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('value'), 
                                      label=atr_models[i].atr_model_name, value=atr_value))
              except:
                atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('value'), 
                                      label=atr_models[i].atr_model_name))
            else:
              atr_value_forms.append(AtributeTextForm(label=atr_models[i].atr_model_name, value=form_dict['atr_values'][i])) 
          else:
            if has_realizations:
              atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('value'), 
                                    label=atr_models[i].atr_model_name))
            else:
              atr_value_forms.append(AtributeTextForm(label=atr_models[i].atr_model_name))
  
  return {'type_form': type_form,
          'atr_value_forms': atr_value_forms,
          'has_realizations': has_realizations}
         
# sort categories names when presented as table of strings
def sortPosCatsAsStrTab(pos_cat_str_tab):
  sorted_pos_cat_objs = PositionCategory.objects.order_by('priority')
  sorted_cats = []
  
  for pos_cat_obj in sorted_pos_cat_objs:
    for pos_cat_str in pos_cat_str_tab:
      if pos_cat_str == pos_cat_obj.category:
        sorted_cats.append(pos_cat_str)
        
  return sorted_cats      

# sort frame_characteristic names when presented as table of strings
def sortFrameChars(frameChars):
  sorted_frame_char_models = Frame_Char_Model.objects.order_by('priority')
  sorted_frame_chars = []
  
  for frame_char_model in sorted_frame_char_models:
    for frame_char in frameChars:
      if frame_char_model.model_name == frame_char.type:
        sorted_frame_chars.append(frame_char)
             
  return sorted_frame_chars  

 
def jsArgToObj(argument):
    arg_obj = Argument.objects.get(text_rep=argument['text_rep'])
    return arg_obj

def jsPosToObj(position, pos_idx=0):
    categories = []
    for category in position['categories']:
      categories.append(category)
    categories = sortPosCatsAsStrTab(categories)
    
    arguments_objs = []
    for arg in position['arguments']:
      arguments_objs.append(jsArgToObj(arg))
      
    argument_objs = sortArguments(arguments_objs)
    
    args_str_tab = []
    last_arg_obj = None
    for arg_obj in argument_objs:
      if not last_arg_obj or last_arg_obj.text_rep != arg_obj.text_rep:
        args_str_tab.append(arg_obj.text_rep)
      last_arg_obj = arg_obj
      
    pos_text_rep = '%s{%s}' % (','.join(categories),';'.join(args_str_tab))
    
    same_positions = Position.objects.filter(text_rep=pos_text_rep)
    if len(same_positions) > 0:
      pos_obj = same_positions[pos_idx]
    else:
      pos_obj = Position(text_rep=pos_text_rep) 
      pos_obj.save()
      for category in categories:
        category_obj = PositionCategory.objects.get(category=category)
        pos_obj.categories.add(category_obj) 
      for arg_obj in argument_objs:
        pos_obj.arguments.add(arg_obj)
   
    return pos_obj

def jsFrameToObj(frame, lemma_entry):
    # szukanie charakterystyk ramki
    frame_characteristic_objs = []
    frame_char_models = Frame_Char_Model.objects.order_by('priority')
    for i in range(len(frame_char_models)):
      frame_char_value = frame_char_models[i].frame_char_values.get(value=frame['characteristics'][i])
      frame_char_type = frame_char_models[i].model_name
      try:
        frame_char_obj = Frame_Characteristic.objects.get(type=frame_char_type, value=frame_char_value)
      except Frame_Characteristic.DoesNotExist:
        frame_char_obj = Frame_Characteristic(type=frame_char_type, value=frame_char_value)
        frame_char_obj.save()
      frame_characteristic_objs.append(frame_char_obj)
    
    positions_objs = []
    for position in frame['positions']:
      pos_obj = jsPosToObj(position)
      positions_objs.append(pos_obj)  
    
    sorted_positions = []  
    sorted_pos_dict = sortPositions(positions_objs)
    last_pos_dict = None
    for pos_dict in sorted_pos_dict:
      sorted_positions.append(pos_dict['position'])
    
    sort_pos_str_tab = []
    for sort_pos in sorted_positions:
      sort_pos_str_tab.append(sort_pos.text_rep)  
 
    if frame['characteristics'][1] == u'się':  
      text_rep = u' %s:%s:%s' % (frame['characteristics'][1], frame['characteristics'][0], '+'.join(sort_pos_str_tab))
    else:
      text_rep = u':%s:%s' % (frame['characteristics'][0], '+'.join(sort_pos_str_tab))
    
    try:
      frame_obj = Frame.objects.get(text_rep=text_rep)
    except Frame.DoesNotExist:
      frame_obj = Frame(text_rep=text_rep)
      frame_obj.save()
      last_pos_obj = None
      pos_obj_count = 0
      for pos_obj in sorted_positions:
        same_pos_db = Position.objects.filter(text_rep=pos_obj.text_rep).order_by('id')
        if not last_pos_obj or last_pos_obj.text_rep != pos_obj.text_rep:
          pos_obj_count = 1
          frame_obj.positions.add(same_pos_db[0])
        else:
          pos_obj_count = pos_obj_count + 1
          if pos_obj_count <= len(same_pos_db):  
            same_pos_obj = same_pos_db[pos_obj_count-1] # nowe
            frame_obj.positions.add(same_pos_obj)  
          else:
            same_pos_obj = Position(text_rep=pos_obj.text_rep) # nowe
            same_pos_obj.save()
            for category in pos_obj.categories.all():
              same_pos_obj.categories.add(category)
            for arg in pos_obj.arguments.all():
              same_pos_obj.arguments.add(arg)            
            frame_obj.positions.add(same_pos_obj)       
        last_pos_obj = pos_obj                          # nowe
      for frame_char in frame_characteristic_objs:
        frame_obj.characteristics.add(frame_char)
        
    return frame_obj

######################### LEMMA NOTES ###################
@ajax(method='post')
def remove_lemma_note(request, message_id):
  message_obj = Message.objects.get(id=message_id)
  
  if(message_obj.sender != request.user or not message_obj.private):
    raise AjaxError('can not remove')

  message_obj.delete();
  
  return {}

############### CZASOWNIKI PODOBNE ###################
@ajax(method='post')
def similar_lemmas_reset(request):
  request.session['similar_lemmas'] = ''
  
  return {}

@ajax(method='post')
def preview_select(request, isPreview):
  if request.session['lemma_preview'] == isPreview:
    reload = False
  else:
    reload = True    
  request.session['lemma_preview'] = isPreview
  
  return {'reload': reload}


def getLemmaCompatibility(lemma, comp_lemma):
  intersection = 0
  
  for old_frame in lemma.old_frames.all():
    old_frames = comp_lemma.old_frames.filter(old_frame_value=old_frame.old_frame_value,
                                              property=old_frame.property,
                                              reflex=old_frame.reflex)
    if old_frames.count() > 0:
      intersection = intersection + 1
  
  sum = lemma.old_frames.count() + comp_lemma.old_frames.count() - intersection
  intersection = float(intersection)
  #sum = float(sum)
  
  # wspolczynnik podobienstwa Jaccard'a
  return (intersection/sum)*100 


@ajax(method='post')
def similar_lemmas_old_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  if not form_dict['compatibility']:
    raise AjaxError('compatibility not selected')
  if not form_dict['compatibility'].isdigit():
    raise AjaxError('compatibility not digit')
  if int(form_dict['compatibility']) < 1 or int(form_dict['compatibility']) > 100:
    raise AjaxError('wrong compatibility range')

  lemma = Lemma.objects.get(id=form_dict['lemma_id'])
  similar_lemmas = []

  for frame in lemma.old_frames.all():
    for relLemma in frame.lemmas.filter(old=False).all():
    # sprawdza czy uzytkownik moze ogladac hasla w danym slowniku, jesli nie to nie ma co liczyc
      try:
        relLemma.vocabulary.viewers.get(username=request.user.username)
        view_lemma = True
      except:
        view_lemma = False
      if (not relLemma.old and view_lemma):
        compatibility = getLemmaCompatibility(lemma, relLemma)
        if compatibility >= int(form_dict['compatibility']):
          similar_lemmas.append(relLemma)
   
  if len(similar_lemmas) > 0:
    q_list = []
    for similar_lemma in similar_lemmas:
      q_list.append(Q(id=similar_lemma.id))
    similar_lemmas_query = Lemma.objects.filter(reduce(operator.or_, q_list)) 
    request.session['similar_lemmas'] = similar_lemmas_query.all()
  else:
    raise AjaxError('similar lemmas not found')

  return {}

def getLemmaCompatibilityNewFr(lemma, comp_lemma):
  intersection = 0
  
  for frame in lemma.frames.all():
    for comp_frame in comp_lemma.frames.all():
      if (frame.text_rep == comp_frame.text_rep):
        intersection = intersection + 1
        break
  
  sum = len(lemma.frames.all()) + len(comp_lemma.frames.all()) - intersection
  intersection = float(intersection)
  sum = float(sum)
  
  # wspolczynnik podobienstwa Jaccard'a
  return (intersection/sum)*100 #((intersection*intersection)/(sum*sum))*100 

@ajax(method='post')
def similar_lemmas_new_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  if not form_dict['compatibility']:
    raise AjaxError('compatibility not selected')
  if not form_dict['compatibility'].isdigit():
    raise AjaxError('compatibility not digit')
  if int(form_dict['compatibility']) < 1 or int(form_dict['compatibility']) > 100:
    raise AjaxError('wrong compatibility range')
  if not form_dict['status']:
    raise AjaxError('status not selected')

  lemma = Lemma.objects.get(id=form_dict['lemma_id'])

  status_priority = Lemma_Status.objects.get(pk=form_dict['status']).priority
  similar_lemmas = []

  for frame in lemma.frames.all():
    for relLemma in frame.lemmas.all():
    # sprawdza czy uzytkownik moze ogladac hasla w danym slowniku, jesli nie to nie ma co liczyc
      try:
        relLemma.vocabulary.viewers.get(username=request.user.username)
        view_lemma = True
      except:
        view_lemma = False
      if(relLemma.status.priority >= status_priority and not relLemma.old 
         and view_lemma):
        compatibility = getLemmaCompatibilityNewFr(lemma, relLemma)
        if compatibility >= int(form_dict['compatibility']):
          similar_lemmas.append(relLemma)
   
  if len(similar_lemmas) > 0:
    q_list = []
    for similar_lemma in similar_lemmas:
      q_list.append(Q(id=similar_lemma.id))
    similar_lemmas_query = Lemma.objects.filter(reduce(operator.or_, q_list)) 
    request.session['similar_lemmas'] = similar_lemmas_query.all()
  else:
    raise AjaxError('similar lemmas not found')
      
  return {}

##############################################

@ajax(method='post')
def pos_cat_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  position = json_decode(form_dict['position_str'])
  
  pos_cat_str_tab = [] 
  if form_dict['category']:
    category_obj = PositionCategory.objects.get(pk=form_dict['category'])
    pos_cat_str_tab.append(category_obj.category)
  if form_dict['control']:
    control_obj = PositionCategory.objects.get(pk=form_dict['control'])
    pos_cat_str_tab.append(control_obj.category)
    
  position['categories'] = pos_cat_str_tab
  
  pos_obj = jsPosToObj(position)
      
  return {'id' : pos_obj.id,
          'text_rep': pos_obj.text_rep,
          'categories': pos_cat_str_tab}
  

@ajax(method='post')
def frame_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  lemma_obj = Lemma.objects.get(id=form_dict['lemma_id'])
  frame = json_decode(form_dict['frame_str'])
  
  if not (form_dict['opinion'] and form_dict['aspect'] and form_dict['reflex']):
    raise AjaxError('empty fields error')
 # tworzenie i dodawanie nowo stworzonych ramek, pozycji, argumentow
 # szukanie charakterystyk ramki
  frame_characteristic_objs = []
  aspect_model = Frame_Char_Model.objects.get(model_name=u'ASPEKT')
  aspect_value = Frame_Char_Value.objects.get(pk=form_dict['aspect'])
  
  try:
    aspect_char_obj = Frame_Characteristic.objects.get(type=aspect_model.model_name, value=aspect_value)
  except Frame_Characteristic.DoesNotExist:
    aspect_char_obj = Frame_Characteristic(type=aspect_model.model_name, value=aspect_value)
    aspect_char_obj.save()
  frame_characteristic_objs.append(aspect_char_obj)
  
  # przepisywanie informacji o zwrotnosci
  reflex_model = Frame_Char_Model.objects.get(model_name=u'ZWROTNOŚĆ')
  reflex_value = Frame_Char_Value.objects.get(pk=form_dict['reflex'])
  
  try:
    reflex_char_obj = Frame_Characteristic.objects.get(type=reflex_model.model_name, value=reflex_value)
  except Frame_Characteristic.DoesNotExist:
    reflex_char_obj = Frame_Characteristic(type=reflex_model.model_name, value=reflex_value)
    reflex_char_obj.save()
  frame_characteristic_objs.append(reflex_char_obj)
    
  positions_objs = []
  for position in frame['positions']:
    pos_obj = jsPosToObj(position)
    positions_objs.append(pos_obj)  
    
  sorted_positions = []  
  sorted_pos_dict = sortPositions(positions_objs)
  for pos_dict in sorted_pos_dict:
    sorted_positions.append(pos_dict['position'])
    
  sort_pos_str_tab = []
  for sort_pos in sorted_positions:
    sort_pos_str_tab.append(sort_pos.text_rep)

  text_rep = ''
  
  if reflex_char_obj.value.value == u'się':  
    text_rep = u' %s:%s:%s' % (reflex_value.value, aspect_value.value ,'+'.join(sort_pos_str_tab))
  else:
    text_rep = u':%s:%s' % (aspect_value.value ,'+'.join(sort_pos_str_tab))
    
  try:
    new_frame_obj = Frame.objects.get(text_rep=text_rep)
  except Frame.DoesNotExist:
    new_frame_obj = Frame(text_rep=text_rep)
    new_frame_obj.save()
    for pos_obj in positions_objs:
      new_frame_obj.positions.add(pos_obj)
    for frame_char in frame_characteristic_objs:
      new_frame_obj.characteristics.add(frame_char)
 
  opinion = Frame_Opinion_Value.objects.get(pk=form_dict['opinion'])
  
  frame_char_str_tab = []
  frame_char_str_tab.append(aspect_value.value)
  frame_char_str_tab.append(reflex_value.value)
      
  return {'id' : new_frame_obj.id,
          'text_rep': new_frame_obj.text_rep,
          'opinion': opinion.value,
          'characteristics': frame_char_str_tab}
  

@ajax(method='post')
def nkjp_example_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  if not (form_dict['sentence'].strip() and form_dict['source'] and form_dict['opinion']):
    raise AjaxError('required fields not selected')
  elif(NKJP_Source.objects.get(pk=form_dict['source']).comment_required and not form_dict['comment'].strip()):
    raise AjaxError('comment required')
  
  source_str = NKJP_Source.objects.get(pk=form_dict['source']).source
  opinion_str = NKJP_Opinion.objects.get(pk=form_dict['opinion']).opinion
      
  return {'sentence' : form_dict['sentence'],
          'source': source_str,
          'opinion': opinion_str,
          'comment': form_dict['comment']}

@ajax(method='post')
def save_new_frames(request, data, id, examples, lemma_examples):
  try:
    old_object = Lemma.objects.get(id=id, old=False)
  except:
    raise AjaxError('concurrent access')
    
  if old_object.locker != None:
    raise AjaxError('concurrent access')
  else:
    old_object.locker = request.user
    old_object.old = True
    old_object.save()
  
  # tworzenie nowej wersji hasla
    new_lemma_ver = Lemma(entry=old_object.entry, owner=old_object.owner,
                    vocabulary=old_object.vocabulary, status=old_object.status, 
                    old=True, locker=request.user)#, checked=old_object.checked)
    new_lemma_ver.save()  
    
    decoded_examples = json_decode(examples)
    decoded_lemma_examples = json_decode(lemma_examples)
  # tworzenie nowo okreslonych ramek, pozycji, argumentow
    frames = json_decode(data)
  
  # tworzenie zmiany do systemu kontroli zmian
    if(old_object.owner):
      lemma_change = Change(user=request.user, entry=old_object, act_owner=old_object.owner)
      lemma_change.save()
    else:
      lemma_change = Change(user=request.user, entry=old_object)
      lemma_change.save()
  
  # przepisywanie starych wersji dla kontroli zmian i dodanie nowej
    for version in old_object.old_versions.all():
      new_lemma_ver.old_versions.add(version)
    new_lemma_ver.old_versions.add(lemma_change)
  
  # przepisywanie wiadomosci
    for message in old_object.messages.all():
      new_lemma_ver.messages.add(message)
    
  # przepisywanie starych ramek
    for old_frame in old_object.old_frames.all():
      new_lemma_ver.old_frames.add(old_frame)
    
  # przepisywa klas zgodnosci zgodnie ze starymi ramkami
    for obj_class in old_object.compatibility_classes.all():
      new_lemma_ver.compatibility_classes.add(obj_class)
    
  # przepisywanie przykladow z Dendrarium
    for dendr_example in old_object.dendr_examples.all():
      new_lemma_ver.dendr_examples.add(dendr_example)
  
  # tworzenie ramek i dolaczanie ich do czasownika 
    for frame in frames:
      frame_obj = jsFrameToObj(frame, new_lemma_ver.entry)
        
    # dodawanie opinii o ramce
      if frame['opinion']:
        frame_opinion_val = Frame_Opinion_Value.objects.get(value=frame['opinion'])
        try:
          frame_opinion_obj = Frame_Opinion.objects.get(frame=frame_obj, value=frame_opinion_val)
        except Frame_Opinion.DoesNotExist:
          frame_opinion_obj = Frame_Opinion(frame=frame_obj, value=frame_opinion_val)
          frame_opinion_obj.save()
      
        new_lemma_ver.frame_opinions.add(frame_opinion_obj)    
      new_lemma_ver.frames.add(frame_obj)
    
  # dodawanie przykladow do ramek
    for example in decoded_examples:
      frame_obj = jsFrameToObj(example['frame'], new_lemma_ver.entry)
      argument_selections = []
      used_pos_obj_ids = []
      for arg_selection in example['arg_selections']:
        try_pos_obj = jsPosToObj(arg_selection['position'])
        pos_objs = Position.objects.filter(text_rep=try_pos_obj.text_rep)
        all_ids_used = False
          
        existing_pos_ids = []
        for pos_obj in pos_objs:
          existing_pos_ids.append(pos_obj.id)
          
        not_used_ids = existing_pos_ids
        for pos in pos_objs.all():
          for pos_id in used_pos_obj_ids:
            if pos_id == pos.id:
              not_used_ids.remove(pos_id)
              
        if len(not_used_ids) > 0:
          position_obj = Position.objects.get(id=not_used_ids[0]) 
        else:
          position_obj = Position(text_rep=try_pos_obj.text_rep)
          position_obj.save()
          for arg in try_pos_obj.arguments.all():
            position_obj.arguments.add(arg)
          for cat in try_pos_obj.categories.all():
            position_obj.categories.add(cat)
            
        used_pos_obj_ids.append(position_obj.id)
        
        # sprawdzanie czy dany obiekt klasy NKJP_ArgSelection istnieje
        argument_objs = [] 
        nkjp_arg_sel_query = NKJP_ArgSelection.objects.filter(position=position_obj)
        for argument in arg_selection['arguments']:
          arg_obj = jsArgToObj(argument)
          argument_objs.append(arg_obj)

          if len(nkjp_arg_sel_query.all()) > 0: # Q objectem to zalatwic
            nkjp_arg_sel_query = nkjp_arg_sel_query.filter(arguments=arg_obj)
        
        nkjp_arg_sel_obj = None
        if len(nkjp_arg_sel_query.all()) > 0:
          for nkjp_arg_sel in nkjp_arg_sel_query.all():
            if len(nkjp_arg_sel.arguments.all()) == len(argument_objs):
              nkjp_arg_sel_obj = nkjp_arg_sel
              break
        if not nkjp_arg_sel_obj:
          nkjp_arg_sel_obj = NKJP_ArgSelection(position=position_obj)
          nkjp_arg_sel_obj.save()
          for arg_obj in argument_objs:
            nkjp_arg_sel_obj.arguments.add(arg_obj)
    
        argument_selections.append(nkjp_arg_sel_obj)
        
      nkjp_source_obj = NKJP_Source.objects.get(source=example['source'])
      nkjp_opinion_obj = NKJP_Opinion.objects.get(opinion=example['opinion'])
      
      # sprawdzanie czy dany obiekt klasy NKJP_Example istnieje
      nkjp_example_sel_query = NKJP_Example.objects.filter(frame=frame_obj, sentence=example['sentence'], source=nkjp_source_obj,
                                                           comment=example['comment'], opinion=nkjp_opinion_obj,
                                                           lemmas__entry=new_lemma_ver.entry) # nowododany warunek wyszukiwania pole wyszukiwania)
      
      for argument_sel in argument_selections:
        if len(nkjp_example_sel_query.all()) > 0:
          nkjp_example_sel_query = nkjp_example_sel_query.filter(arguments=argument_sel)
        else:
          break
      
      if len(nkjp_example_sel_query.all()) > 0:
        nkjp_example_obj = nkjp_example_sel_query.all()[0]
      else:
        nkjp_example_obj = NKJP_Example(frame=frame_obj, sentence=example['sentence'], source=nkjp_source_obj,
                                    comment=example['comment'], opinion=nkjp_opinion_obj,
                                    approved=not nkjp_source_obj.confirmation_required)
        nkjp_example_obj.save()
        for argument_selection in argument_selections:
          nkjp_example_obj.arguments.add(argument_selection)    
        
      new_lemma_ver.nkjp_examples.add(nkjp_example_obj)   
    
# dodawanie przykladow nkjp do czasownika
    for example in decoded_lemma_examples:
      source_obj = NKJP_Source.objects.get(source=example['source'])
      opinion_obj = NKJP_Opinion.objects.get(opinion=example['opinion'])
      # sprawdzanie czy dany obiekt klasy NKJP_Example istnieje      
      nkjp_example_sel_query = NKJP_Example.objects.filter(sentence=example['sentence'], source=source_obj,
                                                           comment=example['comment'], opinion=opinion_obj,
                                                           lemmas__entry=new_lemma_ver.entry) # nowododany warunek wyszukiwania pole wyszukiwania
                                                               
      example_found = False
      for nkjp_example in nkjp_example_sel_query.all():
        if not nkjp_example.frame and len(nkjp_example.arguments.all()) == 0:
          nkjp_lemma_example_obj = nkjp_example
          example_found = True
          break
      
      if not example_found:
        nkjp_lemma_example_obj = NKJP_Example(sentence=example['sentence'], source=source_obj, 
                                    comment=example['comment'], opinion=opinion_obj, 
                                    approved=not source_obj.confirmation_required)
        nkjp_lemma_example_obj.save() 
      

      new_lemma_ver.lemma_nkjp_examples.add(nkjp_lemma_example_obj)
    

    old_object.locker = None;
    old_object.save()
    new_lemma_ver.locker = None;
    try:
      new_lemma_ver = Lemma.objects.get(entry=old_object.entry, owner=old_object.owner,
                            vocabulary=old_object.vocabulary, status=old_object.status, 
                            old=False)#, checked=old_object.checked)
      raise AjaxError('concurrent access')
    except:
      new_lemma_ver.old = False;
      new_lemma_ver.save();
      
  return {'id'           : new_lemma_ver.id,
          'entry'        : new_lemma_ver.entry,
          'error_message': '',
          'frames'       : ''}


############## WALIDACJA #####################
  
@ajax(method='post')
def validate_new_frames(request, data, id, examples, lemma_examples, status_id):
  old_object = Lemma.objects.get(id=id)
  
  decoded_examples = json_decode(examples)
  decoded_lemma_examples = json_decode(lemma_examples)
  
  if status_id == 'reserve':
    status_obj = Lemma_Status.objects.get(status=u'w obróbce')
  elif status_id == 'resign':
    status_obj = Lemma_Status.objects.get(status=u'do obróbki')
  elif status_id == 'ready':
    status_obj = Lemma_Status.objects.get(status=u'gotowe') 
  elif status_id == 'nready':
    status_obj = Lemma_Status.objects.get(status=u'w obróbce')
  elif status_id == 'confirm':
    status_obj = Lemma_Status.objects.get(status=u'sprawdzone') 

  # tworzenie nowo okreslonych ramek, pozycji, argumentow
  frames = json_decode(data)
  nvalid_examples = get_napprv_examples(old_object)
  
  serialized_frames = []
  error_val2 = False
  error_val8 = False
  error_val9 = False
  error_val10 = False
  #error_val11 = False
  error_val12 = False
  error_val15 = False
  error_val16 = False
  
  for frame in frames:
    frame_obj = jsFrameToObj(frame, old_object.entry)
    serialized_frame = frameObjToSerializableDict(old_object, frame_obj)
    serialized_frame['opinion'] = frame['opinion']

# WALIDACJA 2: Rama nie może posiadać pustych pozycji.
    for position in frame_obj.positions.all():
      if position.arguments.count() == 0:
        for serialized_position in serialized_frame['positions']:
          if serialized_position['text_rep'] == position.text_rep:
            serialized_position['error'] = True 
        error_val2 = True
        break
  
# WALIDACJA 8: Przypadek pred nie może wystąpić w pozycji NIEBĘDĄCEJ jednocześnie jako controlee.
# niestety z hardcodami :(
    breakFlag = False
    for position in frame_obj.positions.all():
      if breakFlag:
        break
      for argument in position.arguments.all():
        if breakFlag:
          break
        for atribute in argument.atributes.all():
          if atribute.type == u'PRZYPADEK' and atribute.atribute_value.value == u'pred':
            hasControlee = False
            for category in position.categories.all():
              if category.category == u'controlee':
                hasControlee = True
            if not hasControlee:
              breakFlag = True
              for serialized_position in serialized_frame['positions']:
                if serialized_position['text_rep'] == position.text_rep:
                  serialized_position['error'] = True
              error_val8 = True
              break
    
# WALIDACJA 9: Niedopuszczone jest refl w jednej pozycji z jakimkolwiek innym argumentem.
# niestety z hardcodami :(
    breakFlag = False
    for position in frame_obj.positions.all():
      if breakFlag:
        break
      for argument in position.arguments.all():
        if argument.type == u'refl' and len(position.arguments.all())>1:
          for serialized_position in serialized_frame['positions']:
            if serialized_position['text_rep'] == position.text_rep:
              serialized_position['error'] = True
          error_val9 = True
          breakFlag = True
          break
      
# WALIDACJA 10: Przy zapisie hasła xp musi otrzymać konkretną realizację (nie _).
# niestety z hardcodami :(
    breakFlag = False
    for position in frame_obj.positions.all():
      if breakFlag:
        break
      for argument in position.arguments.all():
        if argument.type == u'xp' and argument.atributes.all()[0].atribute_value.value == u'_':
          for serialized_position in serialized_frame['positions']:
            if breakFlag:
              break
            for serialized_argument in serialized_position['arguments']:
              if serialized_argument['text_rep'] == argument.text_rep:
                serialized_argument['error'] = True
                breakFlag = True
                break
          error_val10 = True
          break
      
# WALIDACJA 11: Przy zapisie hasła rama nie może zawierać w jednej pozycji dwóch argumentów tego samego typu,
# z którego atrybutem jednego jest _, a innego określona realizacja parametru. 
# Dotyczy to również podtypów fraz zdaniowych (nie mogą wystąpić naraz w pozycji np. cp(int-rel(jak)) 
# oraz cp(int-rel(_))).
# niestety z hardcodami :(
 #   breakFlag = False
 #   for position in frame_obj.positions.all():
 #     i = 0     
 #     sorted_arguments = sortArguments(position.arguments.all())
 #     # argumenty sa posortowane wiec wystarczy porownywac aktualny z nastepnym
 #     while i+1 < len(sorted_arguments):
 #       if breakFlag:
 #         break
 #       if sorted_arguments[i].type == sorted_arguments[i+1].type:
 #         sorted_atribute_models = Argument_Model.objects.get(arg_model_name=sorted_arguments[i].type).atribute_models.order_by('priority')
 #
 #         for atribute_model in sorted_atribute_models:
 #           atr = sorted_arguments[i].atributes.get(type=atribute_model.atr_model_name)
 #           atr_next = sorted_arguments[i+1].atributes.get(type=atribute_model.atr_model_name)
 #           
 #           if ((atr.atribute_value.value == u'_' and atr_next.atribute_value.value != u'_') or
 #               (atr.atribute_value.value != u'_' and atr_next.atribute_value.value == u'_')):
 #             for serialized_position in serialized_frame['positions']:
 #               if serialized_position['text_rep'] == position.text_rep:
 #                 serialized_position['error'] = True
 #             error_val11 = True
 #             breakFlag = True
 #             break
 #       i = i+1      

# WALIDACJA 12: Niedopuszczone jest np, prepnp, cp, ncp ani prepncp z przypadkiem pop.
# niestety z hardcodami, wielkimi :(
    breakFlag = False
    for position in frame_obj.positions.all():   
      if breakFlag:
        break
      for argument in position.arguments.all():
        if breakFlag:
          break
        if (argument.type == u'np' or argument.type == u'prepnp' or
           argument.type == u'cp' or argument.type == u'ncp' or
           argument.type == u'prepncp'):
          
          for atribute in argument.atributes.all():
            if breakFlag:
              break
            if atribute.type.startswith(u'PRZYPADEK') and atribute.atribute_value.value == u'postp': 
              error_val12 = True
              for serialized_position in serialized_frame['positions']:
                if breakFlag:
                  break
                for serialized_argument in serialized_position['arguments']:
                  if serialized_argument['text_rep'] == argument.text_rep:
                    serialized_argument['error'] = True
                    breakFlag = True
                    break
     
    # WALIDACJA 15: Haslo nie moze posiadac pustych ramek
    if frame_obj.positions.count() == 0:
      serialized_frame['error'] = True
      error_val15 = True
      
# WALIDACJA 16: czy wszystkie przyklady wlasne zostaly zatwierdzone  
    if status_id and status_obj.check_examples:
      for nvalid_example in nvalid_examples:
        if nvalid_example.frame == frame_obj:
          serialized_frame['error'] = True
          error_val16 = True
          break 
                        
    serialized_frames.append(serialized_frame)
       
  
  if error_val2:
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Wskazana ramka posiada pustą pozycję (przejdź do zakładki z nowymi ramkami aby ją zobaczyć, jeśli ramka nie jest widoczna sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames} 
  if error_val8:
    return {'id'           : '',
              'entry'        : '',
              'error_message': 'Wskazane pozycje posiadają przypadek pred nie posiadając kategorii controlee (przejdź do zakładki z nowymi ramkami aby je zobaczyć, jeśli pozycje nie są widoczne sprawdź ustawienia filtrów i powtórz walidację).',
              'frames'       : serialized_frames}         
  if error_val9:
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Wskazane pozycje posiadają argument refl występujący wraz z innymi argumentami (przejdź do zakładki z nowymi ramkami aby je zobaczyć, jeśli pozycje nie są widoczne sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames}
  if error_val10: 
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Wskazane argumenty typu xp nie posiadają określonej realizacji (przejdź do zakładki z nowymi ramkami aby je zobaczyć, jeśli argumenty nie są widoczne sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames}
  #if error_val11:
  #  return {'id'           : '',
  #          'entry'        : '',
  #          'error_message': 'Wskazane pozycje posiadają jednocześnie argumenty o określonym i nieokreślonym typie (przejdź do zakładki z nowymi ramkami aby je zobaczyć, jeśli pozycje nie są widoczne sprawdź ustawienia filtrów i powtórz walidację)..',
  #          'frames'       : serialized_frames}
  if error_val12:
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Wskazany typ argumentu nie może posiadać przypadka postp (przejdź do zakładki z nowymi ramkami aby zobaczyć błędne argumenty, jeśli argumenty nie są widoczne sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames}
  if error_val15:
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Hasło nie może posiadać pustych ramek (przejdź do zakładki z nowymi ramkami aby je zobaczyć, jeśli ramki nie są widoczne sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames}
  if error_val16:
    return {'id'           : '',
            'entry'        : '',
            'error_message': 'Wskazana ramka nie posiada zatwierdzonych przykładów własnych (przejdź do zakładki z nowymi ramkami aby ją zobaczyć, jeśli ramka nie jest widoczna sprawdź ustawienia filtrów i powtórz walidację).',
            'frames'       : serialized_frames}
     
  return {'id'           : '',
          'entry'        : '',
          'error_message': '',
          'frames'       : ''}

class LemmaGrid(JqGridAjax):
  model = Lemma
  search_field = 'entry'
  field_translation = {
    'id': 'id',
    'entry': 'entry',
    'owner': 'owner__username',
    'vocabulary': 'vocabulary__name',
    'status': 'status__status'
  }
  
  @staticmethod
  def sort_field_special_case(rule):
    if rule['field'] == 'entry' and rule['a_tergo']:
      return 'rev'
    else:
      return rule['field']

  @staticmethod
  def sort_queryset_special_case(queryset, rule):
    if rule['field'] == 'entry' and rule['a_tergo']:
      return queryset.extra(select={'rev': "reverse(haslo)"})
    else:
      return queryset

  @staticmethod
  def filter_special_case(filter, lookup, negated, queryset):

    return True

  @staticmethod
  def get_queryset(vocabularies):
    return True

  @staticmethod
  def apply_mask(lemmas, mask):#, sort_rules):
    matching_lemmas = lemmas.filter(entry__istartswith=mask)
    return matching_lemmas

  @staticmethod
  def filter_value_special_case(queryset, rule, from_value, greater):
    if rule['field'] == 'entry' and rule['a_tergo']:
      if greater:
        comp = '>='
      else:
        comp = '<='
      queryset = queryset.extra(where=["reverse(haslo) " + comp + " %s"],
                                params=[reverse(from_value)])
      return True, queryset
    else:
      return False, queryset

  @staticmethod
  def get_field_special_case(field, lexeme):
    if field == 'part_of_speech':
      return True, lexeme.part_of_speech.symbol
    else:
      return False, None

  @staticmethod
  def response_row(lemma):
    ownerName = ''
    if lemma.owner:
        ownerName = lemma.owner.username
    
    return {
      'id' : lemma.id,
      'entry' : lemma.entry,
      'owner' : ownerName,
      'vocabulary' : lemma.vocabulary.name,
      'status' : lemma.status.status,
    }

  @classmethod
  def get_location(self, filtering_mode, sort_rules, filters, mask, *args):
    selected_pk, index, count = self.get_pk(
      mask, filters, sort_rules, filtering_mode, *args)
    return {
      'rowIndex': index,
      'selected_id': selected_pk,
      'records': count,
    }
    
def order_sort_rules(sort_rules):
  cleared_sort_rules = []
  
  if(sort_rules['id']['priority']):
    cleared_sort_rules.append({'name' : 'id',
                               'rules': sort_rules['id']})
  if(sort_rules['entry']['priority']):
    cleared_sort_rules.append({'name' : 'entry',
                               'rules': sort_rules['entry']})
  if(sort_rules['owner']['priority']):
    cleared_sort_rules.append({'name' : 'owner',
                               'rules': sort_rules['owner']})
  if(sort_rules['vocabulary']['priority']):
    cleared_sort_rules.append({'name' : 'vocabulary',
                               'rules': sort_rules['vocabulary']})
  if(sort_rules['status']['priority']):
    cleared_sort_rules.append({'name' : 'status',
                               'rules': sort_rules['status']})
  
  ordered_sort_rules = []
  while not len(cleared_sort_rules) == 0:
    highest_prior_rule_idx = 0
    for i in range(len(cleared_sort_rules)):
      if cleared_sort_rules[i]['rules']['priority'] < cleared_sort_rules[highest_prior_rule_idx]['rules']['priority']:
        highest_prior_rule_idx = i
    ordered_sort_rules.append(cleared_sort_rules.pop(highest_prior_rule_idx))
    
  return ordered_sort_rules
    
def prepare_sort_rules(sort_rules):
  ordered_sort_rules = order_sort_rules(sort_rules)
    
  prepared_sort_rules = []
  for rule in ordered_sort_rules:
    if rule['name'] == u'owner':
      rule['name'] = rule['name'] + '__username'
    if rule['rules']['sort_order'] == u'desc':
      prepared_sort_rules.append(u'-'+rule['name'])
    else:
      prepared_sort_rules.append(rule['name'])
    
  return prepared_sort_rules

# to co tutaj jest prezentowane jest bardzo glupie, ale na razie innego pomyslu nie mam
def get_lemma_query(prepared_sort_rules, filter_rules, column_rule, lemma_query, user):
  lemmas = Lemma.objects.none()
  visible_vocabs = user.visible_vocabularies.all()
  q_list = []
  for vocab in visible_vocabs:
    q_list.append(Q(vocabulary=vocab))  
  
  lemma_query = lemma_query.filter(reduce(operator.or_, q_list))
  lemma_query = lemma_query.filter(old=False)
  
  ## sortowanie
  if not column_rule:
    entrySortDefined = False
    for sort_rule in prepared_sort_rules:
      if sort_rule.endswith('entry'):
        entrySortDefined = True
        break
    
    if not entrySortDefined:
      prepared_sort_rules.append('entry')
      
    if len(prepared_sort_rules) == 1:
      lemmas = lemma_query.order_by(prepared_sort_rules[0]) 
    elif len(prepared_sort_rules) == 2:
      lemmas = lemma_query.order_by(prepared_sort_rules[0], prepared_sort_rules[1]) 
    elif len(prepared_sort_rules) == 3:
      lemmas = lemma_query.order_by(prepared_sort_rules[0], prepared_sort_rules[1],
                                    prepared_sort_rules[2]) 
    elif len(prepared_sort_rules) == 4:
      lemmas = lemma_query.order_by(prepared_sort_rules[0], prepared_sort_rules[1],
                                    prepared_sort_rules[2], prepared_sort_rules[3])
    elif len(prepared_sort_rules) == 5:
      lemmas = lemma_query.order_by(prepared_sort_rules[0], prepared_sort_rules[1],
                                    prepared_sort_rules[2], prepared_sort_rules[3],
                                    prepared_sort_rules[4])
    elif len(prepared_sort_rules) == 6:
      lemmas = lemma_query.order_by(prepared_sort_rules[0], prepared_sort_rules[1],
                                    prepared_sort_rules[2], prepared_sort_rules[3],
                                    prepared_sort_rules[4], prepared_sort_rules[5])
  else:
    prepared_rule = column_rule['name']
    if column_rule['order'] == u'desc':
      prepared_rule = u'-'+column_rule['name']
    if column_rule['name'] == 'entry':
      lemmas = lemma_query.order_by(prepared_rule)
    elif column_rule['name'] == 'owner':
      lemmas = lemma_query.order_by(prepared_rule+'__username', 'entry')
    else:
      lemmas = lemma_query.order_by(prepared_rule, 'entry')
     
  ## filtrowanie
  if filter_rules['owner']:
    lemmas = lemmas.filter(owner=filter_rules['owner'])
  if filter_rules['vocabulary']:
    lemmas = lemmas.filter(vocabulary=filter_rules['vocabulary'])
  if filter_rules['status']:
    lemmas = lemmas.filter(status=filter_rules['status']) 
 
  if filter_rules['old_frames_property']: 
    lemmas = lemmas.filter(old_frames__property__name=filter_rules['old_frames_property'].name)
  if filter_rules['position']:
    lemmas = lemmas.filter(frames__positions__text_rep=filter_rules['position'].text_rep)
  if filter_rules['argument']:
    lemmas = lemmas.filter(frames__positions__arguments__text_rep=filter_rules['argument'].text_rep)
  if filter_rules['sender']:
    lemmas = lemmas.filter(messages__sender=filter_rules['sender'])
    
  lemmas = lemmas.distinct()
    
  if filter_rules['example_source']:
    lemmas = lemmas.filter((Q(nkjp_examples__source=filter_rules['example_source']) &
                            Q(nkjp_examples__approved=False)) | 
                           (Q(lemma_nkjp_examples__source=filter_rules['example_source']) &
                            Q(lemma_nkjp_examples__approved=False)))
    
    if filter_rules['approver']:
      lemmas = lemmas.filter(Q(nkjp_examples__approvers=filter_rules['approver']) | 
                             Q(lemma_nkjp_examples__approvers=filter_rules['approver'])).distinct()
      
    else:
      q_excluded_lemmas = [] # hasla, w ktorych nie ma jednak hasel do potwierdzenia
      for lemma in lemmas.all():
        examplesToApprove = lemma.nkjp_examples.filter(~Q(approvers=user) & 
                            Q(source=filter_rules['example_source']) & Q(approved=False))
        lemmaExamplesToApprove = lemma.lemma_nkjp_examples.filter(~Q(approvers=user) & 
                                 Q(source=filter_rules['example_source']) & Q(approved=False))
      
        if examplesToApprove.count()==0 and lemmaExamplesToApprove.count()==0:
          q_excluded_lemmas.append(Q(id=lemma.id))
      if len(q_excluded_lemmas)>0:     
        lemmas = lemmas.exclude(reduce(operator.or_, q_excluded_lemmas))
    
  lemmas = lemmas.distinct()
    
  return lemmas

@ajax(method='get')
def get_lemmas(request, page, rows, sort_rules=None, filters=None, mask='',
                target_page=0, totalrows=0):

  similar_lemmas = ''
  if request.session['lemma_preview']:
    sort_rules = request.session['sort_rules_lemma_preview'] 
    filter_rules = request.session['filter_rules_lemma_preview'] 
    column_rule = request.session['sorted_column_lemma_preview'] 
    similar_lemmas = request.session['similar_lemmas']  
  else: 
    sort_rules = request.session['sort_rules'] 
    filter_rules = request.session['filter_rules'] 
    column_rule = request.session['sorted_column']
  
  prepared_sort_rules = prepare_sort_rules(sort_rules)

  if not similar_lemmas:
    lemma_query = get_lemma_query(prepared_sort_rules, filter_rules, column_rule, Lemma.objects, request.user)
  else:
    lemma_query = get_lemma_query(prepared_sort_rules, filter_rules, column_rule, similar_lemmas, request.user)
  
  lemmas = list(lemma_query)

  count = len(lemmas)
  total_pages = math.ceil(count/50)
  page = target_page or page
  limit = totalrows or rows
  total_pages, start, response_rowcount = LemmaGrid.count_pages(
                                                    count, page, limit)
  lemmas = lemmas[start:start + response_rowcount]

  return LemmaGrid.make_response(lemmas, count, page, total_pages)



# Zapytanie o id oraz indeks pierwszego wiersza przy danym sortowaniu,
# którego hasło rozpoczyna się od mask.
# 'selected_id' == None, jeśli takiego nie ma
@ajax(method='get')
def get_location(request, mask='', id=''):
  similar_lemmas = ''
  if request.session['lemma_preview']:
    sort_rules = request.session['sort_rules_lemma_preview'] 
    filter_rules = request.session['filter_rules_lemma_preview'] 
    column_rule = request.session['sorted_column_lemma_preview'] 
    similar_lemmas = request.session['similar_lemmas']  
  else: 
    sort_rules = request.session['sort_rules'] 
    filter_rules = request.session['filter_rules'] 
    column_rule = request.session['sorted_column']
  
  prepared_sort_rules = prepare_sort_rules(sort_rules)

  if not similar_lemmas:
    lemma_query = get_lemma_query(prepared_sort_rules, filter_rules, column_rule, Lemma.objects, request.user)
  else:
    lemma_query = get_lemma_query(prepared_sort_rules, filter_rules, column_rule, similar_lemmas, request.user)
  
  matching_lemmas = list(lemma_query.filter(entry__istartswith=mask))
  
  lemmas = lemma_query
  lemmas_list = list(lemmas)

# warto to potem zastapic czyms madrzejszym
  if(len(matching_lemmas) == 0): 
    matching_lemmas = lemmas_list

  lemma_nfound = False
  firstMatchingLemma = None
  if id:
    try:
      firstMatchingLemma = lemmas.get(id=id)
    except:
      if len(lemmas.all()) > 0:
        firstMatchingLemma = lemmas.all()[0]
      lemma_nfound = True
  else:
    if len(matching_lemmas) > 0:
      firstMatchingLemma = matching_lemmas[0]
    lemma_nfound = True
    
  if firstMatchingLemma:
    id = firstMatchingLemma.id
    index = lemmas_list.index(firstMatchingLemma) 
  else:
    index = 0
    lemma_nfound = True
  
  return {
      'rowIndex': index,
      'selected_id': id,
      'records': len(lemmas),
      'lemma_nfound': lemma_nfound,
    }  

@render()
@ajax(method='get', encode_result=False)
def lemma_edit_form(request, id):  
  return id

#############################################################################
######################### Slowniki
DEFAULT_SAVE_PATH = os.path.join(PROJECT_PATH, 'tmp')
TEXT_VOCABULARY_CLAUSE = u"""
% The Polish Valence Dictionary (Walenty)
% July 20, 2012
%
% The Polish Valence Dictionary (Walenty) is an adaptation of
% the Syntactic Dictionary of Polish Verbs by Marek Świdziński
% in its electronic version provided by Łukasz Dębowski and
% Elżbieta Hajnicz and further expanded by Witold Kieraś to
% include the most frequent verbs in the 1 milion sample of
% NKJP (National Corpus of Polish).
%
% The presented resource results from an automatic conversion
% of the aforementioned dictionary, manually reviewed by Filip
% Skwarski to include correct information about a number of new
% features, including sentential subjects, passivisation, and
% control relations.
%
% The format of the new dictionary has been established by Filip
% Skwarski, Elżbieta Hajnicz, Witold Kieraś, Agnieszka Patejuk,
% Adam Przepiórkowski, Marek Świdziński, and Marcin Woliński.
%
% The dictionary has been edited and compiled using a tool
% created by Bartłomiej Nitoń.
%
% The original Syntactic Dictionary of Polish Verbs derives from:
%
% Marek Świdziński
% Institute of Polish
% Warsaw University
% Warsaw, Poland
%
% © Copyright 1998,2012 by Marek Świdziński
%
% This work is distributed under a CC BY-SA license:
% http://creativecommons.org/licenses/by-sa/2.0/
%
"""


def download_vocabulary(request, file_name):  
  fullpath = os.path.join(DEFAULT_SAVE_PATH, file_name)
  response = None
 
  if file_name.endswith('.txt'):
    fullpath = '/' + file_name
    with open(fullpath, "r") as f:
      data = f.read()
    response = HttpResponse(data, mimetype='text/txt')
    response['Content-Disposition'] = 'attachment; filename=slowal.txt'
    os.remove(fullpath)
    os.rmdir(os.path.split(fullpath)[0])
  elif file_name.endswith('.tex'):
    fullpath = '/' + file_name
    with open(fullpath, "r") as f:
      data = f.read()
    response = HttpResponse(data, mimetype='text/txt')
    response['Content-Disposition'] = 'attachment; filename=slowal.tex'
    os.remove(fullpath)
    os.rmdir(os.path.split(fullpath)[0])
  #elif file_name.endswith('.pdf'):
  #  fullpath = '/' + file_name
  #  with open(fullpath, "rb") as f:
  #    data = f.read()
  #  response =  HttpResponse(data, mimetype='application/pdf')
  #  response['Content-Disposition'] = 'attachment; filename=slowal.pdf'
  #  os.remove(fullpath)
  #  os.rmdir(os.path.split(fullpath)[0])
  
 # to moze sie przydac do przesylania spakowanego pdf
   #temp = tempfile.TemporaryFile()
   #archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)                          
   #archive.write(fullpath, file_name)
   #archive.close()
   #wrapper = FileWrapper(temp)
   #response = HttpResponse("zlosc", content_type='application/zip')
   #response['Content-Disposition'] = 'attachment; filename=slowal.zip'
   #response['Content-Length'] = temp.tell()
   #temp.seek(0)
   
  return response


###########################################
def getArgsList(arguments, real_arg_models):
  if real_arg_models:
    argument_objs = []  
    for argument in arguments:
      has_realizations = False
      for arg_model in real_arg_models:
        if argument.type == arg_model.arg_model_name:
          has_realizations = True
          if argument.realizations.count() > 0:
            argument_objs.extend(argument.realizations.all())
          else:
            argument_objs.append(argument)
          break
      if not has_realizations:
        argument_objs.append(argument)  
    if len(argument_objs) != len(arguments):
      argument_objs = getArgsList(argument_objs, real_arg_models)
    return argument_objs
  else:
    return arguments

def changeArgsToRealizations(frame, real_arg_models, q_real_types):
  position_objs = []
  tmp_positions = []
  for position in frame.positions.all():
    if position.arguments.filter(reduce(operator.or_, q_real_types)).count() > 0:
      argument_objs = getArgsList(position.arguments.all(), real_arg_models)
      new_pos = Position(text_rep='tmp')
      new_pos.save()
      for category in position.categories.all():
        new_pos.categories.add(category)
      for arg_obj in argument_objs:
        new_pos.arguments.add(arg_obj)
      sorted_arguments = sortArguments(argument_objs)
      
      categories = []
      for category in position.categories.all():
        categories.append(category.category)
      categories = sortPosCatsAsStrTab(categories)
      
      args_str_tab = []
      for arg_obj in sorted_arguments:
        args_str_tab.append(arg_obj.text_rep)
      
      pos_text_rep = '%s{%s}' % (','.join(categories),';'.join(args_str_tab))
      new_pos.text_rep = pos_text_rep
      new_pos.save()
      tmp_positions.append(new_pos)
      position_objs.append(new_pos)
    else:
      position_objs.append(position)
      
  sorted_positions = []  
  sorted_pos_dict = sortPositions(position_objs)
  for pos_dict in sorted_pos_dict:
    sorted_positions.append(pos_dict['position'])
    
  sort_pos_str_tab = []
  for sort_pos in sorted_positions:
    sort_pos_str_tab.append(sort_pos.text_rep) 
      
  frame_char_objs = sortFrameChars(frame.characteristics.all())
 
  if frame_char_objs[1].value.value == u'się':  
    text_rep = u' %s:%s:%s' % (frame_char_objs[1].value.value, frame_char_objs[0].value.value, '+'.join(sort_pos_str_tab))
  else:
    text_rep = u':%s:%s' % (frame_char_objs[0].value.value, '+'.join(sort_pos_str_tab))  
  
  for tmp_position in tmp_positions:
    tmp_position.delete()
  
  return text_rep  

import locale
from functools import cmp_to_key
locale.setlocale(locale.LC_ALL, 'pl_PL.UTF-8')

import HTMLParser

@ajax(method='post')
def create_vocabulary(request, form_data):  
  form_dict = dict((x['name'], x['value']) for x in form_data)

  if not form_dict['format']:
    raise AjaxError('format not selected')

  voc_format_obj = VocabularyFormat.objects.get(pk=form_dict['format'])  
  q_vocabularies = [Q(vocabulary__pk=x) for x in form_dict['vocabularies']]
  q_lemma_statuses = [Q(status__pk=x) for x in form_dict['lemma_statuses']]
  q_owners = [Q(owner__pk=x) for x in form_dict['owners']]
  
  q_realizations = []
  q_real_types = [] 
  real_arg_models = []
  for realization_pk in form_dict['realizations']:
    argument_model_obj = Argument_Model.objects.get(pk=realization_pk)
    real_arg_models.append(argument_model_obj)
    q_realizations.append(Q(arguments__type=argument_model_obj.arg_model_name))
    q_real_types.append(Q(type=argument_model_obj.arg_model_name))
  
  lemmas = Lemma.objects.filter(old=False).order_by('entry')
  
  if q_vocabularies:
    lemmas = lemmas.filter(reduce(operator.or_, q_vocabularies))
  if q_lemma_statuses:
    lemmas = lemmas.filter(reduce(operator.or_, q_lemma_statuses))  
  if q_owners:
    lemmas = lemmas.filter(reduce(operator.or_, q_owners)) 
    
  frame_char_models = Frame_Char_Model.objects.order_by('-priority')
  
  sort_reflex_vals = frame_char_models[0].frame_char_values.order_by('priority')
  sort_aspect_vals = frame_char_models[1].frame_char_values.order_by('priority') 
  q_frame_opinions = [Q(value__pk=x) for x in form_dict['frame_opinions']]

  #try:
  if True:
# In a temporary folder, make a temporary file
    tmp_folder = mkdtemp()
    os.chdir(tmp_folder)      
    tmpfile, tmpfilename = mkstemp(dir=tmp_folder)
  # ewentualna zmiana skrotow nazw folderow na pelne nazwy pod windowsem
    #tmpfilename = tmpfilename.replace("admini~1", "Administrator")
    
    if voc_format_obj.format == u'Tekstowy':
     # f = codecs.open( DEFAULT_SAVE_PATH+'slowal.txt', 'w+', 'utf-8-sig' )
      os.close(tmpfile)
      f = codecs.open( tmpfilename, 'w+', 'utf-8-sig' )
      f.write( TEXT_VOCABULARY_CLAUSE )
    
      for lemma in lemmas:
        frame_opinions = None
        if q_frame_opinions:
          frame_opinions = lemma.frame_opinions.filter(reduce(operator.or_, q_frame_opinions))
        for reflex_val in sort_reflex_vals:
          for aspect_val in sort_aspect_vals:
            text_reps = []
            matching_frames = lemma.frames.filter(characteristics__value=reflex_val,
                                                  characteristics__type=frame_char_models[0].model_name 
                                                  ).filter(characteristics__value=aspect_val,
                                                         characteristics__type=frame_char_models[1].model_name)                          
            for frame in matching_frames:
              if not form_dict['frame_opinions'] or (frame_opinions and frame_opinions.filter(frame=frame).count() > 0):
                frame_changed = False
                if q_realizations and frame.positions.filter(reduce(operator.or_, q_realizations)).count() > 0:    
                #f.write(lemma.entry+changeArgsToRealizations(frame, q_real_types).replace('+', ' + ').replace(':',': ')+'\r\n')
                  text_reps.append(changeArgsToRealizations(frame, real_arg_models, q_real_types))
                  frame_changed = True
                if not frame_changed:
                #f.write( lemma.entry+frame.text_rep.replace('+', ' + ').replace(':',': ')+'\r\n' )
                  text_reps.append(frame.text_rep)
                   
            text_reps = sorted(text_reps, key=cmp_to_key(locale.strcoll))
            for text_rep in text_reps:
              f.write( lemma.entry+text_rep.replace('+', ' + ').replace(':',': ').replace(';', '; ')+'\r\n' )

      f.close()   
      #file_name = os.path.split(tmpfilename)[1] + '.txt'
      #os.rename(tmpfilename, os.path.join(DEFAULT_SAVE_PATH, file_name))
      os.rename(tmpfilename, tmpfilename+'.txt')
      file_name = tmpfilename+'.txt'
      
    else:
      h = HTMLParser.HTMLParser()
# Pass the TeX template through Django templating engine and into the temp file
      os.write(tmpfile, smart_str(h.unescape(h.unescape(render_to_string('tex/slowal.tex', {'lemmas': lemmas, 
                                                                      'q_frame_opinions': q_frame_opinions,
                                                                      'sort_reflex_vals': sort_reflex_vals,
                                                                      'sort_aspect_vals': sort_aspect_vals,
                                                                      'download_dict'   : form_dict}
                                                                      ).replace(u'&amp;', '&')
                                                                      .replace(u'&lt;', '<')
                                                                      .replace(u'&gt;', '>')
                                                                      .replace(u'˝', '\"')
                                                                      .replace(u'­', u'\-')))))

      os.close(tmpfile)
      #texfilename = os.path.abspath(texfilename)
# Compile the TeX file with PDFLaTeX
      #os.rename(tmpfilename, DEFAULT_SAVE_PATH + os.path.split(tmpfilename)[1] + '.tex')
      #call(['pdflatex', tmpfilename]) chwilowo usuniete
# Move resulting PDF to a more permanent location
      #file_name = os.path.split(tmpfilename)[1] + '.pdf'
      #os.rename(tmpfilename + '.pdf', DEFAULT_SAVE_PATH + file_name)
# Remove intermediate files
      #os.remove(tmpfilename) chwilowo usuniete
      #os.remove(tmpfilename + '.aux') chwilowo
      #os.remove(tmpfilename + '.log') chwilowo
      file_name = tmpfilename + '.tex'# + '.pdf'
      os.rename(tmpfilename, file_name) # nowe
  # INFO to nie dziala tylko pod windowsem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      #os.rmdir(tmp_folder)
# Remove intermediate files
# INFO to nie dziala tylko pod windowsem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    #os.rmdir(tmp_folder)
    return {'file_name': file_name}
  #except:
  #  raise AjaxError('creating vocabulary error')  
  
  #return {'file_name': vocabulary_name+'.txt'}
  

@render('vocabulary_stats.html')
@ajax(method='get', encode_result=False)
def get_vocabulary_stats(request, vocabulary_name):
  
  if vocabulary_name:
    voc = Vocabulary.objects.get(name=vocabulary_name)     
    lemmas = voc.lemmas.filter(old=False) 
  else:
    lemmas = Lemma.objects.filter(old=False)
  
  lemma_statuses = Lemma_Status.objects.order_by('priority')
  
  voc_stats_dict_tab = []  
  for lemma_status in lemma_statuses.all():
    stat_lemmas = lemmas.filter(status__status=lemma_status.status)
    voc_stat = {'status': lemma_status.status,
                'lemma_amount': len(stat_lemmas.all())}
    voc_stats_dict_tab.append(voc_stat)
    
  return {'lemma_status_tab': voc_stats_dict_tab,
          'all_lemmas_amount': len(lemmas.all())}

@render('vocab_perm_manage_form.html')
@ajax(method='get', encode_result=False)
def vocab_perm_manage_form(request, vocabulary_name):
  vocabulary_obj = Vocabulary.objects.get(name=vocabulary_name) 
  
  form = ManageVocabPermForm(managers=vocabulary_obj.managers, editors=vocabulary_obj.editors,
                             viewers=vocabulary_obj.viewers)

  return {'form': form}

@render('lemma_note_form.html')
@ajax(method='get', encode_result=False)
def lemma_note_form(request, topic):
  form = MessageForm(hide_private=True, topic=topic)

  return {'add_note_form': form}

@ajax(method='post')
def vocab_perm_manage_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  vocabulary = Vocabulary.objects.get(name=form_dict['vocabulary_name'])
  vocabulary.managers.clear()
  vocabulary.editors.clear()
  vocabulary.viewers.clear()
  
  for user_pk in form_dict['managers']:
    selected_user = User.objects.get(pk=user_pk)
    vocabulary.managers.add(selected_user)
    vocabulary.editors.add(selected_user)
    vocabulary.viewers.add(selected_user)
    
  for user_pk in form_dict['editors']:
    selected_user = User.objects.get(pk=user_pk)
    vocabulary.editors.add(selected_user)
    vocabulary.viewers.add(selected_user)
    
  for user_pk in form_dict['viewers']:
    vocabulary.viewers.add(User.objects.get(pk=user_pk))
      
  return {}

@ajax(method='get', encode_result=True)         
def lemma_lookup(request, term):
    results = []
    
    if len(term) > 0:
        model_results = Lemma.objects.filter(old=False).filter(entry__icontains=term).order_by('entry')
        results = [ (x.__unicode__(), x.id) for x in model_results ]

    return {'result': results}

@ajax(method='post')
def delete_lemma(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  entry = form_dict['entry'].strip()  
  if not entry:
    raise AjaxError('entry not selected')
  if ' ' in entry:
    raise AjaxError('whitespace in entry')

  lemmas = Lemma.objects.filter(entry=entry, vocabulary__name=form_dict['vocabulary_name'])
  if len(lemmas) == 0:
    raise AjaxError('lemma not exist')

  for lemma in lemmas:
    # usuwanie klas zgodnosci
    compatibility_classes = list(lemma.compatibility_classes.all())
    while len(compatibility_classes)!=0:
      compatibility_class = compatibility_classes.pop()
      lemma.compatibility_classes.remove(compatibility_class)
      if len(compatibility_class.lemmas.all()) == 0:
        compatibility_class.delete()
    
    # usuwanie kontroli zmian
    old_versions = list(lemma.old_versions.all())
    while len(old_versions)!=0:
      old_version = old_versions.pop()
      lemma.old_versions.remove(old_version)
      if len(old_version.lemmas.all()) == 0:
        old_version.delete()
    
    old_frames = list(lemma.old_frames.all())
    while len(old_frames)!=0:
      old_frame = old_frames.pop()
      lemma.old_frames.remove(old_frame)
      if len(old_frame.lemmas.all()) == 0:
        old_frame.delete()
    
    frames = list(lemma.frames.all())    
    while len(frames)!=0:
      frame = frames.pop()
      lemma.frames.remove(frame)
      if len(frame.lemmas.all()) == 0:
        frame.delete()
    
    nkjp_examples = list(lemma.nkjp_examples.all())
    while len(nkjp_examples)!=0:
      nkjp_example = nkjp_examples.pop()
      lemma.nkjp_examples.remove(nkjp_example)
      arguments_sels = list(nkjp_example.arguments.all())
      while len(arguments_sels)!=0:
        arg_sel = arguments_sels.pop()
        nkjp_example.arguments.remove(arg_sel)
        if len(arg_sel.nkjp_examples.all()) == 0:
          arg_sel.delete()
      if len(nkjp_example.lemmas.all()) == 0:
        nkjp_example.delete()
    
    lemma_nkjp_examples = list(lemma.lemma_nkjp_examples.all())
    while len(lemma_nkjp_examples)!=0:
      lemma_nkjp_example = lemma_nkjp_examples.pop()
      lemma.lemma_nkjp_examples.remove(lemma_nkjp_example)
      if len(lemma_nkjp_example.lemmasSelf.all()) == 0:
        lemma_nkjp_example.delete()
    
    lemma.delete()
    
    for position in Position.objects.all():
      if len(position.frames.all()) == 0:
        position.delete()
        
    for argument in Argument.objects.all():
      if len(argument.positions.all()) == 0:
        argument.delete()
        
    for arg_sel in NKJP_ArgSelection.objects.all():
      if len(arg_sel.nkjp_examples.all()) == 0:
        arg_sel.delete()
    
  return {}


@ajax(method='post')
def lemma_add_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  entry = form_dict['entry'].strip()  
  if not entry:
    raise AjaxError('entry not selected')
  if ' ' in entry:
    raise AjaxError('whitespace in entry')

  same_lemmas = Lemma.objects.filter(entry=entry, vocabulary__name=form_dict['vocabulary_name'])
  if len(same_lemmas) > 0:
    raise AjaxError('lemma exist')

  vocabulary = Vocabulary.objects.get(name=form_dict['vocabulary_name'])
  lemma_statuses = Lemma_Status.objects.order_by('priority')
  
  if form_dict['base_lemma']:
    base_lemma = form_dict['base_lemma'].strip()
    lemmaPattern = re.compile(r'^([^\(]+)\(([^\)]+)\)$')
    m = lemmaPattern.match(base_lemma)
  
    if m:
      base_entry_name = m.group(1).strip()
      base_vocab_name = m.group(2).strip()
      base_lemma_frames = Lemma.objects.get(entry=base_entry_name, vocabulary__name=base_vocab_name, old=False).frames.all()
    
      new_lemma = Lemma(entry=entry, vocabulary=vocabulary, status=lemma_statuses[0],
                      old=False)
      new_lemma.save()
    
      for frame in base_lemma_frames:
        new_lemma.frames.add(frame)
  else:
    new_lemma = Lemma(entry=entry, vocabulary=vocabulary, status=lemma_statuses[0],
                      old=False)
    new_lemma.save()
      
  return {}

######################################################################################
############################### statystyki uzytkownikow

@render('sel_user_stats.html')
@ajax(method='get', encode_result=False)
def get_user_stats(request, user_name):
  if user_name:
    user = User.objects.get(username=user_name)
  else:
    user = request.user
  
  owned_lemmas_n = len(user.lemmas.filter(old=False)) 
  ord_statuses = Lemma_Status.objects.order_by('priority')[1:]
  status_table_dict = []
  all_user_frames_amount = 0

  for status in ord_statuses:
    lemmas = user.lemmas.filter(status=status, old=False)#.all()
    frames_count = 0
    
    for lemma in lemmas:
      for frame in lemma.frames.all():
        most_args = frame.positions.annotate(num_args=Count('arguments')).aggregate(Max('num_args'))['num_args__max']
        
        if most_args:
          frames_count = frames_count + most_args
    
    status_dict = {'status'   : status.status,
                   'lemma_amount' : len(lemmas),
                   'frames_amount': frames_count}
    status_table_dict.append(status_dict)
    
    all_user_frames_amount = all_user_frames_amount + frames_count
    
  return {'lemma_status_tab': status_table_dict,
          'all_user_lemma_amount': owned_lemmas_n,
          'all_user_frames_amount': all_user_frames_amount}
  
######################################################################################
############################### zarzadzanie kontami

@ajax(method='post')
def new_account_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  username = form_dict['username'].strip()
  email = form_dict['email'].strip()
  
  if (not username or not form_dict['password1'] 
      or not form_dict['password2'] or not form_dict['group'] 
      or not form_dict['email']):
    raise AjaxError('empty fields')

  if not email_re.match(email):
    raise AjaxError('wrong e-mail form')

  if ( form_dict['password1'].strip() != form_dict['password2'].strip()): 
    raise AjaxError('passwords not match')
  
  if not re.match("^[A-Za-z0-9_\-@\.\+]+$", username):
    raise AjaxError('invalid username')

  if not re.match("^[A-Za-z0-9_\-@\.\+]+$", form_dict['password1'].strip()):
    raise AjaxError('invalid password')

  try:
    User.objects.get(username=username)
    raise AjaxError('user exist')
  except User.DoesNotExist:
    pass

  password = form_dict['password1'].strip()
  
  group = Group.objects.get(pk=form_dict['group'])
  new_user = User.objects.create_user(username, email, password)
  UserSettings.objects.create(user=new_user)
  new_user.groups.add(group)
      
  return {}

@render('change_user_fun_form.html')
@ajax(method='get', encode_result=False)
def change_user_fun_form(request, user_id):
  if not user_id:
    change_function_form = ChangeUserFunctionForm()
  else:
    change_function_form = ChangeUserFunctionForm(user_id=user_id)

  return {'user_function_form': change_function_form}


@ajax(method='post')
def change_user_fun_form_submit(request, form_data):
  form_dict = dict((x['name'], x['value']) for x in form_data)
  
  if (not form_dict['user'] or not form_dict['group']):
    raise AjaxError('empty fields')

  user = User.objects.get(id=form_dict['user'])
  
  if user.is_superuser:
    raise AjaxError('is superuser')

  user.groups.clear()
  group = Group.objects.get(pk=form_dict['group'])
  user.groups.add(group)
      
  return {}

@ajax(method='post')
def delete_user(request, user_id):
  if not user_id:
    raise AjaxError('user not selected')  

  user = User.objects.get(id=user_id)
  if user.is_superuser:
    raise AjaxError('is superuser')

  if user == request.user:
    raise AjaxError('deleting own account')
  
  
  user.lemmas.clear()
 # to ma wrocic, zeby usuwalo tylko notatki prywatne
 # notes = user.messages.filter(private=False)
 # for note in notes.all():
 #   user.messages.remove(note)
    
  user.delete()
           
  return {}

############################################# realizacje argumentow ####################################
##############################################################################################
@render('arg_realization_form.html')
@ajax(method='get', encode_result=False)
def realization_arg_form(request, form_data):#, id, frames):  
  main_argument = False
  if form_data == 'main_argument':
    main_argument = True
    form_data = ''
    type_form = AddArgumentForm(model_queryset=Argument_Model.objects.filter(has_realizations=True).order_by('priority'),
                                show_related=True)
  elif form_data:
    form_dict = dict((x['name'], x['value']) for x in form_data)
    if form_dict['main_argument']:
      type_form = AddArgumentForm(model_queryset=Argument_Model.objects.filter(has_realizations=True).order_by('priority'),
                                  show_related=True)
      main_argument = True
    else:
      type_form = AddArgumentForm(model_queryset=Argument_Model.objects.all().order_by('priority'),
                                  show_related=True)
  else:
    type_form = AddArgumentForm(model_queryset=Argument_Model.objects.all().order_by('priority'),
                                show_related=True)
    
  atr_value_forms = []

  if form_data: # zaznaczono wartosci
    # prezentowanie formularza na podstawie reprezentacji teksowej argumentu
    if form_dict['arg_text_rep']:
      arg_obj = Argument.objects.get(text_rep=form_dict['arg_text_rep'])
      
      type_form = AddArgumentForm(value=arg_obj.type)
      atribute_models = Argument_Model.objects.get(arg_model_name=arg_obj.type).atribute_models.order_by('priority')  
      
      for atribute_model in atribute_models:
        atribute_obj = arg_obj.atributes.get(type=atribute_model.atr_model_name)
        if atribute_model.text_atribute:
          atr_value_forms.append(AtributeTextForm(label=atribute_model.atr_model_name, value=atribute_obj.atribute_value.value.replace("\'", ''))) 
        else:
          atr_value_forms.append(AtributeChoiceForm(values=atribute_model.atribute_values.order_by('priority'), 
                                 label=atribute_model.atr_model_name, value=atribute_obj.atribute_value))
            
    elif form_dict['arg_model_name']:
      arg_model = Argument_Model.objects.get(arg_model_name=form_dict["arg_model_name"])
      atr_models = arg_model.atribute_models.order_by('priority')
      if form_dict['main_argument']:
        type_form = AddArgumentForm(model_queryset=Argument_Model.objects.filter(has_realizations=True).order_by('priority'),
                                  show_related=True, value=form_dict["arg_model_name"])
      else:
        type_form = AddArgumentForm(value=form_dict["arg_model_name"], show_related=True,
                                    model_queryset=Argument_Model.objects.all().order_by('priority'))
    
      for i in range(len(atr_models)):
        if not atr_models[i].text_atribute:
          if i < len(form_dict['atr_values']):
            atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                    label=atr_models[i].atr_model_name, value=form_dict['atr_values'][i], show_related=True))
          else:
            atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                    label=atr_models[i].atr_model_name, show_related=True))
     
        else:
          if i < len(form_dict['atr_values']):
            if main_argument:
              atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                     label=atr_models[i].atr_model_name, value=form_dict['atr_values'][i], show_related=True))
            else:  
              atr_value_forms.append(AtributeTextForm(label=atr_models[i].atr_model_name, value=form_dict['atr_values'][i])) 
          else:
           if main_argument:
             atr_value_forms.append(AtributeChoiceForm(values=atr_models[i].atribute_values.order_by('priority'), 
                                    label=atr_models[i].atr_model_name, show_related=True))
           else:
             atr_value_forms.append(AtributeTextForm(label=atr_models[i].atr_model_name))
    
  return {'type_form': type_form,
          'atr_value_forms': atr_value_forms,
          'main_argument': main_argument}


def dict_to_argument(dict, id=False):
  # znajdz model argumentu bazowego
  atribute_objs = []
  arg_model_obj = Argument_Model.objects.get(arg_model_name=dict['arg_model_name'])
  atribute_models = arg_model_obj.atribute_models.order_by('priority')
  for i in range(len(atribute_models)):
    if atribute_models[i].text_atribute:
      if not id:
        atr_value = u"\'" + dict['atr_values'][i] +"\'"
        try:
          atr_val_obj = Atribute_Value.objects.get(value=atr_value)
        except:
          atr_val_obj = Atribute_Value(value=atr_value, priority=1000)
          atr_val_obj.save()
      else:
        atr_val_obj = Atribute_Value(pk=dict['atr_values'][i])
      try:
        atr_obj = Atribute.objects.get(type=atribute_models[i].atr_model_name, atribute_value=atr_val_obj)
      except Atribute.DoesNotExist:
        atr_obj = Atribute(type=atribute_models[i].atr_model_name, atribute_value=atr_val_obj)
        atr_obj.save() 
      atribute_objs.append(atr_obj)
      
    else:
      atr_val_init = atribute_models[i].atribute_values.get(pk=dict['atr_values'][i])
      try:
        atr_obj = Atribute.objects.get(type=atribute_models[i].atr_model_name, atribute_value=atr_val_init)
      except Atribute.DoesNotExist:
        atr_obj = Atribute(type=atribute_models[i].atr_model_name, atribute_value=atr_val_init)
        atr_obj.save() 
      atribute_objs.append(atr_obj)
  
  atr_str_tab = []
  for atr_obj in atribute_objs:
    atr_str_tab.append(atr_obj.atribute_value.value)

  arg_text_rep = ''
  if len(atr_str_tab) == 0:
    arg_text_rep = '%s' % (dict['arg_model_name'])
  else: 
    arg_text_rep = '%s(%s)' % (dict['arg_model_name'], ','.join(atr_str_tab))
  
  try:
    arg_obj = Argument.objects.get(text_rep=arg_text_rep)
  except Argument.DoesNotExist:
    arg_obj = Argument(type=dict['arg_model_name'], text_rep=arg_text_rep)
    arg_obj.save()
    for atr_obj in atribute_objs:
      arg_obj.atributes.add(atr_obj)

  return arg_obj


@ajax(method='post')
def add_arg_realization(request, main_arg_data, realization_data):
  result = {}   
  # sprawdz czy wypelniono wszystkie pola formularza argumentu glownego
  main_arg_dict = dict((x['name'], x['value']) for x in main_arg_data)
  if not main_arg_dict['arg_model_name']:
    raise AjaxError('empty main argument fields')
  for atr_value in main_arg_dict['atr_values']:
    if not atr_value:
      raise AjaxError('empty main argument fields')
  
  # sprawdz czy wypelniono wszystkie pola formularza argumentu dodawanego jako realizacja
  realization_dict = dict((x['name'], x['value']) for x in realization_data)
  if not realization_dict['arg_model_name']:
    raise AjaxError('empty realization argument fields')
  for atr_value in realization_dict['atr_values']:
    if not atr_value:
      raise AjaxError('empty realization argument fields')

  # znajdz model argumentu bazowego
  main_arg_obj = dict_to_argument(main_arg_dict, True)
  
  # znajdz obiekt argumentu bedacego realizacja
  realization_obj = dict_to_argument(realization_dict)
  
  main_arg_obj.realizations.add(realization_obj)  
  
  return result

@render('show_realizations.html')
@ajax(method='get', encode_result=False)
def show_realizations(request, form_data):#, id, frames):  
  realizations = []
  arg_obj = None
  error_message = u'Wypełnij wszystkie pola formularza wyboru argumentu głównego.'
  if form_data: # zaznaczono wartosci
    form_dict = dict((x['name'], x['value']) for x in form_data)
       
  # sprawdz czy wypelniono wszystkie pola formularza argumentu glownego
    if not form_dict['arg_model_name']:
      return {'error_message': error_message,
              'realizations': realizations,
              'main_arg_text_rep': '',
              'manage': form_dict['manage']}
    if not form_dict['atr_values']:
      return {'error_message': error_message,
              'realizations': realizations,
              'main_arg_text_rep': '',
              'manage': form_dict['manage']}
    for atr_value in form_dict['atr_values']:
      if not atr_value:
        return {'error_message': error_message,
                'realizations': realizations,
                'main_arg_text_rep': '',
                'manage': form_dict['manage']}
    
    if form_dict['manage']:
      arg_obj = dict_to_argument(form_dict, True)
    else:
      arg_obj = dict_to_argument(form_dict)
      
    realizations = sortArguments(arg_obj.realizations.all())
  
  else:
    return {'error_message': error_message,
            'realizations': realizations,
            'main_arg_text_rep': '',
            'manage': form_dict['manage']}   
  
  return {'error_message': '',
          'realizations': realizations,
          'main_arg_text_rep': arg_obj.text_rep,
          'manage': form_dict['manage']}
  
@ajax(method='post')
def remove_realization(request, realization_id, main_arg_data):
  result = {}   
  # sprawdz czy wypelniono wszystkie pola formularza argumentu glownego
  main_arg_dict = dict((x['name'], x['value']) for x in main_arg_data)
  if not main_arg_dict['arg_model_name']:
    raise AjaxError('empty main argument fields')
  for atr_value in main_arg_dict['atr_values']:
    if not atr_value:
      raise AjaxError('empty main argument fields')

  # znajdz model argumentu bazowego
  main_arg_obj = dict_to_argument(main_arg_dict)
  
  # znajdz obiekt argumentu bedacego realizacja
  realization_obj = Argument.objects.get(id=realization_id)
  
  main_arg_obj.realizations.remove(realization_obj)  
  
  return result


