/*
 * rbcInt.c --
 *
 *      This file constructs the basic functionality of the
 *      rbc commands.
 *
 * Copyright (c) 2009 Samuel Green, Nicholas Hudson, Stanton Sievers, Jarrod Stormo
 * All rights reserved.
 *
 * See "license.terms" for details.
 */

#include "rbcInt.h"

#ifndef RBC_LIBRARY
#ifdef WIN32
#define RBC_LIBRARY  "c:/Program Files/Tcl/lib/rbc"
#else
#define RBC_LIBRARY "unknown"
#endif
#endif

#ifdef WIN32
/*
 * Translation table between X gc functions and Win32 raster op modes.
 */

const int tkpWinRopModes[] = {
    R2_BLACK,			/* GXclear */
    R2_MASKPEN,			/* GXand */
    R2_MASKPENNOT,		/* GXandReverse */
    R2_COPYPEN,			/* GXcopy */
    R2_MASKNOTPEN,		/* GXandInverted */
    R2_NOT,			/* GXnoop */
    R2_XORPEN,			/* GXxor */
    R2_MERGEPEN,		/* GXor */
    R2_NOTMERGEPEN,		/* GXnor */
    R2_NOTXORPEN,		/* GXequiv */
    R2_NOT,			/* GXinvert */
    R2_MERGEPENNOT,		/* GXorReverse */
    R2_NOTCOPYPEN,		/* GXcopyInverted */
    R2_MERGENOTPEN,		/* GXorInverted */
    R2_NOTMASKPEN,		/* GXnand */
    R2_WHITE			/* GXset */
};

/*
 * Translation table between X gc functions and Win32 BitBlt op modes. Some of
 * the operations defined in X don't have names, so we have to construct new
 * opcodes for those functions. This is arcane and probably not all that
 * useful, but at least it's accurate.
 */

const int tkpWinBltModes[] = {
    BLACKNESS,			/* GXclear */
    SRCAND,			/* GXand */
    SRCERASE,			/* GXandReverse */
    SRCCOPY,			/* GXcopy */
    NOTSRCAND,			/* GXandInverted */
    PATCOPY,			/* GXnoop */
    SRCINVERT,			/* GXxor */
    SRCPAINT,			/* GXor */
    NOTSRCERASE,		/* GXnor */
    NOTSRCINVERT,		/* GXequiv */
    DSTINVERT,			/* GXinvert */
    SRCORREVERSE,		/* GXorReverse */
    NOTSRCCOPY,			/* GXcopyInverted */
    MERGEPAINT,			/* GXorInverted */
    SRCNAND,			/* GXnand */
    WHITENESS			/* GXset */
};

/*
 *----------------------------------------------------------------------
 *
 * DllMain --
 *
 *      This wrapper function is used by Windows to invoke the
 *      initialization code for the DLL.
 *
 * Results:
 *      Returns TRUE;
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
BOOL APIENTRY
DllMain(
    HINSTANCE hInst,      	/* Library instance handle. */
    DWORD reason,		    /* Reason this function is being called. */
    LPVOID reserved)		/* Not used. */
{
    return TRUE;
}

/*
 *----------------------------------------------------------------------
 *
 * DllEntryPoint --
 *
 *      TODO: Description
 *
 * Results:
 *      Returns the result from DllMain.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
BOOL APIENTRY
DllEntryPoint(hInst, reason, reserved)
    HINSTANCE hInst;            /* Library instance handle. */
    DWORD reason;               /* Reason this function is being called. */
    LPVOID reserved;            /* Not used. */
{
    return DllMain(hInst, reason, reserved);
}
#endif /* WIN32 */

/*
 * -----------------------------------------------------------------------
 *
 * Rbc_Init --
 *
 *      This procedure is invoked to initialize the "rbc" commands.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      Creates the new commands and adds a new entry into a global Tcl
 *      associative array.
 *
 * ------------------------------------------------------------------------
 */
int DLLEXPORT
Rbc_Init (interp)
    Tcl_Interp *interp; /* Base interpreter to return results to. */
{
    if (Tcl_InitStubs(interp, MIN_VERSION, 0) == NULL) {
        return TCL_ERROR;
    }

    if (Tk_InitStubs(interp, MIN_VERSION, 0) == NULL) {
        return TCL_ERROR;
    }

    if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION) == TCL_ERROR) {
        return TCL_ERROR;
    }

    Tcl_Namespace *nsPtr;
    nsPtr = Tcl_CreateNamespace(interp, "rbc", NULL, NULL);
    if (nsPtr == NULL) {
	    return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "vector", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "graph", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "stripchart", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "barchart", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "busy", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "winop", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    if (Tcl_Export(interp, nsPtr, "spline", 0) != TCL_OK) {
        return TCL_ERROR;
    }

    Rbc_VectorInit(interp);
    Rbc_GraphInit(interp);
    Rbc_WinopInit(interp);
    Rbc_BusyInit(interp);
    Rbc_InitEpsCanvasItem(interp);
    Rbc_SplineInit(interp);

    return TCL_OK;
}
