
/****************************************************************************
 *                                                                         
 * VRML 2.0 to RW3.0 Converter
 * Copyright (C) 1997 Criterion Technologies
 *
 * Author  : Damian Scallan 
 *
 * Module  : AbstractNode.h
 *                                                                         
 * Purpose : Handles the intermediate abstract representation of a Vrml
 *          scene graph created by the parser, which is then used to convert
 *          to a specific form.
 *          
 *          The file contaions methods for AbstractNode's, AbstractFields &
 *          all the basic Vrml field types.
 *                                                                         
 ****************************************************************************/

#ifndef ABSTRACTNODE_H
#define ABSTRACTNODE_H

/****************************************************************************
 Includes
 */

#include "_rpvrml.h"
#include "llinklist.h"
#include "types.h"

/****************************************************************************
 Global Types
 */

/* all the following are used to represent the basic Vrml field types */

typedef RwBool sfbool;

typedef struct sfcolor sfcolor;
struct sfcolor
{
    RwReal r, g, b;
};

typedef RwReal sffloat;

typedef struct sfimage sfimage;
struct sfimage
{
    RwUInt16 width;
    RwUInt16 height;
    RwInt8 components;
    RwUInt8 *pixels;
};

typedef RwInt32 sfint32;

typedef struct sfrotation sfrotation;
struct sfrotation
{
    RwReal x, y, z, angle;
};

typedef RwChar *sfstring;

typedef double sftime;

typedef struct sfvec2f sfvec2f;
struct sfvec2f
{
    RwReal x, y;
};

typedef struct sfvec3f sfvec3f;
struct sfvec3f
{
    RwReal x, y, z;
};

#define FVLx

/* AbstractNode type */
typedef struct AbstractNode AbstractNode;
struct AbstractNode
{
    RwChar *name;
    RwChar *symName;
    RwInt32 Items;
    RwInt32 refCnt;
    RwInt32 lineNum; /* to be used for finding semantic script errors */
    VRMLBool userProto;
    LLinkList fields; /* of AbstractField */
    LLinkList eventIns; /* of AbstractEvent */
    LLinkList eventOuts; /* of AbstractEvent */
};

typedef union sfAny sfAny;
union sfAny
{
    sfbool *sfb;
    sfcolor *sfc;
    sffloat *sff;
    sfint32 *sfi32;
    sfimage *sfi;
    sfrotation *sfr;
    sfstring *sfs;
    sftime *sft;
    sfvec2f *sfv2;
    sfvec3f *sfv3;
    AbstractNode *sfnode;
    void *element;
};

typedef struct Field Field;
struct Field
{
    RwInt32 type;
    RwUInt16 refCnt;
    RwInt32 items;
    RwUInt16 elementSize;
    sfAny *fieldArray;
};

/* AbstractField type */
typedef struct AbstractField AbstractField;
struct AbstractField
{
    RwChar *name;
    RwInt32 type;
    RwInt32 Items;
    RwInt32 refCnt;
    RwInt32 lineNum; /* to be used for finding semantic script errors */
    Field *field;
};

typedef struct AbstractFieldII AbstractFieldII;
struct AbstractFieldII
{
    RwChar *name;
    Field *field;
};

typedef struct AbstractEvent AbstractEvent;
struct AbstractEvent
{
    RwChar *name;
    RwInt32 type;
    LLinkList eventRecList; /* of RouteRec */
};

typedef struct AbstractFieldInfo AbstractFieldInfo;
struct AbstractFieldInfo
{
    RwChar *name;
    RwInt32 type;
    RwInt32 lineNum;
};

typedef struct MFany MFany;
struct MFany
{
    RwInt32 refCnt;
    RwInt32 items;
    void *anyTypeArray;
};

typedef MFany SFany;

typedef struct MFvec3f MFvec3f;
struct MFvec3f
{
    RwInt32 refCnt;
    RwInt32 items;
    sfvec3f *sfvec3fArray;
};

typedef MFvec3f SFvec3f;

typedef struct MFfloat MFfloat;
struct MFfloat
{
    RwInt32 refCnt;
    RwInt32 items;
    sffloat *sfloatArray;
};

typedef MFfloat SFfloat;

typedef union FieldII FieldII;
union FieldII
{
    MFany mfanyClass;
    SFany sfanyClass;
    MFvec3f mfvec3fClass;
    SFvec3f sfvec3fClass;
    MFfloat mffloatClass;
    SFfloat sffloatClass;
};

typedef struct AbstractFieldIII AbstractFieldIII;
struct AbstractFieldIII
{
    RwChar *name;
    RwInt32 type;
    RwInt32 lineNum;
    Field *field;
};

/****************************************************************************
 Function prototypes
 */

#ifdef    __cplusplus
extern "C"
{
#endif         /* __cplusplus */

    RwBool AbstractNodeOpen(void);
    void AbstractNodeClose(void);
    RwBool AbstractNodePushBlockContext(void);
    RwBool AbstractNodePopBlockContext(void);

    AbstractNode *AbstractNode_Create(const RwChar *nm);
    RwBool AbstractNode_Destroy(AbstractNode *an);
    AbstractNode *AbstractNode_Copy(AbstractNode *an);
    AbstractNode *AbstractNode_AddRef(AbstractNode *an);
    RwBool AbstractNode_Print(AbstractNode *an);
    AbstractNode *AbstractNode_GetChildNode(AbstractNode *an, const RwChar *name);
    AbstractField *AbstractNode_GetAbstractField(AbstractNode *an, const RwChar *name);
    AbstractEvent *AbstractNode_GetAbstractEventIn(AbstractNode *an, const RwChar *name);
    AbstractEvent *AbstractNode_GetAbstractEventOut(AbstractNode *an, const RwChar *name);
    RwChar *AbstractNode_GetName(AbstractNode *an);
    RwChar *AbstractNode_GetSymName(AbstractNode *an);
    RwChar *AbstractNode_SetSymName(AbstractNode *an, const RwChar *sn);
    char *AbstractNode_GetBaseName(AbstractNode * an);

    AbstractField *AbstractField_Create(const RwChar *nm, RwInt32 type);
    RwBool AbstractField_Destroy(AbstractField *field);
    AbstractField *AbstractField_Copy(AbstractField *af, const RwChar *newName);
    AbstractField *AbstractField_AddRef(AbstractField *field);
    Field *AbstractField_GetField(AbstractField *af);

    AbstractEvent *AbstractEvent_Create(const RwChar *name, RwInt32 type);
    RwBool AbstractEvent_Destroy(AbstractEvent *ae);
    AbstractEvent *AbstractEvent_Copy(AbstractEvent *ae);

    AbstractNode *AbstractNodeTree_InstanceProto(AbstractNode *an);

    sfbool *sfbool_Create(void);
    RwBool sfbool_Destroy(sfbool *sfb);
    RwBool sfbool_Print(sfbool *sfb);

    sfcolor *sfcolor_Create(void);
    RwBool sfcolor_Destroy(sfcolor *sfc);
    RwBool sfcolor_Print(sfcolor *sfc);
    RwBool sfcolor_Compare(const sfcolor *sfcA, const sfcolor *sfcB);

    sffloat *sffloat_Create(void);
    RwBool sffloat_Destroy(sffloat *sff);
    RwBool sffloat_Print(sffloat *sff);

    sfimage *sfimage_Create(void);
    RwBool sfimage_Destroy(sfimage *sfim);
    RwBool sfimage_Print(sfimage *sfim);

    sfint32 *sfint32_Create(void);
    RwBool sfint32_Destroy(sfint32 *sfi);
    RwBool sfint32_Print(sfint32 *sfi);

    sfrotation *sfrotation_Create(void);
    RwBool sfrotation_Destroy(sfrotation *sfr);
    RwBool sfrotation_Print(sfrotation *sfr);

    sfstring *sfstring_Create(void);
    RwBool sfstring_Destroy(sfstring *sfs);
    RwBool sfstring_Print(sfstring *sfs);

    sftime *sftime_Create(void);
    RwBool sftime_Destroy(sftime *sft);
    RwBool sftime_Print(sftime *sft);

    sfvec2f *sfvec2f_Create(void);
    RwBool sfvec2f_Destroy(sfvec2f *sfv2);
    RwBool sfvec2f_Print(sfvec2f *sfv2);

    sfvec3f *sfvec3f_Create(void);
    RwBool sfvec3f_Destroy(sfvec3f *sfv3);
    RwBool sfvec3f_compare(const sfvec3f *sfv3A, const sfvec3f *sfv3B);
    RwBool sfvec3f_Print(sfvec3f *sfv3);
    sfvec3f *sfvec3f_Read(RwChar *text);

    Field *Field_Create(RwInt32 type);
    RwBool Field_Destroy(Field *field);
    RwBool Field_InitFormFieldList(Field *field, LLinkList *fieldValueList);
    RwInt32 Field_NumElements(Field *field);
    Field *Field_AddRef(Field *field);

#define Field_GetValue(field, i) (((field->fieldArray)[i]).element)

#define FieldSfbool_GetValue(field)     (field->fieldArray->sfb)
#define FieldSfcolor_GetValue(field)    (field->fieldArray->sfc)
#define FieldSffloat_GetValue(field)    (field->fieldArray->sff)
#define FieldSfint32_GetValue(field)    (field->fieldArray->sfi32)
#define FieldSfimage_GetValue(field)    (field->fieldArray->sfi)
#define FieldSfrotation_GetValue(field) (field->fieldArray->sfr)
#define FieldSfstring_GetValue(field)   (field->fieldArray->sfs)
#define FieldSftime_GetValue(field)     (field->fieldArray->sft)
#define FieldSfvec2f_GetValue(field)    (field->fieldArray->sfv2)
#define FieldSfvec3f_GetValue(field)    (field->fieldArray->sfv3)
#define FieldSfnode_GetValue(field)     (field->fieldArray->sfnode)

#define FieldMfcolor_GetValue(field, i)     (((field->fieldArray)[i]).sfc)
#define FieldMffloat_GetValue(field, i)     (((field->fieldArray)[i]).sff)
#define FieldMfint32_GetValue(field, i)     (((field->fieldArray)[i]).sfi32)
#define FieldMfrotation_GetValue(field, i)  (((field->fieldArray)[i]).sfr)
#define FieldMfstring_GetValue(field, i)    (((field->fieldArray)[i]).sfs)
#define FieldMfvec2f_GetValue(field, i)     (((field->fieldArray)[i]).sfv2)
#define FieldMfvec3f_GetValue(field, i)     (((field->fieldArray)[i]).sfv3)
#define FieldMfnode_GetValue(field, i)      (((field->fieldArray)[i]).sfnode)

#ifdef    __cplusplus
}
#endif         /* __cplusplus */

#endif         /* ABSTRACTNODE_H */
