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

from dictionary.common_func import sortArguments, sortPositions 
from dictionary.models import Argument, Frame, Frame_Char_Model, \
                              Frame_Characteristic, Position, PositionCategory, \
                              sortFrameChars, sortPosCatsAsStrTab 

def jsFrameToObj(frame, lemma_entry):
    # szukanie charakterystyk schematu
    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']:
      if len(position['arguments']) > 0:
          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)
                              
    text_rep = u'%s:%s' % (':'.join(frame['characteristics']), 
                           '+'.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]
            frame_obj.positions.add(same_pos_obj)  
          else:
            same_pos_obj = Position(text_rep=pos_obj.text_rep)
            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                       
      for frame_char in frame_characteristic_objs:
        frame_obj.characteristics.add(frame_char)
      if frame_obj.has_phraseologic_arguments():
        frame_obj.phraseologic = True
        frame_obj.save()
        
    return frame_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 jsArgToObj(argument):
    arg_obj = Argument.objects.get(text_rep=argument['text_rep'])
    return arg_obj

def frameObjToSerializableDict(lemma, frame, with_connections=False):
  frame_opinion = ''
  frame_opinions_tab = lemma.frame_opinions.filter(frame__text_rep=frame.text_rep)
  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,
                 'tooltip'           : '',
                 'is_phraseologic'   : frame.phraseologic}
  
  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,
                     'tooltip'   : ''}

    for argument in position['arguments']:
      connections = []
      if with_connections:
          entry = lemma.entry_obj
          connections = entry.matching_connections(frame, position['position'], argument)
      argument_dict = { 'id'      : argument.id,
                        'text_rep': argument.text_rep,
                        'type'    : argument.type,
                        'error'   : False,
                        'tooltip' : '',
                        'connections': connections}  
      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 
