"""
    MoinMoin - Multilingual functions

        Copyright (c) 2002 by Florian Festi
        All rights reserved, see COPYING for details.
"""

# Imports
from MoinMoin import config, wikiutil
import os.path




# translated page operations
def title_search(needle, languages = None, extended=None):
    import re
    
    if not languages: languages = config.languages.keys()

    try:
        needle_re = re.compile(needle, re.IGNORECASE)
    except re.error:
        needle_re = re.compile(re.escape(needle), re.IGNORECASE)

    total_hits = []
    for lang in languages:
        path = os.path.join(config.languages[lang], 'text')
        page_list = wikiutil.getPageList(path)
        hits = filter(needle_re.search, page_list) 
        for i in range(0, len(hits)):
            hits[i] = lang + ':' + hits[i] 
        total_hits.extend(hits)

    # Add all translations
    if extended:
        translation_files = []
        for page in total_hits:
            tf = get_translation_file(page)
            if tf: translation_files.append(tf)
        for tf in translation_files:
            total_hits.extend(read_translations(tf))
        total_hits.sort()
        i = 1
        while i < len(total_hits):
            if total_hits[i] == total_hits[i - 1]:
                del total_hits[i]
            else:
                i = i + 1
    else:
        total_hits.sort()

    return total_hits

def set_translation_automatically(page_name):
    import os.path
    
    pages = []
    for lang in config.languages.keys():
        if os.path.exists(get_interwiki_filename(lang + ':' + page_name)):
            pages.append(lang + ':' + page_name)
    groups = []
    for page in pages:
        group = get_translation_file(page)
        if group and (not group in groups): groups.append(group)
        
    if len(groups) == 1:
        set_translation_file(page_name, groups[0])
        add_translation(groups[0], page_name)
    elif (len(groups) == 0) and (len(pages) == 1):
        translation_file = new_translation_file(page_name)
        set_translation_file(page_name, translation_file)
        set_translation_file(pages[0], translation_file)
        add_translation(translation_file, config.interwikiname+':'+page_name)
        add_translation(translation_file, pages[0])
    else: # ambigous or no translations
        raise IOError

def get_translations(page_name):
    """ returns list of interwiki links
        Does not return pagename
    """
    # test page_name
    page_name = inter_language_link(page_name)
    if not page_name:
        return []
       
    translation_file = get_translation_file(page_name)
    if translation_file:
        translations = read_translations(translation_file)
        l = len(config.interwikiname)            
        for translation in translations:               
            if translation[0:l] == config.interwikiname:
                translations.remove(translation)
        return translations
    else:
        return []

def set_translation(_page_name, _to_page):
    """ Sets translation of page_name to to_page
    """

    errmsg = ''

    # test page_name
    page_name = inter_language_link(_page_name)
    to_page = inter_language_link(_to_page)
    if not page_name: errmsg = _page_name + " is not a valid Interwikilink. "
    if not to_page:
        errmsg = errmsg + _to_page + " is not a valid Interwikilink. "
    if errmsg != '': return errmsg
    
    translation_file = get_translation_file(to_page)
    # page already has translations
    if translation_file:
        errmsg = "added myself to" + to_page
        if add_translation(translation_file,
                           config.interwikiname + ':' + page_name):
            errmsg = (to_page + " has already a translation " +
                      "in your language")
            pg.send_page(request, errmsg)
            return
        # delete myself from my old translationfile
        my_translation_file = get_translation_file(page_name)
        if my_translation_file:
            remove_translation(my_translation_file,
                               config.interwikiname + ':' + page_name)
        set_translation_file(page_name, translation_file)
    # other page doesn't have translation
    else:
        translation_file = get_translation_file(page_name)
        # do we have translations
        if translation_file:
            if add_translation(translation_file, to_page):
                errmsg = ( 'This page "' + page_name +
                           '" has already a translation in this language')
            else:
                set_translation_file(to_page, translation_file)
        else:
            errmsg = 'new translation file'
            # generate new translation file
            translation_file = new_translation_file(page_name)
            set_translation_file(page_name, translation_file)
            set_translation_file(to_page, translation_file)
            add_translation(translation_file,
                            config.interwikiname + ':' + page_name)
            add_translation(translation_file, to_page)
    return errmsg

def unset_translation(_page_name):
    errmsg = ''

    # test page_name
    page_name = inter_language_link(_page_name)
    if not page_name: return _page_name + " is not a valid Interwikilink. "

    translation_file = get_translation_file(page_name)
    if translation_file:
        remove_translation(translation_file, page_name)
        set_translation_file(page_name, None)
    else:
        errmsg = 'no translation'
    return errmsg

##### Internal functions #######################

def inter_language_link(page_name):
    """ Checks page_name if it is a valid interwikilink to another language
        and adds config.interwikilink if it is a local page_name
    """
    interwiki = page_name.split(':', 1)
    # interwikilink
    if len(interwiki) == 2:
        if config.languages.has_key(interwiki[0]):
            return page_name
        for lang in config.languages.keys():
            if lang.lower() == interwiki[0].lower():
                return lang + ':' + interwiki[1]
        return None
    # local page
    else: return config.interwikiname + ':' + page_name
        

def get_translation_file(pagename):
    """ return file name or None """
    lang_file = get_language_file(pagename)
    if os.path.exists(lang_file):
        f = open(lang_file, 'r')
        translationfile = f.read()
        f.close()
        return translationfile
    else:
        return None

def set_translation_file(pagename, translationfilename):
    lang_file = get_language_file(pagename)
    if translationfilename:
        f = open(lang_file, 'w')
        f.write(translationfilename)
        f.close()
    else:
        if os.path.exists(lang_file): os.remove(lang_file)

# translation group file operations 
def read_translations(translation_file):
    translation_file = os.path.join(config.multilingual_dir,
                                        translation_file)
    try:
        f = open(translation_file, 'r')
    except IOError:
        return []
    
    translations = f.readlines()
    for i in range(0, len(translations)):
        translations[i] = translations[i][:-1]
    f.close()
    return translations
                                            
def add_translation(translationfile, interwikilink):
    translationfile = os.path.join(config.multilingual_dir,
                                        translationfile)
    if os.path.exists(translationfile):
        f = open(translationfile, 'r')
        translations = f.readlines()
        f.close()
        # test if there already is a translation in our language
        wiki, page = wikiutil.split_wiki(interwikilink)
        if not wiki:
            wiki = config.interwikiname
            interwikilink = wiki + ':' + interwikilink
        log = 'X'
        l = len(wiki)
        for translation in translations:
            log = log + translation
            if translation[0:l] == wiki:
                return 1
    f = open(translationfile, 'a')
    f. write(interwikilink + '\n')
    f.close()

def remove_translation(translationfile, interwikilink):
    translationfile = os.path.join(config.multilingual_dir,
                                        translationfile)
    if os.path.exists(translationfile):
        f = open(translationfile, 'rw')
        translations = f.readlines()
        f.close()
        for translation in translations:
            if translation == interwikilink + '\n':
                translations.remove(translation)

        if len(translations)>0:
            f = open(translationfile, 'w')
            f.writelines(translations)
            f.close()
        else:
            os.remove(translationfile)

def new_translation_file(page_name):
    translationfile = os.path.join(config.multilingual_dir, page_name)
    newtranslationfile = translationfile
    i = 0
    while os.path.exists(newtranslationfile):
        newtranslationfile = translationfile + `i`
        i = i + 1
    return os.path.basename(newtranslationfile)

# access to external wikis

def get_interwiki_filename(interwikilink):
    """ returns directory or filename """
    interwiki = interwikilink.split(':', 1)
    if len(interwiki) == 2:
        if config.languages.has_key(interwiki[0]):
            return os.path.join(config.languages[interwiki[0]], 'text',
                                wikiutil.quoteFilename(interwiki[1]))
        else:
            return None
    else:
        return os.path.join(config.text_dir,
                            wikiutil.quoteFilename(interwiki[0]))

def get_language_file(interwikilink):
    """ returns directory or filename """
    interwiki = interwikilink.split(':', 1)
    if len(interwiki) == 2:
        if config.languages.has_key(interwiki[0]):
            return os.path.join(config.languages[interwiki[0]], 'lang',
                                wikiutil.quoteFilename(interwiki[1]))
        else:
            return None
    else:
        return os.path.join(config.data_dir, 'lang',
                            wikiutil.quoteFilename(interwiki[0]))
                                                

# HTML
def language_link(page_name, show_name=1):
    """ returns HTML Source: flag and link """
    tag, interwiki, tail = wikiutil.resolve_wiki(page_name)
    if tag == '':
        tag = config.interwikiname
        interwiki = ''
    result= ('<a href="' + interwiki + tail + '">'+
             '<img src="/' + config.default_markup +
             '/img/'+ config.lang_icons[tag] +
             '" alt="' + tag + '">')
    if show_name: result = result + ' ' + tail + ' </a>'
    else: result = result + '</a>'
    return result
