#!/usr/bin/env python
# *************************************************************
#  
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#  
#    http://www.apache.org/licenses/LICENSE-2.0
#  
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#  
# *************************************************************


import getopt
import os
import re
import sys
#
from srclexer import SrcLexer
from srcparser import SrcParser
from boxer import Boxer
# FIXME
from globals import *

def option_parser ():
    import optparse
    p = optparse.OptionParser ()

    p.usage = '''src2xml.py [OPTION]... SRC-FILE...'''

    examples = '''
Examples:
  src2xml.py --output-dir=. --post-process --ignore-includes zoom.src
  src2xml.py --dry-run -I svx/inc -I svx/source/dialog zoom.src
'''

    def format_examples (self):
        return examples

    if 'epilog' in  p.__dict__:
        p.formatter.format_epilog = format_examples
        p.epilog = examples
    else:
        p.formatter.format_description = format_examples
        p.description = examples

    p.description = '''OOo SRC To Layout XML Converter.

Convert OO.o's existing dialog resource files into XML layout files.
'''

    p.add_option ('-l', '--debug-lexer', action='store_true',
                  dest='debug_lexer', default=False,
                  help='debug lexer')

    p.add_option ('-p', '--debug-parser', action='store_true',
                  dest='debug_parser', default=False,
                  help='debug parser')

    p.add_option ('-m', '--debug-macro', action='store_true',
                  dest='debug_macro', default=False,
                  help='debug macro')

    p.add_option ('-n', '--dry-run', action='store_true',
                  dest='dry_run', default=False,
                  help='dry run')

    p.add_option ('-k', '--keep-going', action='store_true',
                  dest='keep_going', default=False,
                  help='continue after error')

    p.add_option ('-i', '--ignore-includes', action='store_true',
                  dest='ignore_includes', default=False,
                  help='ignore #include directives')

    p.add_option ('-I', '--include-dir', action='append',
                  dest='include_path',
                  default=[],
                  metavar='DIR',
                  help='append DIR to include path')

    def from_file (option, opt_str, value, parser):
        lst = getattr (parser.values, option.dest)
        lst += file (value).read ().split ('\n')
        setattr (parser.values, option.dest, lst)

    def from_path (option, opt_str, value, parser):
        lst = getattr (parser.values, option.dest)
        lst += value.split (':')
        setattr (parser.values, option.dest, lst)

    # Junk me?
    p.add_option ('--includes-from-file', action='callback', callback=from_file,
                  dest='include_path',
                  default=[],
                  type='string',
                  metavar='FILE',
                  help='append directory list from FILE to include path')

    p.add_option ('--include-path', action='callback', callback=from_path,
                  dest='include_path',
                  type='string',
                  default=[],
                  metavar='PATH',
                  help='append PATH to include path')

    p.add_option ('--only-expand-macros', action='store_true',
                  dest='only_expand_macros', default=False,
                  help='FIXME: better to say what NOT to expand?')

    p.add_option ('-o', '--output-dir', action='store',
                  dest='output_dir', default=None,
                  metavar='DIR',
                  help='Output to DIR')

    p.add_option ('-s', '--post-process', action='store_true',
                  dest='post_process', default=False,
                  help='post process output for use in Layout')

    p.add_option ('--stop-on-header', action='store_true',
                  dest='stopOnHeader', default=False,
                  help='FIXME: remove this?')

    return p


def convert (file_name, options):
    progress ("parsing %(file_name)s ..." % locals ())
    fullpath = os.path.abspath(file_name)
    if not os.path.isfile(fullpath):
        error("no such file", exit=True)

    ##options.include_path.append (os.path.dirname (fullpath))

    input = file (fullpath, 'r').read()
    lexer = SrcLexer(input, fullpath)
    lexer.expandHeaders = not options.ignore_includes
    lexer.includeDirs = options.include_path
    lexer.stopOnHeader = options.stopOnHeader
    lexer.debugMacro = options.debug_macro
    if options.debug_lexer:
        lexer.debug = True
        lexer.tokenize()
        progress ("-"*68 + "\n")
        progress ("** token dump\n")
        lexer.dumpTokens()
        progress ("** end of token dump\n")
        return

    # Tokenize it using lexer
    lexer.tokenize()

    parser = SrcParser(lexer.getTokens(), lexer.getDefines())
    parser.only_expand_macros = options.only_expand_macros
    if options.debug_parser:
        parser.debug = True
        root = parser.parse()
        s = root.dump()
        return s

    # Parse the tokens.
    root = parser.parse()

    # Box it, and return the XML tree.
    root = Boxer(root).layout()
    output = root.dump()
    if not options.dry_run:
        progress ("\n")
    return output

def dry_one_file (file_name, options):
    try:
        str = convert(file_name, options)
        progress ("  SUCCESS\n")
    except Exception as e:
        if options.keep_going:
            progress ("  FAILED\n")
        else:
            import traceback
            print(traceback.format_exc (None))
            raise e

def post_process (s):
    """Make output directly usable by layout module."""
    s = re.sub ('(</?)([a-z]+)-([a-z]+)-([a-z]+)', r'\1\2\3\4', s)
    s = re.sub ('(</?)([a-z]+)-([a-z]+)', r'\1\2\3', s)
    s = re.sub ('(<(checkbox|(cancel|help|ignore|ok|push|more|no|radio|reset|retry|yes)button|(fixed(info|text)))[^>]*) text=', r'\1 label=', s)
    s = re.sub (' (height|width|x|y)="[0-9]*"', '', s)
    s = re.sub (' (label|text|title)="', r' _\1="', s)
    s = re.sub ('&([^m][^p]*[^;]*)', r'&amp;\1', s)
    s = re.sub (' hide="(TRUE|true|1)"', ' show="false"', s)

    s = s.replace ('<modaldialog', '<modaldialog sizeable="true"')
    s = s.replace (' rid=', ' id=')
    s = s.replace (' border="true"', ' has_border="true"')
    s = s.replace (' def-button="true"', ' defbutton="true"')
    s = s.replace (' drop-down="', ' dropdown="')
    s = s.replace (' tab-stop="', ' tabstop="')
    return s

XML_HEADER = '''<?xml version="1.0" encoding="UTF-8"?>
<!-- This is a template.  i18n translation is not performed in-place;
     i18n translated XML files are generated from this template by
     transex3/layout/tralay.  !-->
'''

def do_one_file (file_name, options):
    str = XML_HEADER
    str += convert(file_name, options)
    str += '\n'

    if options.post_process:
        str = post_process (str)
    h = sys.stdout
    if options.output_dir:
        base = os.path.basename (file_name)
        root, ext = os.path.splitext (base)
        out_name = options.output_dir + '/' + root + '.xml'
        progress ("writing %(out_name)s ..." % locals ())
        h = file (out_name, 'w')
    h.write (str)
    h.flush ()
    progress ("\n")

def main ():
    p = option_parser ()
    (options, files) = option_parser ().parse_args ()
    if not files:
        p.error ("no input files")

    for f in files:
        if options.dry_run:
            dry_one_file (f, options)
        else:
            do_one_file (f, options)

if __name__ == '__main__':
    main ()
