"""Create an applet from a Python script.

This puts up a dialog asking for a Python source file ('TEXT').
The output is a file with the same name but its ".py" suffix dropped.
It is created by copying an applet template and then adding a 'PYC '
resource named __main__ containing the compiled, marshalled script.
"""


import sys
sys.stdout = sys.stderr

import os
import MacOS
try:
    import EasyDialogs
except ImportError:
    EasyDialogs = None
import buildtools
import getopt

if not sys.executable.startswith(sys.exec_prefix):
    # Oh, the joys of using a python script to bootstrap applicatin bundles
    # sys.executable points inside the current application bundle. Because this
    # path contains blanks (two of them actually) this path isn't usable on
    # #! lines. Reset sys.executable to point to the embedded python interpreter
    sys.executable = os.path.join(sys.prefix,
            'Resources/Python.app/Contents/MacOS/Python')

    # Just in case we're not in a framework:
    if not os.path.exists(sys.executable):
        sys.executable = os.path.join(sys.exec_prefix,  'bin/python')

def main():
    try:
        buildapplet()
    except buildtools.BuildError, detail:
        if EasyDialogs is None:
            print detail
        else:
            EasyDialogs.Message(detail)


def buildapplet():
    buildtools.DEBUG=1

    # Find the template
    # (there's no point in proceeding if we can't find it)

    template = buildtools.findtemplate()

    # Ask for source text if not specified in sys.argv[1:]

    if not sys.argv[1:]:
        if EasyDialogs is None:
            usage()
            sys.exit(1)

        filename = EasyDialogs.AskFileForOpen(message='Select Python source or applet:',
                typeList=('TEXT', 'APPL'))
        if not filename:
            return
        tp, tf = os.path.split(filename)
        if tf[-3:] == '.py':
            tf = tf[:-3]
        else:
            tf = tf + '.applet'
        dstfilename = EasyDialogs.AskFileForSave(message='Save application as:',
                savedFileName=tf)
        if not dstfilename: return
        cr, tp = MacOS.GetCreatorAndType(filename)
        if tp == 'APPL':
            buildtools.update(template, filename, dstfilename)
        else:
            buildtools.process(template, filename, dstfilename, 1)
    else:

        SHORTOPTS = "o:r:ne:v?PR"
        LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help", "python=", "destroot=")
        try:
            options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
        except getopt.error:
            usage()
        if options and len(args) > 1:
            sys.stderr.write("Cannot use options when specifying multiple input files")
            sys.exit(1)
        dstfilename = None
        rsrcfilename = None
        raw = 0
        extras = []
        verbose = None
        destroot = ''
        for opt, arg in options:
            if opt in ('-o', '--output'):
                dstfilename = arg
            elif opt in ('-r', '--resource'):
                rsrcfilename = arg
            elif opt in ('-n', '--noargv'):
                raw = 1
            elif opt in ('-e', '--extra'):
                if ':' in arg:
                    arg = arg.split(':')
                extras.append(arg)
            elif opt in ('-P', '--python'):
                # This is a very dirty trick. We set sys.executable
                # so that bundlebuilder will use this in the #! line
                # for the applet bootstrap.
                sys.executable = arg
            elif opt in ('-v', '--verbose'):
                verbose = Verbose()
            elif opt in ('-?', '--help'):
                usage()
            elif opt in ('-d', '--destroot'):
                destroot = arg
        # Loop over all files to be processed
        for filename in args:
            cr, tp = MacOS.GetCreatorAndType(filename)
            if tp == 'APPL':
                buildtools.update(template, filename, dstfilename)
            else:
                buildtools.process(template, filename, dstfilename, 1,
                        rsrcname=rsrcfilename, others=extras, raw=raw,
                        progress=verbose, destroot=destroot)

def usage():
    print "BuildApplet creates an application from a Python source file"
    print "Usage:"
    print "  BuildApplet     interactive, single file, no options"
    print "  BuildApplet src1.py src2.py ...   non-interactive multiple file"
    print "  BuildApplet [options] src.py    non-interactive single file"
    print "Options:"
    print "  --output o        Output file; default based on source filename, short -o"
    print "  --resource r      Resource file; default based on source filename, short -r"
    print "  --noargv          Build applet without drag-and-drop sys.argv emulation, short -n, OSX only"
    print "  --extra src[:dst] Extra file to put in .app bundle, short -e, OSX only"
    print "  --verbose         Verbose, short -v"
    print "  --help            This message, short -?"
    sys.exit(1)

class Verbose:
    """This class mimics EasyDialogs.ProgressBar but prints to stderr"""
    def __init__(self, *args):
        if args and args[0]:
            self.label(args[0])

    def set(self, *args):
        pass

    def inc(self, *args):
        pass

    def label(self, str):
        sys.stderr.write(str+'\n')

if __name__ == '__main__':
    main()
