/**************************************************************************
 *{@C
 *      Copyright:      1988-2023 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UTT_TclLib.c
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    The configuration tables for the Tcl standard
 *                      library, a startup routine, and some data access
 *                      functions.
 *
 *      Exported functions:
 *                      UTT_InitTclLib
 *
 **************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "UT_Compat.h"

#include "UT_Const.h"
#include "UT_Macros.h"
#include "UT_Error.h"
#include "UT_Memory.h"
#include "UT_Crypt.h"

#include <tcl.h>

#include "UTT_Private.h"
#include "UTT_TclIf.h"

/*
 *      The configuration tables for the Tcl basic utilities library
 */

static UT_Bool
    initialized = UT_False;

/* All values in the right column of the constant tables are accessible via Tcl
   as global variables.  Ex.: set i $MAXINT
*/

static UTT_TclConstInt32 iconst[] = 
{
    {UT_True,               "ON"},
    {UT_False,              "OFF"},
    {MaxInt32,              "MAXINT"},
    {C_Sep,                 "DIRSEP"},
    {EOF,                   "EOF"}
};

static UTT_TclConstFloat64 fconst[] =
{
    {UT_PI,                 "PI"},
    {MinFloat32,            "MINFLOAT"},
    {MinNrmFloat32,         "MINNRMFLOAT"},
    {MaxFloat32,            "MAXFLOAT"},
    {Float32Prec,           "FLOATPREC"},
    {MinFloat64,            "MINDOUBLE"},
    {MinNrmFloat64,         "MINNRMDOUBLE"},
    {MaxFloat64,            "MAXDOUBLE"},
    {Float64Prec,           "DOUBLEPREC"}
};

static int SetInt32Global (Tcl_Interp *interp, char *varName, int value)
{
    char valStr[50];
    sprintf (valStr, "%d", value);
    if (!Tcl_SetVar (interp, varName, valStr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG))
        return TCL_ERROR;
    return TCL_OK;
}

static int SetFloat64Global (Tcl_Interp *interp, char *varName, Float64 value)
{
    char valStr[100];
    sprintf (valStr, "%.20g", value);
    if (!Tcl_SetVar (interp, varName, valStr, TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG))
        return TCL_ERROR;
    return TCL_OK;
}

static int CreateConstants (Tcl_Interp *interp)
{
    Int32 i;

    for (i=0; i< sizeof (iconst) / sizeof (UTT_TclConstInt32); i++) {
        if (SetInt32Global (interp, iconst[i].name, iconst[i].value) != TCL_OK) {
            return TCL_ERROR;
        }
    }
    for (i=0; i< sizeof (fconst) / sizeof (UTT_TclConstFloat64); i++) {
        if (SetFloat64Global (interp, fconst[i].name, fconst[i].value) != TCL_OK) {
            return TCL_ERROR;
        }
    }
    return TCL_OK;
}

int UTT_InitTclLib (Tcl_Interp *interp)
{
    if (initialized) {
        return TCL_OK;
    }
    Tcl_CreateCommand (interp, "memcheck", (Tcl_CmdProc *)UTT_MemCheck, 
                       (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
    CreateConstants (interp);
    initialized = UT_True;
    return TCL_OK;
}
