import sys, os

# Template used then the program is a GUI program
WINMAINTEMPLATE = """
#include <windows.h>

int WINAPI WinMain(
    HINSTANCE hInstance,      // handle to current instance
    HINSTANCE hPrevInstance,  // handle to previous instance
    LPSTR lpCmdLine,          // pointer to command line
    int nCmdShow              // show state of window
    )
{
    extern int Py_FrozenMain(int, char **);
    PyImport_FrozenModules = _PyImport_FrozenModules;
    return Py_FrozenMain(__argc, __argv);
}
"""

SERVICETEMPLATE = """
extern int PythonService_main(int, char **);

int main( int argc, char **argv)
{
    PyImport_FrozenModules = _PyImport_FrozenModules;
    return PythonService_main(argc, argv);
}
"""

subsystem_details = {
    # -s flag        : (C entry point template), (is it __main__?), (is it a DLL?)
    'console'        : (None,                    1,                 0),
    'windows'        : (WINMAINTEMPLATE,         1,                 0),
    'service'        : (SERVICETEMPLATE,         0,                 0),
    'com_dll'        : ("",                      0,                 1),
}

def get_custom_entry_point(subsystem):
    try:
        return subsystem_details[subsystem][:2]
    except KeyError:
        raise ValueError, "The subsystem %s is not known" % subsystem


def makemakefile(outfp, vars, files, target):
    save = sys.stdout
    try:
        sys.stdout = outfp
        realwork(vars, files, target)
    finally:
        sys.stdout = save

def realwork(vars, moddefns, target):
    version_suffix = "%r%r" % sys.version_info[:2]
    print "# Makefile for Microsoft Visual C++ generated by freeze.py script"
    print
    print 'target = %s' % target
    print 'pythonhome = %s' % vars['prefix']
    print
    print 'DEBUG=0 # Set to 1 to use the _d versions of Python.'
    print '!IF $(DEBUG)'
    print 'debug_suffix=_d'
    print 'c_debug=/Zi /Od /DDEBUG /D_DEBUG'
    print 'l_debug=/DEBUG'
    print 'temp_dir=Build\\Debug'
    print '!ELSE'
    print 'debug_suffix='
    print 'c_debug=/Ox'
    print 'l_debug='
    print 'temp_dir=Build\\Release'
    print '!ENDIF'
    print

    print '# The following line assumes you have built Python using the standard instructions'
    print '# Otherwise fix the following line to point to the library.'
    print 'pythonlib = "$(pythonhome)/pcbuild/python%s$(debug_suffix).lib"' % version_suffix
    print

    # We only ever write one "entry point" symbol - either
    # "main" or "WinMain".  Therefore, there is no need to
    # pass a subsystem switch to the linker as it works it
    # out all by itself.  However, the subsystem _does_ determine
    # the file extension and additional linker flags.
    target_link_flags = ""
    target_ext = ".exe"
    if subsystem_details[vars['subsystem']][2]:
        target_link_flags = "-dll"
        target_ext = ".dll"


    print "# As the target uses Python%s.dll, we must use this compiler option!" % version_suffix
    print "cdl = /MD"
    print
    print "all: $(target)$(debug_suffix)%s" % (target_ext)
    print

    print '$(temp_dir):'
    print '  if not exist $(temp_dir)\. mkdir $(temp_dir)'
    print

    objects = []
    libs = ["shell32.lib", "comdlg32.lib", "wsock32.lib", "user32.lib", "oleaut32.lib"]
    for moddefn in moddefns:
        print "# Module", moddefn.name
        for file in moddefn.sourceFiles:
            base = os.path.basename(file)
            base, ext = os.path.splitext(base)
            objects.append(base + ".obj")
            print '$(temp_dir)\%s.obj: "%s"' % (base, file)
            print "\t@$(CC) -c -nologo /Fo$* $(cdl) $(c_debug) /D BUILD_FREEZE",
            print '"-I$(pythonhome)/Include"  "-I$(pythonhome)/PC" \\'
            print "\t\t$(cflags) $(cdebug) $(cinclude) \\"
            extra = moddefn.GetCompilerOptions()
            if extra:
                print "\t\t%s \\" % (' '.join(extra),)
            print '\t\t"%s"' % file
            print

        # Add .lib files this module needs
        for modlib in moddefn.GetLinkerLibs():
            if modlib not in libs:
                libs.append(modlib)

    print "ADDN_LINK_FILES=",
    for addn in vars['addn_link']: print '"%s"' % (addn),
    print ; print

    print "OBJS=",
    for obj in objects: print '"$(temp_dir)\%s"' % (obj),
    print ; print

    print "LIBS=",
    for lib in libs: print '"%s"' % (lib),
    print ; print

    print "$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext)
    print "\tlink -out:$(target)$(debug_suffix)%s %s" % (target_ext, target_link_flags), "@<<"
    print "\t$(OBJS)"
    print "\t$(LIBS)"
    print "\t$(ADDN_LINK_FILES)"
    print "\t$(pythonlib) $(lcustom) $(l_debug)"
    print "\t$(resources)"
    print "<<"
    print
    print "clean:"
    print "\t-rm -f *.obj"
    print "\t-rm -f $(target).exe"
