#!/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, 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 ()
