# Liblouis Python ctypes bindings
#
# Copyright (C) 2009, 2010 James Teh <jamie@jantrid.net>
#
# This file is part of liblouis.
# 
# liblouis is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 2.1 of the License, or
# (at your option) any later version.
# 
# liblouis 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
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with liblouis. If not, see <http://www.gnu.org/licenses/>.
# 

"""Liblouis Python ctypes bindings
These bindings allow you to use the liblouis braille translator and back-translator library from within Python.
This documentation is only a Python helper.
Please see the liblouis documentation for more information.

Most of these functions take a C{tableList} argument which specifies
a list of translation tables to use. Please see the liblouis documentation
concerning the C{tableList} parameter to the C{lou_translateString}
function for information about how liblouis searches for these tables.

@author: Michael Curran <mick@kulgan.net>
@author: James Teh <jamie@jantrid.net>
@author: Eitan Isaacson <eitan@ascender.com>
@author: Michael Whapples <mwhapples@aim.com>
@author: Davy Kager <mail@davykager.nl>
@author: Leonard de Ruijter (Babbage B.V.) <alderuijter@gmail.com>
"""

from __future__ import unicode_literals
from ctypes import *
import atexit
import sys

# Some general utility functions
def _createTablesString(tablesList):
    """Creates a tables string for liblouis calls"""
    return b",".join([x.encode(filesystemencoding) if isinstance(x, str) else bytes(x) for x in tablesList])

def _createTypeformbuf(length, typeform=None):
    """Creates a typeform buffer for liblouis calls"""
    return (c_ushort*length)(*typeform) if typeform else (c_ushort*length)()

ENCODING_ERROR_HANDLER = None
createEncodedByteString = None
if sys.version_info.major == 2:
    ENCODING_ERROR_HANDLER = "strict"
    createEncodedByteString = lambda x: unicode(x).encode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)
else: # sys.version_info[0] == 3
    ENCODING_ERROR_HANDLER = "surrogatepass"
    createEncodedByteString = lambda x: str(x).encode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)

try:
    # Native win32
    _loader = windll
    _functype = WINFUNCTYPE
except NameError:
    # Unix/Cygwin
    _loader = cdll
    _functype = CFUNCTYPE
liblouis = _loader["###LIBLOUIS_SONAME###"]

atexit.register(liblouis.lou_free)

liblouis.lou_version.restype = c_char_p

liblouis.lou_charSize.restype = c_int

liblouis.lou_translateString.argtypes = (
    c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char), 
         POINTER(c_int), POINTER(c_ushort), POINTER(c_char), c_int)

liblouis.lou_translate.argtypes = (
    c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char), 
         POINTER(c_int), POINTER(c_ushort), POINTER(c_char), 
         POINTER(c_int), POINTER(c_int), POINTER(c_int), c_int)

liblouis.lou_backTranslateString.argtypes = (
         c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char),
         POINTER(c_int), POINTER(c_ushort), POINTER(c_char), c_int)

liblouis.lou_backTranslate.argtypes = (
         c_char_p, POINTER(c_char), POINTER(c_int), POINTER(c_char), POINTER(c_int),
         POINTER(c_ushort), POINTER(c_char), POINTER(c_int), POINTER(c_int),
         POINTER(c_int), c_int)

liblouis.lou_hyphenate.argtypes = (
         c_char_p, POINTER(c_char), c_int, POINTER(c_char), c_int)

liblouis.lou_checkTable.argtypes = (c_char_p,)

liblouis.lou_compileString.argtypes = (c_char_p, c_char_p)

liblouis.lou_getTypeformForEmphClass.argtypes = (c_char_p, c_char_p)

liblouis.lou_dotsToChar.argtypes = (
    c_char_p, POINTER(c_char), POINTER(c_char), 
         c_int, c_int)

liblouis.lou_charToDots.argtypes = (
    c_char_p, POINTER(c_char), POINTER(c_char), 
         c_int, c_int)

LogCallback = _functype(None, c_int, c_char_p)

liblouis.lou_registerLogCallback.restype = None

liblouis.lou_setLogLevel.restype = None
liblouis.lou_setLogLevel.argtypes = (c_int,)

#{ Module Configuration
#: Specifies the charSize (in bytes) used by liblouis.
#: This is fetched once using L{liblouis.lou_charSize}.
#: Call it directly, since L{charSize} is not yet defined.
#: @type: int
wideCharBytes = liblouis.lou_charSize()
#: Specifies the number by which the input length should be multiplied
#: to calculate the maximum output length.
#: @type: int
# This default will handle the case where every input character is
# undefined in the translation table.
outlenMultiplier = 4 + wideCharBytes * 2
#: Specifies the encoding to use when encode/decode filenames
#: @type: str
filesystemencoding = sys.getfilesystemencoding()
#: Specifies the encoding to use when converting from byte strings to unicode strings.
#: @type: str
conversionEncoding = "utf_%d_le" % (wideCharBytes * 8)
#}

def version():
    """Obtain version information for liblouis.
    @return: The version of liblouis, plus other information, such as
        the release date and perhaps notable changes.
    @rtype: str
    """
    return liblouis.lou_version().decode("ASCII")

def charSize():
    """Obtain charSize information for liblouis.
    @return: The size of the widechar with which liblouis was compiled.
    @rtype: int
    """
    return liblouis.lou_charSize()

def translate(tableList, inbuf, typeform=None, cursorPos=0, mode=0):
    """Translate a string of characters, providing position information.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: The string to translate.
    @type inbuf: str
    @param typeform: A list of typeform constants indicating the typeform for each position in inbuf,
        C{None} for no typeform information.
    @type typeform: list of int
    @param cursorPos: The position of the cursor in inbuf.
    @type cursorPos: int
    @param mode: The translation mode; add multiple values for a combined mode.
    @type mode: int
    @return: A tuple of: the translated string,
        a list of input positions for each position in the output,
        a list of output positions for each position in the input, and
        the position of the cursor in the output.
    @rtype: (str, list of int, list of int, int)
    @raise RuntimeError: If a complete translation could not be done.
    @see: lou_translate in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    inlen = c_int(len(inbuf) // wideCharBytes)
    outlen = c_int(inlen.value*outlenMultiplier)
    outbuf = create_string_buffer(outlen.value * wideCharBytes)
    typeformbuf = None
    if typeform:
        typeformbuf = _createTypeformbuf(outlen.value, typeform)
    inPos = (c_int*outlen.value)()
    outPos = (c_int*inlen.value)()
    cursorPos = c_int(cursorPos)
    if not liblouis.lou_translate(tablesString, inbuf, byref(inlen), 
                                  outbuf, byref(outlen), typeformbuf, 
                                  None, outPos, inPos, byref(cursorPos), mode):
        raise RuntimeError("Can't translate: tables %s, inbuf %s, typeform %s, cursorPos %s, mode %s"%(tableList, inbuf, typeform, cursorPos, mode))
    if isinstance(typeform, list):
        typeform[:] = list(typeformbuf)
    return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER), inPos[:outlen.value], outPos[:inlen.value], cursorPos.value

def translateString(tableList, inbuf, typeform=None, mode=0):
    """Translate a string of characters.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: The string to translate.
    @type inbuf: str
    @param typeform: A list of typeform constants indicating the typeform for each position in inbuf,
        C{None} for no typeform information.
    @type typeform: list of int
    @param mode: The translation mode; add multiple values for a combined mode.
    @type mode: int
    @return: The translated string.
    @rtype: str
    @raise RuntimeError: If a complete translation could not be done.
    @see: lou_translateString in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    inlen = c_int(len(inbuf) // wideCharBytes)
    outlen = c_int(inlen.value*outlenMultiplier)
    outbuf = create_string_buffer(outlen.value * wideCharBytes)
    typeformbuf = None
    if typeform:
        typeformbuf = _createTypeformbuf(outlen.value, typeform)
    if not liblouis.lou_translateString(tablesString, inbuf, byref(inlen), 
                                        outbuf, byref(outlen), typeformbuf, 
                                        None, mode):
        raise RuntimeError("Can't translate: tables %s, inbuf %s, typeform %s, mode %s"%(tableList, inbuf, typeform, mode))
    if isinstance(typeform, list):
        typeform[:] = list(typeformbuf)
    return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)

def backTranslate(tableList, inbuf, typeform=None, cursorPos=0, mode=0):
    """Back translates a string of characters, providing position information.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: Braille to back translate.
    @type inbuf: str
    @param typeform: List where typeform constants will be placed.
    @type typeform: list
    @param cursorPos: Position of cursor.
    @type cursorPos: int
    @param mode: Translation mode.
    @type mode: int
    @return: A tuple: A string of the back translation,
        a list of input positions for each position in the output,
        a list of the output positions for each position in the input and
        the position of the cursor in the output.
    @rtype: (str, list of int, list of int, int)
    @raise RuntimeError: If a complete back translation could not be done.
    @see: lou_backTranslate in the liblouis documentation.
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    inlen = c_int(len(inbuf) // wideCharBytes)
    outlen = c_int(inlen.value * outlenMultiplier)
    outbuf = create_string_buffer(outlen.value * wideCharBytes)
    typeformbuf = None
    if isinstance(typeform, list):
        typeformbuf = _createTypeformbuf(outlen.value)
    inPos = (c_int*outlen.value)()
    outPos = (c_int*inlen.value)()
    cursorPos = c_int(cursorPos)
    if not liblouis.lou_backTranslate(tablesString, inbuf, byref(inlen),
                    outbuf, byref(outlen), typeformbuf, None,
                    outPos, inPos, byref(cursorPos), mode):
        raise RuntimeError("Can't back translate: tables %s, inbuf %s, typeform %s, cursorPos %d, mode %d"%(tableList, inbuf, typeform, cursorPos, mode))
    if isinstance(typeform, list):
        typeform[:] = list(typeformbuf)
    return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER), inPos[:outlen.value], outPos[:inlen.value], cursorPos.value

def backTranslateString(tableList, inbuf, typeform=None, mode=0):
    """Back translate from Braille.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: The Braille to back translate.
    @type inbuf: str
    @param typeform: List for typeform constants to be put in.
        If you don't want typeform data then give None
    @type typeform: list
    @param mode: The translation mode
    @type mode: int
    @return: The back translation of inbuf.
    @rtype: str
    @raise RuntimeError: If a complete back translation could not be done.
    @see: lou_backTranslateString in the liblouis documentation.
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    inlen = c_int(len(inbuf) // wideCharBytes)
    outlen = c_int(inlen.value * outlenMultiplier)
    outbuf = create_string_buffer(outlen.value * wideCharBytes)
    typeformbuf = None
    if isinstance(typeform, list):
        typeformbuf = _createTypeformbuf(outlen.value)
    if not liblouis.lou_backTranslateString(tablesString, inbuf, byref(inlen), outbuf,
                    byref(outlen), typeformbuf, None, mode):
        raise RuntimeError("Can't back translate: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
    if isinstance(typeform, list):
        typeform[:] = list(typeformbuf)
    return outbuf.raw[:outlen.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)

def hyphenate(tableList, inbuf, mode=0):
    """Get information for hyphenation.
    @param tableList: A list of translation tables and hyphenation
        dictionaries.
    @type tableList: list of str
    @param inbuf: The text to get hyphenation information about.
        This should be a single word and leading/trailing whitespace
        and punctuation is ignored.
    @type inbuf: str
    @param mode: Lets liblouis know if inbuf is plain text or Braille.
        Set to 0 for text and anyother value for Braille.
    @type mode: int
    @return: A string with '1' at the beginning of every syllable
        and '0' elsewhere.
    @rtype: str
    @raise RuntimeError: If hyphenation data could not be produced.
    @see: lou_hyphenate in the liblouis documentation.
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    inlen = c_int(len(inbuf) // wideCharBytes)
    hyphen_string = create_string_buffer(inlen.value + 1) 
    if not liblouis.lou_hyphenate(tablesString, inbuf, inlen, hyphen_string, mode):
        raise RuntimeError("Can't hyphenate: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
    return hyphen_string.value.decode("ASCII")

def checkTable(tableList):
    """Check if the specified tables can be found and compiled.
        This can be used to check if a list of tables contains errors
        before sending it to other liblouis functions
        that accept a list of tables.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @raise RuntimeError: If compilation failed.
    @see: lou_checkTable in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    if not liblouis.lou_checkTable(tablesString):
        raise RuntimeError("Can't compile: tables %s"%tableList)

def compileString(tableList, inString):
    """Compile a table entry on the fly at run-time.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inString: The table entry to be added.
    @type inString: str
    @raise RuntimeError: If compilation of the entry failed.
    @see: lou_compileString in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    inBytes = inString.encode("ASCII") if isinstance(inString, str) else bytes(inString)
    if not liblouis.lou_compileString(tablesString, inString):
        raise RuntimeError("Can't compile entry: tables %s, inString %s"%(tableList, inString))

def getTypeformForEmphClass(tableList, emphClass):
    """Get the typeform bit for the named emphasis class.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param emphClass: An emphasis class name.
    @type emphClass: str
    @see: lou_getTypeformForEmphClass in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    return liblouis.lou_getTypeformForEmphClass(tablesString, emphClass)

def dotsToChar(tableList, inbuf):
    """"Convert a string of dot patterns to a string of characters according to the specifications in tableList.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: a string of dot patterns, either in liblouis format or Unicode braille.
    @type inbuf: str
    @raise RuntimeError: If a complete conversion could not be done.
    @see: lou_dotsToChar in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    length = c_int(len(inbuf) // wideCharBytes)
    outbuf = create_string_buffer(length.value * wideCharBytes)
    if not liblouis.lou_dotsToChar(tablesString, inbuf, outbuf, length, 0):
        raise RuntimeError("Can't convert dots to char: tables %s, inbuf %s"%(tableList, inbuf))
    return outbuf.raw[:length.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)

def charToDots(tableList, inbuf, mode=0):
    """"Convert a string of characterss to a string of dot patterns according to the specifications in tableList.
    @param tableList: A list of translation tables.
    @type tableList: list of str
    @param inbuf: a string of characters.
    @type inbuf: str
    @param mode: The translation mode; add multiple values for a combined mode.
    @type mode: int
    @raise RuntimeError: If a complete conversion could not be done.
    @see: lou_charToDOts in the liblouis documentation
    """
    tablesString = _createTablesString(tableList)
    inbuf = createEncodedByteString(inbuf)
    length = c_int(len(inbuf) // wideCharBytes)
    outbuf = create_string_buffer(length.value * wideCharBytes)
    if not liblouis.lou_charToDots(tablesString, inbuf, outbuf, length, mode):
        raise RuntimeError("Can't convert char to dots: tables %s, inbuf %s, mode %d"%(tableList, inbuf, mode))
    return outbuf.raw[:length.value * wideCharBytes].decode(conversionEncoding, errors=ENCODING_ERROR_HANDLER)

def registerLogCallback(logCallback):
    """Register logging callbacks.
    Set to C{None} for default callback.
    @param logCallback: The callback to use.
        The callback must take two arguments:
        @param level: The log level on which a message is logged.
        @type level: int
        @param message: The logged message.
            Note that the callback should provide its own ASCII decoding routine.
        @type message: bytes

        Example callback:

        @louis.LogCallback
        def incomingLouisLog(level, message):
            print("Message %s logged at level %d" % (message.decode("ASCII"), level))

    @type logCallback: L{LogCallback}
    """
    if logCallback is not None and not isinstance(logCallback, LogCallback):
        raise TypeError("logCallback should be of type {} or NoneType".format(LogCallback.__name__))
    return liblouis.lou_registerLogCallback(logCallback)

def setLogLevel(level):
	"""Set the level for logging callback to be called at.
	@param level: one of the C{LOG_*} constants.
	@type level: int
	@raise ValueError: If an invalid log level is provided.
	"""
	if level not in logLevels:
		raise ValueError("Level %d is an invalid log level"%level)
	return liblouis.lou_setLogLevel(level)

#{ Typeforms
plain_text = 0x0000
emph_1 = comp_emph_1 = italic = 0x0001
emph_2 = comp_emph_2 = underline = 0x0002
emph_3 = comp_emph_3 = bold = 0x0004
emph_4 = 0x0008
emph_5 = 0x0010
emph_6 = 0x0020
emph_7 = 0x0040
emph_8 = 0x0080
emph_9 = 0x0100
emph_10 = 0x0200
computer_braille = 0x0400
no_translate = 0x0800
no_contract = 0x1000
#}

#{ Translation modes
noContractions = 1
compbrlAtCursor = 2
dotsIO = 4
compbrlLeftCursor = 32
ucBrl = 64
noUndefined = 128
noUndefinedDots = noUndefined # alias for backward compatiblity
partialTrans = 256
#}

#{ logLevels
LOG_ALL = 0
LOG_DEBUG = 10000
LOG_INFO = 20000
LOG_WARN = 30000
LOG_ERROR = 40000
LOG_FATAL = 50000
LOG_OFF = 60000
#}

logLevels = (LOG_ALL, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL, LOG_OFF)

if __name__ == '__main__':
    # Just some common tests.
    print(version())
    print(translate([b'../tables/en-us-g2.ctb'], 'Hello world!', cursorPos=5))
