#!/usr/bin/python

__version__ = "0.1"

import sys, os
try:
    import hachoir
except ImportError:
    sys.path.append(os.path.join(sys.path[0], '..'))
    import hachoir

from hachoir.error import error, info
from hachoir.cmd_line import (getHachoirOptions, getTerminalCharset,
    createParser, initHachoir)
from optparse import OptionGroup, OptionParser
from hachoir.stream import InputStreamError

def displayVersion(*args):
    print "Hachoir console version %s" % __version__
    print "Hachoir library version %s" % hachoir.__version__
    print
    print "Website: %s" % hachoir.website
    sys.exit(0)

def parseOptions():
    parser = OptionParser(usage="%prog [options] filename")

    common = OptionGroup(parser, "Console", "Option of console display/export")
    common.add_option("--no-curses", help="Disable use of curses output",
        action="store_true", default=False)
    common.add_option("--export-xml", help="Export in XML file",
        type="str", action="store", default=None)
    common.add_option("--max-depth", help="Maximum field depth",
        type="int", action="store", default=3)
    common.add_option("--no-value", help="Don't display field value",
        action="store_true", default=False)
    common.add_option("--no-size", help="Don't display field value",
        action="store_true", default=False)
    common.add_option("--abs-addr", help="Display absolute addresses (instead of relative)",
        action="store_true", default=False)
    common.add_option("--hex-addr", help="Display addresses in hexadecimal",
        action="store_true", default=False)
    common.add_option("--no-human", help="Disable smart display of sizes (ex: 4 KB)",
        action="store_true", default=False)
    common.add_option("--version", help="Display version and exit",
        action="callback", callback=displayVersion)
    parser.add_option_group(common)

    hachoir = getHachoirOptions(parser, console_ui=True)
    parser.add_option_group(hachoir)

    values, arguments = parser.parse_args()
    if len(arguments) != 1:
        parser.print_help()
        sys.exit(1)
    return values, arguments[0]

def exportXML(parser, filename, max_depth):
    from hachoir.export_xml import ExportXML
    export = ExportXML()
    ok = export(filename, parser, max_depth)
    if ok:
        print "Wrote output in file: %s" % filename
    return ok

def display(parser, values):
    if values.no_curses:
        from hachoir.ui.text.console_ui import displayFieldSet
    else:
        from hachoir.ui.text.curses_ui import displayFieldSet
    charset = getTerminalCharset()
    options = {
        "display-value": not(values.no_value),
        "display-size": not(values.no_size),
        "hex-address": values.hex_addr,
        "absolute-address": values.abs_addr,
        "human-size": not(values.no_human)
    }
    displayFieldSet(parser, charset, values.max_depth, options)
    return True

def main():
    # Parser options and initialize Hachoir
    values, filename = parseOptions()
    initHachoir(values)

    # Open file and create parser
    try:
        parser = createParser(filename)
    except InputStreamError, err:
        error("Unable to open file: %s" % err)
        sys.exit(1)
    if not parser:
        error("Unable to parse file: %s" % filename)
        sys.exit(1)

    # Prepare arguments
    if values.max_depth < 1:
        values.max_depth = None

    # XML export
    if values.export_xml:
        ok = exportXML(parser, values.export_xml, values.max_depth)
    else:
        ok = display(parser, values)
    if not ok:
        sys.exit(1)

if __name__ == "__main__":
    main()

