# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2003-2004  Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# $Id: rel_sv.py,v 1.1.2.3 2004/08/04 15:24:21 rshura Exp $

# Written by Alex Roitman, largely based on Relationship.py by Don Allingham
# and on valuable input from Jens Arvidsson

#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------

import RelLib
from gettext import gettext as _

#-------------------------------------------------------------------------
#
# Swedish-specific definitions of relationships
#
#-------------------------------------------------------------------------

_cousin_level = [ "", "kusin", 
"tremänning", "fyrmänning", "femmänning", 
"sexmänning", "sjumänning", "åttamänning",
"niomänning", "tiomänning", "elvammänning", 
"tolvmänning", "trettonmänning", "fjortonmänning",
"femtonmänning", "sextonmänning", "sjuttonmänning",
"artonmänning", "nittonmänning", "tjugomänning" ] 

#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def get_parents(level):
    if level == 0:
        return "föräldrar"
    else:
        return "anor i %d-te generationen" % (level+1)

def get_cousin(level):
    if level>len(_cousin_level)-1:
        return "distant relative"
    else:
        return _cousin_level[level]

def pair_up(rel_list):
    result = []
    item = ""
    for word in rel_list[:]:
        if not word:
            continue
        if word in _cousin_level:
            if item:
                result.append(item)
                item = ""
            result.append(word)
            continue
	if item:
            if word == 'syster':
                item = item[0:-1]
                word = 'ster'
            elif word == 'dotter' and item == 'bror':
                item = 'brors'
            result.append(item + word)
            item = ""
        else:
            item = word
    if item:
        result.append(item)
    gen_result = [ item + 's' for item in result[0:-1] ]
    return ' '.join(gen_result+result[-1:])

def get_direct_ancestor(person,rel_string):
    result = []
    for ix in range(len(rel_string)):
        if rel_string[ix] == 'f':
            result.append('far')
        else:
            result.append('mor')
    return pair_up(result)

def get_direct_descendant(person,rel_string):
    result = []
    for ix in range(len(rel_string)-2,-1,-1):
        if rel_string[ix] == 'f':
            result.append('son')
        else:
            result.append('dotter')
    if person.getGender() == RelLib.Person.male:
        result.append('son')
    else:
        result.append('dotter')
    return pair_up(result)

def get_ancestors_cousin(rel_string_long,rel_string_short):
    result = []
    removed = len(rel_string_long)-len(rel_string_short)
    level = len(rel_string_short)-1
    for ix in range(removed):
        if rel_string_long[ix] == 'f':
            result.append('far')
        else:
            result.append('mor')
    result.append(get_cousin(level))
    return pair_up(result)

def get_cousins_descendant(person,rel_string_long,rel_string_short):
    result = []
    removed = len(rel_string_long)-len(rel_string_short)-1
    level = len(rel_string_short)-1
    if level:
    	result.append(get_cousin(level))
    elif rel_string_long[removed] == 'f':
    	result.append('bror')
    else:
    	result.append('syster')
    for ix in range(removed-1,-1,-1):
        if rel_string_long[ix] == 'f':
            result.append('son')
        else:
            result.append('dotter')
    if person.getGender() == RelLib.Person.male:
        result.append('son')
    else:
        result.append('dotter')
    return pair_up(result)

def get_ancestors_brother(rel_string):
    result = []
    for ix in range(len(rel_string)-1):
        if rel_string[ix] == 'f':
            result.append('far')
        else:
            result.append('mor')
    result.append('bror')
    return pair_up(result)

def get_ancestors_sister(rel_string):
    result = []
    for ix in range(len(rel_string)-1):
        if rel_string[ix] == 'f':
            result.append('far')
        else:
            result.append('mor')
    result.append('syster')
    return pair_up(result)

def is_spouse(orig,other):
    for f in orig.getFamilyList():
        if other == f.getFather() or other == f.getMother():
            return 1
    return 0

def apply_filter(person,rel_str,plist,pmap):
    if person == None:
        return
    plist.append(person)
    pmap[person.getId()] = rel_str
    
    family = person.getMainParents()
    if family:
        apply_filter(family.getFather(),rel_str+'f',plist,pmap)
        apply_filter(family.getMother(),rel_str+'m',plist,pmap)

def get_relationship(orig_person,other_person):
    """
    Returns a string representing the relationshp between the two people,
    along with a list of common ancestors (typically father,mother) 
    
    Special cases: relation strings "", "undefined" and "spouse".
    """

    firstMap = {}
    firstList = []
    secondMap = {}
    secondList = []
    common = []
    rank = 9999999
    
    if orig_person == None:
        return ("undefined",[])
    
    firstName = orig_person.getPrimaryName().getRegularName()
    secondName = other_person.getPrimaryName().getRegularName()
    
    if orig_person == other_person:
        return ('', [])
    if is_spouse(orig_person,other_person):
        if other_person.getGender() == RelLib.Person.male:
            return ("make",[])
        else:
            return ("maka",[])

    try:
        apply_filter(orig_person,'',firstList,firstMap)
        apply_filter(other_person,'',secondList,secondMap)
    except RuntimeError,msg:
        return (_("Relationship loop detected"),None)
    
    for person in firstList:
        if person in secondList:
            new_rank = len(firstMap[person.getId()])
            if new_rank < rank:
                rank = new_rank
                common = [ person ]
            elif new_rank == rank:
                common.append(person)

    if common:
        person = common[0]
        secondRel = firstMap[person.getId()]
        firstRel = secondMap[person.getId()]
    else:
        return ("",[])

    if not firstRel:
        if not secondRel:
            return ('',common)
        else:
            return (get_direct_ancestor(other_person,secondRel),common)
    elif not secondRel:
        return (get_direct_descendant(other_person,firstRel),common)
    elif len(firstRel) == 1:
        if other_person.getGender() == RelLib.Person.male:
            return (get_ancestors_brother(secondRel),common)
        else:
            return (get_ancestors_sister(secondRel),common)
    elif len(secondRel) >= len(firstRel):
        return (get_ancestors_cousin(secondRel,firstRel),common)
    else:
        return (get_cousins_descendant(other_person,firstRel,secondRel),common)


def get_grandparents_string(orig_person,other_person):
    """
    returns a string representing the relationshp between the two people,
    along with a list of common ancestors (typically father,mother) 
    """
    firstMap = {}
    firstList = []
    secondMap = {}
    secondList = []
    common = []
    rank = 9999999

    if orig_person == None:
        return ("undefined",[])

    if orig_person == other_person:
        return ('', [])

    try:
        apply_filter(orig_person,'',firstList,firstMap)
        apply_filter(other_person,'',secondList,secondMap)
    except RuntimeError,msg:
        return (_("Relationship loop detected"),None)
    
    for person in firstList:
        if person in secondList:
            new_rank = len(firstMap[person.getId()])
            if new_rank < rank:
                rank = new_rank
                common = [ person ]
            elif new_rank == rank:
                common.append(person)

    if common:
        person = common[0]
        secondRel = firstMap[person.getId()]
        firstRel = secondMap[person.getId()]
    else:
        return ('', [])

    if not firstRel:
        if not secondRel:
            return ('',common)
        else:
            return (get_parents(len(secondRel)),common)
    else:
        return None

#-------------------------------------------------------------------------
#
# Register this function with the Plugins system 
#
#-------------------------------------------------------------------------
from Plugins import register_relcalc, register_parents

register_relcalc(get_relationship,
    ["sv","SV","sv_SE","swedish","Swedish","sv_SE.UTF8","sv_SE@euro","sv_SE.UTF8@euro",
            "svenska","Svenska", "sv_SE.UTF-8", "sv_SE.utf-8", "sv_SE.utf8"])

register_parents(get_grandparents_string,
    ["sv","SV","sv_SE","swedish","Swedish","sv_SE.UTF8","sv_SE@euro","sv_SE.UTF8@euro",
            "svenska","Svenska", "sv_SE.UTF-8", "sv_SE.utf-8", "sv_SE.utf8"])
