/* tclembed.c - Copyright (C) 2003-2008 Pat Thoyts <patthoyts@users.sourceforge.net>
 *
 * Sample of an embedded Tcl application linked using the Tcl stubs mechanism
 * as seen at http://wiki.tcl.tk/2074.
 *
 * This version demonstrates linking to the stardll (ActiveTcl calls it a
 * basekit DLL) which is a TclKit presented as a DLL.
 *
 * ----------------------------------------------------------------------
 * This source code is public domain.
 * ----------------------------------------------------------------------
 *
 * $Id$
 */

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#ifndef USE_TCL_STUBS
#define USE_TCL_STUBS
#endif
#include <tcl.h>

static Tcl_Interp *InitializeTcl(const char *dllname,int argc, char *args[]);

int
main(int argc, char *argv[])
{
    Tcl_Interp *interp;
    int r = TCL_OK;
    
    interp = InitializeTcl("basekit.dll", argc, argv);
    if (interp == NULL) {
        fprintf(stderr, "error: failed to initialize Tcl runtime\n");
    } else {
        if (argc > 1) {
            r = Tcl_EvalFile(interp, argv[1]);
            printf(Tcl_GetStringResult(interp));
        }
        Tcl_DeleteInterp(interp);
    }
    
    return r;
}

typedef Tcl_Interp * (*LPFNCREATEINTERP) ();
typedef int          (*LPFNBASEKITINIT)  (Tcl_Interp *);
typedef char *       (*LPFNSETKITPATH)   (char *);

Tcl_Interp *
InitializeTcl(const char *dllname, int argc, char *argv[])
{
    TCHAR szLibrary[MAX_PATH];
    HINSTANCE hTcl = NULL;
    Tcl_Interp *interp = NULL;
    
    hTcl = LoadLibraryA(dllname);
    if (hTcl != NULL) {

        LPFNCREATEINTERP lpfnCreateInterp = (LPFNCREATEINTERP)GetProcAddress(hTcl, "Tcl_CreateInterp");
        LPFNBASEKITINIT lpfnBasekitInit = (LPFNBASEKITINIT)GetProcAddress(hTcl, "TclKit_AppInit");
        LPFNSETKITPATH lpfnSetKitPath  = (LPFNSETKITPATH)GetProcAddress(hTcl, "TclKit_SetKitPath");

        if (lpfnCreateInterp != NULL && lpfnBasekitInit != NULL  && lpfnSetKitPath != NULL) 
        {
            interp = lpfnCreateInterp();
            if (interp != NULL) {
                Tcl_InitStubs(interp, "8.4", 0);
                Tcl_FindExecutable(argv[0]);
                GetModuleFileNameA(hTcl, szLibrary, MAX_PATH);
                lpfnSetKitPath(szLibrary);
                if (lpfnBasekitInit(interp) == TCL_OK) {
                    Tcl_InitMemory(interp);
                } else {
                    fprintf(stderr, "TclKit_AppInit: %s\n", Tcl_GetStringResult(interp));
                }
            }
        }
    }
    return interp;
}
