/**************************************************************************
 *{@C
 *      Copyright:      1988-2024 Paul Obermeier (obermeier@poSoft.de)
 *
 *      Module:         Utilities
 *      Filename:       UTT_VecTclIf.h
 *
 *      Author:         Paul Obermeier
 *
 *      Description:    Declaration of macros for using the Tcl wrapper
 *                      functions for the vector and matrix library.
 *
 *      Additional documentation:
 *                      None.
 *
 **************************************************************************/

#ifndef __UTT_VECTCLIF_H__
#define __UTT_VECTCLIF_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <tcl.h>
#include "UT_Compat.h"
#include "UTT_TclIf.h"

/* The get and set functions to access objects defined in the vector and matrix
   library from the Tcl interface.
*/
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetVec2D   (TCLPARAMLIST, Int32 n, UT_Vec2D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetVec3D   (TCLPARAMLIST, Int32 n, UT_Vec3D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetVec2D   (TCLPARAMLIST, Int32 n, const UT_Vec2D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetVec3D   (TCLPARAMLIST, Int32 n, const UT_Vec3D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetDVec2D  (TCLPARAMLIST, Int32 n, UT_DVec2D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetDVec3D  (TCLPARAMLIST, Int32 n, UT_DVec3D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetDVec2D  (TCLPARAMLIST, Int32 n, const UT_DVec2D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetDVec3D  (TCLPARAMLIST, Int32 n, const UT_DVec3D v);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetTfm2D   (TCLPARAMLIST, Int32 n, UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetTfm3D   (TCLPARAMLIST, Int32 n, UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetTfm2D   (TCLPARAMLIST, Int32 n, const UT_Tfm2D T);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetTfm3D   (TCLPARAMLIST, Int32 n, const UT_Tfm3D T);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetCoSys2D (TCLPARAMLIST, Int32 n, UT_CoSys2D *c);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_GetCoSys3D (TCLPARAMLIST, Int32 n, UT_CoSys3D *c);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetCoSys2D (TCLPARAMLIST, Int32 n, const UT_CoSys2D *c);
extern POIMG_IMPORT_EXPORT UT_Bool UTT_SetCoSys3D (TCLPARAMLIST, Int32 n, const UT_CoSys3D *c);

/* Macros for easy use of the UTT_GetVec2D and UTT_SetVec2D functions. */

#define UTT_GetFixGenericVec(func, p_num, var)                          \
    {                                                                   \
        if (((p_num) >= argc -1) ||                                     \
            (!func (clientData, interp, argc, argv, (p_num), (var)))) { \
            UTT_ReturnFalse ((p_num))                                   \
        }                                                               \
    }

#define UTT_GetFixVec2D(p_num, var)                                     \
        UTT_GetFixGenericVec (UTT_GetVec2D, (p_num), (var))

#define UTT_GetFixDVec2D(p_num, var)                                    \
        UTT_GetFixGenericVec (UTT_GetDVec2D, (p_num), (var))

#define UTT_GetOptVec2D(p_num, var, def)                                \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_VecCopy2D ((def), (var));                                \
        } else {                                                        \
            UTT_GetFixVec2D ((p_num), (var));                           \
        }                                                               \
    }

#define UTT_GetOptDVec2D(p_num, var, def)                               \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_DVecCopy2D ((def), (var));                               \
        } else {                                                        \
            UTT_GetFixDVec2D ((p_num), (var));                          \
        }                                                               \
    }

#define UTT_SetFixGenericVec(func, p_num, val)                          \
    {                                                                   \
        if (((p_num) >= argc -1) ||                                     \
            (!func (clientData, interp, argc, argv, (p_num), (val)))) { \
            UTT_ReturnFalse ((p_num))                                   \
        }                                                               \
    }

#define UTT_SetFixVec2D(p_num, val)                                     \
        UTT_SetFixGenericVec (UTT_SetVec2D, (p_num), (val))

#define UTT_SetFixDVec2D(p_num, val)                                    \
        UTT_SetFixGenericVec (UTT_SetDVec2D, (p_num), (val))

#define UTT_SetOptVec2D(p_num, val)                                     \
        UTT_SetOptGenericVec (UTT_SetVec2D, (p_num), (val))

#define UTT_SetOptDVec2D(p_num, val)                                    \
        UTT_SetOptGenericVec (UTT_SetDVec2D, (p_num), (val))

/* Macros for easy use of the UTT_GetVec3D and UTT_SetVec3D functions. */

#define UTT_GetFixVec3D(p_num, var)                                     \
        UTT_GetFixGenericVec (UTT_GetVec3D, (p_num), (var))

#define UTT_GetFixDVec3D(p_num, var)                                    \
        UTT_GetFixGenericVec (UTT_GetDVec3D, (p_num), (var))

#define UTT_GetOptVec3D(p_num, var, def)                                \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_VecCopy3D ((def), (var));                                \
        } else {                                                        \
            UTT_GetFixVec3D ((p_num), (var));                           \
        }                                                               \
    }

#define UTT_GetOptDVec3D(p_num, var, def)                               \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_DVecCopy3D ((def), (var));                               \
        } else {                                                        \
            UTT_GetFixDVec3D ((p_num), (var));                          \
        }                                                               \
    }

#define UTT_SetFixVec3D(p_num, val)                                     \
        UTT_SetFixGenericVec (UTT_SetVec3D, (p_num), (val))

#define UTT_SetFixDVec3D(p_num, val)                                    \
        UTT_SetFixGenericVec (UTT_SetDVec3D, (p_num), (val))

#define UTT_SetOptVec3D(p_num, val)                                     \
        UTT_SetOptGenericVec (UTT_SetVec3D, (p_num), (val))

#define UTT_SetOptDVec3D(p_num, val)                                    \
        UTT_SetOptGenericVec (UTT_SetDVec3D, (p_num), (val))

/* Macros for easy use of the UTT_GetTfm2D and UTT_SetTfm2D functions. */

#define UTT_GetFixTfm2D(p_num, var)                                     \
        UTT_GetFixGenericVec (UTT_GetTfm2D, (p_num), (var))

#define UTT_GetOptTfm2D(p_num, var, def)                                \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_TfmCopy2D ((def), (var));                                \
        } else {                                                        \
            UTT_GetFixTfm2D ((p_num), (var));                           \
        }                                                               \
    }

#define UTT_SetFixTfm2D(p_num, val)                                     \
        UTT_SetFixGenericVec (UTT_SetTfm2D, (p_num), (val))

#define UTT_SetOptTfm2D(p_num, val)                                     \
        UTT_SetOptGenericVec (UTT_SetTfm2D, (p_num), (val))

/* Macros for easy use of the UTT_GetTfm3D and UTT_SetTfm3D functions. */

#define UTT_GetFixTfm3D(p_num, var)                                     \
        UTT_GetFixGenericVec (UTT_GetTfm3D, (p_num), (var))

#define UTT_GetOptTfm3D(p_num, var, def)                                \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_TfmCopy3D ((def), (var));                                \
        } else {                                                        \
            UTT_GetFixTfm3D ((p_num), (var));                           \
        }                                                               \
    }

#define UTT_SetFixTfm3D(p_num, val)                                     \
        UTT_SetFixGenericVec (UTT_SetTfm3D, (p_num), (val))

#define UTT_SetOptTfm3D(p_num, val)                                     \
        UTT_SetOptGenericVec (UTT_SetTfm3D, (p_num), (val))

/* Macros for easy use of the UTT_GetCoSys2D and UTT_SetCoSys2D functions. */

#define UTT_GetFixCoSys2D(p_num, var)                                   \
        UTT_GetFixGenericVec (UTT_GetCoSys2D, (p_num), &(var))

#define UTT_GetOptCoSys2D(p_num, var, def)                              \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_VecCopy2D ((def)->off,    (var).off);                    \
            UT_VecCopy2D ((def)->ori[0], (var).ori[0]);                 \
            UT_VecCopy2D ((def)->ori[1], (var).ori[1]);                 \
        } else {                                                        \
            UTT_GetFixCoSys2D ((p_num), (var));                         \
        }                                                               \
    }

#define UTT_SetFixCoSys2D(p_num, val)                                   \
        UTT_SetFixGenericVec (UTT_SetCoSys2D, (p_num), &(val))

#define UTT_SetOptCoSys2D(p_num, val)                                   \
        UTT_SetOptGenericVec (UTT_SetCoSys2D, (p_num), &(val))

/* Macros for easy use of the UTT_GetCoSys3D and UTT_SetCoSys3D functions. */

#define UTT_GetFixCoSys3D(p_num, var)                                   \
        UTT_GetFixGenericVec (UTT_GetCoSys3D, (p_num), &(var))

#define UTT_GetOptCoSys3D(p_num, var, def)                              \
    {                                                                   \
        if ((p_num) >= argc -1) {                                       \
            UT_VecCopy3D ((def)->off,    (var).off);                    \
            UT_VecCopy3D ((def)->ori[0], (var).ori[0]);                 \
            UT_VecCopy3D ((def)->ori[1], (var).ori[1]);                 \
            UT_VecCopy3D ((def)->ori[2], (var).ori[2]);                 \
        } else {                                                        \
            UTT_GetFixCoSys3D ((p_num), (var));                         \
        }                                                               \
    }

#define UTT_SetFixCoSys3D(p_num, val)                                   \
        UTT_SetFixGenericVec (UTT_SetCoSys3D, (p_num), &(val))

#define UTT_SetOptCoSys3D(p_num, val)                                   \
        UTT_SetOptGenericVec (UTT_SetCoSys3D, (p_num), &(val))

extern POIMG_IMPORT_EXPORT int UTT_InitTclVecLib (Tcl_Interp *interp);

#ifdef __cplusplus
}
#endif

#endif /* __UTT_VECTCLIF_H__ */
