"""Output primitives for the binding generator classes.

This should really be a class, but then everybody would be passing
the output object to each other.  I chose for the simpler approach
of a module with a global variable.  Use SetOutputFile() or
SetOutputFileName() to change the output file.
"""

_NeedClose = 0

def SetOutputFile(file = None, needclose = 0):
    """Call this with an open file object to make it the output file.

    Call it without arguments to close the current file (if necessary)
    and reset it to sys.stdout.
    If the second argument is true, the new file will be explicitly closed
    on a subsequence call.
    """
    global _File, _NeedClose
    if _NeedClose:
        tmp = _File
        _NeedClose = 0
        _File = None
        tmp.close()
    if file is None:
        import sys
        file = sys.stdout
    _File = file
    _NeedClose = file and needclose

def SetOutputFileName(filename = None):
    """Call this with a filename to make it the output file.

    Call it without arguments to close the current file (if necessary)
    and reset it to sys.stdout.
    """
    SetOutputFile()
    if filename:
        SetOutputFile(open(filename, 'w'), 1)

SetOutputFile() # Initialize _File

_Level = 0      # Indentation level

def GetLevel():
    """Return the current indentation level."""
    return _Level

def SetLevel(level):
    """Set the current indentation level.

    This does no type or range checking -- use at own risk.
    """
    global _Level
    _Level = level

def Output(format = "", *args):
    VaOutput(format, args)

def VaOutput(format, args):
    """Call this with a format string and argument tuple for the format.

    A newline is always added.  Each line in the output is indented
    to the proper indentation level -- even if the result of the
    format expansion contains embedded newlines.  Exception: lines
    beginning with '#' are not indented -- these are assumed to be
    C preprprocessor lines.
    """
    text = format % args
    if _Level > 0:
        indent = '\t' * _Level
        lines = text.split('\n')
        for i in range(len(lines)):
            if lines[i] and lines[i][0] != '#':
                lines[i] = indent + lines[i]
        text = '\n'.join(lines)
    _File.write(text + '\n')

def IndentLevel(by = 1):
    """Increment the indentation level by one.

    When called with an argument, adds it to the indentation level.
    """
    global _Level
    if _Level+by < 0:
        raise Error, "indentation underflow (internal error)"
    _Level = _Level + by

def DedentLevel(by = 1):
    """Decrement the indentation level by one.

    When called with an argument, subtracts it from the indentation level.
    """
    IndentLevel(-by)

def OutIndent(format = "", *args):
    """Combine Output() followed by IndentLevel().

    If no text is given, acts like lone IndentLevel().
    """
    if format: VaOutput(format, args)
    IndentLevel()

def OutDedent(format = "", *args):
    """Combine Output() followed by DedentLevel().

    If no text is given, acts like loneDedentLevel().
    """
    if format: VaOutput(format, args)
    DedentLevel()

def OutLbrace(format = "", *args):
    """Like Output, but add a '{' and increase the indentation level.

    If no text is given a lone '{' is output.
    """
    if format:
        format = format + " {"
    else:
        format = "{"
    VaOutput(format, args)
    IndentLevel()

def OutRbrace():
    """Decrease the indentation level and output a '}' on a line by itself."""
    DedentLevel()
    Output("}")

def OutHeader(text, dash):
    """Output a header comment using a given dash character."""
    n = 64 - len(text)
    Output()
    Output("/* %s %s %s */", dash * (n/2), text, dash * (n - n/2))
    Output()

def OutHeader1(text):
    """Output a level 1 header comment (uses '=' dashes)."""
    OutHeader(text, "=")

def OutHeader2(text):
    """Output a level 2 header comment (uses '-' dashes)."""
    OutHeader(text, "-")

def Out(text):
    """Output multiline text that's internally indented.

    Pass this a multiline character string.  The whitespace before the
    first nonblank line of the string will be subtracted from all lines.
    The lines are then output using Output(), but without interpretation
    of formatting (if you need formatting you can do it before the call).
    Recommended use:

        Out('''
            int main(argc, argv)
                int argc;
                char *argv;
            {
                printf("Hello, world\\n");
                exit(0);
            }
        ''')

    Caveat: the indentation must be consistent -- if you use three tabs
    in the first line, (up to) three tabs are removed from following lines,
    but a line beginning with 24 spaces is not trimmed at all.  Don't use
    this as a feature.
    """
    # (Don't you love using triple quotes *inside* triple quotes? :-)

    lines = text.split('\n')
    indent = ""
    for line in lines:
        if line.strip():
            for c in line:
                if not c.isspace():
                    break
                indent = indent + c
            break
    n = len(indent)
    for line in lines:
        if line[:n] == indent:
            line = line[n:]
        else:
            for c in indent:
                if line[:1] <> c: break
                line = line[1:]
        VaOutput("%s", line)


def _test():
    """Test program.  Run when the module is run as a script."""
    OutHeader1("test bgenOutput")
    Out("""
        #include <Python.h>
        #include <stdio.h>

        main(argc, argv)
            int argc;
            char **argv;
        {
            int i;
    """)
    IndentLevel()
    Output("""\
/* Here are a few comment lines.
   Just to test indenting multiple lines.

   End of the comment lines. */
""")
    Output("for (i = 0; i < argc; i++)")
    OutLbrace()
    Output('printf("argv[%%d] = %%s\\n", i, argv[i]);')
    OutRbrace()
    Output("exit(0)")
    OutRbrace()
    OutHeader2("end test")

if __name__ == '__main__':
    _test()
