# -*- 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_fi.py,v 1.1.2.8 2004/08/03 04:01:07 rshura Exp $

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

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

import RelLib
from gettext import gettext as _

#-------------------------------------------------------------------------
#
# Finnish-specific definitions of relationships
#
#-------------------------------------------------------------------------

_parents_level = [ "", "vanhemmat", "isovanhemmat", "isoisovanhemmat",
"isoisoisovanhemmat", "isoisoisoisovanhemmat" ]

#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def get_cousin(level):
    if level == 0:
        return ""
    elif level == 1:
        return "serkku"
    elif level == 2:
        return "pikkuserkku"
    elif level > 2:
        return "%d. serkku" % level

def get_cousin_genitive(level):
    if level == 0:
        return ""
    elif level == 1:
        return "serkun"
    elif level == 2:
        return "pikkuserkun"
    elif level > 2:
        return "%d. serkun" % level

def get_parents(level):
    if level>len(_parents_level)-1:
        return "kaukaiset esivanhemmat"
    else:
        return _parents_level[level]

def get_direct_ancestor(person,rel_string):
    result = []
    for ix in range(len(rel_string)-1):
        if rel_string[ix] == 'f':
            result.append('isän')
        else:
            result.append('äidin')
    if person.getGender() == RelLib.Person.male:
        result.append('isä')
    else:
        result.append('äiti')
    return ' '.join(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('pojan')
        elif rel_string[ix] == 'm':
            result.append('tyttären')
        else:
            result.append('lapsen')
    if person.getGender() == RelLib.Person.male:
        result.append('poika')
    elif person.getGender() == RelLib.Person.female:
        result.append('tytär')
    else:
        result.append('lapsi')
    return ' '.join(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('isän')
        else:
            result.append('äidin')
    result.append(get_cousin(level))
    return ' '.join(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_genitive(level))
    elif rel_string_long[removed] == 'f':
    	result.append('veljen')
    else:
    	result.append('sisaren')
    for ix in range(removed-1,-1,-1):
        if rel_string_long[ix] == 'f':
            result.append('pojan')
        elif rel_string_long[ix] == 'm':
            result.append('tyttären')
        else:
            result.append('lapsen')
    if person.getGender() == RelLib.Person.male:
        result.append('poika')
    elif person.getGender() == RelLib.Person.female:
        result.append('tytär')
    else:
        result.append('lapsi')
    return ' '.join(result)

def get_ancestors_brother(rel_string):
    result = []
    for ix in range(len(rel_string)-1):
        if rel_string[ix] == 'f':
            result.append('isän')
        else:
            result.append('äidin')
    result.append('veli')
    return ' '.join(result)

def get_ancestors_sister(rel_string):
    result = []
    for ix in range(len(rel_string)-1):
        if rel_string[ix] == 'f':
            result.append('isän')
        else:
            result.append('äidin')
    result.append('sisar')
    return ' '.join(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):
        return ("puoliso",[])

    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,
    ["fi","FI","fi_FI","finnish","Finnish","fi_FI.UTF8","fi_FI@euro","fi_FI.UTF8@euro",
            "suomi","Suomi", "fi_FI.UTF-8", "fi_FI.utf-8", "fi_FI.utf8"])

register_parents(get_grandparents_string,
    ["fi","FI","fi_FI","suomi","Suomi","fi_FI.UTF8","fi_FI@euro","fi_FI.UTF8@euro",
            "finnish","Finnish", "fi_FI.UTF-8", "fi_FI.utf-8", "fi_FI.utf8"])
